From 57ff487e7acaf7f55a45c0a80cb9647bb1d83801 Mon Sep 17 00:00:00 2001 From: derek Date: Fri, 9 Sep 2011 15:09:53 -0400 Subject: [PATCH] Refactored shared pipe/file behavior into ILocalIODevice --- src/api/CMakeLists.txt | 2 + src/api/IBamIODevice.h | 5 ++- src/api/internal/BamFile_p.cpp | 47 +++++---------------- src/api/internal/BamFile_p.h | 17 +++----- src/api/internal/BamPipe_p.cpp | 56 ++++++++------------------ src/api/internal/BamPipe_p.h | 17 ++------ src/api/internal/BamReader_p.cpp | 12 ++++-- src/api/internal/BamWriter_p.cpp | 3 +- src/api/internal/BgzfStream_p.cpp | 6 ++- src/api/internal/ILocalIODevice_p.cpp | 56 ++++++++++++++++++++++++++ src/api/internal/ILocalIODevice_p.h | 50 +++++++++++++++++++++++ src/api/internal/IRemoteIODevice_p.cpp | 0 src/api/internal/IRemoteIODevice_p.h | 0 13 files changed, 161 insertions(+), 110 deletions(-) create mode 100644 src/api/internal/ILocalIODevice_p.cpp create mode 100644 src/api/internal/ILocalIODevice_p.h create mode 100644 src/api/internal/IRemoteIODevice_p.cpp create mode 100644 src/api/internal/IRemoteIODevice_p.h diff --git a/src/api/CMakeLists.txt b/src/api/CMakeLists.txt index e9c3b65..5a03712 100644 --- a/src/api/CMakeLists.txt +++ b/src/api/CMakeLists.txt @@ -39,6 +39,8 @@ set( BamToolsAPISources 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 diff --git a/src/api/IBamIODevice.h b/src/api/IBamIODevice.h index c59bb4a..99454b2 100644 --- a/src/api/IBamIODevice.h +++ b/src/api/IBamIODevice.h @@ -21,6 +21,8 @@ class API_EXPORT IBamIODevice { // IBamIODevice interface public: + + // pure virtuals virtual void Close(void) =0; virtual bool IsRandomAccess(void) const =0; virtual bool Open(const OpenMode mode) =0; @@ -28,7 +30,8 @@ class API_EXPORT IBamIODevice { 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; - public: + + // default implementation provided virtual std::string ErrorString(void); virtual bool IsOpen(void) const; virtual OpenMode Mode(void) const; diff --git a/src/api/internal/BamFile_p.cpp b/src/api/internal/BamFile_p.cpp index d9c8673..6cb5be4 100644 --- a/src/api/internal/BamFile_p.cpp +++ b/src/api/internal/BamFile_p.cpp @@ -2,9 +2,9 @@ // BamFile_p.cpp (c) 2011 Derek Barnett // Marth Lab, Department of Biology, Boston College // --------------------------------------------------------------------------- -// Last modified: 8 September 2011 (DB) +// Last modified: 9 September 2011 (DB) // --------------------------------------------------------------------------- -// Provides reading of local BAM files +// Provides BAM file-specific IO behavior // *************************************************************************** #include @@ -12,32 +12,21 @@ using namespace BamTools; using namespace BamTools::Internal; #include +#include using namespace std; BamFile::BamFile(const string& filename) - : IBamIODevice() - , m_stream(0) + : ILocalIODevice() , m_filename(filename) { } -BamFile::~BamFile(void) { - Close(); -} +BamFile::~BamFile(void) { } void BamFile::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; - m_filename.clear(); + if ( IsOpen() ) { + m_filename.clear(); + ILocalIODevice::Close(); + } } bool BamFile::IsRandomAccess(void) const { @@ -72,24 +61,8 @@ bool BamFile::Open(const IBamIODevice::OpenMode mode) { return true; } -size_t BamFile::Read(char* data, const unsigned int numBytes) { - BT_ASSERT_X( m_stream, "BamFile::Read() - null stream" ); - BT_ASSERT_X( (m_mode == IBamIODevice::ReadOnly), "BamFile::Read() - device not in read-only mode"); - return fread(data, sizeof(char), numBytes, m_stream); -} - 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); } - -int64_t BamFile::Tell(void) const { - BT_ASSERT_X( m_stream, "BamFile::Tell() - null stream" ); - return ftell64(m_stream); -} - -size_t BamFile::Write(const char* data, const unsigned int numBytes) { - BT_ASSERT_X( m_stream, "BamFile::Write() - null stream" ); - BT_ASSERT_X( (m_mode == IBamIODevice::WriteOnly), "BamFile::Write() - device not in write-only mode" ); - return fwrite(data, sizeof(char), numBytes, m_stream); -} diff --git a/src/api/internal/BamFile_p.h b/src/api/internal/BamFile_p.h index d0712ef..fd25a3e 100644 --- a/src/api/internal/BamFile_p.h +++ b/src/api/internal/BamFile_p.h @@ -2,9 +2,9 @@ // BamFile_p.h (c) 2011 Derek Barnett // Marth Lab, Department of Biology, Boston College // --------------------------------------------------------------------------- -// Last modified: 8 September 2011 (DB) +// Last modified: 9 September 2011 (DB) // --------------------------------------------------------------------------- -// Provides reading/writing of local BAM files +// Provides BAM file-specific IO behavior // *************************************************************************** #ifndef BAMFILE_P_H @@ -20,35 +20,28 @@ // // We mean it. -#include +#include #include namespace BamTools { namespace Internal { -class BamFile : public IBamIODevice { +class BamFile : public ILocalIODevice { // ctor & dtor public: BamFile(const std::string& filename); ~BamFile(void); - // IBamIODevice implementation + // ILocalIODevice 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: - FILE* m_stream; std::string m_filename; }; diff --git a/src/api/internal/BamPipe_p.cpp b/src/api/internal/BamPipe_p.cpp index 6bfbf6f..62fd789 100644 --- a/src/api/internal/BamPipe_p.cpp +++ b/src/api/internal/BamPipe_p.cpp @@ -2,9 +2,9 @@ // BamPipe_p.cpp (c) 2011 Derek Barnett // Marth Lab, Department of Biology, Boston College // --------------------------------------------------------------------------- -// Last modified: 8 September 2011 (DB) +// Last modified: 9 September 2011 (DB) // --------------------------------------------------------------------------- -// Provides reading/writing of piped BAM files (stdin/stdout) +// Provides BAM pipe-specific IO behavior // *************************************************************************** #include @@ -12,30 +12,12 @@ using namespace BamTools; using namespace BamTools::Internal; #include +#include using namespace std; -BamPipe::BamPipe(void) - : IBamIODevice() - , m_stream(0) -{ } +BamPipe::BamPipe(void) : ILocalIODevice() { } -BamPipe::~BamPipe(void) { - Close(); -} - -void BamPipe::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; -} +BamPipe::~BamPipe(void) { } bool BamPipe::IsRandomAccess(void) const { return false; @@ -69,24 +51,18 @@ bool BamPipe::Open(const IBamIODevice::OpenMode mode) { return true; } -size_t BamPipe::Read(char* data, const unsigned int numBytes) { - BT_ASSERT_X( m_stream, "BamPipe::Read() - null stream" ); - BT_ASSERT_X( (m_mode == IBamIODevice::ReadOnly), "BamPipe::Read() - device not in read-only mode"); - return fread(data, sizeof(char), numBytes, m_stream); -} - bool BamPipe::Seek(const int64_t& position) { - (void)position; // suppress compiler warning about unused variable - return false; // seeking not allowed in pipe -} +// (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; -int64_t BamPipe::Tell(void) const { - BT_ASSERT_X( m_stream, "BamPipe::Tell() - null stream" ); - return ftell64(m_stream); -} +// return ( fseek64(m_stream, position, SEEK_SET) == 0); -size_t BamPipe::Write(const char* data, const unsigned int numBytes) { - BT_ASSERT_X( m_stream, "BamPipe::Write() - null stream" ); - BT_ASSERT_X( (m_mode == IBamIODevice::WriteOnly), "BamPipe::Write() - device not in write-only mode" ); - return fwrite(data, sizeof(char), numBytes, m_stream); } diff --git a/src/api/internal/BamPipe_p.h b/src/api/internal/BamPipe_p.h index 386ede0..a9725be 100644 --- a/src/api/internal/BamPipe_p.h +++ b/src/api/internal/BamPipe_p.h @@ -4,7 +4,7 @@ // --------------------------------------------------------------------------- // Last modified: 8 September 2011 (DB) // --------------------------------------------------------------------------- -// Provides reading/writing of piped BAM files (stdin/stdout) +// Provides BAM pipe-specific IO behavior // *************************************************************************** #ifndef BAMPIPE_P_H @@ -20,13 +20,13 @@ // // We mean it. -#include +#include #include namespace BamTools { namespace Internal { -class BamPipe : public IBamIODevice { +class BamPipe : public ILocalIODevice { // ctor & dtor public: @@ -35,20 +35,9 @@ class BamPipe : public IBamIODevice { // 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: - FILE* m_stream; }; } // namespace Internal diff --git a/src/api/internal/BamReader_p.cpp b/src/api/internal/BamReader_p.cpp index 87fe310..e4e2310 100644 --- a/src/api/internal/BamReader_p.cpp +++ b/src/api/internal/BamReader_p.cpp @@ -344,17 +344,23 @@ bool BamReaderPrivate::OpenIndex(const std::string& indexFilename) { // returns BAM file pointer to beginning of alignment data bool BamReaderPrivate::Rewind(void) { - if ( !m_stream.IsOpen() ) + 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(); diff --git a/src/api/internal/BamWriter_p.cpp b/src/api/internal/BamWriter_p.cpp index 508b6da..8f1b167 100644 --- a/src/api/internal/BamWriter_p.cpp +++ b/src/api/internal/BamWriter_p.cpp @@ -10,6 +10,7 @@ #include #include +#include #include using namespace BamTools; using namespace BamTools::Internal; @@ -134,7 +135,7 @@ bool BamWriterPrivate::Open(const string& filename, 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 diff --git a/src/api/internal/BgzfStream_p.cpp b/src/api/internal/BgzfStream_p.cpp index b79164d..4db9b15 100644 --- a/src/api/internal/BgzfStream_p.cpp +++ b/src/api/internal/BgzfStream_p.cpp @@ -428,8 +428,10 @@ bool BgzfStream::Seek(const int64_t& position) { 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() ) + if ( !IsOpen() /*|| !m_device->IsRandomAccess()*/ ) { + cerr << "BgzfStream::Seek() - device not open" << endl; return false; + } // determine adjusted offset & address int blockOffset = (position & 0xFFFF); @@ -437,7 +439,7 @@ bool BgzfStream::Seek(const int64_t& position) { // attempt seek in file if ( !m_device->Seek(blockAddress) ) { - fprintf(stderr, "BgzfStream ERROR: unable to seek in file\n"); + cerr << "BgzfStream ERROR: unable to seek in file" << endl; return false; } diff --git a/src/api/internal/ILocalIODevice_p.cpp b/src/api/internal/ILocalIODevice_p.cpp new file mode 100644 index 0000000..9e9a2b3 --- /dev/null +++ b/src/api/internal/ILocalIODevice_p.cpp @@ -0,0 +1,56 @@ +// *************************************************************************** +// 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 +using namespace BamTools; +using namespace BamTools::Internal; + +#include +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); +} diff --git a/src/api/internal/ILocalIODevice_p.h b/src/api/internal/ILocalIODevice_p.h new file mode 100644 index 0000000..1e64899 --- /dev/null +++ b/src/api/internal/ILocalIODevice_p.h @@ -0,0 +1,50 @@ +// *************************************************************************** +// 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 + +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 diff --git a/src/api/internal/IRemoteIODevice_p.cpp b/src/api/internal/IRemoteIODevice_p.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/api/internal/IRemoteIODevice_p.h b/src/api/internal/IRemoteIODevice_p.h new file mode 100644 index 0000000..e69de29 -- 2.39.5