1 /*
2     New style BAM writer. This file is part of Sambamba.
3     Copyright (C) 2017 Pjotr Prins <pjotr.prins@thebird.nl>
4 
5     Sambamba is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published
7     by the Free Software Foundation; either version 2 of the License,
8     or (at your option) any later version.
9 
10     Sambamba is distributed in the hope that it will be useful, but
11     WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18     02111-1307 USA
19 
20 */
21 
22 module bio.std.experimental.hts.bam.writer;
23 
24 import std.conv;
25 import core.stdc.stdio: fopen, fread, fclose;
26 import std.exception;
27 import std.file;
28 import std.stdio;
29 import std..string;
30 import std.typecons;
31 import std.bitmanip;
32 
33 
34 import bio.std.hts.bam.cigar; //depends on undead
35 import bio.std.hts.bam.constants;
36 
37 import bio.std.experimental.hts.bgzf;
38 import bio.std.experimental.hts.bgzf_writer;
39 import bio.std.experimental.hts.constants;
40 
41 import bio.std.experimental.hts.bam.header;
42 import bio.std.experimental.hts.bam.reader : ProcessReadBlob, Offset;
43 
44 struct ModifyProcessReadBlob { // make this generic later
45   ProcessReadBlob _read2;
46 
47   @property ubyte[] toBlob() {
48     return _read2.toBlob();
49   }
50 
51   @property void set_qc_fail() {
52     auto data = _read2.toBlob;
53     // writeln(_read2._flag);
54     // data[Offset.flag_nc] = data[Offset.flag_nc] & 0x200;
55     // writeln(data[Offset.flag_nc]);
56     // buf.write!(T,Endian.littleEndian)(value,0);
57     //  ushort _flag()          { return fetch!ushort(Offset.flag); }
58 
59     ushort flag = _read2._flag | 0x200;
60     // writeln("flag=",flag);
61     data[Offset.flag..Offset.flag+4].write!(ushort,Endian.littleEndian)(flag,0);
62   }
63 }
64 
65 struct BamWriter {
66   BgzfWriter bgzf_writer;
67 
68   this(string fn, ref BamHeader header, int compression_level = -1) {
69     bgzf_writer = BgzfWriter(fn,compression_level);
70     write_bam_header(bgzf_writer,header);
71   }
72 
73   void push(ModifyProcessReadBlob read) {
74     auto mod = read;
75     auto blob = mod.toBlob;
76     // another hack for now:
77     bgzf_writer.write!int(cast(int)(blob.length+2*int.sizeof));
78     bgzf_writer.write!int(cast(int)mod._read2.raw_ref_id);
79     bgzf_writer.write!int(cast(int)mod._read2.raw_start_pos);
80     bgzf_writer.write(blob);
81   }
82 
83   void push(ProcessReadBlob read) {
84     push(ModifyProcessReadBlob(read));
85   }
86 
87 }