#define IBAMIODEVICE_H
#include "api/api_global.h"
+#include <cstdio>
#include <string>
namespace BamTools {
// IBamIODevice interface
public:
+ // TODO: add seek(pos, *from*)
+
// pure virtuals
virtual void Close(void) =0;
virtual bool IsRandomAccess(void) const =0;
virtual bool Open(const OpenMode mode) =0;
virtual int64_t Read(char* data, const unsigned int numBytes) =0;
- virtual bool Seek(const int64_t& position) =0;
+ virtual bool Seek(const int64_t& position, const int origin = SEEK_SET) =0;
virtual int64_t Tell(void) const =0;
virtual int64_t Write(const char* data, const unsigned int numBytes) =0;
// creates a new BamIndex object, depending on extension of @indexFilename
BamIndex* BamIndexFactory::CreateIndexFromFilename(const string& indexFilename, BamReaderPrivate* reader) {
- // if file doesn't exist, return null index
- if ( !BamTools::FileExists(indexFilename) )
- return 0;
+// // if file doesn't exist, return null index
+// if ( !BamTools::FileExists(indexFilename) )
+// return 0;
// get file extension from index filename, including dot (".EXT")
// if can't get file extension, return null index
// try to find index of preferred type first
// return index filename if found
string indexFilename = CreateIndexFilename(bamFilename, preferredType);
- if ( !indexFilename.empty() && BamTools::FileExists(indexFilename) )
+ if ( !indexFilename.empty() /*&& BamTools::FileExists(indexFilename)*/ )
return indexFilename;
// couldn't find preferred type, try the other supported types
// return index filename if found
if ( preferredType != BamIndex::STANDARD ) {
indexFilename = CreateIndexFilename(bamFilename, BamIndex::STANDARD);
- if ( !indexFilename.empty() && BamTools::FileExists(indexFilename) )
+ if ( !indexFilename.empty() /*&& BamTools::FileExists(indexFilename)*/ )
return indexFilename;
}
if ( preferredType != BamIndex::BAMTOOLS ) {
indexFilename = CreateIndexFilename(bamFilename, BamIndex::BAMTOOLS);
- if ( !indexFilename.empty() && BamTools::FileExists(indexFilename) )
+ if ( !indexFilename.empty()/* && BamTools::FileExists(indexFilename) */)
return indexFilename;
}
#include "api/BamAlignment.h"
#include "api/internal/bam/BamReader_p.h"
#include "api/internal/index/BamStandardIndex_p.h"
+#include "api/internal/io/BamDeviceFactory_p.h"
#include "api/internal/utils/BamException_p.h"
using namespace BamTools;
using namespace BamTools::Internal;
// ----------------------------
BamStandardIndex::RaiiWrapper::RaiiWrapper(void)
- : IndexStream(0)
+ : Device(0)
, Buffer(0)
{ }
BamStandardIndex::RaiiWrapper::~RaiiWrapper(void) {
- if ( IndexStream ) {
- fclose(IndexStream);
- IndexStream = 0;
+ if ( Device ) {
+ Device->Close();
+ delete Device;
+ Device = 0;
}
if ( Buffer ) {
for ( int j = 0; j < numAlignmentChunks; ++j ) {
// read chunk start & stop from buffer
- memcpy((char*)&chunkStart, Resources.Buffer+offset, sizeof(uint64_t));
+ memcpy((char*)&chunkStart, m_resources.Buffer+offset, sizeof(uint64_t));
offset += sizeof(uint64_t);
- memcpy((char*)&chunkStop, Resources.Buffer+offset, sizeof(uint64_t));
+ memcpy((char*)&chunkStop, m_resources.Buffer+offset, sizeof(uint64_t));
offset += sizeof(uint64_t);
// swap endian-ness if necessary
// check 'magic number' to see if file is BAI index
char magic[4];
- const size_t elementsRead = fread(magic, sizeof(char), 4, Resources.IndexStream);
- if ( elementsRead != 4 )
+ const int64_t numBytesRead = m_resources.Device->Read(magic, sizeof(magic));
+ if ( numBytesRead != 4 )
throw BamException("BamStandardIndex::CheckMagicNumber", "could not read BAI magic number");
// compare to expected value
void BamStandardIndex::CloseFile(void) {
// close file stream
- if ( IsFileOpen() ) {
- fclose(Resources.IndexStream);
- Resources.IndexStream = 0;
+ if ( IsDeviceOpen() ) {
+ m_resources.Device->Close();
+ delete m_resources.Device;
+ m_resources.Device = 0;
}
// clear index file summary data
m_indexFileSummary.clear();
// clean up I/O buffer
- delete[] Resources.Buffer;
- Resources.Buffer = 0;
+ delete[] m_resources.Buffer;
+ m_resources.Buffer = 0;
m_bufferLength = 0;
}
// open new index file (read & write)
string indexFilename = m_reader->Filename() + Extension();
- OpenFile(indexFilename, "w+b");
+ OpenFile(indexFilename, IBamIODevice::ReadWrite);
// initialize BaiFileSummary with number of references
const int& numReferences = m_reader->GetReferenceCount();
return ( refSummary.NumBins > 0 );
}
-bool BamStandardIndex::IsFileOpen(void) const {
- return ( Resources.IndexStream != 0 );
+bool BamStandardIndex::IsDeviceOpen(void) const {
+ if ( m_resources.Device == 0 )
+ return false;
+ return m_resources.Device->IsOpen();
}
// 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);
// validate format
CheckMagicNumber();
chunks = mergedChunks;
}
-void BamStandardIndex::OpenFile(const std::string& filename, const char* mode) {
+void BamStandardIndex::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.Device->Open(mode);
+ if ( !IsDeviceOpen() ) {
const string message = string("could not open file: ") + filename;
throw BamException("BamStandardIndex::OpenFile", message);
}
}
void BamStandardIndex::ReadBinID(uint32_t& binId) {
- const size_t elementsRead = fread(&binId, sizeof(binId), 1, Resources.IndexStream);
+ const int64_t numBytesRead = m_resources.Device->Read((char*)&binId, sizeof(binId));
if ( m_isBigEndian ) SwapEndian_32(binId);
- if ( elementsRead != 1 )
+ if ( numBytesRead != sizeof(binId) )
throw BamException("BamStandardIndex::ReadBinID", "could not read BAI bin ID");
}
void BamStandardIndex::ReadIntoBuffer(const unsigned int& bytesRequested) {
// ensure that our buffer is big enough for request
- BamStandardIndex::CheckBufferSize(Resources.Buffer, m_bufferLength, bytesRequested);
+ BamStandardIndex::CheckBufferSize(m_resources.Buffer, m_bufferLength, bytesRequested);
// read from BAI file stream
- const size_t bytesRead = fread( Resources.Buffer, sizeof(char), bytesRequested, Resources.IndexStream );
- if ( bytesRead != (size_t)bytesRequested ) {
+ const int64_t bytesRead = m_resources.Device->Read(m_resources.Buffer, bytesRequested);
+ if ( bytesRead != (int64_t)bytesRequested ) {
stringstream s("");
s << "expected to read: " << bytesRequested << " bytes, "
<< "but instead read: " << bytesRead;
}
void BamStandardIndex::ReadLinearOffset(uint64_t& linearOffset) {
- const size_t elementsRead = fread(&linearOffset, sizeof(linearOffset), 1, Resources.IndexStream);
+ const int64_t numBytesRead = m_resources.Device->Read((char*)&linearOffset, sizeof(linearOffset));
if ( m_isBigEndian ) SwapEndian_64(linearOffset);
- if ( elementsRead != 1 )
+ if ( numBytesRead != sizeof(linearOffset) )
throw BamException("BamStandardIndex::ReadLinearOffset", "could not read BAI linear offset");
}
void BamStandardIndex::ReadNumAlignmentChunks(int& numAlignmentChunks) {
- const size_t elementsRead = fread(&numAlignmentChunks, sizeof(numAlignmentChunks), 1, Resources.IndexStream);
+ const int64_t numBytesRead = m_resources.Device->Read((char*)&numAlignmentChunks, sizeof(numAlignmentChunks));
if ( m_isBigEndian ) SwapEndian_32(numAlignmentChunks);
- if ( elementsRead != 1 )
+ if ( numBytesRead != sizeof(numAlignmentChunks) )
throw BamException("BamStandardIndex::ReadNumAlignmentChunks", "could not read BAI chunk count");
}
void BamStandardIndex::ReadNumBins(int& numBins) {
- const size_t elementsRead = fread(&numBins, sizeof(numBins), 1, Resources.IndexStream);
+ const int64_t numBytesRead = m_resources.Device->Read((char*)&numBins, sizeof(numBins));
if ( m_isBigEndian ) SwapEndian_32(numBins);
- if ( elementsRead != 1 )
+ if ( numBytesRead != sizeof(numBins) )
throw BamException("BamStandardIndex::ReadNumBins", "could not read BAI bin count");
}
void BamStandardIndex::ReadNumLinearOffsets(int& numLinearOffsets) {
- const size_t elementsRead = fread(&numLinearOffsets, sizeof(numLinearOffsets), 1, Resources.IndexStream);
+ const int64_t numBytesRead = m_resources.Device->Read((char*)&numLinearOffsets, sizeof(numLinearOffsets));
if ( m_isBigEndian ) SwapEndian_32(numLinearOffsets);
- if ( elementsRead != 1 )
+ if ( numBytesRead != sizeof(numLinearOffsets) )
throw BamException("BamStandardIndex::ReadNumAlignmentChunks", "could not read BAI linear offset count");
}
void BamStandardIndex::ReadNumReferences(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));
if ( m_isBigEndian ) SwapEndian_32(numReferences);
- if ( elementsRead != 1 )
+ if ( numBytesRead != sizeof(numReferences) )
throw BamException("BamStandardIndex::ReadNumReferences", "could not read reference count");
}
}
// seek to position in index file stream
-void BamStandardIndex::Seek(const int64_t& position, const int& origin) {
- if ( fseek64(Resources.IndexStream, position, origin) != 0 )
+void BamStandardIndex::Seek(const int64_t& position, const int origin) {
+ if ( !m_resources.Device->Seek(position, origin) )
throw BamException("BamStandardIndex::Seek", "could not seek in BAI file");
}
// return position of file pointer in index file stream
int64_t BamStandardIndex::Tell(void) const {
- return ftell64(Resources.IndexStream);
+ return m_resources.Device->Tell();
}
void BamStandardIndex::WriteAlignmentChunk(const BaiAlignmentChunk& chunk) {
}
// write to index file
- size_t elementsWritten = 0;
- elementsWritten += fwrite(&start, sizeof(start), 1, Resources.IndexStream);
- elementsWritten += fwrite(&stop, sizeof(stop), 1, Resources.IndexStream);
- if ( elementsWritten != 2 )
+ int64_t numBytesWritten = 0;
+ numBytesWritten += m_resources.Device->Write((const char*)&start, sizeof(start));
+ numBytesWritten += m_resources.Device->Write((const char*)&stop, sizeof(stop));
+ if ( numBytesWritten != (sizeof(start)+sizeof(stop)) )
throw BamException("BamStandardIndex::WriteAlignmentChunk", "could not write BAI alignment chunk");
}
// write chunks
int32_t chunkCount = chunks.size();
if ( m_isBigEndian ) SwapEndian_32(chunkCount);
- const size_t elementsWritten = fwrite(&chunkCount, sizeof(chunkCount), 1, Resources.IndexStream);
- if ( elementsWritten != 1 )
+ const int64_t numBytesWritten = m_resources.Device->Write((const char*)&chunkCount, sizeof(chunkCount));
+ if ( numBytesWritten != sizeof(chunkCount) )
throw BamException("BamStandardIndex::WriteAlignmentChunks", "could not write BAI chunk count");
// iterate over chunks
// write BAM bin ID
uint32_t binKey = binId;
if ( m_isBigEndian ) SwapEndian_32(binKey);
- const size_t elementsWritten = fwrite(&binKey, sizeof(binKey), 1, Resources.IndexStream);
- if ( elementsWritten != 1 )
+ const int64_t numBytesWritten = m_resources.Device->Write((const char*)&binKey, sizeof(binKey));
+ if ( numBytesWritten != sizeof(binKey) )
throw BamException("BamStandardIndex::WriteBin", "could not write bin ID");
// write bin's alignment chunks
// write number of bins
int32_t binCount = bins.size();
if ( m_isBigEndian ) SwapEndian_32(binCount);
- const size_t elementsWritten = fwrite(&binCount, sizeof(binCount), 1, Resources.IndexStream);
- if ( elementsWritten != 1 )
+ const int64_t numBytesWritten = m_resources.Device->Write((const char*)&binCount, sizeof(binCount));
+ if ( numBytesWritten != sizeof(binCount) )
throw BamException("BamStandardIndex::WriteBins", "could not write bin count");
// save summary for reference's bins
void BamStandardIndex::WriteHeader(void) {
- size_t elementsWritten = 0;
+ int64_t numBytesWritten = 0;
// write magic number
- elementsWritten += fwrite(BamStandardIndex::BAI_MAGIC, sizeof(char), 4, Resources.IndexStream);
+ numBytesWritten += m_resources.Device->Write(BamStandardIndex::BAI_MAGIC, 4);
// write number of reference sequences
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));
- if ( elementsWritten != 5 )
+ if ( numBytesWritten != sizeof(numReferences)+4 )
throw BamException("BamStandardIndex::WriteHeader", "could not write BAI header");
}
// make sure linear offsets are sorted before writing & saving summary
SortLinearOffsets(linearOffsets);
- size_t elementsWritten = 0;
+ int64_t numBytesWritten = 0;
// write number of linear offsets
int32_t offsetCount = linearOffsets.size();
if ( m_isBigEndian ) SwapEndian_32(offsetCount);
- elementsWritten += fwrite(&offsetCount, sizeof(offsetCount), 1, Resources.IndexStream);
+ numBytesWritten += m_resources.Device->Write((const char*)&offsetCount, sizeof(offsetCount));
// save summary for reference's linear offsets
SaveLinearOffsetsSummary(refId, linearOffsets.size());
// write linear offset
uint64_t linearOffset = (*offsetIter);
if ( m_isBigEndian ) SwapEndian_64(linearOffset);
- elementsWritten += fwrite(&linearOffset, sizeof(linearOffset), 1, Resources.IndexStream);
+ numBytesWritten += m_resources.Device->Write((const char*)&linearOffset, sizeof(linearOffset));
}
- if ( elementsWritten != (linearOffsets.size() + 1) )
+ if ( numBytesWritten != (sizeof(offsetCount) + linearOffsets.size()*sizeof(uint64_t)) )
throw BamException("BamStandardIndex::WriteLinearOffsets", "could not write BAI linear offsets");
}
#include "api/BamAux.h"
#include "api/BamIndex.h"
+#include "api/IBamIODevice.h"
#include <map>
#include <set>
#include <string>
// index file ops
void CheckMagicNumber(void);
void CloseFile(void);
- bool IsFileOpen(void) const;
- void OpenFile(const std::string& filename, const char* mode);
- void Seek(const int64_t& position, const int& origin);
+ bool IsDeviceOpen(void) const;
+ void OpenFile(const std::string& filename, IBamIODevice::OpenMode mode);
+ void Seek(const int64_t& position, const int origin);
int64_t Tell(void) const;
// BAI index building methods
// our input buffer
unsigned int m_bufferLength;
-
struct RaiiWrapper {
- FILE* IndexStream;
+ IBamIODevice* Device;
char* Buffer;
RaiiWrapper(void);
~RaiiWrapper(void);
};
- RaiiWrapper Resources;
+ RaiiWrapper m_resources;
// static methods
private:
#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
#include "api/BamAux.h"
#include "api/BamIndex.h"
+#include "api/IBamIODevice.h"
#include <map>
#include <string>
#include <vector>
void CheckMagicNumber(void);
void CheckVersion(void);
void CloseFile(void);
- bool IsFileOpen(void) const;
- void OpenFile(const std::string& filename, const char* mode);
- void Seek(const int64_t& position, const int& origin);
+ bool IsDeviceOpen(void) const;
+ void OpenFile(const std::string& filename, IBamIODevice::OpenMode mode);
+ void Seek(const int64_t& position, const int origin);
int64_t Tell(void) const;
// index-creation methods
struct RaiiWrapper {
FILE* IndexStream;
+ IBamIODevice* Device;
RaiiWrapper(void);
~RaiiWrapper(void);
};
- RaiiWrapper Resources;
+ RaiiWrapper m_resources;
// static constants
private:
m_stream = fopen(m_filename.c_str(), "rb");
else if ( mode == IBamIODevice::WriteOnly )
m_stream = fopen(m_filename.c_str(), "wb");
+ else if ( mode == IBamIODevice::ReadWrite )
+ m_stream = fopen(m_filename.c_str(), "w+b");
else {
SetErrorString("BamFile::Open", "unknown open mode requested");
return false;
return true;
}
-bool BamFile::Seek(const int64_t& position) {
+bool BamFile::Seek(const int64_t& position, const int origin) {
BT_ASSERT_X( m_stream, "BamFile::Seek() - null stream" );
- return ( fseek64(m_stream, position, SEEK_SET) == 0 );
+ return ( fseek64(m_stream, position, origin) == 0 );
}
void Close(void);
bool IsRandomAccess(void) const;
bool Open(const IBamIODevice::OpenMode mode);
- bool Seek(const int64_t& position);
+ bool Seek(const int64_t& position, const int origin = SEEK_SET);
// data members
private:
return true;
}
-bool BamFtp::Seek(const int64_t& position) {
+bool BamFtp::Seek(const int64_t& position, const int origin) {
// if FTP device not in a valid state
if ( !IsOpen() ) {
m_commandSocket->DisconnectFromHost();
// update file position & return success
- m_filePosition = position;
+ if ( origin == SEEK_CUR )
+ m_filePosition += position;
+ else if ( origin == SEEK_SET)
+ m_filePosition = position;
+ else {
+ // TODO: set error string
+ return false;
+ }
return true;
}
bool IsRandomAccess(void) const;
bool Open(const IBamIODevice::OpenMode mode);
int64_t Read(char* data, const unsigned int numBytes);
- bool Seek(const int64_t& position);
+ bool Seek(const int64_t& position, const int origin = SEEK_SET);
int64_t Tell(void) const;
int64_t Write(const char* data, const unsigned int numBytes);
return false;
}
-bool BamHttp::Seek(const int64_t& position) {
+bool BamHttp::Seek(const int64_t& position, const int origin) {
// if HTTP device not in a valid state
if ( !IsOpen() ) {
// discard socket's buffer contents, update positions, & return success
m_socket->ClearBuffer();
- m_filePosition = position;
- m_endRangeFilePosition = position;
+
+ if ( origin == SEEK_CUR )
+ m_filePosition += position;
+ else if ( origin == SEEK_SET )
+ m_filePosition = position;
+ else {
+ // TODO: set error string
+ return false;
+ }
+ m_endRangeFilePosition = m_filePosition;
return true;
}
bool IsRandomAccess(void) const;
bool Open(const IBamIODevice::OpenMode mode);
int64_t Read(char* data, const unsigned int numBytes);
- bool Seek(const int64_t& position);
+ bool Seek(const int64_t& position, const int origin = SEEK_SET);
int64_t Tell(void) const;
int64_t Write(const char* data, const unsigned int numBytes);
return true;
}
-bool BamPipe::Seek(const int64_t& ) {
+bool BamPipe::Seek(const int64_t&, const int) {
SetErrorString("BamPipe::Seek", "random access not allowed in FIFO pipe");
return false;
}
public:
bool IsRandomAccess(void) const;
bool Open(const IBamIODevice::OpenMode mode);
- bool Seek(const int64_t& position);
+ bool Seek(const int64_t& position, const int origin = SEEK_SET);
};
} // namespace Internal
# include "api/internal/io/NetUnix_p.h"
#endif
-#include <iostream> // debug
-
// standard C++ includes
#include <cstdlib>
#include <cstring>
// do 'normal' lookup
else {
- cout << "HostInfo::Lookup() - looking up addresses for domain name: " << hostname << endl;
-
// setup address lookup 'hints'
addrinfo hints;
memset(&hints, 0, sizeof(hints));
// if everything OK
if ( status == 0 ) {
- cout << "HostInfo::Lookup() - found addresses" << endl;
-
// iterate over all IP addresses found
addrinfo* p = res;
for ( ; p != NULL; p = p->ai_next ) {
if ( p->ai_family == AF_INET ) {
sockaddr_in* ipv4 = (sockaddr_in*)p->ai_addr;
HostAddress a( ntohl(ipv4->sin_addr.s_addr) );
- cout << "\t" << a.GetIPString() << endl;
uniqueAddresses.insert(a);
}
else if ( p->ai_family == AF_INET6 ) {
sockaddr_in6* ipv6 = (sockaddr_in6*)p->ai_addr;
HostAddress a(ipv6->sin6_addr.s6_addr);
- cout << "\t" << a.GetIPString() << endl;
uniqueAddresses.insert(a);
}
}