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