]> git.donarmstrong.com Git - bamtools.git/blob - src/api/BamAux.h
29a0209c06951f2db13367098432b2d59c98b932
[bamtools.git] / src / api / BamAux.h
1 // ***************************************************************************\r
2 // BamAux.h (c) 2009 Derek Barnett, Michael Str�mberg\r
3 // Marth Lab, Department of Biology, Boston College\r
4 // ---------------------------------------------------------------------------\r
5 // Last modified: 10 October 2011 (DB)\r
6 // ---------------------------------------------------------------------------\r
7 // Provides data structures & utility methods that are used throughout the API.\r
8 // ***************************************************************************\r
9 \r
10 #ifndef BAMAUX_H\r
11 #define BAMAUX_H\r
12 \r
13 #include <api/api_global.h>\r
14 #include <fstream> \r
15 #include <iostream>\r
16 #include <string>\r
17 #include <vector>\r
18 \r
19 /*! \file BamAux.h\r
20 \r
21     Provides data structures & utility methods that are used throughout the API.\r
22 */\r
23 \r
24 /*! \namespace BamTools\r
25     \brief Contains all BamTools classes & methods.\r
26 \r
27     The BamTools API contained in this namespace contains classes and methods\r
28     for reading, writing, and manipulating BAM alignment files.\r
29 */\r
30 namespace BamTools {\r
31 \r
32 // ----------------------------------------------------------------\r
33 // CigarOp\r
34 \r
35 /*! \struct BamTools::CigarOp\r
36     \brief Represents a CIGAR alignment operation.\r
37 \r
38     \sa \samSpecURL for more details on using CIGAR operations.\r
39 */\r
40 struct API_EXPORT CigarOp {\r
41   \r
42     char     Type;   //!< CIGAR operation type (MIDNSHPX=)\r
43     uint32_t Length; //!< CIGAR operation length (number of bases)\r
44     \r
45     //! constructor\r
46     CigarOp(const char type = '\0', \r
47             const uint32_t& length = 0)\r
48         : Type(type)\r
49         , Length(length) \r
50     { }\r
51 };\r
52 \r
53 // ----------------------------------------------------------------\r
54 // RefData\r
55 \r
56 /*! \struct BamTools::RefData\r
57     \brief Represents a reference sequence entry\r
58 */\r
59 struct API_EXPORT RefData {\r
60    \r
61     std::string RefName;    //!< name of reference sequence\r
62     int32_t     RefLength;  //!< length of reference sequence\r
63     \r
64     //! constructor\r
65     RefData(const std::string& name = "",\r
66             const int32_t& length = 0)\r
67         : RefName(name)\r
68         , RefLength(length)\r
69     { }\r
70 };\r
71 \r
72 //! convenience typedef for vector of RefData entries\r
73 typedef std::vector<RefData> RefVector;\r
74 \r
75 // ----------------------------------------------------------------\r
76 // BamRegion\r
77 \r
78 /*! \struct BamTools::BamRegion\r
79     \brief Represents a sequential genomic region\r
80 \r
81     Allowed to span multiple (sequential) references.\r
82 \r
83     \warning BamRegion now represents a zero-based, HALF-OPEN interval.\r
84     In previous versions of BamTools (0.x & 1.x) all intervals were treated\r
85     as zero-based, CLOSED.\r
86 */\r
87 struct API_EXPORT BamRegion {\r
88   \r
89     int LeftRefID;      //!< reference ID for region's left boundary\r
90     int LeftPosition;   //!< position for region's left boundary\r
91     int RightRefID;     //!< reference ID for region's right boundary\r
92     int RightPosition;  //!< position for region's right boundary\r
93     \r
94     //! constructor\r
95     BamRegion(const int& leftID   = -1, \r
96               const int& leftPos  = -1,\r
97               const int& rightID  = -1,\r
98               const int& rightPos = -1)\r
99         : LeftRefID(leftID)\r
100         , LeftPosition(leftPos)\r
101         , RightRefID(rightID)\r
102         , RightPosition(rightPos)\r
103     { }\r
104     \r
105     //! copy constructor\r
106     BamRegion(const BamRegion& other)\r
107         : LeftRefID(other.LeftRefID)\r
108         , LeftPosition(other.LeftPosition)\r
109         , RightRefID(other.RightRefID)\r
110         , RightPosition(other.RightPosition)\r
111     { }\r
112     \r
113     //! Clears region boundaries\r
114     void clear(void) {\r
115         LeftRefID  = -1; LeftPosition  = -1;\r
116         RightRefID = -1; RightPosition = -1;\r
117     }\r
118 \r
119     //! Returns true if region has a left boundary\r
120     bool isLeftBoundSpecified(void) const {\r
121         return ( LeftRefID >= 0 && LeftPosition >= 0 );\r
122     }\r
123 \r
124     //! Returns true if region boundaries are not defined\r
125     bool isNull(void) const {\r
126         return ( !isLeftBoundSpecified() && !isRightBoundSpecified() );\r
127     }\r
128 \r
129     //! Returns true if region has a right boundary\r
130     bool isRightBoundSpecified(void) const {\r
131         return ( RightRefID >= 0 && RightPosition >= 1 );\r
132     }\r
133 };\r
134 \r
135 // ----------------------------------------------------------------\r
136 // General utility methods\r
137 \r
138 /*! \fn bool FileExists(const std::string& filename)\r
139     \brief returns true if the file exists\r
140 */\r
141 API_EXPORT inline bool FileExists(const std::string& filename) {\r
142     std::ifstream f(filename.c_str(), std::ifstream::in);\r
143     return !f.fail();\r
144 }\r
145 \r
146 /*! \fn void SwapEndian_16(int16_t& x)\r
147     \brief swaps endianness of signed 16-bit integer, in place\r
148 */\r
149 API_EXPORT inline void SwapEndian_16(int16_t& x) {\r
150     x = ((x >> 8) | (x << 8));\r
151 }\r
152 \r
153 /*! \fn void SwapEndian_16(uint16_t& x)\r
154     \brief swaps endianness of unsigned 16-bit integer, in place\r
155 */\r
156 API_EXPORT inline void SwapEndian_16(uint16_t& x) {\r
157     x = ((x >> 8) | (x << 8));\r
158 }\r
159 \r
160 /*! \fn void SwapEndian_32(int32_t& x)\r
161     \brief swaps endianness of signed 32-bit integer, in place\r
162 */\r
163 API_EXPORT inline void SwapEndian_32(int32_t& x) {\r
164     x = ( (x >> 24) | \r
165          ((x << 8) & 0x00FF0000) | \r
166          ((x >> 8) & 0x0000FF00) | \r
167           (x << 24)\r
168         );\r
169 }\r
170 \r
171 /*! \fn void SwapEndian_32(uint32_t& x)\r
172     \brief swaps endianness of unsigned 32-bit integer, in place\r
173 */\r
174 API_EXPORT inline void SwapEndian_32(uint32_t& x) {\r
175     x = ( (x >> 24) | \r
176          ((x << 8) & 0x00FF0000) | \r
177          ((x >> 8) & 0x0000FF00) | \r
178           (x << 24)\r
179         );\r
180 }\r
181 \r
182 /*! \fn void SwapEndian_64(int64_t& x)\r
183     \brief swaps endianness of signed 64-bit integer, in place\r
184 */\r
185 API_EXPORT inline void SwapEndian_64(int64_t& x) {\r
186     x = ( (x >> 56) | \r
187          ((x << 40) & 0x00FF000000000000ll) |\r
188          ((x << 24) & 0x0000FF0000000000ll) |\r
189          ((x << 8)  & 0x000000FF00000000ll) |\r
190          ((x >> 8)  & 0x00000000FF000000ll) |\r
191          ((x >> 24) & 0x0000000000FF0000ll) |\r
192          ((x >> 40) & 0x000000000000FF00ll) |\r
193           (x << 56)\r
194         );\r
195 }\r
196 \r
197 /*! \fn void SwapEndian_64(uint64_t& x)\r
198     \brief swaps endianness of unsigned 64-bit integer, in place\r
199 */\r
200 API_EXPORT inline void SwapEndian_64(uint64_t& x) {\r
201     x = ( (x >> 56) | \r
202          ((x << 40) & 0x00FF000000000000ll) |\r
203          ((x << 24) & 0x0000FF0000000000ll) |\r
204          ((x << 8)  & 0x000000FF00000000ll) |\r
205          ((x >> 8)  & 0x00000000FF000000ll) |\r
206          ((x >> 24) & 0x0000000000FF0000ll) |\r
207          ((x >> 40) & 0x000000000000FF00ll) |\r
208           (x << 56)\r
209         );\r
210 }\r
211 \r
212 /*! \fn void SwapEndian_16p(char* data)\r
213     \brief swaps endianness of the next 2 bytes in a buffer, in place\r
214 */\r
215 API_EXPORT inline void SwapEndian_16p(char* data) {\r
216     uint16_t& value = (uint16_t&)*data; \r
217     SwapEndian_16(value);\r
218 }\r
219 \r
220 /*! \fn void SwapEndian_32p(char* data)\r
221     \brief swaps endianness of the next 4 bytes in a buffer, in place\r
222 */\r
223 API_EXPORT inline void SwapEndian_32p(char* data) {\r
224     uint32_t& value = (uint32_t&)*data; \r
225     SwapEndian_32(value);\r
226 }\r
227 \r
228 /*! \fn void SwapEndian_64p(char* data)\r
229     \brief swaps endianness of the next 8 bytes in a buffer, in place\r
230 */\r
231 API_EXPORT inline void SwapEndian_64p(char* data) {\r
232     uint64_t& value = (uint64_t&)*data; \r
233     SwapEndian_64(value);\r
234 }\r
235 \r
236 /*! \fn bool SystemIsBigEndian(void)\r
237     \brief checks host architecture's byte order\r
238     \return \c true if system uses big-endian ordering\r
239 */\r
240 API_EXPORT inline bool SystemIsBigEndian(void) {\r
241    const uint16_t one = 0x0001;\r
242    return ((*(char*) &one) == 0 );\r
243 }\r
244 \r
245 /*! \fn void PackUnsignedInt(char* buffer, unsigned int value)\r
246     \brief stores unsigned integer value in a byte buffer\r
247 \r
248     \param[out] buffer destination buffer\r
249     \param[in]  value  value to 'pack' in buffer\r
250 */\r
251 API_EXPORT inline void PackUnsignedInt(char* buffer, unsigned int value) {\r
252     buffer[0] = (char)value;\r
253     buffer[1] = (char)(value >> 8);\r
254     buffer[2] = (char)(value >> 16);\r
255     buffer[3] = (char)(value >> 24);\r
256 }\r
257 \r
258 /*! \fn void PackUnsignedShort(char* buffer, unsigned short value)\r
259     \brief stores unsigned short integer value in a byte buffer\r
260 \r
261     \param[out] buffer destination buffer\r
262     \param[in]  value  value to 'pack' in buffer\r
263 */\r
264 API_EXPORT inline void PackUnsignedShort(char* buffer, unsigned short value) {\r
265     buffer[0] = (char)value;\r
266     buffer[1] = (char)(value >> 8);\r
267 }\r
268 \r
269 /*! \fn double UnpackDouble(const char* buffer)\r
270     \brief reads a double value from byte buffer\r
271 \r
272     \param[in] buffer source byte buffer\r
273     \return the (double) value read from the buffer\r
274 */\r
275 API_EXPORT inline double UnpackDouble(const char* buffer) {\r
276     union { double value; unsigned char valueBuffer[sizeof(double)]; } 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     un.valueBuffer[4] = buffer[4];\r
283     un.valueBuffer[5] = buffer[5];\r
284     un.valueBuffer[6] = buffer[6];\r
285     un.valueBuffer[7] = buffer[7];\r
286     return un.value;\r
287 }\r
288 \r
289 /*! \fn double UnpackDouble(char* buffer)\r
290     \brief reads a double value from byte buffer\r
291 \r
292     This is an overloaded function.\r
293 \r
294     \param[in] buffer source byte buffer\r
295     \return the (double) value read from the buffer\r
296 */\r
297 API_EXPORT inline double UnpackDouble(char* buffer) {\r
298     return UnpackDouble( (const char*)buffer );\r
299 }\r
300 \r
301 /*! \fn double UnpackFloat(const char* buffer)\r
302     \brief reads a float value from byte buffer\r
303 \r
304     \param[in] buffer source byte buffer\r
305     \return the (float) value read from the buffer\r
306 */\r
307 API_EXPORT inline float UnpackFloat(const char* buffer) {\r
308     union { float value; unsigned char valueBuffer[sizeof(float)]; } un;\r
309     un.value = 0;\r
310     un.valueBuffer[0] = buffer[0];\r
311     un.valueBuffer[1] = buffer[1];\r
312     un.valueBuffer[2] = buffer[2];\r
313     un.valueBuffer[3] = buffer[3];\r
314     return un.value;\r
315 }\r
316 \r
317 /*! \fn double UnpackFloat(char* buffer)\r
318     \brief reads a float value from byte buffer\r
319 \r
320     This is an overloaded function.\r
321 \r
322     \param[in] buffer source byte buffer\r
323     \return the (float) value read from the buffer\r
324 */\r
325 API_EXPORT inline float UnpackFloat(char* buffer) {\r
326     return UnpackFloat( (const char*)buffer );\r
327 }\r
328 \r
329 /*! \fn signed int UnpackSignedInt(const char* buffer)\r
330     \brief reads a signed integer value from byte buffer\r
331 \r
332     \param[in] buffer source byte buffer\r
333     \return the (signed int) value read from the buffer\r
334 */\r
335 API_EXPORT inline signed int UnpackSignedInt(const char* buffer) {\r
336     union { signed int value; unsigned char valueBuffer[sizeof(signed int)]; } un;\r
337     un.value = 0;\r
338     un.valueBuffer[0] = buffer[0];\r
339     un.valueBuffer[1] = buffer[1];\r
340     un.valueBuffer[2] = buffer[2];\r
341     un.valueBuffer[3] = buffer[3];\r
342     return un.value;\r
343 }\r
344 \r
345 /*! \fn signed int UnpackSignedInt(char* buffer)\r
346     \brief reads a signed integer value from byte buffer\r
347 \r
348     This is an overloaded function.\r
349 \r
350     \param[in] buffer source byte buffer\r
351     \return the (signed int) value read from the buffer\r
352 */\r
353 API_EXPORT inline signed int UnpackSignedInt(char* buffer) {\r
354     return UnpackSignedInt( (const char*) buffer );\r
355 }\r
356 \r
357 /*! \fn signed short UnpackSignedShort(const char* buffer)\r
358     \brief reads a signed short integer value from byte buffer\r
359 \r
360     \param[in] buffer source byte buffer\r
361     \return the (signed short) value read from the buffer\r
362 */\r
363 API_EXPORT inline signed short UnpackSignedShort(const char* buffer) {\r
364     union { signed short value; unsigned char valueBuffer[sizeof(signed short)]; } un;\r
365     un.value = 0;\r
366     un.valueBuffer[0] = buffer[0];\r
367     un.valueBuffer[1] = buffer[1];\r
368     return un.value;\r
369 }\r
370 \r
371 /*! \fn signed short UnpackSignedShort(char* buffer)\r
372     \brief reads a signed short integer value from byte buffer\r
373 \r
374     This is an overloaded function.\r
375 \r
376     \param[in] buffer source byte buffer\r
377     \return the (signed short) value read from the buffer\r
378 */\r
379 API_EXPORT inline signed short UnpackSignedShort(char* buffer) {\r
380     return UnpackSignedShort( (const char*)buffer );\r
381 }\r
382 \r
383 /*! \fn unsigned int UnpackUnsignedInt(const char* buffer)\r
384     \brief reads an unsigned integer value from byte buffer\r
385 \r
386     \param[in] buffer source byte buffer\r
387     \return the (unsigned int) value read from the buffer\r
388 */\r
389 API_EXPORT inline unsigned int UnpackUnsignedInt(const char* buffer) {\r
390     union { unsigned int value; unsigned char valueBuffer[sizeof(unsigned int)]; } un;\r
391     un.value = 0;\r
392     un.valueBuffer[0] = buffer[0];\r
393     un.valueBuffer[1] = buffer[1];\r
394     un.valueBuffer[2] = buffer[2];\r
395     un.valueBuffer[3] = buffer[3];\r
396     return un.value;\r
397 }\r
398 \r
399 /*! \fn unsigned int UnpackUnsignedInt(char* buffer)\r
400     \brief reads an unsigned integer value from byte buffer\r
401 \r
402     This is an overloaded function.\r
403 \r
404     \param[in] buffer source byte buffer\r
405     \return the (unsigned int) value read from the buffer\r
406 */\r
407 API_EXPORT inline unsigned int UnpackUnsignedInt(char* buffer) {\r
408     return UnpackUnsignedInt( (const char*)buffer );\r
409 }\r
410 \r
411 /*! \fn unsigned short UnpackUnsignedShort(const char* buffer)\r
412     \brief reads an unsigned short integer value from byte buffer\r
413 \r
414     \param[in] buffer source byte buffer\r
415     \return the (unsigned short) value read from the buffer\r
416 */\r
417 API_EXPORT inline unsigned short UnpackUnsignedShort(const char* buffer) {\r
418     union { unsigned short value; unsigned char valueBuffer[sizeof(unsigned short)]; } un;\r
419     un.value = 0;\r
420     un.valueBuffer[0] = buffer[0];\r
421     un.valueBuffer[1] = buffer[1];\r
422     return un.value;\r
423 }\r
424 \r
425 /*! \fn unsigned short UnpackUnsignedShort(char* buffer)\r
426     \brief reads an unsigned short integer value from byte buffer\r
427 \r
428     This is an overloaded function.\r
429 \r
430     \param[in] buffer source byte buffer\r
431     \return the (unsigned short) value read from the buffer\r
432 */\r
433 API_EXPORT inline unsigned short UnpackUnsignedShort(char* buffer) {\r
434     return UnpackUnsignedShort( (const char*)buffer );\r
435 }\r
436 \r
437 // ----------------------------------------------------------------\r
438 // 'internal' helper structs\r
439 \r
440 /*! \struct RaiiBuffer\r
441     \internal\r
442 */\r
443 struct RaiiBuffer {\r
444     RaiiBuffer(const size_t n)\r
445         : Buffer( new char[n]() )\r
446     { }\r
447     ~RaiiBuffer(void) {\r
448         delete[] Buffer;\r
449     }\r
450     char* Buffer;\r
451 };\r
452 \r
453 } // namespace BamTools\r
454 \r
455 #endif // BAMAUX_H\r