// BamConstants.h (c) 2011 Derek Barnett
// Marth Lab, Department of Biology, Boston College
// ---------------------------------------------------------------------------
-// Last modified: 19 April 2011 (DB)
+// Last modified: 9 September 2011 (DB)
// ---------------------------------------------------------------------------
// Provides basic constants for handling BAM files.
// ***************************************************************************
const unsigned int BAM_HEADER_MAGIC_LENGTH = 4;
// BAM alignment core size
-const int BAM_CORE_SIZE = 32;
-const int BAM_CORE_BUFFER_SIZE = 8;
+const unsigned int BAM_CORE_SIZE = 32;
+const unsigned int BAM_CORE_BUFFER_SIZE = 8;
// BAM alignment flags
const int BAM_ALIGNMENT_PAIRED = 0x0001;
// BZGF constants
const int BGZF_BLOCK_HEADER_LENGTH = 18;
const int BGZF_BLOCK_FOOTER_LENGTH = 8;
-const int BGZF_MAX_BLOCK_SIZE = 65536;
-const int BGZF_DEFAULT_BLOCK_SIZE = 65536;
+const unsigned int BGZF_MAX_BLOCK_SIZE = 65536;
+const unsigned int BGZF_DEFAULT_BLOCK_SIZE = 65536;
} // namespace Constants
} // namespace BamTools
SamReadGroupDictionary.cpp
SamSequence.cpp
SamSequenceDictionary.cpp
+ internal/BamDeviceFactory_p.cpp
+ internal/BamFile_p.cpp
+ internal/BamFtp_p.cpp
internal/BamHeader_p.cpp
+ internal/BamHttp_p.cpp
internal/BamIndexFactory_p.cpp
internal/BamMultiReader_p.cpp
+ internal/BamPipe_p.cpp
internal/BamRandomAccessController_p.cpp
internal/BamReader_p.cpp
internal/BamStandardIndex_p.cpp
internal/BamToolsIndex_p.cpp
internal/BamWriter_p.cpp
internal/BgzfStream_p.cpp
+ internal/ILocalIODevice_p.cpp
+ internal/IRemoteIODevice_p.cpp
internal/SamFormatParser_p.cpp
internal/SamFormatPrinter_p.cpp
internal/SamHeaderValidator_p.cpp
ExportHeader(APIHeaders BamMultiReader.h ${ApiIncludeDir})
ExportHeader(APIHeaders BamReader.h ${ApiIncludeDir})
ExportHeader(APIHeaders BamWriter.h ${ApiIncludeDir})
+ExportHeader(APIHeaders IBamIODevice.h ${ApiIncludeDir})
ExportHeader(APIHeaders SamConstants.h ${ApiIncludeDir})
ExportHeader(APIHeaders SamHeader.h ${ApiIncludeDir})
ExportHeader(APIHeaders SamProgram.h ${ApiIncludeDir})
--- /dev/null
+#ifndef IBAMIODEVICE_H
+#define IBAMIODEVICE_H
+
+#include <api/api_global.h>
+#include <string>
+
+namespace BamTools {
+
+class API_EXPORT IBamIODevice {
+
+ // enums
+ public: enum OpenMode { NotOpen = 0
+ , ReadOnly
+ , WriteOnly
+ };
+
+ // ctor & dtor
+ public:
+ IBamIODevice(void);
+ virtual ~IBamIODevice(void);
+
+ // IBamIODevice interface
+ public:
+
+ // pure virtuals
+ virtual void Close(void) =0;
+ virtual bool IsRandomAccess(void) const =0;
+ virtual bool Open(const OpenMode mode) =0;
+ virtual size_t Read(char* data, const unsigned int numBytes) =0;
+ virtual bool Seek(const int64_t& position) =0;
+ virtual int64_t Tell(void) const =0;
+ virtual size_t Write(const char* data, const unsigned int numBytes) =0;
+
+ // default implementation provided
+ virtual std::string ErrorString(void);
+ virtual bool IsOpen(void) const;
+ virtual OpenMode Mode(void) const;
+
+ // internal methods
+ protected:
+ void SetErrorString(const std::string& errorString);
+
+ // data members
+ protected:
+ OpenMode m_mode;
+ std::string m_errorString;
+};
+
+inline
+IBamIODevice::IBamIODevice(void)
+ : m_mode(IBamIODevice::NotOpen)
+{ }
+
+inline
+IBamIODevice::~IBamIODevice(void) { }
+
+inline
+std::string IBamIODevice::ErrorString(void) {
+ std::string e = m_errorString;
+ m_errorString.clear();
+ return e;
+}
+
+inline
+bool IBamIODevice::IsOpen(void) const {
+ return ( m_mode != IBamIODevice::NotOpen );
+}
+
+inline
+IBamIODevice::OpenMode IBamIODevice::Mode(void) const {
+ return m_mode;
+}
+
+inline
+void IBamIODevice::SetErrorString(const std::string& errorString) {
+ m_errorString = errorString;
+}
+
+} // namespace BamTools
+
+#endif // IBAMIODEVICE_H
--- /dev/null
+// ***************************************************************************
+// BamDeviceFactory_p.cpp (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 8 September 2011 (DB)
+// ---------------------------------------------------------------------------
+// Creates built-in concrete implementations of IBamIODevices
+// ***************************************************************************
+
+#include <api/internal/BamDeviceFactory_p.h>
+#include <api/internal/BamFile_p.h>
+#include <api/internal/BamFtp_p.h>
+#include <api/internal/BamHttp_p.h>
+#include <api/internal/BamPipe_p.h>
+using namespace BamTools;
+using namespace BamTools::Internal;
+
+#include <iostream>
+using namespace std;
+
+IBamIODevice* BamDeviceFactory::CreateDevice(const string& source) {
+
+ // check for requested pipe
+ if ( source == "-" || source == "stdin" || source == "stdout" )
+ return new BamPipe;
+
+ // check for HTTP prefix
+ if ( source.find("http://") == 0 )
+ return new BamHttp(source);
+
+ // check for FTP prefix
+ if ( source.find("ftp://") == 0 )
+ return new BamFtp(source);
+
+ // otherwise assume a "normal" file
+ return new BamFile(source);
+}
--- /dev/null
+// ***************************************************************************
+// BamDeviceFactory_p.h (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 8 September 2011 (DB)
+// ---------------------------------------------------------------------------
+// Creates built-in concrete implementations of IBamIODevices
+// ***************************************************************************
+
+#ifndef BAMDEVICEFACTORY_P_H
+#define BAMDEVICEFACTORY_P_H
+
+// -------------
+// W A R N I N G
+// -------------
+//
+// This file is not part of the BamTools API. It exists purely as an
+// implementation detail. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+
+#include <api/IBamIODevice.h>
+#include <string>
+
+namespace BamTools {
+namespace Internal {
+
+class BamDeviceFactory {
+ public:
+ static IBamIODevice* CreateDevice(const std::string& source);
+};
+
+} // namespace Internal
+} // namespace BamTools
+
+#endif // BAMDEVICEFACTORY_P_H
--- /dev/null
+// ***************************************************************************
+// BamFile_p.cpp (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 9 September 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides BAM file-specific IO behavior
+// ***************************************************************************
+
+#include <api/internal/BamFile_p.h>
+using namespace BamTools;
+using namespace BamTools::Internal;
+
+#include <cstdio>
+#include <iostream>
+using namespace std;
+
+BamFile::BamFile(const string& filename)
+ : ILocalIODevice()
+ , m_filename(filename)
+{ }
+
+BamFile::~BamFile(void) { }
+
+void BamFile::Close(void) {
+ if ( IsOpen() ) {
+ m_filename.clear();
+ ILocalIODevice::Close();
+ }
+}
+
+bool BamFile::IsRandomAccess(void) const {
+ return true;
+}
+
+bool BamFile::Open(const IBamIODevice::OpenMode mode) {
+
+ // make sure we're starting with a fresh file stream
+ Close();
+
+ // attempt to open FILE* depending on requested openmode
+ if ( mode == IBamIODevice::ReadOnly )
+ m_stream = fopen(m_filename.c_str(), "rb");
+ else if ( mode == IBamIODevice::WriteOnly )
+ m_stream = fopen(m_filename.c_str(), "wb");
+ else {
+ SetErrorString("BamFile ERROR - unknown device open mode");
+ return false;
+ }
+
+ // check that we obtained a valid FILE*
+ if ( m_stream == 0 ) {
+ string error = "BamFile ERROR - could not open handle on ";
+ error += ( (m_filename.empty()) ? "empty filename" : m_filename );
+ SetErrorString(error);
+ return false;
+ }
+
+ // store current IO mode & return success
+ m_mode = mode;
+ return true;
+}
+
+bool BamFile::Seek(const int64_t& position) {
+ BT_ASSERT_X( m_stream, "BamFile::Seek() - null stream" );
+ cerr << "BamFile::Seek() - about to attempt seek" << endl;
+ return ( fseek64(m_stream, position, SEEK_SET) == 0);
+}
--- /dev/null
+// ***************************************************************************
+// BamFile_p.h (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 9 September 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides BAM file-specific IO behavior
+// ***************************************************************************
+
+#ifndef BAMFILE_P_H
+#define BAMFILE_P_H
+
+// -------------
+// W A R N I N G
+// -------------
+//
+// This file is not part of the BamTools API. It exists purely as an
+// implementation detail. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+
+#include <api/internal/ILocalIODevice_p.h>
+#include <string>
+
+namespace BamTools {
+namespace Internal {
+
+class BamFile : public ILocalIODevice {
+
+ // ctor & dtor
+ public:
+ BamFile(const std::string& filename);
+ ~BamFile(void);
+
+ // ILocalIODevice implementation
+ public:
+ void Close(void);
+ bool IsRandomAccess(void) const;
+ bool Open(const IBamIODevice::OpenMode mode);
+ bool Seek(const int64_t& position);
+
+ // data members
+ private:
+ std::string m_filename;
+};
+
+} // namespace Internal
+} // namespace BamTools
+
+#endif // BAMFILE_P_H
--- /dev/null
+// ***************************************************************************
+// BamFtp_p.cpp (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 9 September 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides reading/writing of BAM files on FTP server
+// ***************************************************************************
+
+#include <api/internal/BamFtp_p.h>
+using namespace BamTools;
+using namespace BamTools::Internal;
+
+using namespace std;
+
+BamFtp::BamFtp(const string& url)
+ : IBamIODevice()
+{
+ BT_ASSERT_X(false, "BamFtp not yet implemented");
+}
+
+BamFtp::~BamFtp(void) { }
+
+void BamFtp::Close(void) {
+ return ;
+}
+
+bool BamFtp::IsRandomAccess(void) const {
+ return true;
+}
+
+bool BamFtp::Open(const IBamIODevice::OpenMode mode) {
+ (void) mode;
+ return true;
+}
+
+size_t BamFtp::Read(char* data, const unsigned int numBytes) {
+ (void)data;
+ (void)numBytes;
+ return 0;
+}
+
+bool BamFtp::Seek(const int64_t& position) {
+ (void)position;
+ return true;
+}
+
+int64_t BamFtp::Tell(void) const {
+ return -1;
+}
+
+size_t BamFtp::Write(const char* data, const unsigned int numBytes) {
+ (void)data;
+ (void)numBytes;
+ return 0;
+}
--- /dev/null
+// ***************************************************************************
+// BamFtp_p.h (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 8 September 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides reading/writing of BAM files on FTP server
+// ***************************************************************************
+
+#ifndef BAMFTP_P_H
+#define BAMFTP_P_H
+
+// -------------
+// W A R N I N G
+// -------------
+//
+// This file is not part of the BamTools API. It exists purely as an
+// implementation detail. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+
+#include <api/IBamIODevice.h>
+#include <string>
+
+namespace BamTools {
+namespace Internal {
+
+class BamFtp : public IBamIODevice {
+
+ // ctor & dtor
+ public:
+ BamFtp(const std::string& url);
+ ~BamFtp(void);
+
+ // IBamIODevice implementation
+ public:
+ void Close(void);
+ bool IsRandomAccess(void) const;
+ bool Open(const IBamIODevice::OpenMode mode);
+ size_t Read(char* data, const unsigned int numBytes);
+ bool Seek(const int64_t& position);
+ int64_t Tell(void) const;
+ size_t Write(const char* data, const unsigned int numBytes);
+
+ // internal methods
+ private:
+
+ // data members
+ private:
+};
+
+} // namespace Internal
+} // namespace BamTools
+
+#endif // BAMFTP_P_H
// try to read magic number
char buffer[Constants::BAM_HEADER_MAGIC_LENGTH];
- if ( stream->Read(buffer, Constants::BAM_HEADER_MAGIC_LENGTH) != (int)Constants::BAM_HEADER_MAGIC_LENGTH ) {
+ if ( stream->Read(buffer, Constants::BAM_HEADER_MAGIC_LENGTH) != Constants::BAM_HEADER_MAGIC_LENGTH ) {
fprintf(stderr, "BamHeader ERROR: could not read magic number\n");
return false;
}
--- /dev/null
+// ***************************************************************************
+// BamHttp_p.cpp (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 9 September 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides reading/writing of BAM files on HTTP server
+// ***************************************************************************
+
+#include <api/internal/BamHttp_p.h>
+using namespace BamTools;
+using namespace BamTools::Internal;
+
+using namespace std;
+
+BamHttp::BamHttp(const string& url)
+ : IBamIODevice()
+{
+ BT_ASSERT_X(false, "BamHttp not yet implemented");
+}
+
+BamHttp::~BamHttp(void) { }
+
+void BamHttp::Close(void) {
+ return ;
+}
+
+bool BamHttp::IsRandomAccess(void) const {
+ return true;
+}
+
+bool BamHttp::Open(const IBamIODevice::OpenMode mode) {
+ (void) mode;
+ return true;
+}
+
+size_t BamHttp::Read(char* data, const unsigned int numBytes) {
+ (void)data;
+ (void)numBytes;
+ return 0;
+}
+
+bool BamHttp::Seek(const int64_t& position) {
+ (void)position;
+ return true;
+}
+
+int64_t BamHttp::Tell(void) const {
+ return -1;
+}
+
+size_t BamHttp::Write(const char* data, const unsigned int numBytes) {
+ (void)data;
+ (void)numBytes;
+ return 0;
+}
--- /dev/null
+// ***************************************************************************
+// BamHttp_p.h (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 8 September 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides reading/writing of BAM files on HTTP server
+// ***************************************************************************
+
+#ifndef BAMHTTP_P_H
+#define BAMHTTP_P_H
+
+// -------------
+// W A R N I N G
+// -------------
+//
+// This file is not part of the BamTools API. It exists purely as an
+// implementation detail. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+
+#include <api/IBamIODevice.h>
+#include <string>
+
+namespace BamTools {
+namespace Internal {
+
+class BamHttp : public IBamIODevice {
+
+ // ctor & dtor
+ public:
+ BamHttp(const std::string& url);
+ ~BamHttp(void);
+
+ // IBamIODevice implementation
+ public:
+ void Close(void);
+ bool IsRandomAccess(void) const;
+ bool Open(const IBamIODevice::OpenMode mode);
+ size_t Read(char* data, const unsigned int numBytes);
+ bool Seek(const int64_t& position);
+ int64_t Tell(void) const;
+ size_t Write(const char* data, const unsigned int numBytes);
+
+ // internal methods
+ private:
+
+ // data members
+ private:
+};
+
+} // namespace Internal
+} // namespace BamTools
+
+#endif // BAMHTTP_P_H
--- /dev/null
+// ***************************************************************************
+// BamPipe_p.cpp (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 9 September 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides BAM pipe-specific IO behavior
+// ***************************************************************************
+
+#include <api/internal/BamPipe_p.h>
+using namespace BamTools;
+using namespace BamTools::Internal;
+
+#include <cstdio>
+#include <iostream>
+using namespace std;
+
+BamPipe::BamPipe(void) : ILocalIODevice() { }
+
+BamPipe::~BamPipe(void) { }
+
+bool BamPipe::IsRandomAccess(void) const {
+ return false;
+}
+
+bool BamPipe::Open(const IBamIODevice::OpenMode mode) {
+
+ // make sure we're starting with a fresh pipe
+ Close();
+
+ // open stdin/stdout depending on requested openmode
+ if ( mode == IBamIODevice::ReadOnly )
+ m_stream = freopen(0, "rb", stdin);
+ else if ( mode == IBamIODevice::WriteOnly )
+ m_stream = freopen(0, "wb", stdout);
+ else {
+ SetErrorString("BamPipe ERROR - unsupported device mode");
+ return false;
+ }
+
+ // check that we obtained a valid FILE*
+ if ( m_stream == 0 ) {
+ string error = "BamPipe ERROR - could not open handle on ";
+ error += ( (mode == IBamIODevice::ReadOnly) ? "stdin" : "stdout" );
+ SetErrorString(error);
+ return false;
+ }
+
+ // store current IO mode & return success
+ m_mode = mode;
+ return true;
+}
+
+bool BamPipe::Seek(const int64_t& position) {
+// (void)position; // suppress compiler warning about unused variable
+// return false; // seeking not allowed in pipe
+
+ BT_ASSERT_X( m_stream, "BamFile::Seek() - null stream" );
+ cerr << "BamPipe::Seek() - about to attempt seek" << endl;
+ bool result = ( fseek64(m_stream, position, SEEK_SET) == 0);
+ if ( !result ) {
+ cerr << "BamPipe can't be seeked in" << endl;
+ }
+ return result;
+
+// return ( fseek64(m_stream, position, SEEK_SET) == 0);
+
+}
--- /dev/null
+// ***************************************************************************
+// BamPipe_p.h (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 8 September 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides BAM pipe-specific IO behavior
+// ***************************************************************************
+
+#ifndef BAMPIPE_P_H
+#define BAMPIPE_P_H
+
+// -------------
+// W A R N I N G
+// -------------
+//
+// This file is not part of the BamTools API. It exists purely as an
+// implementation detail. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+
+#include <api/internal/ILocalIODevice_p.h>
+#include <string>
+
+namespace BamTools {
+namespace Internal {
+
+class BamPipe : public ILocalIODevice {
+
+ // ctor & dtor
+ public:
+ BamPipe(void);
+ ~BamPipe(void);
+
+ // IBamIODevice implementation
+ public:
+ bool IsRandomAccess(void) const;
+ bool Open(const IBamIODevice::OpenMode mode);
+ bool Seek(const int64_t& position);
+};
+
+} // namespace Internal
+} // namespace BamTools
+
+#endif // BAMPIPE_P_H
}
void BamRandomAccessController::ClearIndex(void) {
+ if ( m_index == 0 )
+ return;
delete m_index;
m_index = 0;
}
#include <api/BamConstants.h>
#include <api/BamReader.h>
+#include <api/IBamIODevice.h>
+#include <api/internal/BamDeviceFactory_p.h>
#include <api/internal/BamHeader_p.h>
#include <api/internal/BamRandomAccessController_p.h>
#include <api/internal/BamReader_p.h>
// useful for operations requiring ONLY positional or other alignment-related information
bool BamReaderPrivate::GetNextAlignmentCore(BamAlignment& alignment) {
+ if ( !m_stream.IsOpen() )
+ return false;
+
// skip if region is set but has no alignments
if ( m_randomAccessController.HasRegion() &&
!m_randomAccessController.RegionHasAlignments() )
}
bool BamReaderPrivate::IsOpen(void) const {
- return m_stream.IsOpen;
+ return m_stream.IsOpen();
}
// load BAM header data
// swap core endian-ness if necessary
if ( m_isBigEndian ) {
- for ( int i = 0; i < Constants::BAM_CORE_SIZE; i+=sizeof(uint32_t) )
+ for ( unsigned int i = 0; i < Constants::BAM_CORE_SIZE; i+=sizeof(uint32_t) )
BamTools::SwapEndian_32p(&x[i]);
}
const unsigned int dataLength = alignment.SupportData.BlockLength - Constants::BAM_CORE_SIZE;
char* allCharData = (char*)calloc(sizeof(char), dataLength);
- if ( m_stream.Read(allCharData, dataLength) == (signed int)dataLength ) {
+ if ( m_stream.Read(allCharData, dataLength) == dataLength ) {
// store 'allCharData' in supportData structure
alignment.SupportData.AllCharData.assign((const char*)allCharData, dataLength);
// opens BAM file (and index)
bool BamReaderPrivate::Open(const string& filename) {
- // close current BAM file if open
- if ( m_stream.IsOpen )
- Close();
+ // make sure we're starting with a fresh slate
+ Close();
// attempt to open BgzfStream for reading
- if ( !m_stream.Open(filename, "rb") ) {
+ if ( !m_stream.Open(filename, IBamIODevice::ReadOnly) ) {
cerr << "BamReader ERROR: Could not open BGZF stream for " << filename << endl;
return false;
}
// returns BAM file pointer to beginning of alignment data
bool BamReaderPrivate::Rewind(void) {
+ if ( !m_stream.IsOpen() ) {
+ cerr << "BRP::Rewind() - stream not open" << endl;
+ return false;
+ }
+
// attempt rewind to first alignment
- if ( !m_stream.Seek(m_alignmentsBeginOffset) )
+ if ( !m_stream.Seek(m_alignmentsBeginOffset) ) {
+ cerr << "BRP::Rewind() - could not seek to ABO (1st time)" << endl;
return false;
+ }
// verify that we can read first alignment
BamAlignment al;
- if ( !LoadNextAlignment(al) )
+ if ( !LoadNextAlignment(al) ) {
+ cerr << "BRP::Rewind() - could not read first alignment" << endl;
return false;
+ }
// reset region
m_randomAccessController.ClearRegion();
#include <api/BamAlignment.h>
#include <api/BamConstants.h>
+#include <api/IBamIODevice.h>
#include <api/internal/BamWriter_p.h>
using namespace BamTools;
using namespace BamTools::Internal;
// returns whether BAM file is open for writing or not
bool BamWriterPrivate::IsOpen(void) const {
- return m_stream.IsOpen;
+ return m_stream.IsOpen();
}
// opens the alignment archive
const RefVector& referenceSequences)
{
// open the BGZF file for writing, return failure if error
- if ( !m_stream.Open(filename, "wb") )
+ if ( !m_stream.Open(filename, IBamIODevice::WriteOnly) )
return false;
// write BAM file 'metadata' components
// BgzfStream_p.cpp (c) 2011 Derek Barnett
// Marth Lab, Department of Biology, Boston College
// ---------------------------------------------------------------------------
-// Last modified: 2 September 2011(DB)
+// Last modified: 9 September 2011(DB)
// ---------------------------------------------------------------------------
// Based on BGZF routines developed at the Broad Institute.
// Provides the basic functionality for reading & writing BGZF files
// Replaces the old BGZF.* files to avoid clashing with other toolkits
// ***************************************************************************
+#include <api/internal/BamDeviceFactory_p.h>
#include <api/internal/BgzfStream_p.h>
using namespace BamTools;
using namespace BamTools::Internal;
#include <cstring>
#include <algorithm>
+#include <iostream>
using namespace std;
// constructor
BgzfStream::BgzfStream(void)
- : UncompressedBlockSize(Constants::BGZF_DEFAULT_BLOCK_SIZE)
- , CompressedBlockSize(Constants::BGZF_MAX_BLOCK_SIZE)
- , BlockLength(0)
- , BlockOffset(0)
- , BlockAddress(0)
- , IsOpen(false)
- , IsWriteOnly(false)
- , IsWriteCompressed(true)
- , Stream(NULL)
- , UncompressedBlock(NULL)
- , CompressedBlock(NULL)
+ : m_uncompressedBlockSize(Constants::BGZF_DEFAULT_BLOCK_SIZE)
+ , m_compressedBlockSize(Constants::BGZF_MAX_BLOCK_SIZE)
+ , m_blockLength(0)
+ , m_blockOffset(0)
+ , m_blockAddress(0)
+ , m_uncompressedBlock(NULL)
+ , m_compressedBlock(NULL)
+ , m_isOpen(false)
+ , m_isWriteOnly(false)
+ , m_isWriteCompressed(true)
+ , m_device(0)
+ , m_stream(NULL)
{
try {
- CompressedBlock = new char[CompressedBlockSize];
- UncompressedBlock = new char[UncompressedBlockSize];
+ m_compressedBlock = new char[m_compressedBlockSize];
+ m_uncompressedBlock = new char[m_uncompressedBlockSize];
} catch( std::bad_alloc& ba ) {
fprintf(stderr, "BgzfStream ERROR: unable to allocate memory\n");
exit(1);
// destructor
BgzfStream::~BgzfStream(void) {
- if( CompressedBlock ) delete[] CompressedBlock;
- if( UncompressedBlock ) delete[] UncompressedBlock;
+ if( m_compressedBlock ) delete[] m_compressedBlock;
+ if( m_uncompressedBlock ) delete[] m_uncompressedBlock;
}
// closes BGZF file
void BgzfStream::Close(void) {
- // skip if file not open
- if ( !IsOpen ) return;
+ // skip if no device open
+ if ( m_device == 0 )
+ return;
// if writing to file, flush the current BGZF block,
// then write an empty block (as EOF marker)
- if ( IsWriteOnly ) {
+ if ( m_device->IsOpen() && (m_device->Mode() == IBamIODevice::WriteOnly) ) {
FlushBlock();
int blockLength = DeflateBlock();
- fwrite(CompressedBlock, 1, blockLength, Stream);
+ m_device->Write(m_compressedBlock, blockLength);
}
- // flush and close stream
- fflush(Stream);
- fclose(Stream);
+ // close device
+ m_device->Close();
- // reset flags
- IsWriteCompressed = true;
- IsOpen = false;
+ // clean up & reset flags
+ delete m_device;
+ m_device = 0;
+ m_isWriteCompressed = true;
+ m_isOpen = false;
}
// compresses the current block
-int BgzfStream::DeflateBlock(void) {
+unsigned int BgzfStream::DeflateBlock(void) {
// initialize the gzip header
- char* buffer = CompressedBlock;
+ char* buffer = m_compressedBlock;
memset(buffer, 0, 18);
buffer[0] = Constants::GZIP_ID1;
buffer[1] = (char)Constants::GZIP_ID2;
buffer[14] = Constants::BGZF_LEN;
// set compression level
- const int compressionLevel = ( IsWriteCompressed ? Z_DEFAULT_COMPRESSION : 0 );
+ const int compressionLevel = ( m_isWriteCompressed ? Z_DEFAULT_COMPRESSION : 0 );
// loop to retry for blocks that do not compress enough
- int inputLength = BlockOffset;
- int compressedLength = 0;
- unsigned int bufferSize = CompressedBlockSize;
+ int inputLength = m_blockOffset;
+ unsigned int compressedLength = 0;
+ unsigned int bufferSize = m_compressedBlockSize;
while ( true ) {
z_stream zs;
zs.zalloc = NULL;
zs.zfree = NULL;
- zs.next_in = (Bytef*)UncompressedBlock;
+ zs.next_in = (Bytef*)m_uncompressedBlock;
zs.avail_in = inputLength;
zs.next_out = (Bytef*)&buffer[Constants::BGZF_BLOCK_HEADER_LENGTH];
zs.avail_out = bufferSize - Constants::BGZF_BLOCK_HEADER_LENGTH - Constants::BGZF_BLOCK_FOOTER_LENGTH;
// store the CRC32 checksum
unsigned int crc = crc32(0, NULL, 0);
- crc = crc32(crc, (Bytef*)UncompressedBlock, inputLength);
+ crc = crc32(crc, (Bytef*)m_uncompressedBlock, inputLength);
BamTools::PackUnsignedInt(&buffer[compressedLength - 8], crc);
BamTools::PackUnsignedInt(&buffer[compressedLength - 4], inputLength);
// ensure that we have less than a block of data left
- int remaining = BlockOffset - inputLength;
+ int remaining = m_blockOffset - inputLength;
if ( remaining > 0 ) {
if ( remaining > inputLength ) {
fprintf(stderr, "BgzfStream ERROR: after deflate, remainder too large\n");
exit(1);
}
- memcpy(UncompressedBlock, UncompressedBlock + inputLength, remaining);
+ memcpy(m_uncompressedBlock, m_uncompressedBlock + inputLength, remaining);
}
// update block data
- BlockOffset = remaining;
+ m_blockOffset = remaining;
// return result
return compressedLength;
// flushes the data in the BGZF block
void BgzfStream::FlushBlock(void) {
+ BT_ASSERT_X( m_device, "BgzfStream::FlushBlock() - attempting to flush to null device" );
+
// flush all of the remaining blocks
- while ( BlockOffset > 0 ) {
+ while ( m_blockOffset > 0 ) {
// compress the data block
- int blockLength = DeflateBlock();
+ unsigned int blockLength = DeflateBlock();
// flush the data to our output stream
- int numBytesWritten = fwrite(CompressedBlock, 1, blockLength, Stream);
+ unsigned int numBytesWritten = m_device->Write(m_compressedBlock, blockLength);
if ( numBytesWritten != blockLength ) {
fprintf(stderr, "BgzfStream ERROR: expected to write %u bytes during flushing, but wrote %u bytes\n",
blockLength, numBytesWritten);
}
// update block data
- BlockAddress += blockLength;
+ m_blockAddress += blockLength;
}
}
z_stream zs;
zs.zalloc = NULL;
zs.zfree = NULL;
- zs.next_in = (Bytef*)CompressedBlock + 18;
+ zs.next_in = (Bytef*)m_compressedBlock + 18;
zs.avail_in = blockLength - 16;
- zs.next_out = (Bytef*)UncompressedBlock;
- zs.avail_out = UncompressedBlockSize;
+ zs.next_out = (Bytef*)m_uncompressedBlock;
+ zs.avail_out = m_uncompressedBlockSize;
int status = inflateInit2(&zs, Constants::GZIP_WINDOW_BITS);
if ( status != Z_OK ) {
return zs.total_out;
}
+bool BgzfStream::IsOpen(void) const {
+ if ( m_device == 0 )
+ return false;
+ return m_device->IsOpen();
+}
+
+bool BgzfStream::Open(const string& filename, const IBamIODevice::OpenMode mode) {
+
+ // close current device if necessary
+ Close();
+
+ // sanity check
+ BT_ASSERT_X( (m_device == 0), "BgzfStream::Open() - unable to properly close previous IO device" );
+
+ // retrieve new IO device depending on filename
+ m_device = BamDeviceFactory::CreateDevice(filename);
+
+ // sanity check
+ BT_ASSERT_X( m_device, "BgzfStream::Open() - unable to create IO device from filename" );
+
+ // if device fails to open
+ if ( !m_device->Open(mode) ) {
+ cerr << "BgzfStream::Open() - unable to open IO device:" << endl;
+ cerr << m_device->ErrorString();
+ return false;
+ }
+
+ // otherwise, set flag & return true
+ m_isOpen = true;
+ m_isWriteOnly = ( mode == IBamIODevice::WriteOnly );
+ return true;
+
+}
+
// opens the BGZF file for reading (mode is either "rb" for reading, or "wb" for writing)
bool BgzfStream::Open(const string& filename, const char* mode) {
// close current stream, if necessary, before opening next
- if ( IsOpen ) Close();
+ if ( m_isOpen ) Close();
// determine open mode
if ( strcmp(mode, "rb") == 0 )
- IsWriteOnly = false;
+ m_isWriteOnly = false;
else if ( strcmp(mode, "wb") == 0)
- IsWriteOnly = true;
+ m_isWriteOnly = true;
else {
fprintf(stderr, "BgzfStream ERROR: unknown file mode: %s\n", mode);
return false;
// open BGZF stream on a file
if ( (filename != "stdin") && (filename != "stdout") && (filename != "-"))
- Stream = fopen(filename.c_str(), mode);
+ m_stream = fopen(filename.c_str(), mode);
// open BGZF stream on stdin
else if ( (filename == "stdin" || filename == "-") && (strcmp(mode, "rb") == 0 ) )
- Stream = freopen(NULL, mode, stdin);
+ m_stream = freopen(NULL, mode, stdin);
// open BGZF stream on stdout
else if ( (filename == "stdout" || filename == "-") && (strcmp(mode, "wb") == 0) )
- Stream = freopen(NULL, mode, stdout);
+ m_stream = freopen(NULL, mode, stdout);
- if ( !Stream ) {
+ if ( !m_stream ) {
fprintf(stderr, "BgzfStream ERROR: unable to open file %s\n", filename.c_str() );
return false;
}
// set flag & return success
- IsOpen = true;
+ m_isOpen = true;
return true;
}
// reads BGZF data into a byte buffer
-int BgzfStream::Read(char* data, const unsigned int dataLength) {
+unsigned int BgzfStream::Read(char* data, const unsigned int dataLength) {
- // if stream not open for reading (or empty request)
- if ( !IsOpen || IsWriteOnly || dataLength == 0 )
+ if ( dataLength == 0 )
+ return 0;
+
+ // if stream not open for reading
+ BT_ASSERT_X( m_device, "BgzfStream::Read() - trying to read from null device");
+ if ( !m_device->IsOpen() || (m_device->Mode() != IBamIODevice::ReadOnly) )
return 0;
// read blocks as needed until desired data length is retrieved
while ( numBytesRead < dataLength ) {
// determine bytes available in current block
- int bytesAvailable = BlockLength - BlockOffset;
+ int bytesAvailable = m_blockLength - m_blockOffset;
// read (and decompress) next block if needed
if ( bytesAvailable <= 0 ) {
if ( !ReadBlock() ) return -1;
- bytesAvailable = BlockLength - BlockOffset;
+ bytesAvailable = m_blockLength - m_blockOffset;
if ( bytesAvailable <= 0 ) break;
}
// copy data from uncompressed source buffer into data destination buffer
- char* buffer = UncompressedBlock;
+ char* buffer = m_uncompressedBlock;
int copyLength = min( (int)(dataLength-numBytesRead), bytesAvailable );
- memcpy(output, buffer + BlockOffset, copyLength);
+ memcpy(output, buffer + m_blockOffset, copyLength);
// update counters
- BlockOffset += copyLength;
- output += copyLength;
- numBytesRead += copyLength;
+ m_blockOffset += copyLength;
+ output += copyLength;
+ numBytesRead += copyLength;
}
// update block data
- if ( BlockOffset == BlockLength ) {
- BlockAddress = ftell64(Stream);
- BlockOffset = 0;
- BlockLength = 0;
+ if ( m_blockOffset == m_blockLength ) {
+ m_blockAddress = m_device->Tell();
+ m_blockOffset = 0;
+ m_blockLength = 0;
}
return numBytesRead;
// reads a BGZF block
bool BgzfStream::ReadBlock(void) {
- char header[Constants::BGZF_BLOCK_HEADER_LENGTH];
- int64_t blockAddress = ftell64(Stream);
+ BT_ASSERT_X( m_device, "BgzfStream::ReadBlock() - trying to read from null IO device");
+
+ // store block's starting address
+ int64_t blockAddress = m_device->Tell();
// read block header from file
- int count = fread(header, 1, sizeof(header), Stream);
+ char header[Constants::BGZF_BLOCK_HEADER_LENGTH];
+ int numBytesRead = m_device->Read(header, Constants::BGZF_BLOCK_HEADER_LENGTH);
// if block header empty
- if ( count == 0 ) {
- BlockLength = 0;
+ if ( numBytesRead == 0 ) {
+ m_blockLength = 0;
return true;
}
// if block header invalid size
- if ( count != sizeof(header) ) {
+ if ( numBytesRead != Constants::BGZF_BLOCK_HEADER_LENGTH ) {
fprintf(stderr, "BgzfStream ERROR: read block failed - could not read block header\n");
return false;
}
// copy header contents to compressed buffer
int blockLength = BamTools::UnpackUnsignedShort(&header[16]) + 1;
- char* compressedBlock = CompressedBlock;
+ char* compressedBlock = m_compressedBlock;
memcpy(compressedBlock, header, Constants::BGZF_BLOCK_HEADER_LENGTH);
int remaining = blockLength - Constants::BGZF_BLOCK_HEADER_LENGTH;
// read remainder of block
- count = fread(&compressedBlock[Constants::BGZF_BLOCK_HEADER_LENGTH], 1, remaining, Stream);
- if ( count != remaining ) {
+ numBytesRead = m_device->Read(&compressedBlock[Constants::BGZF_BLOCK_HEADER_LENGTH], remaining);
+ if ( numBytesRead != remaining ) {
fprintf(stderr, "BgzfStream ERROR: read block failed - could not read data from block\n");
return false;
}
// decompress block data
- count = InflateBlock(blockLength);
- if ( count < 0 ) {
+ numBytesRead = InflateBlock(blockLength);
+ if ( numBytesRead < 0 ) {
fprintf(stderr, "BgzfStream ERROR: read block failed - could not decompress block data\n");
return false;
}
// update block data
- if ( BlockLength != 0 )
- BlockOffset = 0;
- BlockAddress = blockAddress;
- BlockLength = count;
+ if ( m_blockLength != 0 )
+ m_blockOffset = 0;
+ m_blockAddress = blockAddress;
+ m_blockLength = numBytesRead;
// return success
return true;
// seek to position in BGZF file
bool BgzfStream::Seek(const int64_t& position) {
- // skip if not open
- if ( !IsOpen ) return false;
+ BT_ASSERT_X( m_device, "BgzfStream::Seek() - trying to seek on null IO device");
+
+ // skip if not open or not seek-able
+ if ( !IsOpen() /*|| !m_device->IsRandomAccess()*/ ) {
+ cerr << "BgzfStream::Seek() - device not open" << endl;
+ return false;
+ }
// determine adjusted offset & address
int blockOffset = (position & 0xFFFF);
int64_t blockAddress = (position >> 16) & 0xFFFFFFFFFFFFLL;
// attempt seek in file
- if ( fseek64(Stream, blockAddress, SEEK_SET) != 0 ) {
- fprintf(stderr, "BgzfStream ERROR: unable to seek in file\n");
+ if ( !m_device->Seek(blockAddress) ) {
+ cerr << "BgzfStream ERROR: unable to seek in file" << endl;
return false;
}
// update block data & return success
- BlockLength = 0;
- BlockAddress = blockAddress;
- BlockOffset = blockOffset;
+ m_blockLength = 0;
+ m_blockAddress = blockAddress;
+ m_blockOffset = blockOffset;
return true;
}
void BgzfStream::SetWriteCompressed(bool ok) {
- IsWriteCompressed = ok;
+ m_isWriteCompressed = ok;
}
// get file position in BGZF file
int64_t BgzfStream::Tell(void) const {
- if ( !IsOpen )
- return 0;
- return ( (BlockAddress << 16) | (BlockOffset & 0xFFFF) );
+ if ( !m_isOpen ) return 0;
+ return ( (m_blockAddress << 16) | (m_blockOffset & 0xFFFF) );
}
// writes the supplied data into the BGZF buffer
-unsigned int BgzfStream::Write(const char* data, const unsigned int dataLen) {
+unsigned int BgzfStream::Write(const char* data, const unsigned int dataLength) {
- // skip if file not open for writing
- if ( !IsOpen || !IsWriteOnly ) return false;
+ BT_ASSERT_X( m_device, "BgzfStream::Write() - trying to write to null IO device");
+ BT_ASSERT_X( (m_device->Mode() == IBamIODevice::WriteOnly),
+ "BgzfStream::Write() - trying to write to non-writable IO device");
// write blocks as needed til all data is written
unsigned int numBytesWritten = 0;
const char* input = data;
- unsigned int blockLength = UncompressedBlockSize;
- while ( numBytesWritten < dataLen ) {
+ unsigned int blockLength = m_uncompressedBlockSize;
+ while ( numBytesWritten < dataLength ) {
// copy data contents to uncompressed output buffer
- unsigned int copyLength = min(blockLength - BlockOffset, dataLen - numBytesWritten);
- char* buffer = UncompressedBlock;
- memcpy(buffer + BlockOffset, input, copyLength);
+ unsigned int copyLength = min(blockLength - m_blockOffset, dataLength - numBytesWritten);
+ char* buffer = m_uncompressedBlock;
+ memcpy(buffer + m_blockOffset, input, copyLength);
// update counter
- BlockOffset += copyLength;
+ m_blockOffset += copyLength;
input += copyLength;
numBytesWritten += copyLength;
// flush (& compress) output buffer when full
- if ( BlockOffset == blockLength ) FlushBlock();
+ if ( m_blockOffset == blockLength )
+ FlushBlock();
}
// return result
#include <api/BamAux.h>
#include <api/BamConstants.h>
+#include <api/IBamIODevice.h>
#include "zlib.h"
#include <cstdio>
#include <string>
public:
// closes BGZF file
void Close(void);
- // opens the BGZF file (mode is either "rb" for reading, or "wb" for writing)
+ bool IsOpen(void) const;
+ // opens the BGZF stream in requested mode
bool Open(const std::string& filename, const char* mode);
+ bool Open(const std::string& filename, const IBamIODevice::OpenMode mode);
// reads BGZF data into a byte buffer
- int Read(char* data, const unsigned int dataLength);
+ unsigned int Read(char* data, const unsigned int dataLength);
// seek to position in BGZF file
bool Seek(const int64_t& position);
+ // sets IO device (closes previous, if any, but does not attempt to open)
+ void SetIODevice(IBamIODevice* device);
// enable/disable compressed output
void SetWriteCompressed(bool ok);
// get file position in BGZF file
int64_t Tell(void) const;
// writes the supplied data into the BGZF buffer
- unsigned int Write(const char* data, const unsigned int dataLen);
+ unsigned int Write(const char* data, const unsigned int dataLength);
// internal methods
private:
// compresses the current block
- int DeflateBlock(void);
+ unsigned int DeflateBlock(void);
// flushes the data in the BGZF block
void FlushBlock(void);
// de-compresses the current block
// data members
public:
- unsigned int UncompressedBlockSize;
- unsigned int CompressedBlockSize;
- unsigned int BlockLength;
- unsigned int BlockOffset;
- uint64_t BlockAddress;
- bool IsOpen;
- bool IsWriteOnly;
- bool IsWriteCompressed;
- FILE* Stream;
- char* UncompressedBlock;
- char* CompressedBlock;
+ unsigned int m_uncompressedBlockSize;
+ unsigned int m_compressedBlockSize;
+ unsigned int m_blockLength;
+ unsigned int m_blockOffset;
+ uint64_t m_blockAddress;
+
+ char* m_uncompressedBlock;
+ char* m_compressedBlock;
+
+ bool m_isOpen;
+ bool m_isWriteOnly;
+ bool m_isWriteCompressed;
+
+ IBamIODevice* m_device;
+ FILE* m_stream;
};
// -------------------------------------------------------------
--- /dev/null
+// ***************************************************************************
+// ILocalIODevice_p.cpp (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 8 September 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides shared behavior for files & pipes
+// ***************************************************************************
+
+#include <api/internal/ILocalIODevice_p.h>
+using namespace BamTools;
+using namespace BamTools::Internal;
+
+#include <cstdio>
+using namespace std;
+
+ILocalIODevice::ILocalIODevice(void)
+ : IBamIODevice()
+ , m_stream(0)
+{ }
+
+ILocalIODevice::~ILocalIODevice(void) {
+ Close();
+}
+
+void ILocalIODevice::Close(void) {
+
+ // skip if not open
+ if ( !IsOpen() )
+ return;
+
+ // flush & close FILE*
+ fflush(m_stream);
+ fclose(m_stream);
+
+ // reset internals
+ m_mode = IBamIODevice::NotOpen;
+ m_stream = 0;
+}
+
+size_t ILocalIODevice::Read(char* data, const unsigned int numBytes) {
+ BT_ASSERT_X( m_stream, "ILocalIODevice::Read() - null stream" );
+ BT_ASSERT_X( (m_mode == IBamIODevice::ReadOnly), "ILocalIODevice::Read() - device not in read-only mode");
+ return fread(data, sizeof(char), numBytes, m_stream);
+}
+
+int64_t ILocalIODevice::Tell(void) const {
+ BT_ASSERT_X( m_stream, "ILocalIODevice::Tell() - null stream" );
+ return ftell64(m_stream);
+}
+
+size_t ILocalIODevice::Write(const char* data, const unsigned int numBytes) {
+ BT_ASSERT_X( m_stream, "ILocalIODevice::Write() - null stream" );
+ BT_ASSERT_X( (m_mode == IBamIODevice::WriteOnly), "ILocalIODevice::Write() - device not in write-only mode" );
+ return fwrite(data, sizeof(char), numBytes, m_stream);
+}
--- /dev/null
+// ***************************************************************************
+// ILocalIODevice_p.h (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 8 September 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides shared behavior for files & pipes
+// ***************************************************************************
+
+#ifndef ILOCALIODEVICE_P_H
+#define ILOCALIODEVICE_P_H
+
+// -------------
+// W A R N I N G
+// -------------
+//
+// This file is not part of the BamTools API. It exists purely as an
+// implementation detail. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+
+#include <api/IBamIODevice.h>
+
+namespace BamTools {
+namespace Internal {
+
+class ILocalIODevice : public IBamIODevice {
+
+ // ctor & dtor
+ public:
+ ILocalIODevice(void);
+ virtual ~ILocalIODevice(void);
+
+ // IBamIODevice implementation
+ public:
+ virtual void Close(void);
+ virtual size_t Read(char* data, const unsigned int numBytes);
+ virtual int64_t Tell(void) const;
+ virtual size_t Write(const char* data, const unsigned int numBytes);
+
+ // data members
+ protected:
+ FILE* m_stream;
+};
+
+} // namespace Internal
+} // namespace BamTools
+
+#endif // ILOCALIODEVICE_P_H
#endif
#endif // BAMTOOLS_TYPES
+#include <cassert>
+#include <stdexcept>
+#ifndef BAMTOOLS_ASSERTS
+#define BT_ASSERT_UNREACHABLE assert( false )
+#define BT_ASSERT_X( condition, message ) if (!( condition )) throw std::runtime_error( message );
+#endif // BAMTOOLS_ASSERTS
+
#endif // BAMTOOLS_GLOBAL_H
// bamtools_utilities.h (c) 2010 Derek Barnett, Erik Garrison
// Marth Lab, Department of Biology, Boston College
// ---------------------------------------------------------------------------
-// Last modified: 9 June 2011
+// Last modified: 8 September 2011
// ---------------------------------------------------------------------------
// Provides general utilities used by BamTools sub-tools.
// ***************************************************************************
#include <api/BamAux.h>
#include <utils/utils_global.h>
-#include <cassert>
-#include <stdexcept>
#include <string>
#include <vector>
-#define BAMTOOLS_ASSERT_UNREACHABLE assert( false )
-#define BAMTOOLS_ASSERT_MESSAGE( condition, message ) if (!( condition )) throw std::runtime_error( message );
+#define BAMTOOLS_ASSERT_UNREACHABLE BT_ASSERT_UNREACHABLE
+#define BAMTOOLS_ASSERT_MESSAGE( condition, message ) BT_ASSERT_X( condition, message )
namespace BamTools {