diff --git a/src/api/BamReader.cpp b/src/api/BamReader.cpp index c4f04322..927e511d 100644 --- a/src/api/BamReader.cpp +++ b/src/api/BamReader.cpp @@ -276,6 +276,22 @@ bool BamReader::Open(const std::string& filename) { return d->Open(filename); } +/*! \fn bool BamReader::Open(const std::string& filename, IBamIODevice* device) + \brief Opens a BAM file with a custom io device. + + If BamReader is already opened on another file, this function closes + that file, then attempts to open requested \a filename. + + \param[in] filename name of BAM file to open + + \returns \c true if BAM file was opened successfully + \sa Close(), IsOpen(), OpenIndex() +*/ +bool BamReader::Open(const std::string& filename, IBamIODevice* device) +{ + return d->Open(filename, device); +} + /*! \fn bool BamReader::OpenIndex(const std::string& indexFilename) \brief Opens a BAM index file. diff --git a/src/api/BamReader.h b/src/api/BamReader.h index 15b41354..4d1bf163 100644 --- a/src/api/BamReader.h +++ b/src/api/BamReader.h @@ -1,4 +1,4 @@ -// *************************************************************************** +// *************************************************************************** // BamReader.h (c) 2009 Derek Barnett, Michael Str�mberg // Marth Lab, Department of Biology, Boston College // --------------------------------------------------------------------------- @@ -14,6 +14,7 @@ #include "api/BamAlignment.h" #include "api/BamIndex.h" #include "api/SamHeader.h" +#include "api/IBamIODevice.h" #include namespace BamTools { @@ -46,6 +47,8 @@ class API_EXPORT BamReader { bool Jump(int refID, int position = 0); // opens a BAM file bool Open(const std::string& filename); + // opens a BAM file with a custom io device. Device is deleted by BamReader so it must be created on a heap + bool Open(const std::string& filename, IBamIODevice* device); // returns internal file pointer to beginning of alignment data bool Rewind(void); // sets the target region of interest diff --git a/src/api/BamWriter.cpp b/src/api/BamWriter.cpp index cbbfdae7..8030b570 100644 --- a/src/api/BamWriter.cpp +++ b/src/api/BamWriter.cpp @@ -96,6 +96,15 @@ bool BamWriter::Open(const std::string& filename, return d->Open(filename, samHeaderText, referenceSequences); } +bool BamWriter::Open(const std::string& filename, + const SamHeader& samHeader, + const RefVector& referenceSequences, + IBamIODevice* device) +{ + return d->Open(filename, samHeader.ToString(), referenceSequences, device); +} + + /*! \fn bool BamWriter::Open(const std::string& filename, const SamHeader& samHeader, const RefVector& referenceSequences) diff --git a/src/api/BamWriter.h b/src/api/BamWriter.h index f4817211..66644813 100644 --- a/src/api/BamWriter.h +++ b/src/api/BamWriter.h @@ -12,6 +12,7 @@ #include "api/api_global.h" #include "api/BamAux.h" +#include "api/IBamIODevice.h" #include namespace BamTools { @@ -54,6 +55,12 @@ class API_EXPORT BamWriter { bool Open(const std::string& filename, const SamHeader& samHeader, const RefVector& referenceSequences); + // opens a BAM file for writing using a custom oi device + // Device is deleted by BamWriter so it must be created on a heap + bool Open(const std::string& filename, + const SamHeader& samHeader, + const RefVector& referenceSequences, + IBamIODevice* device); // saves the alignment to the alignment archive bool SaveAlignment(const BamAlignment& alignment); // sets the output compression mode diff --git a/src/api/internal/bam/BamReader_p.cpp b/src/api/internal/bam/BamReader_p.cpp index 737d5980..caf5d2aa 100644 --- a/src/api/internal/bam/BamReader_p.cpp +++ b/src/api/internal/bam/BamReader_p.cpp @@ -363,7 +363,7 @@ bool BamReaderPrivate::LocateIndex(const BamIndex::IndexType& preferredType) { } // opens BAM file (and index) -bool BamReaderPrivate::Open(const string& filename) { +bool BamReaderPrivate::Open(const string& filename, IBamIODevice* device) { try { @@ -371,7 +371,7 @@ bool BamReaderPrivate::Open(const string& filename) { Close(); // open BgzfStream - m_stream.Open(filename, IBamIODevice::ReadOnly); + m_stream.Open(filename, IBamIODevice::ReadOnly, device); // load BAM metadata LoadHeaderData(); diff --git a/src/api/internal/bam/BamReader_p.h b/src/api/internal/bam/BamReader_p.h index a49ad2a5..c6d49a24 100644 --- a/src/api/internal/bam/BamReader_p.h +++ b/src/api/internal/bam/BamReader_p.h @@ -27,6 +27,7 @@ #include "api/internal/bam/BamHeader_p.h" #include "api/internal/bam/BamRandomAccessController_p.h" #include "api/internal/io/BgzfStream_p.h" +#include "api/IBamIODevice.h" #include namespace BamTools { @@ -46,7 +47,7 @@ class BamReaderPrivate { bool Close(void); const std::string Filename(void) const; bool IsOpen(void) const; - bool Open(const std::string& filename); + bool Open(const std::string& filename, IBamIODevice* device = 0); bool Rewind(void); bool SetRegion(const BamRegion& region); diff --git a/src/api/internal/bam/BamWriter_p.cpp b/src/api/internal/bam/BamWriter_p.cpp index 637bb7a1..aada7a4a 100644 --- a/src/api/internal/bam/BamWriter_p.cpp +++ b/src/api/internal/bam/BamWriter_p.cpp @@ -155,12 +155,13 @@ bool BamWriterPrivate::IsOpen(void) const { // opens the alignment archive bool BamWriterPrivate::Open(const string& filename, const string& samHeaderText, - const RefVector& referenceSequences) + const RefVector& referenceSequences, + IBamIODevice* device) { try { // open the BGZF file for writing - m_stream.Open(filename, IBamIODevice::WriteOnly); + m_stream.Open(filename, IBamIODevice::WriteOnly, device); // write BAM file 'metadata' components WriteMagicNumber(); diff --git a/src/api/internal/bam/BamWriter_p.h b/src/api/internal/bam/BamWriter_p.h index d5bbe8d6..91fddd13 100644 --- a/src/api/internal/bam/BamWriter_p.h +++ b/src/api/internal/bam/BamWriter_p.h @@ -22,6 +22,7 @@ #include "api/BamAux.h" #include "api/internal/io/BgzfStream_p.h" +#include "api/IBamIODevice.h" #include #include @@ -45,7 +46,8 @@ class BamWriterPrivate { bool IsOpen(void) const; bool Open(const std::string& filename, const std::string& samHeaderText, - const BamTools::RefVector& referenceSequences); + const BamTools::RefVector& referenceSequences, + IBamIODevice* device = 0); bool SaveAlignment(const BamAlignment& al); void SetWriteCompressed(bool ok); diff --git a/src/api/internal/io/BgzfStream_p.cpp b/src/api/internal/io/BgzfStream_p.cpp index 1f4e0d88..b691b5f9 100644 --- a/src/api/internal/io/BgzfStream_p.cpp +++ b/src/api/internal/io/BgzfStream_p.cpp @@ -268,15 +268,21 @@ bool BgzfStream::IsOpen(void) const { return m_device->IsOpen(); } -void BgzfStream::Open(const string& filename, const IBamIODevice::OpenMode mode) { +void BgzfStream::Open(const string& filename, const IBamIODevice::OpenMode mode, IBamIODevice* device) { // close current device if necessary Close(); 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); - BT_ASSERT_X( m_device, "BgzfStream::Open() - unable to create IO device from filename" ); + // or use the device provided by the client + if (device == 0) { + m_device = BamDeviceFactory::CreateDevice(filename); + } + else { + m_device = device; + } + BT_ASSERT_X( m_device, "BgzfStream::Open() - unable to create IO device from filename" ); // if device fails to open if ( !m_device->Open(mode) ) { diff --git a/src/api/internal/io/BgzfStream_p.h b/src/api/internal/io/BgzfStream_p.h index a386c1a3..b6ec578f 100644 --- a/src/api/internal/io/BgzfStream_p.h +++ b/src/api/internal/io/BgzfStream_p.h @@ -44,7 +44,7 @@ class BgzfStream { // returns true if BgzfStream open for IO bool IsOpen(void) const; // opens the BGZF file - void Open(const std::string& filename, const IBamIODevice::OpenMode mode); + void Open(const std::string& filename, const IBamIODevice::OpenMode mode, IBamIODevice* device = 0); // reads BGZF data into a byte buffer size_t Read(char* data, const size_t dataLength); // seek to position in BGZF file