#include "api/BamAlignment.h"
#include "api/internal/bam/BamReader_p.h"
#include "api/internal/index/BamToolsIndex_p.h"
+#include "api/internal/io/BamDeviceFactory_p.h"
#include "api/internal/io/BgzfStream_p.h"
#include "api/internal/utils/BamException_p.h"
using namespace BamTools;
BamToolsIndex::RaiiWrapper::RaiiWrapper(void)
: IndexStream(0)
+ , Device(0)
{ }
BamToolsIndex::RaiiWrapper::~RaiiWrapper(void) {
- if ( IndexStream )
+ if ( IndexStream ) {
fclose(IndexStream);
+ IndexStream = 0;
+ }
+
+ if ( Device ) {
+ Device->Close();
+ delete Device;
+ Device = 0;
+ }
}
// ------------------------------
// read magic number
char magic[4];
- size_t elementsRead = fread(magic, sizeof(char), 4, Resources.IndexStream);
- if ( elementsRead != 4 )
+ const int64_t numBytesRead = m_resources.Device->Read(magic, 4);
+ if ( numBytesRead != 4 )
throw BamException("BamToolsIndex::CheckMagicNumber", "could not read BTI magic number");
// validate expected magic number
void BamToolsIndex::CheckVersion(void) {
// read version from file
- size_t elementsRead = fread(&m_inputVersion, sizeof(m_inputVersion), 1, Resources.IndexStream);
- if ( elementsRead != 1 )
+ const int64_t numBytesRead = m_resources.Device->Read((char*)&m_inputVersion, sizeof(m_inputVersion));
+// size_t elementsRead = fread(&m_inputVersion, sizeof(m_inputVersion), 1, m_resources.IndexStream);
+// if ( elementsRead != 1 )
+ if ( numBytesRead != sizeof(m_inputVersion) )
throw BamException("BamToolsIndex::CheckVersion", "could not read format version");
if ( m_isBigEndian ) SwapEndian_32(m_inputVersion);
}
void BamToolsIndex::CloseFile(void) {
- if ( IsFileOpen() ) {
- fclose(Resources.IndexStream);
- Resources.IndexStream = 0;
+ if ( IsDeviceOpen() ) {
+ fclose(m_resources.IndexStream);
+ m_resources.IndexStream = 0;
+
+ m_resources.Device->Close();
+ delete m_resources.Device;
+ m_resources.Device = 0;
}
m_indexFileSummary.clear();
}
try {
// open new index file (read & write)
const string indexFilename = m_reader->Filename() + Extension();
- OpenFile(indexFilename, "w+b");
+ OpenFile(indexFilename, IBamIODevice::ReadWrite);
// initialize BtiFileSummary with number of references
const int& numReferences = m_reader->GetReferenceCount();
}
// returns true if the index stream is open
-bool BamToolsIndex::IsFileOpen(void) const {
- return ( Resources.IndexStream != 0 );
+bool BamToolsIndex::IsDeviceOpen(void) const {
+ if ( m_resources.Device == 0 )
+ return false;
+ return m_resources.Device->IsOpen();
+// return ( m_resources.IndexStream != 0 );
}
// attempts to use index data to jump to @region, returns success/fail
try {
// attempt to open file (read-only)
- OpenFile(filename, "rb");
+ OpenFile(filename, IBamIODevice::ReadOnly);
// load metadata & generate in-memory summary
LoadHeader();
CheckVersion();
// use file's BTI block size to set member variable
- const size_t elementsRead = fread(&m_blockSize, sizeof(m_blockSize), 1, Resources.IndexStream);
+ const int64_t numBytesRead = m_resources.Device->Read((char*)&m_blockSize, sizeof(m_blockSize));
+// const size_t elementsRead = fread(&m_blockSize, sizeof(m_blockSize), 1, m_resources.IndexStream);
if ( m_isBigEndian ) SwapEndian_32(m_blockSize);
- if ( elementsRead != 1 )
+// if ( elementsRead != 1 )
+ if ( numBytesRead != sizeof(m_blockSize) )
throw BamException("BamToolsIndex::LoadHeader", "could not read BTI block size");
}
void BamToolsIndex::LoadNumBlocks(int& numBlocks) {
- const size_t elementsRead = fread(&numBlocks, sizeof(numBlocks), 1, Resources.IndexStream);
+ const int64_t numBytesRead = m_resources.Device->Read((char*)&numBlocks, sizeof(numBlocks));
+// const size_t elementsRead = fread(&numBlocks, sizeof(numBlocks), 1, m_resources.IndexStream);
if ( m_isBigEndian ) SwapEndian_32(numBlocks);
- if ( elementsRead != 1 )
+// if ( elementsRead != 1 )
+ if ( numBytesRead != sizeof(numBlocks) )
throw BamException("BamToolsIndex::LoadNumBlocks", "could not read number of BTI blocks");
}
void BamToolsIndex::LoadNumReferences(int& numReferences) {
- const size_t elementsRead = fread(&numReferences, sizeof(numReferences), 1, Resources.IndexStream);
+ const int64_t numBytesRead = m_resources.Device->Read((char*)&numReferences, sizeof(numReferences));
+// const size_t elementsRead = fread(&numReferences, sizeof(numReferences), 1, m_resources.IndexStream);
if ( m_isBigEndian ) SwapEndian_32(numReferences);
- if ( elementsRead != 1 )
+// if ( elementsRead != 1 )
+ if ( numBytesRead != sizeof(numReferences) )
throw BamException("BamToolsIndex::LoadNumReferences", "could not read number of references");
}
SkipBlocks(numBlocks);
}
-void BamToolsIndex::OpenFile(const std::string& filename, const char* mode) {
+void BamToolsIndex::OpenFile(const std::string& filename, IBamIODevice::OpenMode mode) {
// make sure any previous index file is closed
CloseFile();
+ m_resources.Device = BamDeviceFactory::CreateDevice(filename);
+ if ( m_resources.Device == 0 ) {
+ const string message = string("could not open file: ") + filename;
+ throw BamException("BamStandardIndex::OpenFile", message);
+ }
+
// attempt to open file
- Resources.IndexStream = fopen(filename.c_str(), mode);
- if ( !IsFileOpen() ) {
+// m_resources.IndexStream = fopen(filename.c_str(), mode);
+ m_resources.Device->Open(mode);
+ if ( !IsDeviceOpen() ) {
const string message = string("could not open file: ") + filename;
throw BamException("BamToolsIndex::OpenFile", message);
}
void BamToolsIndex::ReadBlock(BtiBlock& block) {
// read in block data members
- size_t elementsRead = 0;
- elementsRead += fread(&block.MaxEndPosition, sizeof(block.MaxEndPosition), 1, Resources.IndexStream);
- elementsRead += fread(&block.StartOffset, sizeof(block.StartOffset), 1, Resources.IndexStream);
- elementsRead += fread(&block.StartPosition, sizeof(block.StartPosition), 1, Resources.IndexStream);
+// size_t elementsRead = 0;
+// elementsRead += fread(&block.MaxEndPosition, sizeof(block.MaxEndPosition), 1, m_resources.IndexStream);
+// elementsRead += fread(&block.StartOffset, sizeof(block.StartOffset), 1, m_resources.IndexStream);
+// elementsRead += fread(&block.StartPosition, sizeof(block.StartPosition), 1, m_resources.IndexStream);
+
+ int64_t numBytesRead = 0;
+ numBytesRead += m_resources.Device->Read((char*)&block.MaxEndPosition, sizeof(block.MaxEndPosition));
+ numBytesRead += m_resources.Device->Read((char*)&block.StartOffset, sizeof(block.StartOffset));
+ numBytesRead += m_resources.Device->Read((char*)&block.StartPosition, sizeof(block.StartPosition));
// swap endian-ness if necessary
if ( m_isBigEndian ) {
SwapEndian_32(block.StartPosition);
}
- if ( elementsRead != 3 )
+// if ( elementsRead != 3 )
+ const int expectedBytes = sizeof(block.MaxEndPosition) +
+ sizeof(block.StartOffset) +
+ sizeof(block.StartPosition);
+ if ( numBytesRead != expectedBytes )
throw BamException("BamToolsIndex::ReadBlock", "could not read block");
}
ReadBlocks(refSummary, refEntry.Blocks);
}
-void BamToolsIndex::Seek(const int64_t& position, const int& origin) {
- if ( fseek64(Resources.IndexStream, position, origin) != 0 )
+void BamToolsIndex::Seek(const int64_t& position, const int origin) {
+ if ( !m_resources.Device->Seek(position, origin) )
+// if ( fseek64(m_resources.IndexStream, position, origin) != 0 )
throw BamException("BamToolsIndex::Seek", "could not seek in BAI file");
}
}
int64_t BamToolsIndex::Tell(void) const {
- return ftell64(Resources.IndexStream);
+ return m_resources.Device->Tell();
+// return ftell64(m_resources.IndexStream);
}
void BamToolsIndex::WriteBlock(const BtiBlock& block) {
}
// write the reference index entry
- size_t elementsWritten = 0;
- elementsWritten += fwrite(&maxEndPosition, sizeof(maxEndPosition), 1, Resources.IndexStream);
- elementsWritten += fwrite(&startOffset, sizeof(startOffset), 1, Resources.IndexStream);
- elementsWritten += fwrite(&startPosition, sizeof(startPosition), 1, Resources.IndexStream);
- if ( elementsWritten != 3 )
+ int64_t numBytesWritten = 0;
+ numBytesWritten += m_resources.Device->Write((const char*)&maxEndPosition, sizeof(maxEndPosition));
+ numBytesWritten += m_resources.Device->Write((const char*)&startOffset, sizeof(startOffset));
+ numBytesWritten += m_resources.Device->Write((const char*)&startPosition, sizeof(startPosition));
+ const int expectedBytes = sizeof(maxEndPosition) +
+ sizeof(startOffset) +
+ sizeof(startPosition);
+
+// size_t elementsWritten = 0;
+// elementsWritten += fwrite(&maxEndPosition, sizeof(maxEndPosition), 1, m_resources.IndexStream);
+// elementsWritten += fwrite(&startOffset, sizeof(startOffset), 1, m_resources.IndexStream);
+// elementsWritten += fwrite(&startPosition, sizeof(startPosition), 1, m_resources.IndexStream);
+// if ( elementsWritten != 3 )
+ if ( numBytesWritten != expectedBytes )
throw BamException("BamToolsIndex::WriteBlock", "could not write BTI block");
}
void BamToolsIndex::WriteHeader(void) {
- size_t elementsWritten = 0;
+ int64_t numBytesWritten = 0 ;
+// size_t elementsWritten = 0;
// write BTI index format 'magic number'
- elementsWritten += fwrite(BamToolsIndex::BTI_MAGIC, 1, 4, Resources.IndexStream);
+ numBytesWritten += m_resources.Device->Write(BamToolsIndex::BTI_MAGIC, 4);
+// elementsWritten += fwrite(BamToolsIndex::BTI_MAGIC, 1, 4, m_resources.IndexStream);
// write BTI index format version
int32_t currentVersion = (int32_t)m_outputVersion;
if ( m_isBigEndian ) SwapEndian_32(currentVersion);
- elementsWritten += fwrite(¤tVersion, sizeof(currentVersion), 1, Resources.IndexStream);
+ numBytesWritten += m_resources.Device->Write((const char*)¤tVersion, sizeof(currentVersion));
+// elementsWritten += fwrite(¤tVersion, sizeof(currentVersion), 1, m_resources.IndexStream);
// write block size
uint32_t blockSize = m_blockSize;
if ( m_isBigEndian ) SwapEndian_32(blockSize);
- elementsWritten += fwrite(&blockSize, sizeof(blockSize), 1, Resources.IndexStream);
+ numBytesWritten += m_resources.Device->Write((const char*)&blockSize, sizeof(blockSize));
+// elementsWritten += fwrite(&blockSize, sizeof(blockSize), 1, m_resources.IndexStream);
// write number of references
int32_t numReferences = m_indexFileSummary.size();
if ( m_isBigEndian ) SwapEndian_32(numReferences);
- elementsWritten += fwrite(&numReferences, sizeof(numReferences), 1, Resources.IndexStream);
+ numBytesWritten += m_resources.Device->Write((const char*)&numReferences, sizeof(numReferences));
+// elementsWritten += fwrite(&numReferences, sizeof(numReferences), 1, m_resources.IndexStream);
+
+ const int expectedBytes = 4 +
+ sizeof(currentVersion) +
+ sizeof(blockSize) +
+ sizeof(numReferences);
- if ( elementsWritten != 7 )
+// if ( elementsWritten != 7 )
+ if ( numBytesWritten != expectedBytes )
throw BamException("BamToolsIndex::WriteHeader", "could not write BTI header");
}
// write number of blocks this reference
uint32_t numBlocks = refEntry.Blocks.size();
if ( m_isBigEndian ) SwapEndian_32(numBlocks);
- const size_t elementsWritten = fwrite(&numBlocks, sizeof(numBlocks), 1, Resources.IndexStream);
- if ( elementsWritten != 1 )
+ const int64_t numBytesWritten = m_resources.Device->Write((const char*)&numBlocks, sizeof(numBlocks));
+// const size_t elementsWritten = fwrite(&numBlocks, sizeof(numBlocks), 1, m_resources.IndexStream);
+// if ( elementsWritten != 1 )
+ if ( numBytesWritten != sizeof(numBlocks) )
throw BamException("BamToolsIndex::WriteReferenceEntry", "could not write number of blocks");
// write actual block entries