// IBamIODevice.h (c) 2011 Derek Barnett
// Marth Lab, Department of Biology, Boston College
// ---------------------------------------------------------------------------
-// Last modified: 10 October 2011 (DB)
+// Last modified: 10 November 2011 (DB)
// ---------------------------------------------------------------------------
// Base class for all BAM I/O devices (e.g. local file, pipe, HTTP, FTP, etc.)
//
// BamIndexFactory_p.cpp (c) 2011 Derek Barnett
// Marth Lab, Department of Biology, Boston College
// ---------------------------------------------------------------------------
-// Last modified: 25 October 2011 (DB)
+// Last modified: 10 November 2011 (DB)
// ---------------------------------------------------------------------------
// Provides interface for generating BamIndex implementations
// ***************************************************************************
-#include "api/BamAux.h"
#include "api/internal/index/BamIndexFactory_p.h"
#include "api/internal/index/BamStandardIndex_p.h"
#include "api/internal/index/BamToolsIndex_p.h"
// 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;
-
// get file extension from index filename, including dot (".EXT")
// if can't get file extension, return null index
const string extension = FileExtension(indexFilename);
// 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() )
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() )
return indexFilename;
}
if ( preferredType != BamIndex::BAMTOOLS ) {
indexFilename = CreateIndexFilename(bamFilename, BamIndex::BAMTOOLS);
- if ( !indexFilename.empty()/* && BamTools::FileExists(indexFilename) */)
+ if ( !indexFilename.empty() )
return indexFilename;
}
// BamStandardIndex.cpp (c) 2010 Derek Barnett
// Marth Lab, Department of Biology, Boston College
// ---------------------------------------------------------------------------
-// Last modified: 25 October 2011 (DB)
+// Last modified: 10 November 2011 (DB)
// ---------------------------------------------------------------------------
// Provides index operations for the standardized BAM index format (".bai")
// ***************************************************************************
// BamStandardIndex.h (c) 2010 Derek Barnett
// Marth Lab, Department of Biology, Boston College
// ---------------------------------------------------------------------------
-// Last modified: 10 October 2011 (DB)
+// Last modified: 10 November 2011 (DB)
// ---------------------------------------------------------------------------
// Provides index operations for the standardized BAM index format (".bai")
// ***************************************************************************
// BamToolsIndex.cpp (c) 2010 Derek Barnett
// Marth Lab, Department of Biology, Boston College
// ---------------------------------------------------------------------------
-// Last modified: 25 October 2011 (DB)
+// Last modified: 10 November 2011 (DB)
// ---------------------------------------------------------------------------
// Provides index operations for the BamTools index format (".bti")
// ***************************************************************************
// ----------------------------
BamToolsIndex::RaiiWrapper::RaiiWrapper(void)
- : IndexStream(0)
- , Device(0)
+ : Device(0)
{ }
BamToolsIndex::RaiiWrapper::~RaiiWrapper(void) {
- if ( IndexStream ) {
- fclose(IndexStream);
- IndexStream = 0;
- }
-
if ( Device ) {
Device->Close();
delete Device;
// read version from file
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 ( IsDeviceOpen() ) {
- fclose(m_resources.IndexStream);
- m_resources.IndexStream = 0;
-
m_resources.Device->Close();
delete m_resources.Device;
m_resources.Device = 0;
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
// use file's BTI block size to set member variable
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 ( numBytesRead != sizeof(m_blockSize) )
throw BamException("BamToolsIndex::LoadHeader", "could not read BTI block size");
}
void BamToolsIndex::LoadNumBlocks(int& numBlocks) {
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 ( numBytesRead != sizeof(numBlocks) )
throw BamException("BamToolsIndex::LoadNumBlocks", "could not read number of BTI blocks");
}
void BamToolsIndex::LoadNumReferences(int& numReferences) {
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 ( numBytesRead != sizeof(numReferences) )
throw BamException("BamToolsIndex::LoadNumReferences", "could not read number of references");
}
}
// attempt to open file
-// m_resources.IndexStream = fopen(filename.c_str(), mode);
m_resources.Device->Open(mode);
if ( !IsDeviceOpen() ) {
const string message = string("could not open file: ") + filename;
void BamToolsIndex::ReadBlock(BtiBlock& block) {
// read in block data members
-// 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));
SwapEndian_32(block.StartPosition);
}
-// if ( elementsRead != 3 )
+ // check block read ok
const int expectedBytes = sizeof(block.MaxEndPosition) +
sizeof(block.StartOffset) +
sizeof(block.StartPosition);
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 m_resources.Device->Tell();
-// return ftell64(m_resources.IndexStream);
}
void BamToolsIndex::WriteBlock(const BtiBlock& block) {
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));
+
+ // check block written ok
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) {
int64_t numBytesWritten = 0 ;
-// size_t elementsWritten = 0;
// write BTI index format 'magic number'
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);
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);
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);
numBytesWritten += m_resources.Device->Write((const char*)&numReferences, sizeof(numReferences));
-// elementsWritten += fwrite(&numReferences, sizeof(numReferences), 1, m_resources.IndexStream);
+ // check header written ok
const int expectedBytes = 4 +
sizeof(currentVersion) +
sizeof(blockSize) +
sizeof(numReferences);
-
-// if ( elementsWritten != 7 )
if ( numBytesWritten != expectedBytes )
throw BamException("BamToolsIndex::WriteHeader", "could not write BTI header");
}
uint32_t numBlocks = refEntry.Blocks.size();
if ( m_isBigEndian ) SwapEndian_32(numBlocks);
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");
// BamToolsIndex.h (c) 2010 Derek Barnett
// Marth Lab, Department of Biology, Boston College
// ---------------------------------------------------------------------------
-// Last modified: 10 October 2011 (DB)
+// Last modified: 10 November 2011 (DB)
// ---------------------------------------------------------------------------
// Provides index operations for the BamTools index format (".bti")
// ***************************************************************************
Version m_outputVersion;
struct RaiiWrapper {
- FILE* IndexStream;
IBamIODevice* Device;
RaiiWrapper(void);
~RaiiWrapper(void);
// BamFile_p.cpp (c) 2011 Derek Barnett
// Marth Lab, Department of Biology, Boston College
// ---------------------------------------------------------------------------
-// Last modified: 25 October 2011 (DB)
+// Last modified: 10 November 2011 (DB)
// ---------------------------------------------------------------------------
// Provides BAM file-specific IO behavior
// ***************************************************************************
// BamFile_p.h (c) 2011 Derek Barnett
// Marth Lab, Department of Biology, Boston College
// ---------------------------------------------------------------------------
-// Last modified: 25 October 2011 (DB)
+// Last modified: 10 November 2011 (DB)
// ---------------------------------------------------------------------------
// Provides BAM file-specific IO behavior
// ***************************************************************************
// BamFtp_p.cpp (c) 2011 Derek Barnett
// Marth Lab, Department of Biology, Boston College
// ---------------------------------------------------------------------------
-// Last modified: 8 November 2011 (DB)
+// Last modified: 10 November 2011 (DB)
// ---------------------------------------------------------------------------
// Provides reading/writing of BAM files on FTP server
// ***************************************************************************
using namespace BamTools;
using namespace BamTools::Internal;
-#include <iostream> // debug
-
#include <cctype>
#include <cstdlib>
#include <sstream>
// constants
// -----------
-static const uint16_t FTP_PORT = 21;
-static const string FTP_PREFIX = "ftp://";
-static const size_t FTP_PREFIX_LENGTH = 6;
-static const string FTP_NEWLINE = "\r\n";
+static const uint16_t FTP_PORT = 21;
+static const string FTP_PREFIX = "ftp://";
+static const size_t FTP_PREFIX_LENGTH = 6;
+static const string FTP_NEWLINE = "\r\n";
+
static const string DEFAULT_USER = "anonymous";
static const string DEFAULT_PASS = "anonymous@";
+
static const string ABOR_CMD = "ABOR";
static const string USER_CMD = "USER";
static const string PASS_CMD = "PASS";
static const string REST_CMD = "REST";
static const string RETR_CMD = "RETR";
static const string TYPE_CMD = "TYPE";
-static const char COLON_CHAR = ':';
-static const char COMMA_CHAR = ',';
-static const char DOT_CHAR = '.';
-static const char MINUS_CHAR = '-';
-static const char SLASH_CHAR = '/';
-static const char SPACE_CHAR = ' ';
-static const char LEFT_PAREN_CHAR = '(';
-static const char RIGHT_PAREN_CHAR = ')';
+
+static const char CMD_SEPARATOR = ' ';
+static const char HOST_SEPARATOR = '/';
+static const char IP_SEPARATOR = '.';
+
+static const char MULTILINE_CONTINUE = '-';
+
+static const char PASV_REPLY_PREFIX = '(';
+static const char PASV_REPLY_SEPARATOR = ',';
+static const char PASV_REPLY_SUFFIX = ')';
// -----------------
// utility methods
}
// send USER command
- string userCommand = USER_CMD + SPACE_CHAR + m_username + FTP_NEWLINE;
+ string userCommand = USER_CMD + CMD_SEPARATOR + m_username + FTP_NEWLINE;
if ( !SendCommand(userCommand, true) ) {
Close();
return false;
}
// send PASS command
- string passwordCommand = PASS_CMD + SPACE_CHAR + m_password + FTP_NEWLINE;
+ string passwordCommand = PASS_CMD + CMD_SEPARATOR + m_password + FTP_NEWLINE;
if ( !SendCommand(passwordCommand, true) ) {
Close();
return false;
}
// send TYPE command
- string typeCommand = TYPE_CMD + SPACE_CHAR + "I" + FTP_NEWLINE;
+ string typeCommand = TYPE_CMD + CMD_SEPARATOR + 'I' + FTP_NEWLINE;
if ( !SendCommand(typeCommand, true) ) {
Close();
return false;
stringstream fpStream("");
fpStream << m_filePosition;
- string restartCommand = REST_CMD + SPACE_CHAR + fpStream.str() + FTP_NEWLINE;
+ string restartCommand = REST_CMD + CMD_SEPARATOR + fpStream.str() + FTP_NEWLINE;
if ( !SendCommand(restartCommand, true) ) {
// TODO: set error string
return false;
}
// main file retrieval request
- string retrieveCommand = RETR_CMD + SPACE_CHAR + m_filename + FTP_NEWLINE;
+ string retrieveCommand = RETR_CMD + CMD_SEPARATOR + m_filename + FTP_NEWLINE;
if ( !SendCommand(retrieveCommand, false) ) {
// TODO: set error string
return false;
return false;
// find parentheses
- const size_t leftParenFound = m_response.find(LEFT_PAREN_CHAR);
- const size_t rightParenFound = m_response.find(RIGHT_PAREN_CHAR);
+ const size_t leftParenFound = m_response.find(PASV_REPLY_PREFIX);
+ const size_t rightParenFound = m_response.find(PASV_REPLY_SUFFIX);
if ( leftParenFound == string::npos || rightParenFound == string::npos )
return false;
const string hostAndPort(responseBegin+leftParenFound+1, responseBegin+rightParenFound);
// parse into string fields
- vector<string> fields = split(hostAndPort, COMMA_CHAR);
+ vector<string> fields = split(hostAndPort, PASV_REPLY_SEPARATOR);
if ( fields.size() != 6 )
return false;
// fetch passive connection IP
- m_dataHostname = fields[0] + DOT_CHAR +
- fields[1] + DOT_CHAR +
- fields[2] + DOT_CHAR +
+ m_dataHostname = fields[0] + IP_SEPARATOR +
+ fields[1] + IP_SEPARATOR +
+ fields[2] + IP_SEPARATOR +
fields[3];
// fetch passive connection port
return;
// find end of host name portion (first '/' hit after the prefix)
- const size_t firstSlashFound = tempUrl.find(SLASH_CHAR, FTP_PREFIX_LENGTH);
+ const size_t firstSlashFound = tempUrl.find(HOST_SEPARATOR, FTP_PREFIX_LENGTH);
if ( firstSlashFound == string::npos ) {
; // no slash found... no filename given along with host?
}
isdigit(headerLine[0]) &&
isdigit(headerLine[1]) &&
isdigit(headerLine[2]) &&
- ( headerLine[3] != MINUS_CHAR )
+ ( headerLine[3] != MULTILINE_CONTINUE )
)
{
headerEnd = true;
// BamFtp_p.h (c) 2011 Derek Barnett
// Marth Lab, Department of Biology, Boston College
// ---------------------------------------------------------------------------
-// Last modified: 10 October 2011 (DB)
+// Last modified: 10 November 2011 (DB)
// ---------------------------------------------------------------------------
// Provides reading/writing of BAM files on FTP server
// ***************************************************************************
// data members
private:
- // our main socket
+
+ // our main sockets
TcpSocket* m_commandSocket;
TcpSocket* m_dataSocket;
// BamHttp_p.cpp (c) 2011 Derek Barnett
// Marth Lab, Department of Biology, Boston College
// ---------------------------------------------------------------------------
-// Last modified: 8 November 2011 (DB)
+// Last modified: 10 November 2011 (DB)
// ---------------------------------------------------------------------------
// Provides reading/writing of BAM files on HTTP server
// ***************************************************************************
static const string HTTP_PORT = "80";
static const string HTTP_PREFIX = "http://";
static const size_t HTTP_PREFIX_LENGTH = 7;
-static const char COLON_CHAR = ':';
-static const char SLASH_CHAR = '/';
+
+static const string DOUBLE_NEWLINE = "\n\n";
+
+static const string GET_METHOD = "GET";
+static const string HOST_HEADER = "Host";
+static const string RANGE_HEADER = "Range";
+static const string BYTES_PREFIX = "bytes=";
+
+static const char HOST_SEPARATOR = '/';
+static const char PROXY_SEPARATOR = ':';
// -----------------
// utility methods
return;
// find end of host name portion (first '/' hit after the prefix)
- const size_t firstSlashFound = tempUrl.find(SLASH_CHAR, HTTP_PREFIX_LENGTH);
+ const size_t firstSlashFound = tempUrl.find(HOST_SEPARATOR, HTTP_PREFIX_LENGTH);
if ( firstSlashFound == string::npos ) {
; // no slash found... no filename given along with host?
}
// fetch hostname (check for proxy port)
string hostname = tempUrl.substr(HTTP_PREFIX_LENGTH, (firstSlashFound - HTTP_PREFIX_LENGTH));
- const size_t colonFound = hostname.find(COLON_CHAR);
+ const size_t colonFound = hostname.find(PROXY_SEPARATOR);
if ( colonFound != string::npos ) {
; // TODO: handle proxy port (later, just skip for now)
} else {
// there is data left from last request
if ( m_endRangeFilePosition > m_filePosition ) {
- // try to read either the total 'remainingBytes' or whatever we have remaining from last request range
+ // try to read either the total 'remainingBytes' or
+ // whatever we have remaining from last request range
const size_t rangeRemainingBytes = m_endRangeFilePosition - m_filePosition;
const size_t bytesToRead = std::min(remainingBytes, rangeRemainingBytes);
const int64_t socketBytesRead = ReadFromSocket(data+bytesReadSoFar, bytesToRead);
m_filePosition += socketBytesRead;
}
- // otherwise, this is a 1st-time read OR we already read everything from the last GET request
+ // otherwise, this is a 1st-time read or
+ // we already read everything from the last GET request
else {
// request for next range
// fetch header, up until double new line
string responseHeader;
- static const string doubleNewLine = "\n\n";
do {
// read line & append to full header
const string headerLine = m_socket->ReadLine();
responseHeader += headerLine;
- } while ( !endsWith(responseHeader, doubleNewLine) );
+ } while ( !endsWith(responseHeader, DOUBLE_NEWLINE) );
// sanity check
if ( responseHeader.empty() ) {
// create range string
m_endRangeFilePosition = m_filePosition + numBytes;
stringstream range("");
- range << "bytes=" << m_filePosition << "-" << m_endRangeFilePosition;
+ range << BYTES_PREFIX << m_filePosition << '-' << m_endRangeFilePosition;
// make sure we're connected
if ( !EnsureSocketConnection() )
return false;
// create request
- m_request = new HttpRequestHeader("GET", m_filename);
- m_request->SetField("Host", m_hostname);
- m_request->SetField("Range", range.str());
+ m_request = new HttpRequestHeader(GET_METHOD, m_filename);
+ m_request->SetField(HOST_HEADER, m_hostname);
+ m_request->SetField(RANGE_HEADER, range.str());
// write request to socket
const string requestHeader = m_request->ToString();
// BamHttp_p.h (c) 2011 Derek Barnett
// Marth Lab, Department of Biology, Boston College
// ---------------------------------------------------------------------------
-// Last modified: 7 November 2011 (DB)
+// Last modified: 10 November 2011 (DB)
// ---------------------------------------------------------------------------
// Provides reading/writing of BAM files on HTTP server
// ***************************************************************************
// BamPipe_p.cpp (c) 2011 Derek Barnett
// Marth Lab, Department of Biology, Boston College
// ---------------------------------------------------------------------------
-// Last modified: 25 October 2011 (DB)
+// Last modified: 10 November 2011 (DB)
// ---------------------------------------------------------------------------
// Provides BAM pipe-specific IO behavior
// ***************************************************************************
else if ( mode == IBamIODevice::WriteOnly )
m_stream = freopen(0, "wb", stdout);
else {
- const string errorType = string( mode == IBamIODevice::ReadWrite ? "unsupported"
- : "unknown" );
+ const string errorType = string( (mode == IBamIODevice::ReadWrite) ? "unsupported"
+ : "unknown" );
const string message = errorType + " open mode requested";
SetErrorString("BamPipe::Open", message);
return false;
// BamPipe_p.h (c) 2011 Derek Barnett
// Marth Lab, Department of Biology, Boston College
// ---------------------------------------------------------------------------
-// Last modified: 25 October 2011 (DB)
+// Last modified: 10 November 2011 (DB)
// ---------------------------------------------------------------------------
// Provides BAM pipe-specific IO behavior
// ***************************************************************************
+// ***************************************************************************
+// ByteArray_p.cpp (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 10 November 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides a dynamic, variable-length byte buffer
+// ***************************************************************************
+
#include "api/internal/io/ByteArray_p.h"
using namespace BamTools;
using namespace BamTools::Internal;
-#include <iostream> // debug
-
#include <cstdlib>
#include <cstring>
using namespace std;
+// ***************************************************************************
+// ByteArray_p.h (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 10 November 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides a dynamic, variable-length byte buffer
+// ***************************************************************************
+
#ifndef BYTEARRAY_P_H
#define BYTEARRAY_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/api_global.h"
#include <string>
#include <vector>
+// ***************************************************************************
+// HostAddress_p.cpp (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 10 November 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides a generic IP address container
+// ***************************************************************************
+
#include "api/internal/io/HostAddress_p.h"
using namespace BamTools;
using namespace BamTools::Internal;
// split a string into fields, on delimiter character
static inline
-vector<string> split(const string& source, char delim) {
+vector<string> Split(const string& source, char delim) {
stringstream ss(source);
string field;
vector<string> fields;
// return number of occurrences of @pattern in @source
static inline
-uint8_t countHits(const string& source, const string& pattern) {
+uint8_t CountHits(const string& source, const string& pattern) {
uint8_t count(0);
size_t found = source.find(pattern);
}
static
-bool parseIp4(const string& address, uint32_t& maybeIp4 ) {
+bool ParseIp4(const string& address, uint32_t& maybeIp4 ) {
// split IP address into string fields
- vector<string> addressFields = split(address, '.');
+ vector<string> addressFields = Split(address, '.');
if ( addressFields.size() != 4 )
return false;
}
static
-bool parseIp6(const string& address, uint8_t* maybeIp6 ) {
+bool ParseIp6(const string& address, uint8_t* maybeIp6 ) {
string tmp = address;
tmp = tmp.substr(0, percentFound);
// split IP address into string fields
- vector<string> fields = split(tmp, ':');
+ vector<string> fields = Split(tmp, ':');
const uint8_t numFields = fields.size();
if ( numFields < 3 || numFields > 8 )
return false;
// get number of '::' separators
- const uint8_t numColonColons = countHits(tmp, "::");
+ const uint8_t numColonColons = CountHits(tmp, "::");
if ( numFields == 8 && numColonColons > 1 )
return false;
// parse the IPv4 section
uint32_t maybeIp4;
- if ( !parseIp4(field, maybeIp4) )
+ if ( !ParseIp4(field, maybeIp4) )
return false;
// store IPv4 fields in IPv6 container
memset(&m_ip6Address, 0, sizeof(IPv6Address));
m_ipString.clear();
- // this may feel funny, but cleared IP value (equivalent to '0.0.0.0') is technically valid IP
- // and that's not really what this flag is checking
+ // this may feel funny, but cleared IP (equivalent to '0.0.0.0') is technically valid
+ // and that's not really what this flag is checking anyway
//
- // this flag is only false iff the string passed in is a 'plain-text' hostname (www.foo.bar)
+ // this flag is false *iff* the string passed in is a 'plain-text' hostname (www.foo.bar)
m_hasIpAddress = true;
}
if ( found != string::npos ) {
// try parse IP6 address
uint8_t maybeIp6[16];
- if ( parseIp6(s, maybeIp6) ) {
+ if ( ParseIp6(s, maybeIp6) ) {
SetAddress(maybeIp6);
m_protocol = HostAddress::IPv6Protocol;
return true;
found = s.find('.');
if ( found != string::npos ) {
uint32_t maybeIp4(0);
- if ( parseIp4(s, maybeIp4) ) {
+ if ( ParseIp4(s, maybeIp4) ) {
SetAddress(maybeIp4);
m_protocol = HostAddress::IPv4Protocol;
return true;
+// ***************************************************************************
+// HostAddress_p.h (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 10 November 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides a generic IP address container
+// ***************************************************************************
+
#ifndef HOSTADDRESS_P_H
#define HOSTADDRESS_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/api_global.h"
#include <cstring>
#include <string>
+// ***************************************************************************
+// HostInfo_p.cpp (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 10 November 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides DNS lookup functionality for hostname & its discovered addresses
+// ***************************************************************************
+
#include "api/internal/io/HostInfo_p.h"
using namespace BamTools;
using namespace BamTools::Internal;
using namespace std;
// -------------------------
-// HostInfo basics
+// HostInfo implementation
// -------------------------
HostInfo::HostInfo(void)
m_hostName = name;
}
-// ------------------------------
+// ---------------------------------
// HostInfo::Lookup(host, port)
-// ------------------------------
+// - the real "heavy-lifter" here
+// ---------------------------------
HostInfo HostInfo::Lookup(const string& hostname, const string& port) {
+// ***************************************************************************
+// HostInfo_p.h (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 10 November 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides DNS lookup functionality for hostname/IP addresses
+// ***************************************************************************
+
#ifndef HOSTINFO_P_H
#define HOSTINFO_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/io/HostAddress_p.h"
#include <string>
#include <vector>
+// ***************************************************************************
+// HttpHeader_p.cpp (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 10 November 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides a generic interface for parsing/generating HTTP headers, along
+// with specialized request & response header types
+// ***************************************************************************
+
#include "api/internal/io/HttpHeader_p.h"
using namespace BamTools;
using namespace BamTools::Internal;
+// ***************************************************************************
+// HttpHeader_p.h (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 10 November 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides a generic interface for parsing/generating HTTP headers, along
+// with specialized request & response header types
+// ***************************************************************************
+
#ifndef HTTP_HEADER_P_H
#define HTTP_HEADER_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/api_global.h"
#include <map>
#include <string>
+// ***************************************************************************
+// NetUnix_p.h (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 10 November 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides common networking-related includes, etc. for all UNIX-like systems
+// ***************************************************************************
+
#ifndef NETUNIX_P_H
#define NETUNIX_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.
+
#ifndef _WIN32 // <-- source files only include the proper Net*_p.h, but this is a double-check
#include <arpa/inet.h>
# define BT_SOCKLEN_T socklen_t
#endif
-namespace BamTools {
-namespace Internal {
-
-} // namespace Internal
-} // namespace BamTools
-
#endif // _WIN32
#endif // NETUNIX_P_H
+// ***************************************************************************
+// NetWin_p.h (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 10 November 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides common networking-related includes, etc. for Windows systems
+//
+// Note: only supports XP and later
+// ***************************************************************************
+
#ifndef NETWIN_P_H
#define NETWIN_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.
+
#ifdef _WIN32 // <-- source files only include the proper Net*_p.h, but this is a double-check
#include <winsock2.h> // <-- should bring 'windows.h' along with it
+// ***************************************************************************
+// RollingBuffer_p.cpp (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 10 November 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides a dynamic I/O FIFO byte queue, which removes bytes as they are
+// read from the front of the buffer and grows to accept bytes being written
+// to buffer end.
+//
+// implementation note: basically a 'smart' wrapper around 1..* ByteArrays
+// ***************************************************************************
+
#include "api/internal/io/RollingBuffer_p.h"
using namespace BamTools;
using namespace BamTools::Internal;
-#include <iostream> // for debug
-
#include <climits>
#include <cstring>
#include <algorithm>
return bytesReadSoFar;
}
-string RollingBuffer::ReadLine(size_t max) {
-
- ByteArray result;
- result.Resize(max);
-
- size_t numBytesRead = 0;
-
- // if max not provided, we need to read incrementally
- if ( max == 0 ) {
- max = UINT_MAX;
-
- // make sure we leave room for null terminator
- result.Resize(1);
-
- size_t readResult;
- do {
- result.Resize(std::min(max, result.Size()+m_bufferGrowth));
- readResult = ReadLine(result.Data() + numBytesRead, result.Size() - numBytesRead);
- if ( readResult > 0 || numBytesRead == 0 )
- numBytesRead += readResult;
- } while ( readResult == m_bufferGrowth && result[numBytesRead-1] != '\n');
- }
-
- // otherwise read line with provided max
- else numBytesRead = ReadLine(result.Data(), result.Size());
-
- // adjust byte array depending on numBytesRead
- if ( numBytesRead == 0 )
- result.Clear();
- else
- result.Resize(numBytesRead);
-
- // return string from byte array
- return string(result.ConstData(), result.Size());
-}
-
const char* RollingBuffer::ReadPointer(void) const {
// return null if empty buffer
+// ***************************************************************************
+// RollingBuffer_p.h (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 10 November 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides a dynamic I/O FIFO byte queue, which removes bytes as they are
+// read from the front of the buffer and grows to accept bytes being written
+// to buffer end.
+//
+// implementation note: basically a 'smart' wrapper around 1..* ByteArrays
+// ***************************************************************************
+
#ifndef ROLLINGBUFFER_P_H
#define ROLLINGBUFFER_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/api_global.h"
#include "api/internal/io/ByteArray_p.h"
#include <deque>
// ctors & dtor
public:
- RollingBuffer(size_t growth); // inits buffer, new byte arrays will try to be of size @growth
- ~RollingBuffer(void); // dtor
+ RollingBuffer(size_t growth);
+ ~RollingBuffer(void);
// RollingBuffer interface
public:
- size_t BlockSize(void) const; // returns current buffer size
- bool CanReadLine(void) const; // checks buffer for carriage return
- void Chop(size_t n); // frees @n bytes from end of buffer
- void Clear(void); // clears entire buffer structure
- void Free(size_t n); // frees @n bytes from front of buffer
- size_t IndexOf(char c) const; // checks buffer for @c
- bool IsEmpty(void) const; // returns whether buffer contains data
- size_t Read(char* dest, size_t max); // returns up to @maxLen bytes into @dest, returns exactly how many bytes were read from buffer
+
+ // returns current buffer size
+ size_t BlockSize(void) const;
+ // checks buffer for new line
+ bool CanReadLine(void) const;
+ // frees @n bytes from end of buffer
+ void Chop(size_t n);
+ // clears entire buffer structure
+ void Clear(void);
+ // frees @n bytes from front of buffer
+ void Free(size_t n);
+ // checks buffer for @c
+ size_t IndexOf(char c) const;
+ // returns whether buffer contains data
+ bool IsEmpty(void) const;
+ // reads up to @maxLen bytes into @dest
+ // returns exactly how many bytes were read from buffer
+ size_t Read(char* dest, size_t max);
+ // reads until newline (or up to @maxLen bytes)
+ // returns exactly how many bytes were read from buffer
size_t ReadLine(char* dest, size_t max);
- std::string ReadLine(size_t max = 0);
const char* ReadPointer(void) const; // returns a C-fxn compatible char* to byte data
char* Reserve(size_t n); // ensures that buffer contains space for @n incoming bytes, returns write-able char*
+// ***************************************************************************
+// TcpSocketEngine_p.cpp (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 10 November 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides low-level implementation of TCP I/O
+// ***************************************************************************
+
+// N.B. - this file contains the top-level, platform-independent logic. "Native" methods
+// are called as needed from the TcpSocketEngine_<X>.cpp files. Selection of the proper
+// native method file should have been handled at build-time by CMake.
+
#include "api/internal/io/HostInfo_p.h"
#include "api/internal/io/TcpSocketEngine_p.h"
-
using namespace BamTools;
using namespace BamTools::Internal;
+// ***************************************************************************
+// TcpSocketEngine_p.h (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 10 November 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides low-level implementation of TCP I/O
+// ***************************************************************************
+
#ifndef TCPSOCKETENGINE_P_H
#define TCPSOCKETENGINE_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/io/HostAddress_p.h"
#include "api/internal/io/TcpSocket_p.h"
bool nativeConnect(const HostAddress& address, const uint16_t port);
bool nativeCreateSocket(HostAddress::NetworkProtocol protocol);
void nativeDisconnect(void);
- bool nativeFetchConnectionParameters(void);
- int64_t nativeNumBytesAvailable(void) const;
+ int64_t nativeNumBytesAvailable(void) const;
int64_t nativeRead(char* dest, size_t max);
int nativeSelect(int msecs, bool isRead) const;
int64_t nativeWrite(const char* data, size_t length);
+// ***************************************************************************
+// TcpSocketEngine_unix_p.cpp (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 10 November 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides low-level implementation of TCP I/O for all UNIX-like systems
+// ***************************************************************************
+
#include "api/internal/io/TcpSocketEngine_p.h"
#include "api/internal/io/NetUnix_p.h"
using namespace BamTools;
bool TcpSocketEngine::nativeCreateSocket(HostAddress::NetworkProtocol protocol) {
// get protocol value for requested protocol type
- const int protocolNum = ( (protocol == HostAddress::IPv6Protocol) ? AF_INET6 : AF_INET );
+ const int protocolNum = ( (protocol == HostAddress::IPv6Protocol) ? AF_INET6
+ : AF_INET );
// attempt to create socket
int socketFd = socket(protocolNum, SOCK_STREAM, IPPROTO_TCP);
break;
}
}
-
return static_cast<int64_t>(ret);
}
-// negative value for msecs will block (forever) until
+// negative value for msecs will block (forever) until ready
int TcpSocketEngine::nativeSelect(int msecs, bool isRead) const {
// set up FD set
break;
}
}
-
return static_cast<int64_t>(writtenBytes);
}
+// ***************************************************************************
+// TcpSocketEngine_win_p.cpp (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 10 November 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides low-level implementation of TCP I/O for all Windows systems
+// ***************************************************************************
+
#include "api/internal/io/TcpSocketEngine_p.h"
#include "api/internal/io/NetWin_p.h"
using namespace BamTools;
namespace BamTools {
namespace Internal {
-static inline
-void getPortAndAddress(const sockaddr* s, uint16_t& port, HostAddress& address) {
-
- // IPv6
- if (s->sa_family == AF_INET6) {
- sockaddr_in6* ip6 = (sockaddr_in6*)s;
- port = ntohs(ip6->sin6_port);
- IPv6Address tmp;
- memcpy(&tmp, &ip6->sin6_addr.in6_addr, sizeof(tmp));
- address.SetAddress(tmp);
- return;
- }
-
- // IPv4
- if ( s->sa_family == AF_INET ) {
- sockaddr_in* ip4 = (sockaddr_in*)s;
- port = ntohl(ip4->sin_port);
- address.SetAddress( ntohl(ip4->sin_addr) );
- return;
- }
-
- // should be unreachable
- BT_ASSERT_X(false, "TcpSocketEngine::getPortAndAddress() : unknown network protocol ");
- return false;
-}
+//static inline
+//void getPortAndAddress(const sockaddr* s, uint16_t& port, HostAddress& address) {
+
+// // IPv6
+// if (s->sa_family == AF_INET6) {
+// sockaddr_in6* ip6 = (sockaddr_in6*)s;
+// port = ntohs(ip6->sin6_port);
+// IPv6Address tmp;
+// memcpy(&tmp, &ip6->sin6_addr.in6_addr, sizeof(tmp));
+// address.SetAddress(tmp);
+// return;
+// }
+
+// // IPv4
+// if ( s->sa_family == AF_INET ) {
+// sockaddr_in* ip4 = (sockaddr_in*)s;
+// port = ntohl(ip4->sin_port);
+// address.SetAddress( ntohl(ip4->sin_addr) );
+// return;
+// }
+
+// // should be unreachable
+// BT_ASSERT_X(false, "TcpSocketEngine::getPortAndAddress() : unknown network protocol ");
+// return false;
+//}
} // namespace Internal
} // namespace BamTools
// --------------------------------
void TcpSocketEngine::nativeClose(void) {
- close(m_socketDescriptor);
+
+// close(m_socketDescriptor);
}
bool TcpSocketEngine::nativeConnect(const HostAddress& address, const uint16_t port) {
// setup connection parameters from address/port
- sockaddr_in sockAddrIPv4;
- sockaddr_in6 sockAddrIPv6;
- sockaddr* sockAddrPtr = 0;
- BT_SOCKLEN_T sockAddrSize = 0;
-
- // IPv6
- if ( address.GetProtocol() == HostAddress::IPv6Protocol ) {
-
- memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6));
- sockAddrIPv6.sin6_family = AF_INET6;
- sockAddrIPv6.sin6_port = htons(port);
-
- IPv6Address ip6 = address.GetIPv6Address();
- memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &ip6, sizeof(ip6));
-
- sockAddrSize = sizeof(sockAddrIPv6);
- sockAddrPtr = (sockaddr*)&sockAddrIPv6;
- }
-
- // IPv4
- else if ( address.GetProtocol() == HostAddress::IPv4Protocol ) {
-
- memset(&sockAddrIPv4, 0, sizeof(sockAddrIPv4));
- sockAddrIPv4.sin_family = AF_INET;
- sockAddrIPv4.sin_port = htons(port);
- sockAddrIPv4.sin_addr.s_addr = htonl(address.GetIPv4Address());
-
- sockAddrSize = sizeof(sockAddrIPv4);
- sockAddrPtr = (sockaddr*)&sockAddrIPv4;
- }
-
- // unknown (should be unreachable)
- else BT_ASSERT_X(false, "TcpSocketEngine::nativeConnect() : unknown network protocol");
-
- // attempt conenction
- int connectResult = connect(socketDescriptor, sockAddrPtr, sockAddrSize);
-
- // if hit error
- if ( connectResult == -1 ) {
-
- // see what error was encountered
- switch ( errno ) {
-
- case EISCONN:
- m_socketState = TcpSocket::ConnectedState;
- break;
- case ECONNREFUSED:
- case EINVAL:
- m_socketError = TcpSocket::ConnectionRefusedError;
- m_socketState = TcpSocket::UnconnectedState;
- m_errorString = "connection refused";
- break;
- case ETIMEDOUT:
- m_socketError = TcpSocket::NetworkError;
- m_errorString = "connection timed out";
- break;
- case EHOSTUNREACH:
- m_socketError = TcpSocket::NetworkError;
- m_socketState = TcpSocket::UnconnectedState;
- m_errorString = "host unreachable";
- break;
- case ENETUNREACH:
- m_socketError = TcpSocket::NetworkError;
- m_socketState = TcpSocket::UnconnectedState;
- m_errorString = "network unreachable";
- break;
- case EADDRINUSE:
- m_socketError = TcpSocket::NetworkError;
- m_errorString = "address already in use";
- break;
- case EACCES:
- case EPERM:
- m_socketError = TcpSocket::SocketAccessError;
- m_socketState = TcpSocket::UnconnectedState;
- m_errorString = "permission denied";
- case EAFNOSUPPORT:
- case EBADF:
- case EFAULT:
- case ENOTSOCK:
- m_socketState = TcpSocket::UnconnectedState;
- default:
- break;
- }
-
- if ( m_socketState != TcpSocket::ConnectedState )
- return false;
- }
-
- // otherwise, we should be good
- // update state & return success
- m_socketState = TcpSocket::ConnectedState;
- return true;
+// sockaddr_in sockAddrIPv4;
+// sockaddr_in6 sockAddrIPv6;
+// sockaddr* sockAddrPtr = 0;
+// BT_SOCKLEN_T sockAddrSize = 0;
+
+// // IPv6
+// if ( address.GetProtocol() == HostAddress::IPv6Protocol ) {
+
+// memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6));
+// sockAddrIPv6.sin6_family = AF_INET6;
+// sockAddrIPv6.sin6_port = htons(port);
+
+// IPv6Address ip6 = address.GetIPv6Address();
+// memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &ip6, sizeof(ip6));
+
+// sockAddrSize = sizeof(sockAddrIPv6);
+// sockAddrPtr = (sockaddr*)&sockAddrIPv6;
+// }
+
+// // IPv4
+// else if ( address.GetProtocol() == HostAddress::IPv4Protocol ) {
+
+// memset(&sockAddrIPv4, 0, sizeof(sockAddrIPv4));
+// sockAddrIPv4.sin_family = AF_INET;
+// sockAddrIPv4.sin_port = htons(port);
+// sockAddrIPv4.sin_addr.s_addr = htonl(address.GetIPv4Address());
+
+// sockAddrSize = sizeof(sockAddrIPv4);
+// sockAddrPtr = (sockaddr*)&sockAddrIPv4;
+// }
+
+// // unknown (should be unreachable)
+// else BT_ASSERT_X(false, "TcpSocketEngine::nativeConnect() : unknown network protocol");
+
+// // attempt conenction
+// int connectResult = connect(socketDescriptor, sockAddrPtr, sockAddrSize);
+
+// // if hit error
+// if ( connectResult == -1 ) {
+
+// // see what error was encountered
+// switch ( errno ) {
+
+// case EISCONN:
+// m_socketState = TcpSocket::ConnectedState;
+// break;
+// case ECONNREFUSED:
+// case EINVAL:
+// m_socketError = TcpSocket::ConnectionRefusedError;
+// m_socketState = TcpSocket::UnconnectedState;
+// m_errorString = "connection refused";
+// break;
+// case ETIMEDOUT:
+// m_socketError = TcpSocket::NetworkError;
+// m_errorString = "connection timed out";
+// break;
+// case EHOSTUNREACH:
+// m_socketError = TcpSocket::NetworkError;
+// m_socketState = TcpSocket::UnconnectedState;
+// m_errorString = "host unreachable";
+// break;
+// case ENETUNREACH:
+// m_socketError = TcpSocket::NetworkError;
+// m_socketState = TcpSocket::UnconnectedState;
+// m_errorString = "network unreachable";
+// break;
+// case EADDRINUSE:
+// m_socketError = TcpSocket::NetworkError;
+// m_errorString = "address already in use";
+// break;
+// case EACCES:
+// case EPERM:
+// m_socketError = TcpSocket::SocketAccessError;
+// m_socketState = TcpSocket::UnconnectedState;
+// m_errorString = "permission denied";
+// case EAFNOSUPPORT:
+// case EBADF:
+// case EFAULT:
+// case ENOTSOCK:
+// m_socketState = TcpSocket::UnconnectedState;
+// default:
+// break;
+// }
+
+// if ( m_socketState != TcpSocket::ConnectedState )
+// return false;
+// }
+
+// // otherwise, we should be good
+// // update state & return success
+// m_socketState = TcpSocket::ConnectedState;
+// return true;
}
bool TcpSocketEngine::nativeCreateSocket(HostAddress::NetworkProtocol protocol) {
- // get protocol value for requested protocol type
- const int protocolNum = ( (protocol == HostAddress::IPv6Protocol) ? AF_INET6 : AF_INET );
-
- // attempt to create socket
- int socketFd = socket(protocolNum, SOCK_STREAM, IPPROTO_TCP);
-
- // if we fetched an invalid socket descriptor
- if ( socketFd <= 0 ) {
-
- // see what error we got
- switch ( errno ) {
- case EPROTONOSUPPORT:
- case EAFNOSUPPORT:
- case EINVAL:
- m_socketError = TcpSocket::UnsupportedSocketOperationError;
- m_errorString = "protocol not supported";
- break;
- case ENFILE:
- case EMFILE:
- case ENOBUFS:
- case ENOMEM:
- m_socketError = TcpSocket::SocketResourceError;
- m_errorString = "out of resources";
- break;
- case EACCES:
- m_socketError = TcpSocket::SocketAccessError;
- m_errorString = "permission denied";
- break;
- default:
- break;
- }
-
- // return failure
- return false;
- }
-
- // otherwise, store our socket FD & return success
- m_socketDescriptor = socketFd;
- return true;
+// // get protocol value for requested protocol type
+// const int protocolNum = ( (protocol == HostAddress::IPv6Protocol) ? AF_INET6 : AF_INET );
+
+// // attempt to create socket
+// int socketFd = socket(protocolNum, SOCK_STREAM, IPPROTO_TCP);
+
+// // if we fetched an invalid socket descriptor
+// if ( socketFd <= 0 ) {
+
+// // see what error we got
+// switch ( errno ) {
+// case EPROTONOSUPPORT:
+// case EAFNOSUPPORT:
+// case EINVAL:
+// m_socketError = TcpSocket::UnsupportedSocketOperationError;
+// m_errorString = "protocol not supported";
+// break;
+// case ENFILE:
+// case EMFILE:
+// case ENOBUFS:
+// case ENOMEM:
+// m_socketError = TcpSocket::SocketResourceError;
+// m_errorString = "out of resources";
+// break;
+// case EACCES:
+// m_socketError = TcpSocket::SocketAccessError;
+// m_errorString = "permission denied";
+// break;
+// default:
+// break;
+// }
+
+// // return failure
+// return false;
+// }
+
+// // otherwise, store our socket FD & return success
+// m_socketDescriptor = socketFd;
+// return true;
}
-bool TcpSocketEngine::nativeFetchConnectionParameters(void) {
-
- // reset addresses/ports
- m_localAddress.Clear();
- m_remoteAddress.Clear();
- m_localPort = 0;
- m_remotePort = 0;
-
- // skip (return failure) if invalid socket FD
- if ( m_socketDescriptor == -1 )
- return false;
-
- sockaddr sa;
- BT_SOCKLEN_T sockAddrSize = sizeof(sa);
-
- // fetch local address info
- memset(&sa, 0, sizeof(sa));
- if ( getsockname(m_socketDescriptor, &sa, &sockAddrSize) == 0 ) {
- getPortAndAddress(&sa, m_localPort, m_localAddress);
- }
- else if ( errno == EBADF ) {
- m_socketError = TcpSocket::UnsupportedSocketOperationError;
- m_errorString = "invalid socket descriptor";
- return false;
- }
-
- // fetch remote address
- if ( getpeername(m_socketDescriptor, &sa, &sockAddrSize) == 0 )
- getPortAndAddress(&sa, m_remotePort, m_remoteAddress);
-
- // return success
- return true;
-}
+//bool TcpSocketEngine::nativeFetchConnectionParameters(void) {
+
+// // reset addresses/ports
+// m_localAddress.Clear();
+// m_remoteAddress.Clear();
+// m_localPort = 0;
+// m_remotePort = 0;
+
+// // skip (return failure) if invalid socket FD
+// if ( m_socketDescriptor == -1 )
+// return false;
+
+// sockaddr sa;
+// BT_SOCKLEN_T sockAddrSize = sizeof(sa);
+
+// // fetch local address info
+// memset(&sa, 0, sizeof(sa));
+// if ( getsockname(m_socketDescriptor, &sa, &sockAddrSize) == 0 ) {
+// getPortAndAddress(&sa, m_localPort, m_localAddress);
+// }
+// else if ( errno == EBADF ) {
+// m_socketError = TcpSocket::UnsupportedSocketOperationError;
+// m_errorString = "invalid socket descriptor";
+// return false;
+// }
+
+// // fetch remote address
+// if ( getpeername(m_socketDescriptor, &sa, &sockAddrSize) == 0 )
+// getPortAndAddress(&sa, m_remotePort, m_remoteAddress);
+
+// // return success
+// return true;
+//}
size_t TcpSocketEngine::nativeNumBytesAvailable(void) const {
- // fetch number of bytes, return 0 on error
- int numBytes(0);
- if ( ioctl(m_socketDescriptor, FIONREAD, (char*)&numBytes) < 0 )
- return 0;
- return static_cast<size_t>(numBytes);
+// // fetch number of bytes, return 0 on error
+// int numBytes(0);
+// if ( ioctl(m_socketDescriptor, FIONREAD, (char*)&numBytes) < 0 )
+// return 0;
+// return static_cast<size_t>(numBytes);
}
int64_t TcpSocketEngine::nativeRead(char* dest, size_t max) {
- if ( !IsValid() )
- return -1;
-
- ssize_t ret = read(m_socketDescriptor, dest, max);
- if ( ret < 0 ) {
- ret = -1;
- switch ( errno ) {
- case EAGAIN :
- // No data was available for reading
- ret = -2;
- break;
- case ECONNRESET :
- ret = 0;
- break;
- default:
- break;
- }
- }
-
- return static_cast<int64_t>(ret);
+// if ( !IsValid() )
+// return -1;
+
+// ssize_t ret = read(m_socketDescriptor, dest, max);
+// if ( ret < 0 ) {
+// ret = -1;
+// switch ( errno ) {
+// case EAGAIN :
+// // No data was available for reading
+// ret = -2;
+// break;
+// case ECONNRESET :
+// ret = 0;
+// break;
+// default:
+// break;
+// }
+// }
+
+// return static_cast<int64_t>(ret);
}
// negative value for msecs will block (forever) until
int TcpSocketEngine::nativeSelect(int msecs, bool isRead) const {
- // set up FD set
- fd_set fds;
- FD_ZERO(&fds);
- FD_SET(m_socketDescriptor, &fds);
-
- // setup our timeout
- timeval tv;
- tv.tv_sec = msecs / 1000;
- tv.tv_usec = (msecs % 1000) * 1000;
-
- // do 'select'
- int ret;
- if ( isRead )
- ret = select(m_socketDescriptor + 1, &fds, 0, 0, (msecs < 0 ? 0 : &tv));
- else
- ret = select(m_socketDescriptor + 1, 0, &fds, 0, (msecs < 0 ? 0 : &tv));
- return ret;
+// // set up FD set
+// fd_set fds;
+// FD_ZERO(&fds);
+// FD_SET(m_socketDescriptor, &fds);
+
+// // setup our timeout
+// timeval tv;
+// tv.tv_sec = msecs / 1000;
+// tv.tv_usec = (msecs % 1000) * 1000;
+
+// // do 'select'
+// int ret;
+// if ( isRead )
+// ret = select(m_socketDescriptor + 1, &fds, 0, 0, (msecs < 0 ? 0 : &tv));
+// else
+// ret = select(m_socketDescriptor + 1, 0, &fds, 0, (msecs < 0 ? 0 : &tv));
+// return ret;
}
int64_t TcpSocketEngine::nativeWrite(const char* data, size_t length) {
- ssize_t writtenBytes = write(m_socketDescriptor, data, length);
- if ( writtenBytes < 0 ) {
- switch (errno) {
- case EPIPE:
- case ECONNRESET:
- writtenBytes = -1;
- m_socketError = TcpSocket::RemoteHostClosedError;
- m_errorString = "remote host closed connection";
- Close();
- break;
- case EAGAIN:
- writtenBytes = 0;
- break;
- default:
- break;
- }
- }
-
- return static_cast<int64_t>(writtenBytes);
+// ssize_t writtenBytes = write(m_socketDescriptor, data, length);
+// if ( writtenBytes < 0 ) {
+// switch (errno) {
+// case EPIPE:
+// case ECONNRESET:
+// writtenBytes = -1;
+// m_socketError = TcpSocket::RemoteHostClosedError;
+// m_errorString = "remote host closed connection";
+// Close();
+// break;
+// case EAGAIN:
+// writtenBytes = 0;
+// break;
+// default:
+// break;
+// }
+// }
+
+// return static_cast<int64_t>(writtenBytes);
}
// TcpSocket_p.cpp (c) 2011 Derek Barnett
// Marth Lab, Department of Biology, Boston College
// ---------------------------------------------------------------------------
-// Last modified: 25 October 2011 (DB)
+// Last modified: 10 November 2011 (DB)
// ---------------------------------------------------------------------------
-// Provides generic TCP socket (buffered) I/O
+// Provides basic TCP I/O interface
// ***************************************************************************
#include "api/internal/io/ByteArray_p.h"
using namespace BamTools;
using namespace BamTools::Internal;
-#include <iostream> // debug
-
#include <algorithm>
#include <sstream>
#include <vector>
// TcpSocket_p.h (c) 2011 Derek Barnett
// Marth Lab, Department of Biology, Boston College
// ---------------------------------------------------------------------------
-// Last modified: 25 October 2011 (DB)
+// Last modified: 10 November 2011 (DB)
// ---------------------------------------------------------------------------
-// Provides TCP socket I/O
+// Provides basic TCP I/O interface
// ***************************************************************************
#ifndef TCPSOCKET_P_H