]> git.donarmstrong.com Git - bamtools.git/blob - BGZF.h
Added support for reading FASTA sequences, as well as generating FASTA index (.fai...
[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: 9 July 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     // ---------------------------------\r
69     // data members\r
70     \r
71     unsigned int UncompressedBlockSize;\r
72     unsigned int CompressedBlockSize;\r
73     unsigned int BlockLength;\r
74     unsigned int BlockOffset;\r
75     uint64_t BlockAddress;\r
76     bool     IsOpen;\r
77     bool     IsWriteOnly;\r
78     FILE*    Stream;\r
79     char*    UncompressedBlock;\r
80     char*    CompressedBlock;\r
81 \r
82     // ---------------------------------\r
83     // constructor & destructor\r
84     \r
85     BgzfData(void);\r
86     ~BgzfData(void);\r
87 \r
88     // ---------------------------------\r
89     // main interface methods\r
90     \r
91     // closes BGZF file\r
92     void Close(void);\r
93     // opens the BGZF file (mode is either "rb" for reading, or "wb" for writing)\r
94     bool Open(const std::string& filename, const char* mode);\r
95     // reads BGZF data into a byte buffer\r
96     int Read(char* data, const unsigned int dataLength);\r
97     // seek to position in BGZF file\r
98     bool Seek(int64_t position);\r
99     // get file position in BGZF file\r
100     int64_t Tell(void);\r
101     // writes the supplied data into the BGZF buffer\r
102     unsigned int Write(const char* data, const unsigned int dataLen);\r
103 \r
104     // ---------------------------------\r
105     // internal methods\r
106     \r
107     // compresses the current block\r
108     int DeflateBlock(void);\r
109     // flushes the data in the BGZF block\r
110     void FlushBlock(void);\r
111     // de-compresses the current block\r
112     int InflateBlock(const int& blockLength);\r
113     // reads a BGZF block\r
114     bool ReadBlock(void);\r
115     \r
116     // ---------------------------------\r
117     // static 'utility' methods\r
118     \r
119     // checks BGZF block header\r
120     static inline bool CheckBlockHeader(char* header);\r
121     // packs an unsigned integer into the specified buffer\r
122     static inline void PackUnsignedInt(char* buffer, unsigned int value);\r
123     // packs an unsigned short into the specified buffer\r
124     static inline void PackUnsignedShort(char* buffer, unsigned short value);\r
125     // unpacks a buffer into a double\r
126     static inline double UnpackDouble(char* buffer);\r
127     static inline double UnpackDouble(const char* buffer);\r
128     // unpacks a buffer into a float\r
129     static inline float UnpackFloat(char* buffer);\r
130     static inline float UnpackFloat(const char* buffer);\r
131     // unpacks a buffer into a signed int\r
132     static inline signed int UnpackSignedInt(char* buffer);\r
133     static inline signed int UnpackSignedInt(const char* buffer);\r
134     // unpacks a buffer into a signed short\r
135     static inline signed short UnpackSignedShort(char* buffer);\r
136     static inline signed short UnpackSignedShort(const char* buffer);\r
137     // unpacks a buffer into an unsigned int\r
138     static inline unsigned int UnpackUnsignedInt(char* buffer);\r
139     static inline unsigned int UnpackUnsignedInt(const char* buffer);\r
140     // unpacks a buffer into an unsigned short\r
141     static inline unsigned short UnpackUnsignedShort(char* buffer);\r
142     static inline unsigned short UnpackUnsignedShort(const char* buffer);\r
143 };\r
144 \r
145 // -------------------------------------------------------------\r
146 // static 'utility' method implementations\r
147 \r
148 // checks BGZF block header\r
149 inline\r
150 bool BgzfData::CheckBlockHeader(char* header) {\r
151     return (header[0] == GZIP_ID1 &&\r
152             header[1] == (char)GZIP_ID2 &&\r
153             header[2] == Z_DEFLATED &&\r
154             (header[3] & FLG_FEXTRA) != 0 &&\r
155             BgzfData::UnpackUnsignedShort(&header[10]) == BGZF_XLEN &&\r
156             header[12] == BGZF_ID1 &&\r
157             header[13] == BGZF_ID2 &&\r
158             BgzfData::UnpackUnsignedShort(&header[14]) == BGZF_LEN );\r
159 }\r
160 \r
161 // 'packs' an unsigned integer into the specified buffer\r
162 inline\r
163 void BgzfData::PackUnsignedInt(char* buffer, unsigned int value) {\r
164     buffer[0] = (char)value;\r
165     buffer[1] = (char)(value >> 8);\r
166     buffer[2] = (char)(value >> 16);\r
167     buffer[3] = (char)(value >> 24);\r
168 }\r
169 \r
170 // 'packs' an unsigned short into the specified buffer\r
171 inline\r
172 void BgzfData::PackUnsignedShort(char* buffer, unsigned short value) {\r
173     buffer[0] = (char)value;\r
174     buffer[1] = (char)(value >> 8);\r
175 }\r
176 \r
177 // 'unpacks' a buffer into a double (includes both non-const & const char* flavors)\r
178 inline\r
179 double BgzfData::UnpackDouble(char* buffer) {\r
180     union { double value; unsigned char valueBuffer[sizeof(double)]; } un;\r
181     un.value = 0;\r
182     un.valueBuffer[0] = buffer[0];\r
183     un.valueBuffer[1] = buffer[1];\r
184     un.valueBuffer[2] = buffer[2];\r
185     un.valueBuffer[3] = buffer[3];\r
186     un.valueBuffer[4] = buffer[4];\r
187     un.valueBuffer[5] = buffer[5];\r
188     un.valueBuffer[6] = buffer[6];\r
189     un.valueBuffer[7] = buffer[7];\r
190     return un.value;\r
191 }\r
192 \r
193 inline\r
194 double BgzfData::UnpackDouble(const char* buffer) {\r
195     union { double value; unsigned char valueBuffer[sizeof(double)]; } un;\r
196     un.value = 0;\r
197     un.valueBuffer[0] = buffer[0];\r
198     un.valueBuffer[1] = buffer[1];\r
199     un.valueBuffer[2] = buffer[2];\r
200     un.valueBuffer[3] = buffer[3];\r
201     un.valueBuffer[4] = buffer[4];\r
202     un.valueBuffer[5] = buffer[5];\r
203     un.valueBuffer[6] = buffer[6];\r
204     un.valueBuffer[7] = buffer[7];\r
205     return un.value;\r
206 }\r
207 \r
208 // 'unpacks' a buffer into a float (includes both non-const & const char* flavors)\r
209 inline\r
210 float BgzfData::UnpackFloat(char* buffer) {\r
211     union { float value; unsigned char valueBuffer[sizeof(float)]; } un;\r
212     un.value = 0;\r
213     un.valueBuffer[0] = buffer[0];\r
214     un.valueBuffer[1] = buffer[1];\r
215     un.valueBuffer[2] = buffer[2];\r
216     un.valueBuffer[3] = buffer[3];\r
217     return un.value;\r
218 }\r
219 \r
220 inline\r
221 float BgzfData::UnpackFloat(const char* buffer) {\r
222     union { float value; unsigned char valueBuffer[sizeof(float)]; } un;\r
223     un.value = 0;\r
224     un.valueBuffer[0] = buffer[0];\r
225     un.valueBuffer[1] = buffer[1];\r
226     un.valueBuffer[2] = buffer[2];\r
227     un.valueBuffer[3] = buffer[3];\r
228     return un.value;\r
229 }\r
230 \r
231 // 'unpacks' a buffer into a signed int (includes both non-const & const char* flavors)\r
232 inline\r
233 signed int BgzfData::UnpackSignedInt(char* buffer) {\r
234     union { signed int value; unsigned char valueBuffer[sizeof(signed int)]; } un;\r
235     un.value = 0;\r
236     un.valueBuffer[0] = buffer[0];\r
237     un.valueBuffer[1] = buffer[1];\r
238     un.valueBuffer[2] = buffer[2];\r
239     un.valueBuffer[3] = buffer[3];\r
240     return un.value;\r
241 }\r
242 \r
243 inline\r
244 signed int BgzfData::UnpackSignedInt(const char* buffer) {\r
245     union { signed int value; unsigned char valueBuffer[sizeof(signed int)]; } un;\r
246     un.value = 0;\r
247     un.valueBuffer[0] = buffer[0];\r
248     un.valueBuffer[1] = buffer[1];\r
249     un.valueBuffer[2] = buffer[2];\r
250     un.valueBuffer[3] = buffer[3];\r
251     return un.value;\r
252 }\r
253 \r
254 // 'unpacks' a buffer into a signed short (includes both non-const & const char* flavors)\r
255 inline\r
256 signed short BgzfData::UnpackSignedShort(char* buffer) {\r
257     union { signed short value; unsigned char valueBuffer[sizeof(signed short)]; } un;\r
258     un.value = 0;\r
259     un.valueBuffer[0] = buffer[0];\r
260     un.valueBuffer[1] = buffer[1];\r
261     return un.value;\r
262 }\r
263 \r
264 inline\r
265 signed short BgzfData::UnpackSignedShort(const char* buffer) {\r
266     union { signed short value; unsigned char valueBuffer[sizeof(signed short)]; } un;\r
267     un.value = 0;\r
268     un.valueBuffer[0] = buffer[0];\r
269     un.valueBuffer[1] = buffer[1];\r
270     return un.value;\r
271 }\r
272 \r
273 // 'unpacks' a buffer into an unsigned int (includes both non-const & const char* flavors)\r
274 inline\r
275 unsigned int BgzfData::UnpackUnsignedInt(char* buffer) {\r
276     union { unsigned int value; unsigned char valueBuffer[sizeof(unsigned int)]; } un;\r
277     un.value = 0;\r
278     un.valueBuffer[0] = buffer[0];\r
279     un.valueBuffer[1] = buffer[1];\r
280     un.valueBuffer[2] = buffer[2];\r
281     un.valueBuffer[3] = buffer[3];\r
282     return un.value;\r
283 }\r
284 \r
285 inline\r
286 unsigned int BgzfData::UnpackUnsignedInt(const char* buffer) {\r
287     union { unsigned int value; unsigned char valueBuffer[sizeof(unsigned int)]; } un;\r
288     un.value = 0;\r
289     un.valueBuffer[0] = buffer[0];\r
290     un.valueBuffer[1] = buffer[1];\r
291     un.valueBuffer[2] = buffer[2];\r
292     un.valueBuffer[3] = buffer[3];\r
293     return un.value;\r
294 }\r
295 \r
296 // 'unpacks' a buffer into an unsigned short (includes both non-const & const char* flavors)\r
297 inline\r
298 unsigned short BgzfData::UnpackUnsignedShort(char* buffer) {\r
299     union { unsigned short value; unsigned char valueBuffer[sizeof(unsigned short)]; } un;\r
300     un.value = 0;\r
301     un.valueBuffer[0] = buffer[0];\r
302     un.valueBuffer[1] = buffer[1];\r
303     return un.value;\r
304 }\r
305 \r
306 inline\r
307 unsigned short BgzfData::UnpackUnsignedShort(const char* buffer) {\r
308     union { unsigned short value; unsigned char valueBuffer[sizeof(unsigned short)]; } un;\r
309     un.value = 0;\r
310     un.valueBuffer[0] = buffer[0];\r
311     un.valueBuffer[1] = buffer[1];\r
312     return un.value;\r
313 }\r
314 \r
315 } // namespace BamTools\r
316 \r
317 #endif // BGZF_H\r