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: 25 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
22 Provides data structures & utility methods that are used throughout the API.
\r
25 /*! \namespace BamTools
\r
26 \brief Contains all BamTools classes & methods.
\r
28 The BamTools API contained in this namespace contains classes and methods
\r
29 for reading, writing, and manipulating BAM alignment files.
\r
31 namespace BamTools {
\r
33 // ----------------------------------------------------------------
\r
36 /*! \struct BamTools::CigarOp
\r
37 \brief Represents a CIGAR alignment operation.
\r
39 \sa \samSpecURL for more details on using CIGAR operations.
\r
41 struct API_EXPORT CigarOp {
\r
43 char Type; //!< CIGAR operation type (MIDNSHPX=)
\r
44 uint32_t Length; //!< CIGAR operation length (number of bases)
\r
47 CigarOp(const char type = '\0',
\r
48 const uint32_t& length = 0)
\r
54 // ----------------------------------------------------------------
\r
57 /*! \struct BamTools::RefData
\r
58 \brief Represents a reference sequence entry
\r
60 struct API_EXPORT RefData {
\r
62 std::string RefName; //!< name of reference sequence
\r
63 int32_t RefLength; //!< length of reference sequence
\r
66 RefData(const std::string& name = "",
\r
67 const int32_t& length = 0)
\r
73 //! convenience typedef for vector of RefData entries
\r
74 typedef std::vector<RefData> RefVector;
\r
76 // ----------------------------------------------------------------
\r
79 /*! \struct BamTools::BamRegion
\r
80 \brief Represents a sequential genomic region
\r
82 Allowed to span multiple (sequential) references.
\r
84 \warning BamRegion now represents a zero-based, HALF-OPEN interval.
\r
85 In previous versions of BamTools (0.x & 1.x) all intervals were treated
\r
86 as zero-based, CLOSED.
\r
88 struct API_EXPORT BamRegion {
\r
90 int LeftRefID; //!< reference ID for region's left boundary
\r
91 int LeftPosition; //!< position for region's left boundary
\r
92 int RightRefID; //!< reference ID for region's right boundary
\r
93 int RightPosition; //!< position for region's right boundary
\r
96 BamRegion(const int& leftID = -1,
\r
97 const int& leftPos = -1,
\r
98 const int& rightID = -1,
\r
99 const int& rightPos = -1)
\r
100 : LeftRefID(leftID)
\r
101 , LeftPosition(leftPos)
\r
102 , RightRefID(rightID)
\r
103 , RightPosition(rightPos)
\r
106 //! copy constructor
\r
107 BamRegion(const BamRegion& other)
\r
108 : LeftRefID(other.LeftRefID)
\r
109 , LeftPosition(other.LeftPosition)
\r
110 , RightRefID(other.RightRefID)
\r
111 , RightPosition(other.RightPosition)
\r
114 //! Clears region boundaries
\r
116 LeftRefID = -1; LeftPosition = -1;
\r
117 RightRefID = -1; RightPosition = -1;
\r
120 //! Returns true if region has a left boundary
\r
121 bool isLeftBoundSpecified(void) const {
\r
122 return ( LeftRefID >= 0 && LeftPosition >= 0 );
\r
125 //! Returns true if region boundaries are not defined
\r
126 bool isNull(void) const {
\r
127 return ( !isLeftBoundSpecified() && !isRightBoundSpecified() );
\r
130 //! Returns true if region has a right boundary
\r
131 bool isRightBoundSpecified(void) const {
\r
132 return ( RightRefID >= 0 && RightPosition >= 1 );
\r
136 // ----------------------------------------------------------------
\r
137 // General utility methods
\r
139 /*! \fn bool FileExists(const std::string& filename)
\r
140 \brief returns true if the file exists
\r
142 API_EXPORT inline bool FileExists(const std::string& filename) {
\r
143 std::ifstream f(filename.c_str(), std::ifstream::in);
\r
147 /*! \fn void SwapEndian_16(int16_t& x)
\r
148 \brief swaps endianness of signed 16-bit integer, in place
\r
150 API_EXPORT inline void SwapEndian_16(int16_t& x) {
\r
151 x = ((x >> 8) | (x << 8));
\r
154 /*! \fn void SwapEndian_16(uint16_t& x)
\r
155 \brief swaps endianness of unsigned 16-bit integer, in place
\r
157 API_EXPORT inline void SwapEndian_16(uint16_t& x) {
\r
158 x = ((x >> 8) | (x << 8));
\r
161 /*! \fn void SwapEndian_32(int32_t& x)
\r
162 \brief swaps endianness of signed 32-bit integer, in place
\r
164 API_EXPORT inline void SwapEndian_32(int32_t& x) {
\r
166 ((x << 8) & 0x00FF0000) |
\r
167 ((x >> 8) & 0x0000FF00) |
\r
172 /*! \fn void SwapEndian_32(uint32_t& x)
\r
173 \brief swaps endianness of unsigned 32-bit integer, in place
\r
175 API_EXPORT inline void SwapEndian_32(uint32_t& x) {
\r
177 ((x << 8) & 0x00FF0000) |
\r
178 ((x >> 8) & 0x0000FF00) |
\r
183 /*! \fn void SwapEndian_64(int64_t& x)
\r
184 \brief swaps endianness of signed 64-bit integer, in place
\r
186 API_EXPORT inline void SwapEndian_64(int64_t& x) {
\r
188 ((x << 40) & 0x00FF000000000000ll) |
\r
189 ((x << 24) & 0x0000FF0000000000ll) |
\r
190 ((x << 8) & 0x000000FF00000000ll) |
\r
191 ((x >> 8) & 0x00000000FF000000ll) |
\r
192 ((x >> 24) & 0x0000000000FF0000ll) |
\r
193 ((x >> 40) & 0x000000000000FF00ll) |
\r
198 /*! \fn void SwapEndian_64(uint64_t& x)
\r
199 \brief swaps endianness of unsigned 64-bit integer, in place
\r
201 API_EXPORT inline void SwapEndian_64(uint64_t& x) {
\r
203 ((x << 40) & 0x00FF000000000000ll) |
\r
204 ((x << 24) & 0x0000FF0000000000ll) |
\r
205 ((x << 8) & 0x000000FF00000000ll) |
\r
206 ((x >> 8) & 0x00000000FF000000ll) |
\r
207 ((x >> 24) & 0x0000000000FF0000ll) |
\r
208 ((x >> 40) & 0x000000000000FF00ll) |
\r
213 /*! \fn void SwapEndian_16p(char* data)
\r
214 \brief swaps endianness of the next 2 bytes in a buffer, in place
\r
216 API_EXPORT inline void SwapEndian_16p(char* data) {
\r
217 uint16_t& value = (uint16_t&)*data;
\r
218 SwapEndian_16(value);
\r
221 /*! \fn void SwapEndian_32p(char* data)
\r
222 \brief swaps endianness of the next 4 bytes in a buffer, in place
\r
224 API_EXPORT inline void SwapEndian_32p(char* data) {
\r
225 uint32_t& value = (uint32_t&)*data;
\r
226 SwapEndian_32(value);
\r
229 /*! \fn void SwapEndian_64p(char* data)
\r
230 \brief swaps endianness of the next 8 bytes in a buffer, in place
\r
232 API_EXPORT inline void SwapEndian_64p(char* data) {
\r
233 uint64_t& value = (uint64_t&)*data;
\r
234 SwapEndian_64(value);
\r
237 /*! \fn bool SystemIsBigEndian(void)
\r
238 \brief checks host architecture's byte order
\r
239 \return \c true if system uses big-endian ordering
\r
241 API_EXPORT inline bool SystemIsBigEndian(void) {
\r
242 const uint16_t one = 0x0001;
\r
243 return ((*(char*) &one) == 0 );
\r
246 /*! \fn void PackUnsignedInt(char* buffer, unsigned int value)
\r
247 \brief stores unsigned integer value in a byte buffer
\r
249 \param[out] buffer destination buffer
\r
250 \param[in] value value to 'pack' in buffer
\r
252 API_EXPORT inline void PackUnsignedInt(char* buffer, unsigned int value) {
\r
253 buffer[0] = (char)value;
\r
254 buffer[1] = (char)(value >> 8);
\r
255 buffer[2] = (char)(value >> 16);
\r
256 buffer[3] = (char)(value >> 24);
\r
259 /*! \fn void PackUnsignedShort(char* buffer, unsigned short value)
\r
260 \brief stores unsigned short integer value in a byte buffer
\r
262 \param[out] buffer destination buffer
\r
263 \param[in] value value to 'pack' in buffer
\r
265 API_EXPORT inline void PackUnsignedShort(char* buffer, unsigned short value) {
\r
266 buffer[0] = (char)value;
\r
267 buffer[1] = (char)(value >> 8);
\r
270 /*! \fn double UnpackDouble(const char* buffer)
\r
271 \brief reads a double value from byte buffer
\r
273 \param[in] buffer source byte buffer
\r
274 \return the (double) value read from the buffer
\r
276 API_EXPORT inline double UnpackDouble(const char* buffer) {
\r
277 union { double value; unsigned char valueBuffer[sizeof(double)]; } un;
\r
279 un.valueBuffer[0] = buffer[0];
\r
280 un.valueBuffer[1] = buffer[1];
\r
281 un.valueBuffer[2] = buffer[2];
\r
282 un.valueBuffer[3] = buffer[3];
\r
283 un.valueBuffer[4] = buffer[4];
\r
284 un.valueBuffer[5] = buffer[5];
\r
285 un.valueBuffer[6] = buffer[6];
\r
286 un.valueBuffer[7] = buffer[7];
\r
290 /*! \fn double UnpackDouble(char* buffer)
\r
291 \brief reads a double value from byte buffer
\r
293 This is an overloaded function.
\r
295 \param[in] buffer source byte buffer
\r
296 \return the (double) value read from the buffer
\r
298 API_EXPORT inline double UnpackDouble(char* buffer) {
\r
299 return UnpackDouble( (const char*)buffer );
\r
302 /*! \fn double UnpackFloat(const char* buffer)
\r
303 \brief reads a float value from byte buffer
\r
305 \param[in] buffer source byte buffer
\r
306 \return the (float) value read from the buffer
\r
308 API_EXPORT inline float UnpackFloat(const char* buffer) {
\r
309 union { float value; unsigned char valueBuffer[sizeof(float)]; } un;
\r
311 un.valueBuffer[0] = buffer[0];
\r
312 un.valueBuffer[1] = buffer[1];
\r
313 un.valueBuffer[2] = buffer[2];
\r
314 un.valueBuffer[3] = buffer[3];
\r
318 /*! \fn double UnpackFloat(char* buffer)
\r
319 \brief reads a float value from byte buffer
\r
321 This is an overloaded function.
\r
323 \param[in] buffer source byte buffer
\r
324 \return the (float) value read from the buffer
\r
326 API_EXPORT inline float UnpackFloat(char* buffer) {
\r
327 return UnpackFloat( (const char*)buffer );
\r
330 /*! \fn signed int UnpackSignedInt(const char* buffer)
\r
331 \brief reads a signed integer value from byte buffer
\r
333 \param[in] buffer source byte buffer
\r
334 \return the (signed int) value read from the buffer
\r
336 API_EXPORT inline signed int UnpackSignedInt(const char* buffer) {
\r
337 union { signed int value; unsigned char valueBuffer[sizeof(signed int)]; } un;
\r
339 un.valueBuffer[0] = buffer[0];
\r
340 un.valueBuffer[1] = buffer[1];
\r
341 un.valueBuffer[2] = buffer[2];
\r
342 un.valueBuffer[3] = buffer[3];
\r
346 /*! \fn signed int UnpackSignedInt(char* buffer)
\r
347 \brief reads a signed integer value from byte buffer
\r
349 This is an overloaded function.
\r
351 \param[in] buffer source byte buffer
\r
352 \return the (signed int) value read from the buffer
\r
354 API_EXPORT inline signed int UnpackSignedInt(char* buffer) {
\r
355 return UnpackSignedInt( (const char*) buffer );
\r
358 /*! \fn signed short UnpackSignedShort(const char* buffer)
\r
359 \brief reads a signed short integer value from byte buffer
\r
361 \param[in] buffer source byte buffer
\r
362 \return the (signed short) value read from the buffer
\r
364 API_EXPORT inline signed short UnpackSignedShort(const char* buffer) {
\r
365 union { signed short value; unsigned char valueBuffer[sizeof(signed short)]; } un;
\r
367 un.valueBuffer[0] = buffer[0];
\r
368 un.valueBuffer[1] = buffer[1];
\r
372 /*! \fn signed short UnpackSignedShort(char* buffer)
\r
373 \brief reads a signed short integer value from byte buffer
\r
375 This is an overloaded function.
\r
377 \param[in] buffer source byte buffer
\r
378 \return the (signed short) value read from the buffer
\r
380 API_EXPORT inline signed short UnpackSignedShort(char* buffer) {
\r
381 return UnpackSignedShort( (const char*)buffer );
\r
384 /*! \fn unsigned int UnpackUnsignedInt(const char* buffer)
\r
385 \brief reads an unsigned integer value from byte buffer
\r
387 \param[in] buffer source byte buffer
\r
388 \return the (unsigned int) value read from the buffer
\r
390 API_EXPORT inline unsigned int UnpackUnsignedInt(const char* buffer) {
\r
391 union { unsigned int value; unsigned char valueBuffer[sizeof(unsigned int)]; } un;
\r
393 un.valueBuffer[0] = buffer[0];
\r
394 un.valueBuffer[1] = buffer[1];
\r
395 un.valueBuffer[2] = buffer[2];
\r
396 un.valueBuffer[3] = buffer[3];
\r
400 /*! \fn unsigned int UnpackUnsignedInt(char* buffer)
\r
401 \brief reads an unsigned integer value from byte buffer
\r
403 This is an overloaded function.
\r
405 \param[in] buffer source byte buffer
\r
406 \return the (unsigned int) value read from the buffer
\r
408 API_EXPORT inline unsigned int UnpackUnsignedInt(char* buffer) {
\r
409 return UnpackUnsignedInt( (const char*)buffer );
\r
412 /*! \fn unsigned short UnpackUnsignedShort(const char* buffer)
\r
413 \brief reads an unsigned short integer value from byte buffer
\r
415 \param[in] buffer source byte buffer
\r
416 \return the (unsigned short) value read from the buffer
\r
418 API_EXPORT inline unsigned short UnpackUnsignedShort(const char* buffer) {
\r
419 union { unsigned short value; unsigned char valueBuffer[sizeof(unsigned short)]; } un;
\r
421 un.valueBuffer[0] = buffer[0];
\r
422 un.valueBuffer[1] = buffer[1];
\r
426 /*! \fn unsigned short UnpackUnsignedShort(char* buffer)
\r
427 \brief reads an unsigned short integer value from byte buffer
\r
429 This is an overloaded function.
\r
431 \param[in] buffer source byte buffer
\r
432 \return the (unsigned short) value read from the buffer
\r
434 API_EXPORT inline unsigned short UnpackUnsignedShort(char* buffer) {
\r
435 return UnpackUnsignedShort( (const char*)buffer );
\r
438 // ----------------------------------------------------------------
\r
439 // 'internal' helper structs
\r
441 /*! \struct RaiiBuffer
\r
444 struct RaiiBuffer {
\r
448 const size_t NumBytes;
\r
451 RaiiBuffer(const size_t n)
\r
452 : Buffer( new char[n]() )
\r
456 ~RaiiBuffer(void) {
\r
462 memset(Buffer, 0, NumBytes);
\r
466 } // namespace BamTools
\r