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 bio2.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 import bio.bam.cigar;
34 import bio.bam.constants;
35 
36 import bio2.bgzf;
37 import bio2.bgzf_writer;
38 import bio2.constants;
39 
40 import bio2.bam.header;
41 import bio2.bam.reader : ProcessReadBlob, Offset;
42 
43 struct ModifyProcessReadBlob { // make this generic later
44   ProcessReadBlob _read2;
45 
46   @property ubyte[] toBlob() {
47     return _read2.toBlob();
48   }
49 
50   @property void set_qc_fail() {
51     auto data = _read2.toBlob;
52     // writeln(_read2._flag);
53     // data[Offset.flag_nc] = data[Offset.flag_nc] & 0x200;
54     // writeln(data[Offset.flag_nc]);
55     // buf.write!(T,Endian.littleEndian)(value,0);
56     //  ushort _flag()          { return fetch!ushort(Offset.flag); }
57 
58     ushort flag = _read2._flag | 0x200;
59     // writeln("flag=",flag);
60     data[Offset.flag..Offset.flag+4].write!(ushort,Endian.littleEndian)(flag,0);
61   }
62 }
63 
64 struct BamWriter {
65   BgzfWriter bgzf_writer;
66 
67   this(string fn, ref BamHeader header, int compression_level = -1) {
68     bgzf_writer = BgzfWriter(fn,compression_level);
69     write_bam_header(bgzf_writer,header);
70   }
71 
72   void push(ModifyProcessReadBlob read) {
73     auto mod = read;
74     auto blob = mod.toBlob;
75     // another hack for now:
76     bgzf_writer.write!int(cast(int)(blob.length+2*int.sizeof));
77     bgzf_writer.write!int(cast(int)mod._read2.raw_ref_id);
78     bgzf_writer.write!int(cast(int)mod._read2.raw_start_pos);
79     bgzf_writer.write(blob);
80   }
81 
82   void push(ProcessReadBlob read) {
83     push(ModifyProcessReadBlob(read));
84   }
85 
86 }