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
13 #include "api/api_global.h"
\r
21 Provides data structures & utility methods that are used throughout the API.
\r
24 /*! \namespace BamTools
\r
25 \brief Contains all BamTools classes & methods.
\r
27 The BamTools API contained in this namespace contains classes and methods
\r
28 for reading, writing, and manipulating BAM alignment files.
\r
30 namespace BamTools {
\r
32 // ----------------------------------------------------------------
\r
35 /*! \struct BamTools::CigarOp
\r
36 \brief Represents a CIGAR alignment operation.
\r
38 \sa \samSpecURL for more details on using CIGAR operations.
\r
40 struct API_EXPORT CigarOp {
\r
42 char Type; //!< CIGAR operation type (MIDNSHPX=)
\r
43 uint32_t Length; //!< CIGAR operation length (number of bases)
\r
46 CigarOp(const char type = '\0',
\r
47 const uint32_t& length = 0)
\r
53 // ----------------------------------------------------------------
\r
56 /*! \struct BamTools::RefData
\r
57 \brief Represents a reference sequence entry
\r
59 struct API_EXPORT RefData {
\r
61 std::string RefName; //!< name of reference sequence
\r
62 int32_t RefLength; //!< length of reference sequence
\r
65 RefData(const std::string& name = "",
\r
66 const int32_t& length = 0)
\r
72 //! convenience typedef for vector of RefData entries
\r
73 typedef std::vector<RefData> RefVector;
\r
75 // ----------------------------------------------------------------
\r
78 /*! \struct BamTools::BamRegion
\r
79 \brief Represents a sequential genomic region
\r
81 Allowed to span multiple (sequential) references.
\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
87 struct API_EXPORT BamRegion {
\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
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
100 , LeftPosition(leftPos)
\r
101 , RightRefID(rightID)
\r
102 , RightPosition(rightPos)
\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
113 //! Clears region boundaries
\r
115 LeftRefID = -1; LeftPosition = -1;
\r
116 RightRefID = -1; RightPosition = -1;
\r
119 //! Returns true if region has a left boundary
\r
120 bool isLeftBoundSpecified(void) const {
\r
121 return ( LeftRefID >= 0 && LeftPosition >= 0 );
\r
124 //! Returns true if region boundaries are not defined
\r
125 bool isNull(void) const {
\r
126 return ( !isLeftBoundSpecified() && !isRightBoundSpecified() );
\r
129 //! Returns true if region has a right boundary
\r
130 bool isRightBoundSpecified(void) const {
\r
131 return ( RightRefID >= 0 && RightPosition >= 1 );
\r
135 // ----------------------------------------------------------------
\r
136 // General utility methods
\r
138 /*! \fn bool FileExists(const std::string& filename)
\r
139 \brief returns true if the file exists
\r
141 API_EXPORT inline bool FileExists(const std::string& filename) {
\r
142 std::ifstream f(filename.c_str(), std::ifstream::in);
\r
146 /*! \fn void SwapEndian_16(int16_t& x)
\r
147 \brief swaps endianness of signed 16-bit integer, in place
\r
149 API_EXPORT inline void SwapEndian_16(int16_t& x) {
\r
150 x = ((x >> 8) | (x << 8));
\r
153 /*! \fn void SwapEndian_16(uint16_t& x)
\r
154 \brief swaps endianness of unsigned 16-bit integer, in place
\r
156 API_EXPORT inline void SwapEndian_16(uint16_t& x) {
\r
157 x = ((x >> 8) | (x << 8));
\r
160 /*! \fn void SwapEndian_32(int32_t& x)
\r
161 \brief swaps endianness of signed 32-bit integer, in place
\r
163 API_EXPORT inline void SwapEndian_32(int32_t& x) {
\r
165 ((x << 8) & 0x00FF0000) |
\r
166 ((x >> 8) & 0x0000FF00) |
\r
171 /*! \fn void SwapEndian_32(uint32_t& x)
\r
172 \brief swaps endianness of unsigned 32-bit integer, in place
\r
174 API_EXPORT inline void SwapEndian_32(uint32_t& x) {
\r
176 ((x << 8) & 0x00FF0000) |
\r
177 ((x >> 8) & 0x0000FF00) |
\r
182 /*! \fn void SwapEndian_64(int64_t& x)
\r
183 \brief swaps endianness of signed 64-bit integer, in place
\r
185 API_EXPORT inline void SwapEndian_64(int64_t& x) {
\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
197 /*! \fn void SwapEndian_64(uint64_t& x)
\r
198 \brief swaps endianness of unsigned 64-bit integer, in place
\r
200 API_EXPORT inline void SwapEndian_64(uint64_t& x) {
\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
212 /*! \fn void SwapEndian_16p(char* data)
\r
213 \brief swaps endianness of the next 2 bytes in a buffer, in place
\r
215 API_EXPORT inline void SwapEndian_16p(char* data) {
\r
216 uint16_t& value = (uint16_t&)*data;
\r
217 SwapEndian_16(value);
\r
220 /*! \fn void SwapEndian_32p(char* data)
\r
221 \brief swaps endianness of the next 4 bytes in a buffer, in place
\r
223 API_EXPORT inline void SwapEndian_32p(char* data) {
\r
224 uint32_t& value = (uint32_t&)*data;
\r
225 SwapEndian_32(value);
\r
228 /*! \fn void SwapEndian_64p(char* data)
\r
229 \brief swaps endianness of the next 8 bytes in a buffer, in place
\r
231 API_EXPORT inline void SwapEndian_64p(char* data) {
\r
232 uint64_t& value = (uint64_t&)*data;
\r
233 SwapEndian_64(value);
\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
240 API_EXPORT inline bool SystemIsBigEndian(void) {
\r
241 const uint16_t one = 0x0001;
\r
242 return ((*(char*) &one) == 0 );
\r
245 /*! \fn void PackUnsignedInt(char* buffer, unsigned int value)
\r
246 \brief stores unsigned integer value in a byte buffer
\r
248 \param[out] buffer destination buffer
\r
249 \param[in] value value to 'pack' in buffer
\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
258 /*! \fn void PackUnsignedShort(char* buffer, unsigned short value)
\r
259 \brief stores unsigned short integer value in a byte buffer
\r
261 \param[out] buffer destination buffer
\r
262 \param[in] value value to 'pack' in buffer
\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
269 /*! \fn double UnpackDouble(const char* buffer)
\r
270 \brief reads a double value from byte buffer
\r
272 \param[in] buffer source byte buffer
\r
273 \return the (double) value read from the buffer
\r
275 API_EXPORT inline double UnpackDouble(const char* buffer) {
\r
276 union { double value; unsigned char valueBuffer[sizeof(double)]; } un;
\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
289 /*! \fn double UnpackDouble(char* buffer)
\r
290 \brief reads a double value from byte buffer
\r
292 This is an overloaded function.
\r
294 \param[in] buffer source byte buffer
\r
295 \return the (double) value read from the buffer
\r
297 API_EXPORT inline double UnpackDouble(char* buffer) {
\r
298 return UnpackDouble( (const char*)buffer );
\r
301 /*! \fn double UnpackFloat(const char* buffer)
\r
302 \brief reads a float value from byte buffer
\r
304 \param[in] buffer source byte buffer
\r
305 \return the (float) value read from the buffer
\r
307 API_EXPORT inline float UnpackFloat(const char* buffer) {
\r
308 union { float value; unsigned char valueBuffer[sizeof(float)]; } un;
\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
317 /*! \fn double UnpackFloat(char* buffer)
\r
318 \brief reads a float value from byte buffer
\r
320 This is an overloaded function.
\r
322 \param[in] buffer source byte buffer
\r
323 \return the (float) value read from the buffer
\r
325 API_EXPORT inline float UnpackFloat(char* buffer) {
\r
326 return UnpackFloat( (const char*)buffer );
\r
329 /*! \fn signed int UnpackSignedInt(const char* buffer)
\r
330 \brief reads a signed integer value from byte buffer
\r
332 \param[in] buffer source byte buffer
\r
333 \return the (signed int) value read from the buffer
\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
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
345 /*! \fn signed int UnpackSignedInt(char* buffer)
\r
346 \brief reads a signed integer value from byte buffer
\r
348 This is an overloaded function.
\r
350 \param[in] buffer source byte buffer
\r
351 \return the (signed int) value read from the buffer
\r
353 API_EXPORT inline signed int UnpackSignedInt(char* buffer) {
\r
354 return UnpackSignedInt( (const char*) buffer );
\r
357 /*! \fn signed short UnpackSignedShort(const char* buffer)
\r
358 \brief reads a signed short integer value from byte buffer
\r
360 \param[in] buffer source byte buffer
\r
361 \return the (signed short) value read from the buffer
\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
366 un.valueBuffer[0] = buffer[0];
\r
367 un.valueBuffer[1] = buffer[1];
\r
371 /*! \fn signed short UnpackSignedShort(char* buffer)
\r
372 \brief reads a signed short integer value from byte buffer
\r
374 This is an overloaded function.
\r
376 \param[in] buffer source byte buffer
\r
377 \return the (signed short) value read from the buffer
\r
379 API_EXPORT inline signed short UnpackSignedShort(char* buffer) {
\r
380 return UnpackSignedShort( (const char*)buffer );
\r
383 /*! \fn unsigned int UnpackUnsignedInt(const char* buffer)
\r
384 \brief reads an unsigned integer value from byte buffer
\r
386 \param[in] buffer source byte buffer
\r
387 \return the (unsigned int) value read from the buffer
\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
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
399 /*! \fn unsigned int UnpackUnsignedInt(char* buffer)
\r
400 \brief reads an unsigned integer value from byte buffer
\r
402 This is an overloaded function.
\r
404 \param[in] buffer source byte buffer
\r
405 \return the (unsigned int) value read from the buffer
\r
407 API_EXPORT inline unsigned int UnpackUnsignedInt(char* buffer) {
\r
408 return UnpackUnsignedInt( (const char*)buffer );
\r
411 /*! \fn unsigned short UnpackUnsignedShort(const char* buffer)
\r
412 \brief reads an unsigned short integer value from byte buffer
\r
414 \param[in] buffer source byte buffer
\r
415 \return the (unsigned short) value read from the buffer
\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
420 un.valueBuffer[0] = buffer[0];
\r
421 un.valueBuffer[1] = buffer[1];
\r
425 /*! \fn unsigned short UnpackUnsignedShort(char* buffer)
\r
426 \brief reads an unsigned short integer value from byte buffer
\r
428 This is an overloaded function.
\r
430 \param[in] buffer source byte buffer
\r
431 \return the (unsigned short) value read from the buffer
\r
433 API_EXPORT inline unsigned short UnpackUnsignedShort(char* buffer) {
\r
434 return UnpackUnsignedShort( (const char*)buffer );
\r
437 // ----------------------------------------------------------------
\r
438 // 'internal' helper structs
\r
440 /*! \struct RaiiBuffer
\r
443 struct RaiiBuffer {
\r
444 RaiiBuffer(const size_t n)
\r
445 : Buffer( new char[n]() )
\r
447 ~RaiiBuffer(void) {
\r
453 } // namespace BamTools
\r