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