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: 4 March 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
23 /*! \namespace BamTools
\r
24 \brief Contains all BamTools classes & methods.
\r
26 The BamTools API contained in this namespace contains classes and methods
\r
27 for reading, writing, and manipulating BAM alignment files.
\r
29 namespace BamTools {
\r
31 // ----------------------------------------------------------------
\r
34 /*! \struct BamTools::CigarOp
\r
35 \brief Represents a CIGAR alignment operation.
\r
37 \sa http://samtools.sourceforge.net/SAM-1.3.pdf for more details on using CIGAR operations.
\r
39 struct API_EXPORT CigarOp {
\r
41 char Type; //!< CIGAR operation type (MIDNSHP)
\r
42 uint32_t Length; //!< CIGAR operation length (number of bases)
\r
45 CigarOp(const char type = '\0',
\r
46 const uint32_t& length = 0)
\r
52 // ----------------------------------------------------------------
\r
55 /*! \struct BamTools::RefData
\r
56 \brief Represents a reference sequence entry
\r
58 struct API_EXPORT RefData {
\r
60 std::string RefName; //!< name of reference sequence
\r
61 int32_t RefLength; //!< length of reference sequence
\r
64 RefData(const std::string& name = "",
\r
65 const int32_t& length = 0)
\r
71 //! convenience typedef for vector of RefData entries
\r
72 typedef std::vector<RefData> RefVector;
\r
74 // ----------------------------------------------------------------
\r
77 /*! \struct BamTools::BamRegion
\r
78 \brief Represents a sequential genomic region
\r
80 Allowed to span multiple (sequential) references.
\r
82 struct API_EXPORT BamRegion {
\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
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
95 , LeftPosition(leftPos)
\r
96 , RightRefID(rightID)
\r
97 , RightPosition(rightPos)
\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
108 //! Clears region boundaries
\r
110 LeftRefID = -1; LeftPosition = -1;
\r
111 RightRefID = -1; RightPosition = -1;
\r
114 //! Returns true if region has a left boundary
\r
115 bool isLeftBoundSpecified(void) const {
\r
116 return ( LeftRefID >= 0 && LeftPosition >= 0 );
\r
119 //! Returns true if region boundaries are not defined
\r
120 bool isNull(void) const {
\r
121 return ( !isLeftBoundSpecified() && !isRightBoundSpecified() );
\r
124 //! Returns true if region has a right boundary
\r
125 bool isRightBoundSpecified(void) const {
\r
126 return ( RightRefID >= 0 && RightPosition >= 0 );
\r
130 // ----------------------------------------------------------------
\r
131 // General utility methods
\r
133 /*! \fn bool FileExists(const std::string& filename)
\r
134 \brief checks if file exists
\r
136 Attempts to open file in a read-only mode.
\r
138 \return \c true if file can be opened successfully
\r
140 API_EXPORT inline bool FileExists(const std::string& filename) {
\r
141 std::ifstream f(filename.c_str(), std::ifstream::in);
\r
145 /*! \fn void SwapEndian_16(int16_t& x)
\r
146 \brief swaps endianness of signed 16-bit integer, in place
\r
148 Swaps endian representation of value in \a x.
\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 Swaps endian representation of value in \a x.
\r
159 API_EXPORT inline void SwapEndian_16(uint16_t& x) {
\r
160 x = ((x >> 8) | (x << 8));
\r
163 /*! \fn void SwapEndian_32(int32_t& x)
\r
164 \brief swaps endianness of signed 32-bit integer, in place
\r
166 Swaps endian representation of value in \a x.
\r
168 API_EXPORT inline void SwapEndian_32(int32_t& x) {
\r
170 ((x << 8) & 0x00FF0000) |
\r
171 ((x >> 8) & 0x0000FF00) |
\r
176 /*! \fn void SwapEndian_32(uint32_t& x)
\r
177 \brief swaps endianness of unsigned 32-bit integer, in place
\r
179 Swaps endian representation of value in \a x.
\r
181 API_EXPORT inline void SwapEndian_32(uint32_t& x) {
\r
183 ((x << 8) & 0x00FF0000) |
\r
184 ((x >> 8) & 0x0000FF00) |
\r
189 /*! \fn void SwapEndian_64(int64_t& x)
\r
190 \brief swaps endianness of signed 64-bit integer, in place
\r
192 Swaps endian representation of value in \a x.
\r
194 API_EXPORT inline void SwapEndian_64(int64_t& x) {
\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
206 /*! \fn void SwapEndian_64(uint64_t& x)
\r
207 \brief swaps endianness of unsigned 64-bit integer, in place
\r
209 Swaps endian representation of value in \a x.
\r
211 API_EXPORT inline void SwapEndian_64(uint64_t& x) {
\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
223 /*! \fn void SwapEndian_16p(char* data)
\r
224 \brief swaps endianness of the next 2 bytes in a buffer, in place
\r
226 Swaps endian representation the next 2 bytes in \a data.
\r
228 API_EXPORT inline void SwapEndian_16p(char* data) {
\r
229 uint16_t& value = (uint16_t&)*data;
\r
230 SwapEndian_16(value);
\r
233 /*! \fn void SwapEndian_32p(char* data)
\r
234 \brief swaps endianness of the next 4 bytes in a buffer, in place
\r
236 Swaps endian representation the next 4 bytes in \a data.
\r
238 API_EXPORT inline void SwapEndian_32p(char* data) {
\r
239 uint32_t& value = (uint32_t&)*data;
\r
240 SwapEndian_32(value);
\r
243 /*! \fn void SwapEndian_64p(char* data)
\r
244 \brief swaps endianness of the next 8 bytes in a buffer, in place
\r
246 Swaps endian representation the next 8 bytes in \a data.
\r
248 API_EXPORT inline void SwapEndian_64p(char* data) {
\r
249 uint64_t& value = (uint64_t&)*data;
\r
250 SwapEndian_64(value);
\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
257 API_EXPORT inline bool SystemIsBigEndian(void) {
\r
258 const uint16_t one = 0x0001;
\r
259 return ((*(char*) &one) == 0 );
\r
262 /*! \fn void PackUnsignedInt(char* buffer, unsigned int value)
\r
263 \brief stores unsigned integer value in a byte buffer
\r
265 \param buffer destination buffer
\r
266 \param value unsigned integer to 'pack' in buffer
\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
275 /*! \fn void PackUnsignedShort(char* buffer, unsigned short value)
\r
276 \brief stores unsigned short integer value in a byte buffer
\r
278 \param buffer destination buffer
\r
279 \param value unsigned short integer to 'pack' in buffer
\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
286 /*! \fn double UnpackDouble(const char* buffer)
\r
287 \brief reads a double value from byte buffer
\r
289 \param buffer source byte buffer
\r
290 \return the (double) value read from the buffer
\r
292 API_EXPORT inline double UnpackDouble(const char* buffer) {
\r
293 union { double value; unsigned char valueBuffer[sizeof(double)]; } un;
\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
306 /*! \fn double UnpackDouble(char* buffer)
\r
307 \brief reads a double value from byte buffer
\r
309 This is an overloaded function.
\r
311 \param buffer source byte buffer
\r
312 \return the (double) value read from the buffer
\r
314 API_EXPORT inline double UnpackDouble(char* buffer) {
\r
315 return UnpackDouble( (const char*)buffer );
\r
318 /*! \fn double UnpackFloat(const char* buffer)
\r
319 \brief reads a float value from byte buffer
\r
321 \param buffer source byte buffer
\r
322 \return the (float) value read from the buffer
\r
324 API_EXPORT inline float UnpackFloat(const char* buffer) {
\r
325 union { float value; unsigned char valueBuffer[sizeof(float)]; } un;
\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
334 /*! \fn double UnpackFloat(char* buffer)
\r
335 \brief reads a float value from byte buffer
\r
337 This is an overloaded function.
\r
339 \param buffer source byte buffer
\r
340 \return the (float) value read from the buffer
\r
342 API_EXPORT inline float UnpackFloat(char* buffer) {
\r
343 return UnpackFloat( (const char*)buffer );
\r
346 /*! \fn signed int UnpackSignedInt(const char* buffer)
\r
347 \brief reads a signed integer value from byte buffer
\r
349 \param buffer source byte buffer
\r
350 \return the (signed int) value read from the buffer
\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
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
362 /*! \fn signed int UnpackSignedInt(char* buffer)
\r
363 \brief reads a signed integer value from byte buffer
\r
365 This is an overloaded function.
\r
367 \param buffer source byte buffer
\r
368 \return the (signed int) value read from the buffer
\r
370 API_EXPORT inline signed int UnpackSignedInt(char* buffer) {
\r
371 return UnpackSignedInt( (const char*) buffer );
\r
374 /*! \fn signed short UnpackSignedShort(const char* buffer)
\r
375 \brief reads a signed short integer value from byte buffer
\r
377 \param buffer source byte buffer
\r
378 \return the (signed short) value read from the buffer
\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
383 un.valueBuffer[0] = buffer[0];
\r
384 un.valueBuffer[1] = buffer[1];
\r
388 /*! \fn signed short UnpackSignedShort(char* buffer)
\r
389 \brief reads a signed short integer value from byte buffer
\r
391 This is an overloaded function.
\r
393 \param buffer source byte buffer
\r
394 \return the (signed short) value read from the buffer
\r
396 API_EXPORT inline signed short UnpackSignedShort(char* buffer) {
\r
397 return UnpackSignedShort( (const char*)buffer );
\r
400 /*! \fn unsigned int UnpackUnsignedInt(const char* buffer)
\r
401 \brief reads an unsigned integer value from byte buffer
\r
403 \param buffer source byte buffer
\r
404 \return the (unsigned int) value read from the buffer
\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
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
416 /*! \fn unsigned int UnpackUnsignedInt(char* buffer)
\r
417 \brief reads an unsigned integer value from byte buffer
\r
419 This is an overloaded function.
\r
421 \param buffer source byte buffer
\r
422 \return the (unsigned int) value read from the buffer
\r
424 API_EXPORT inline unsigned int UnpackUnsignedInt(char* buffer) {
\r
425 return UnpackUnsignedInt( (const char*)buffer );
\r
428 /*! \fn unsigned short UnpackUnsignedShort(const char* buffer)
\r
429 \brief reads an unsigned short integer value from byte buffer
\r
431 \param buffer source byte buffer
\r
432 \return the (unsigned short) value read from the buffer
\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
437 un.valueBuffer[0] = buffer[0];
\r
438 un.valueBuffer[1] = buffer[1];
\r
442 /*! \fn unsigned short UnpackUnsignedShort(char* buffer)
\r
443 \brief reads an unsigned short integer value from byte buffer
\r
445 This is an overloaded function.
\r
447 \param buffer source byte buffer
\r
448 \return the (unsigned short) value read from the buffer
\r
450 API_EXPORT inline unsigned short UnpackUnsignedShort(char* buffer) {
\r
451 return UnpackUnsignedShort( (const char*)buffer );
\r
454 } // namespace BamTools
\r