]> git.donarmstrong.com Git - bamtools.git/blob - BGZF.h
json output
[bamtools.git] / BGZF.h
1 // ***************************************************************************\r
2 // BGZF.h (c) 2009 Derek Barnett, Michael Str�mberg\r
3 // Marth Lab, Department of Biology, Boston College\r
4 // All rights reserved.\r
5 // ---------------------------------------------------------------------------\r
6 // Last modified: 11 January 2010 (DB)\r
7 // ---------------------------------------------------------------------------\r
8 // BGZF routines were adapted from the bgzf.c code developed at the Broad\r
9 // Institute.\r
10 // ---------------------------------------------------------------------------\r
11 // Provides the basic functionality for reading & writing BGZF files\r
12 // ***************************************************************************\r
13 \r
14 #ifndef BGZF_H\r
15 #define BGZF_H\r
16 \r
17 // 'C' includes\r
18 #include <cstdio>\r
19 #include <cstdlib>\r
20 #include <cstring>\r
21 \r
22 // C++ includes\r
23 #include <string>\r
24 \r
25 // zlib includes\r
26 #include "zlib.h"\r
27 \r
28 // Platform-specific type definitions\r
29 #ifndef BAMTOOLS_TYPES\r
30 #define BAMTOOLS_TYPES\r
31         #ifdef _MSC_VER\r
32                 typedef char                 int8_t;\r
33                 typedef unsigned char       uint8_t;\r
34                 typedef short               int16_t;\r
35                 typedef unsigned short     uint16_t;\r
36                 typedef int                 int32_t;\r
37                 typedef unsigned int       uint32_t;\r
38                 typedef long long           int64_t;\r
39                 typedef unsigned long long uint64_t;\r
40         #else\r
41                 #include <stdint.h>\r
42         #endif\r
43 #endif // BAMTOOLS_TYPES\r
44 \r
45 namespace BamTools {\r
46 \r
47 // zlib constants\r
48 const int GZIP_ID1   = 31;\r
49 const int GZIP_ID2   = 139;\r
50 const int CM_DEFLATE = 8;\r
51 const int FLG_FEXTRA = 4;\r
52 const int OS_UNKNOWN = 255;\r
53 const int BGZF_XLEN  = 6;\r
54 const int BGZF_ID1   = 66;\r
55 const int BGZF_ID2   = 67;\r
56 const int BGZF_LEN   = 2;\r
57 const int GZIP_WINDOW_BITS    = -15;\r
58 const int Z_DEFAULT_MEM_LEVEL = 8;\r
59 \r
60 // BZGF constants\r
61 const int BLOCK_HEADER_LENGTH = 18;\r
62 const int BLOCK_FOOTER_LENGTH = 8;\r
63 const int MAX_BLOCK_SIZE      = 65536;\r
64 const int DEFAULT_BLOCK_SIZE  = 65536;\r
65 \r
66 struct BgzfData {\r
67 \r
68     // data members\r
69     unsigned int UncompressedBlockSize;\r
70     unsigned int CompressedBlockSize;\r
71     unsigned int BlockLength;\r
72     unsigned int BlockOffset;\r
73     uint64_t BlockAddress;\r
74     bool     IsOpen;\r
75     bool     IsWriteOnly;\r
76     FILE*    Stream;\r
77     char*    UncompressedBlock;\r
78     char*    CompressedBlock;\r
79 \r
80     // constructor & destructor\r
81     BgzfData(void);\r
82     ~BgzfData(void);\r
83 \r
84     // closes BGZF file\r
85     void Close(void);\r
86     // compresses the current block\r
87     int DeflateBlock(void);\r
88     // flushes the data in the BGZF block\r
89     void FlushBlock(void);\r
90     // de-compresses the current block\r
91     int InflateBlock(const int& blockLength);\r
92     // opens the BGZF file for reading (mode is either "rb" for reading, or "wb" for writing\r
93     void Open(const std::string& filename, const char* mode);\r
94     // reads BGZF data into a byte buffer\r
95     int Read(char* data, const unsigned int dataLength);\r
96     // reads BGZF block\r
97     int ReadBlock(void);\r
98     // seek to position in BAM file\r
99     bool Seek(int64_t position);\r
100     // get file position in BAM file\r
101     int64_t Tell(void);\r
102     // writes the supplied data into the BGZF buffer\r
103     unsigned int Write(const char* data, const unsigned int dataLen);\r
104 \r
105     // checks BGZF block header\r
106     static inline bool CheckBlockHeader(char* header);\r
107     // packs an unsigned integer into the specified buffer\r
108     static inline void PackUnsignedInt(char* buffer, unsigned int value);\r
109     // packs an unsigned short into the specified buffer\r
110     static inline void PackUnsignedShort(char* buffer, unsigned short value);\r
111     \r
112     // unpacks a buffer into a signed int\r
113     static inline signed int UnpackSignedInt(char* buffer);\r
114     // unpacks a buffer into an unsigned int\r
115     static inline unsigned int UnpackUnsignedInt(char* buffer);\r
116     // unpacks a buffer into a signed short\r
117     static inline signed short UnpackSignedShort(char* buffer);\r
118     // unpacks a buffer into an unsigned short\r
119     static inline unsigned short UnpackUnsignedShort(char* buffer);\r
120     // unpacks a buffer into a double\r
121     static inline double UnpackDouble(char* buffer);\r
122     // unpacks a buffer into a float\r
123     static inline float UnpackFloat(char* buffer); \r
124     \r
125     // unpacks a buffer into a signed int\r
126     static inline signed int UnpackSignedInt(const char* buffer);\r
127     // unpacks a buffer into an unsigned int\r
128     static inline unsigned int UnpackUnsignedInt(const char* buffer);\r
129     // unpacks a buffer into a signed short\r
130     static inline signed short UnpackSignedShort(const char* buffer);\r
131     // unpacks a buffer into an unsigned short\r
132     static inline unsigned short UnpackUnsignedShort(const char* buffer);\r
133     // unpacks a buffer into a double\r
134     static inline double UnpackDouble(const char* buffer);\r
135     // unpacks a buffer into a float\r
136     static inline float UnpackFloat(const char* buffer); \r
137 };\r
138 \r
139 // -------------------------------------------------------------\r
140 \r
141 inline\r
142 bool BgzfData::CheckBlockHeader(char* header) {\r
143     return (header[0] == GZIP_ID1 &&\r
144             header[1] == (char)GZIP_ID2 &&\r
145             header[2] == Z_DEFLATED &&\r
146             (header[3] & FLG_FEXTRA) != 0 &&\r
147             BgzfData::UnpackUnsignedShort(&header[10]) == BGZF_XLEN &&\r
148             header[12] == BGZF_ID1 &&\r
149             header[13] == BGZF_ID2 &&\r
150             BgzfData::UnpackUnsignedShort(&header[14]) == BGZF_LEN );\r
151 }\r
152 \r
153 // 'packs' an unsigned integer into the specified buffer\r
154 inline\r
155 void BgzfData::PackUnsignedInt(char* buffer, unsigned int value) {\r
156     buffer[0] = (char)value;\r
157     buffer[1] = (char)(value >> 8);\r
158     buffer[2] = (char)(value >> 16);\r
159     buffer[3] = (char)(value >> 24);\r
160 }\r
161 \r
162 // 'packs' an unsigned short into the specified buffer\r
163 inline\r
164 void BgzfData::PackUnsignedShort(char* buffer, unsigned short value) {\r
165     buffer[0] = (char)value;\r
166     buffer[1] = (char)(value >> 8);\r
167 }\r
168 \r
169 // 'unpacks' a buffer into a signed int\r
170 inline\r
171 signed int BgzfData::UnpackSignedInt(char* buffer) {\r
172     union { signed int value; unsigned char valueBuffer[sizeof(signed int)]; } un;\r
173     un.value = 0;\r
174     un.valueBuffer[0] = buffer[0];\r
175     un.valueBuffer[1] = buffer[1];\r
176     un.valueBuffer[2] = buffer[2];\r
177     un.valueBuffer[3] = buffer[3];\r
178     return un.value;\r
179 }\r
180 \r
181 // 'unpacks' a buffer into an unsigned int\r
182 inline\r
183 unsigned int BgzfData::UnpackUnsignedInt(char* buffer) {\r
184     union { unsigned int value; unsigned char valueBuffer[sizeof(unsigned int)]; } un;\r
185     un.value = 0;\r
186     un.valueBuffer[0] = buffer[0];\r
187     un.valueBuffer[1] = buffer[1];\r
188     un.valueBuffer[2] = buffer[2];\r
189     un.valueBuffer[3] = buffer[3];\r
190     return un.value;\r
191 }\r
192 \r
193 // 'unpacks' a buffer into a signed short\r
194 inline\r
195 signed short BgzfData::UnpackSignedShort(char* buffer) {\r
196     union { signed short value; unsigned char valueBuffer[sizeof(signed short)]; } un;\r
197     un.value = 0;\r
198     un.valueBuffer[0] = buffer[0];\r
199     un.valueBuffer[1] = buffer[1];\r
200     return un.value;\r
201 }\r
202 \r
203 // 'unpacks' a buffer into an unsigned short\r
204 inline\r
205 unsigned short BgzfData::UnpackUnsignedShort(char* buffer) {\r
206     union { unsigned short value; unsigned char valueBuffer[sizeof(unsigned short)]; } un;\r
207     un.value = 0;\r
208     un.valueBuffer[0] = buffer[0];\r
209     un.valueBuffer[1] = buffer[1];\r
210     return un.value;\r
211 }\r
212 \r
213 // 'unpacks' a buffer into a double\r
214 inline\r
215 double BgzfData::UnpackDouble(char* buffer) {\r
216     union { double value; unsigned char valueBuffer[sizeof(double)]; } un;\r
217     un.value = 0;\r
218     un.valueBuffer[0] = buffer[0];\r
219     un.valueBuffer[1] = buffer[1];\r
220     un.valueBuffer[2] = buffer[2];\r
221     un.valueBuffer[3] = buffer[3];\r
222     un.valueBuffer[4] = buffer[4];\r
223     un.valueBuffer[5] = buffer[5];\r
224     un.valueBuffer[6] = buffer[6];\r
225     un.valueBuffer[7] = buffer[7];\r
226     return un.value;\r
227 }\r
228 \r
229 // 'unpacks' a buffer into a float\r
230 inline\r
231 float BgzfData::UnpackFloat(char* buffer) {\r
232     union { float value; unsigned char valueBuffer[sizeof(float)]; } un;\r
233     un.value = 0;\r
234     un.valueBuffer[0] = buffer[0];\r
235     un.valueBuffer[1] = buffer[1];\r
236     un.valueBuffer[2] = buffer[2];\r
237     un.valueBuffer[3] = buffer[3];\r
238     return un.value;\r
239 }\r
240 \r
241 // ---------\r
242 \r
243 // 'unpacks' a buffer into a signed int\r
244 inline\r
245 signed int BgzfData::UnpackSignedInt(const char* buffer) {\r
246     union { signed int value; unsigned char valueBuffer[sizeof(signed int)]; } un;\r
247     un.value = 0;\r
248     un.valueBuffer[0] = buffer[0];\r
249     un.valueBuffer[1] = buffer[1];\r
250     un.valueBuffer[2] = buffer[2];\r
251     un.valueBuffer[3] = buffer[3];\r
252     return un.value;\r
253 }\r
254 \r
255 // 'unpacks' a buffer into an unsigned int\r
256 inline\r
257 unsigned int BgzfData::UnpackUnsignedInt(const char* buffer) {\r
258     union { unsigned int value; unsigned char valueBuffer[sizeof(unsigned int)]; } un;\r
259     un.value = 0;\r
260     un.valueBuffer[0] = buffer[0];\r
261     un.valueBuffer[1] = buffer[1];\r
262     un.valueBuffer[2] = buffer[2];\r
263     un.valueBuffer[3] = buffer[3];\r
264     return un.value;\r
265 }\r
266 \r
267 // 'unpacks' a buffer into a signed short\r
268 inline\r
269 signed short BgzfData::UnpackSignedShort(const char* buffer) {\r
270     union { signed short value; unsigned char valueBuffer[sizeof(signed short)]; } un;\r
271     un.value = 0;\r
272     un.valueBuffer[0] = buffer[0];\r
273     un.valueBuffer[1] = buffer[1];\r
274     return un.value;\r
275 }\r
276 \r
277 // 'unpacks' a buffer into an unsigned short\r
278 inline\r
279 unsigned short BgzfData::UnpackUnsignedShort(const char* buffer) {\r
280     union { unsigned short value; unsigned char valueBuffer[sizeof(unsigned short)]; } un;\r
281     un.value = 0;\r
282     un.valueBuffer[0] = buffer[0];\r
283     un.valueBuffer[1] = buffer[1];\r
284     return un.value;\r
285 }\r
286 \r
287 // 'unpacks' a buffer into a double\r
288 inline\r
289 double BgzfData::UnpackDouble(const char* buffer) {\r
290     union { double value; unsigned char valueBuffer[sizeof(double)]; } un;\r
291     un.value = 0;\r
292     un.valueBuffer[0] = buffer[0];\r
293     un.valueBuffer[1] = buffer[1];\r
294     un.valueBuffer[2] = buffer[2];\r
295     un.valueBuffer[3] = buffer[3];\r
296     un.valueBuffer[4] = buffer[4];\r
297     un.valueBuffer[5] = buffer[5];\r
298     un.valueBuffer[6] = buffer[6];\r
299     un.valueBuffer[7] = buffer[7];\r
300     return un.value;\r
301 }\r
302 \r
303 // 'unpacks' a buffer into a float\r
304 inline\r
305 float BgzfData::UnpackFloat(const char* buffer) {\r
306     union { float value; unsigned char valueBuffer[sizeof(float)]; } un;\r
307     un.value = 0;\r
308     un.valueBuffer[0] = buffer[0];\r
309     un.valueBuffer[1] = buffer[1];\r
310     un.valueBuffer[2] = buffer[2];\r
311     un.valueBuffer[3] = buffer[3];\r
312     return un.value;\r
313 }\r
314 \r
315 } // namespace BamTools\r
316 \r
317 #endif // BGZF_H\r