ovr_sdk

view LibOVR/Src/Net/OVR_PacketizedTCPSocket.cpp @ 0:1b39a1b46319

initial 0.4.4
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 14 Jan 2015 06:51:16 +0200
parents
children
line source
1 /************************************************************************************
3 Filename : OVR_PacketizedTCPSocket.cpp
4 Content : TCP with automated message framing.
5 Created : June 10, 2014
6 Authors : Kevin Jenkins
8 Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
10 Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
11 you may not use the Oculus VR Rift SDK except in compliance with the License,
12 which is provided at the time of installation or download, or which
13 otherwise accompanies this software in either electronic or hard copy form.
15 You may obtain a copy of the License at
17 http://www.oculusvr.com/licenses/LICENSE-3.2
19 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
20 distributed under the License is distributed on an "AS IS" BASIS,
21 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 See the License for the specific language governing permissions and
23 limitations under the License.
25 ************************************************************************************/
27 #include "OVR_PacketizedTCPSocket.h"
29 namespace OVR { namespace Net {
32 //-----------------------------------------------------------------------------
33 // Constants
35 static const int LENGTH_FIELD_BYTES = 4;
38 //-----------------------------------------------------------------------------
39 // PacketizedTCPSocket
41 PacketizedTCPSocket::PacketizedTCPSocket()
42 {
43 pRecvBuff = 0;
44 pRecvBuffSize = 0;
45 Transport = TransportType_PacketizedTCP;
46 }
48 PacketizedTCPSocket::PacketizedTCPSocket(SocketHandle _sock, bool isListenSocket) : PacketizedTCPSocketBase(_sock, isListenSocket)
49 {
50 pRecvBuff = 0;
51 pRecvBuffSize = 0;
52 Transport = TransportType_PacketizedTCP;
53 }
55 PacketizedTCPSocket::~PacketizedTCPSocket()
56 {
57 OVR_FREE(pRecvBuff);
58 }
60 int PacketizedTCPSocket::Send(const void* pData, int bytes)
61 {
62 Lock::Locker locker(&sendLock);
64 if (bytes <= 0)
65 {
66 return -1;
67 }
69 // Convert length to 4 endian-neutral bytes
70 uint32_t lengthWord = bytes;
71 uint8_t lengthBytes[LENGTH_FIELD_BYTES] = {
72 (uint8_t)lengthWord,
73 (uint8_t)(lengthWord >> 8),
74 (uint8_t)(lengthWord >> 16),
75 (uint8_t)(lengthWord >> 24)
76 };
78 int s = PacketizedTCPSocketBase::Send(lengthBytes, LENGTH_FIELD_BYTES);
79 if (s > 0)
80 {
81 return PacketizedTCPSocketBase::Send(pData,bytes);
82 }
83 else
84 {
85 return s;
86 }
87 }
89 int PacketizedTCPSocket::SendAndConcatenate(const void** pDataArray, int* dataLengthArray, int arrayCount)
90 {
91 Lock::Locker locker(&sendLock);
93 if (arrayCount == 0)
94 return 0;
96 int totalBytes = 0;
97 for (int i = 0; i < arrayCount; i++)
98 totalBytes += dataLengthArray[i];
100 // Convert length to 4 endian-neutral bytes
101 uint32_t lengthWord = totalBytes;
102 uint8_t lengthBytes[LENGTH_FIELD_BYTES] = {
103 (uint8_t)lengthWord,
104 (uint8_t)(lengthWord >> 8),
105 (uint8_t)(lengthWord >> 16),
106 (uint8_t)(lengthWord >> 24)
107 };
109 int s = PacketizedTCPSocketBase::Send(lengthBytes, LENGTH_FIELD_BYTES);
110 if (s > 0)
111 {
112 for (int i = 0; i < arrayCount; i++)
113 {
114 PacketizedTCPSocketBase::Send(pDataArray[i], dataLengthArray[i]);
115 }
116 }
118 return s;
119 }
121 void PacketizedTCPSocket::OnRecv(SocketEvent_TCP* eventHandler, uint8_t* pData, int bytesRead)
122 {
123 uint8_t* dataSource = NULL;
124 int dataSourceSize = 0;
126 recvBuffLock.DoLock();
128 if (pRecvBuff == NULL)
129 {
130 dataSource = pData;
131 dataSourceSize = bytesRead;
132 }
133 else
134 {
135 uint8_t* pRecvBuffNew = (uint8_t*)OVR_REALLOC(pRecvBuff, bytesRead + pRecvBuffSize);
136 if (!pRecvBuffNew)
137 {
138 OVR_FREE(pRecvBuff);
139 pRecvBuff = NULL;
140 pRecvBuffSize = 0;
141 recvBuffLock.Unlock();
142 return;
143 }
144 else
145 {
146 pRecvBuff = pRecvBuffNew;
148 memcpy(pRecvBuff + pRecvBuffSize, pData, bytesRead);
150 dataSourceSize = pRecvBuffSize + bytesRead;
151 dataSource = pRecvBuff;
152 }
153 }
155 int bytesReadFromStream;
156 while (bytesReadFromStream = BytesFromStream(dataSource, dataSourceSize),
157 LENGTH_FIELD_BYTES + bytesReadFromStream <= dataSourceSize)
158 {
159 dataSource += LENGTH_FIELD_BYTES;
160 dataSourceSize -= LENGTH_FIELD_BYTES;
162 TCPSocket::OnRecv(eventHandler, dataSource, bytesReadFromStream);
164 dataSource += bytesReadFromStream;
165 dataSourceSize -= bytesReadFromStream;
166 }
168 if (dataSourceSize > 0)
169 {
170 if (dataSource != NULL)
171 {
172 if (pRecvBuff == NULL)
173 {
174 pRecvBuff = (uint8_t*)OVR_ALLOC(dataSourceSize);
175 if (!pRecvBuff)
176 {
177 pRecvBuffSize = 0;
178 recvBuffLock.Unlock();
179 return;
180 }
181 else
182 {
183 memcpy(pRecvBuff, dataSource, dataSourceSize);
184 }
185 }
186 else
187 {
188 memmove(pRecvBuff, dataSource, dataSourceSize);
189 }
190 }
191 }
192 else
193 {
194 if (pRecvBuff != NULL)
195 OVR_FREE(pRecvBuff);
197 pRecvBuff = NULL;
198 }
199 pRecvBuffSize = dataSourceSize;
201 recvBuffLock.Unlock();
202 }
204 int PacketizedTCPSocket::BytesFromStream(uint8_t* pData, int bytesRead)
205 {
206 if (pData != 0 && bytesRead >= LENGTH_FIELD_BYTES)
207 {
208 return pData[0] | ((uint32_t)pData[1] << 8) | ((uint32_t)pData[2] << 16) | ((uint32_t)pData[3] << 24);
209 }
211 return 0;
212 }
215 }} // OVR::Net