1 // ***************************************************************************
2 // TcpSocketEngine_p.cpp (c) 2011 Derek Barnett
3 // Marth Lab, Department of Biology, Boston College
4 // ---------------------------------------------------------------------------
5 // Last modified: 8 December 2011 (DB)
6 // ---------------------------------------------------------------------------
7 // Provides low-level implementation of TCP I/O
8 // ***************************************************************************
10 // N.B. - this file contains the top-level, platform-independent logic. "Native" methods
11 // are called as needed from the TcpSocketEngine_<X>.cpp files. Selection of the proper
12 // native method file should have been handled at build-time by CMake.
14 #include "api/internal/io/HostInfo_p.h"
15 #include "api/internal/io/TcpSocketEngine_p.h"
17 using namespace BamTools;
18 using namespace BamTools::Internal;
20 TcpSocketEngine::TcpSocketEngine(void)
21 : m_socketDescriptor(-1)
24 , m_socketError(TcpSocket::UnknownSocketError)
25 , m_socketState(TcpSocket::UnconnectedState)
28 TcpSocketEngine::TcpSocketEngine(const TcpSocketEngine& other)
29 : m_socketDescriptor(other.m_socketDescriptor)
30 // , m_localAddress(other.m_localAddress)
31 , m_remoteAddress(other.m_remoteAddress)
32 // , m_localPort(other.m_localPort)
33 , m_remotePort(other.m_remotePort)
34 , m_socketError(other.m_socketError)
35 , m_socketState(other.m_socketState)
36 , m_errorString(other.m_errorString)
39 TcpSocketEngine::~TcpSocketEngine(void) {
43 void TcpSocketEngine::Close(void) {
45 // close socket if we have valid FD
46 if ( m_socketDescriptor != -1 ) {
48 m_socketDescriptor = -1;
52 m_socketState = TcpSocket::UnconnectedState;
53 // m_localAddress.Clear();
54 m_remoteAddress.Clear();
59 bool TcpSocketEngine::Connect(const HostAddress& address, const uint16_t port) {
61 // return failure if invalid FD or already connected
62 if ( !IsValid() || (m_socketState == TcpSocket::ConnectedState) ) {
63 // TODO: set error string
67 // attempt to connect to host address on requested port
68 if ( !nativeConnect(address, port) ) {
69 // TODO: set error string
73 // if successful, store remote host address port & return success
74 // TODO: (later) fetch proxied remote & local host/port here
75 m_remoteAddress = address;
80 std::string TcpSocketEngine::GetErrorString(void) const {
84 //HostAddress TcpSocketEngine::GetLocalAddress(void) const {
85 // return m_localAddress;
88 //uint16_t TcpSocketEngine::GetLocalPort(void) const {
89 // return m_localPort;
92 HostAddress TcpSocketEngine::GetRemoteAddress(void) const {
93 return m_remoteAddress;
96 uint16_t TcpSocketEngine::GetRemotePort(void) const {
100 int TcpSocketEngine::GetSocketDescriptor(void) const {
101 return m_socketDescriptor;
104 TcpSocket::SocketError TcpSocketEngine::GetSocketError(void) {
105 return m_socketError;
108 TcpSocket::SocketState TcpSocketEngine::GetSocketState(void) {
109 return m_socketState;
112 bool TcpSocketEngine::Initialize(HostAddress::NetworkProtocol protocol) {
114 // close current socket if we have one open
118 // attempt to create new socket
119 return nativeCreateSocket(protocol);
122 bool TcpSocketEngine::IsValid(void) const {
123 return (m_socketDescriptor != -1);
126 int64_t TcpSocketEngine::NumBytesAvailable(void) const {
128 // return 0 if socket FD is invalid
130 // TODO: set error string
134 // otherwise check socket to see how much is ready
135 return nativeNumBytesAvailable();
138 int64_t TcpSocketEngine::Read(char* dest, size_t max) {
140 // return failure if can't read
141 if ( !IsValid() || (m_socketState != TcpSocket::ConnectedState) )
144 // otherwise return number of bytes read
145 return nativeRead(dest, max);
148 bool TcpSocketEngine::WaitForRead(int msec, bool* timedOut) {
150 // reset timedOut flag
153 // need to wait for our socket to be ready to read
154 const int ret = nativeSelect(msec, true);
159 m_socketError = TcpSocket::SocketTimeoutError;
160 m_errorString = "socket timed out";
163 // return if any sockets available for reading
167 bool TcpSocketEngine::WaitForWrite(int msec, bool* timedOut) {
169 // reset timedOut flag
172 // need to wait for our socket to be ready to write
173 const int ret = nativeSelect(msec, false);
178 m_socketError = TcpSocket::SocketTimeoutError;
179 m_errorString = "socket timed out";
182 // return if any sockets available for reading
186 int64_t TcpSocketEngine::Write(const char* data, size_t length) {
188 // return failure if can't write
189 if ( !IsValid() || (m_socketState != TcpSocket::ConnectedState) ) {
190 // TODO: set error string
194 // otherwise return number of bytes written
195 return nativeWrite(data, length);