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