]> git.donarmstrong.com Git - bamtools.git/blob - src/api/internal/io/TcpSocketEngine_p.cpp
467eaeb83921194a3d077a43b5bb879e1e521d41
[bamtools.git] / src / api / internal / io / TcpSocketEngine_p.cpp
1 // ***************************************************************************
2 // TcpSocketEngine_p.cpp (c) 2011 Derek Barnett
3 // Marth Lab, Department of Biology, Boston College
4 // ---------------------------------------------------------------------------
5 // Last modified: 10 November 2011 (DB)
6 // ---------------------------------------------------------------------------
7 // Provides low-level implementation of TCP I/O
8 // ***************************************************************************
9
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.
13
14 #include "api/internal/io/HostInfo_p.h"
15 #include "api/internal/io/TcpSocketEngine_p.h"
16 using namespace BamTools;
17 using namespace BamTools::Internal;
18
19 TcpSocketEngine::TcpSocketEngine(void)
20     : m_socketDescriptor(-1)
21 //    , m_localPort(0)
22     , m_remotePort(0)
23     , m_socketError(TcpSocket::UnknownSocketError)
24     , m_socketState(TcpSocket::UnconnectedState)
25 { }
26
27 TcpSocketEngine::TcpSocketEngine(const TcpSocketEngine& other)
28     : m_socketDescriptor(other.m_socketDescriptor)
29 //    , m_localAddress(other.m_localAddress)
30     , m_remoteAddress(other.m_remoteAddress)
31 //    , m_localPort(other.m_localPort)
32     , m_remotePort(other.m_remotePort)
33     , m_socketError(other.m_socketError)
34     , m_socketState(other.m_socketState)
35     , m_errorString(other.m_errorString)
36 { }
37
38 TcpSocketEngine::~TcpSocketEngine(void) {
39     Close();
40 }
41
42 void TcpSocketEngine::Close(void) {
43
44     // close socket if we have valid FD
45     if ( m_socketDescriptor != -1 ) {
46         nativeClose();
47         m_socketDescriptor = -1;
48     }
49
50     // reset state
51     m_socketState = TcpSocket::UnconnectedState;
52 //    m_localAddress.Clear();
53     m_remoteAddress.Clear();
54 //    m_localPort = 0;
55     m_remotePort = 0;
56 }
57
58 bool TcpSocketEngine::Connect(const HostAddress& address, const uint16_t port) {
59
60     // return failure if invalid FD or already connected
61     if ( !IsValid() || (m_socketState == TcpSocket::ConnectedState) ) {
62         // TODO: set error string
63         return false;
64     }
65
66     // attempt to connect to host address on requested port
67     if ( !nativeConnect(address, port) ) {
68         // TODO: set error string
69         return false;
70     }
71
72     // if successful, store remote host address port & return success
73     // TODO: (later) fetch proxied remote & local host/port  here
74     m_remoteAddress = address;
75     m_remotePort    = port;
76     return true;
77 }
78
79 std::string TcpSocketEngine::GetErrorString(void) const {
80     return m_errorString;
81 }
82
83 //HostAddress TcpSocketEngine::GetLocalAddress(void) const {
84 //    return m_localAddress;
85 //}
86
87 //uint16_t TcpSocketEngine::GetLocalPort(void) const {
88 //    return m_localPort;
89 //}
90
91 HostAddress TcpSocketEngine::GetRemoteAddress(void) const {
92     return m_remoteAddress;
93 }
94
95 uint16_t TcpSocketEngine::GetRemotePort(void) const {
96     return m_remotePort;
97 }
98
99 int TcpSocketEngine::GetSocketDescriptor(void) const {
100     return m_socketDescriptor;
101 }
102
103 TcpSocket::SocketError TcpSocketEngine::GetSocketError(void) {
104     return m_socketError;
105 }
106
107 TcpSocket::SocketState TcpSocketEngine::GetSocketState(void) {
108     return m_socketState;
109 }
110
111 bool TcpSocketEngine::Initialize(HostAddress::NetworkProtocol protocol) {
112
113     // close current socket if we have one open
114     if ( IsValid() )
115         Close();
116
117     // attempt to create new socket
118     return nativeCreateSocket(protocol);
119 }
120
121 bool TcpSocketEngine::IsValid(void) const {
122     return (m_socketDescriptor != -1);
123 }
124
125 int64_t TcpSocketEngine::NumBytesAvailable(void) const {
126
127     // return 0 if socket FD is invalid
128     if ( !IsValid() ) {
129         // TODO: set error string
130         return -1;
131     }
132
133     // otherwise check socket to see how much is ready
134     return nativeNumBytesAvailable();
135 }
136
137 int64_t TcpSocketEngine::Read(char* dest, size_t max) {
138
139     // return failure if can't read
140     if ( !IsValid() || (m_socketState != TcpSocket::ConnectedState) )
141         return -1;
142
143     // otherwise return number of bytes read
144     return nativeRead(dest, max);
145 }
146
147 bool TcpSocketEngine::WaitForRead(int msec, bool* timedOut) {
148
149     // reset timedOut flag
150     *timedOut = false;
151
152     // need to wait for our socket to be ready to read
153     int ret = nativeSelect(msec, true);
154
155     // if timed out
156     if ( ret == 0 ) {
157         *timedOut = true;
158         m_socketError = TcpSocket::SocketTimeoutError;
159         m_errorString = "socket timed out";
160     }
161
162     // return if any sockets available for reading
163     return ( ret > 0 );
164 }
165
166 bool TcpSocketEngine::WaitForWrite(int msec, bool* timedOut) {
167
168     // reset timedOut flag
169     *timedOut = false;
170
171     // need to wait for our socket to be ready to write
172     int ret = nativeSelect(msec, false);
173
174     // if timed out
175     if ( ret == 0 ) {
176         *timedOut = true;
177         m_socketError = TcpSocket::SocketTimeoutError;
178         m_errorString = "socket timed out";
179     }
180
181     // return if any sockets available for reading
182     return ( ret > 0 );
183 }
184
185 int64_t TcpSocketEngine::Write(const char* data, size_t length) {
186
187     // return failure if can't write
188     if ( !IsValid() || (m_socketState != TcpSocket::ConnectedState) ) {
189         // TODO: set error string
190         return -1;
191     }
192
193     // otherwise return number of bytes written
194     return nativeWrite(data, length);
195 }