ovr_sdk
diff 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 diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/LibOVR/Src/Net/OVR_PacketizedTCPSocket.cpp Wed Jan 14 06:51:16 2015 +0200 1.3 @@ -0,0 +1,215 @@ 1.4 +/************************************************************************************ 1.5 + 1.6 +Filename : OVR_PacketizedTCPSocket.cpp 1.7 +Content : TCP with automated message framing. 1.8 +Created : June 10, 2014 1.9 +Authors : Kevin Jenkins 1.10 + 1.11 +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. 1.12 + 1.13 +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); 1.14 +you may not use the Oculus VR Rift SDK except in compliance with the License, 1.15 +which is provided at the time of installation or download, or which 1.16 +otherwise accompanies this software in either electronic or hard copy form. 1.17 + 1.18 +You may obtain a copy of the License at 1.19 + 1.20 +http://www.oculusvr.com/licenses/LICENSE-3.2 1.21 + 1.22 +Unless required by applicable law or agreed to in writing, the Oculus VR SDK 1.23 +distributed under the License is distributed on an "AS IS" BASIS, 1.24 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1.25 +See the License for the specific language governing permissions and 1.26 +limitations under the License. 1.27 + 1.28 +************************************************************************************/ 1.29 + 1.30 +#include "OVR_PacketizedTCPSocket.h" 1.31 + 1.32 +namespace OVR { namespace Net { 1.33 + 1.34 + 1.35 +//----------------------------------------------------------------------------- 1.36 +// Constants 1.37 + 1.38 +static const int LENGTH_FIELD_BYTES = 4; 1.39 + 1.40 + 1.41 +//----------------------------------------------------------------------------- 1.42 +// PacketizedTCPSocket 1.43 + 1.44 +PacketizedTCPSocket::PacketizedTCPSocket() 1.45 +{ 1.46 + pRecvBuff = 0; 1.47 + pRecvBuffSize = 0; 1.48 + Transport = TransportType_PacketizedTCP; 1.49 +} 1.50 + 1.51 +PacketizedTCPSocket::PacketizedTCPSocket(SocketHandle _sock, bool isListenSocket) : PacketizedTCPSocketBase(_sock, isListenSocket) 1.52 +{ 1.53 + pRecvBuff = 0; 1.54 + pRecvBuffSize = 0; 1.55 + Transport = TransportType_PacketizedTCP; 1.56 +} 1.57 + 1.58 +PacketizedTCPSocket::~PacketizedTCPSocket() 1.59 +{ 1.60 + OVR_FREE(pRecvBuff); 1.61 +} 1.62 + 1.63 +int PacketizedTCPSocket::Send(const void* pData, int bytes) 1.64 +{ 1.65 + Lock::Locker locker(&sendLock); 1.66 + 1.67 + if (bytes <= 0) 1.68 + { 1.69 + return -1; 1.70 + } 1.71 + 1.72 + // Convert length to 4 endian-neutral bytes 1.73 + uint32_t lengthWord = bytes; 1.74 + uint8_t lengthBytes[LENGTH_FIELD_BYTES] = { 1.75 + (uint8_t)lengthWord, 1.76 + (uint8_t)(lengthWord >> 8), 1.77 + (uint8_t)(lengthWord >> 16), 1.78 + (uint8_t)(lengthWord >> 24) 1.79 + }; 1.80 + 1.81 + int s = PacketizedTCPSocketBase::Send(lengthBytes, LENGTH_FIELD_BYTES); 1.82 + if (s > 0) 1.83 + { 1.84 + return PacketizedTCPSocketBase::Send(pData,bytes); 1.85 + } 1.86 + else 1.87 + { 1.88 + return s; 1.89 + } 1.90 +} 1.91 + 1.92 +int PacketizedTCPSocket::SendAndConcatenate(const void** pDataArray, int* dataLengthArray, int arrayCount) 1.93 +{ 1.94 + Lock::Locker locker(&sendLock); 1.95 + 1.96 + if (arrayCount == 0) 1.97 + return 0; 1.98 + 1.99 + int totalBytes = 0; 1.100 + for (int i = 0; i < arrayCount; i++) 1.101 + totalBytes += dataLengthArray[i]; 1.102 + 1.103 + // Convert length to 4 endian-neutral bytes 1.104 + uint32_t lengthWord = totalBytes; 1.105 + uint8_t lengthBytes[LENGTH_FIELD_BYTES] = { 1.106 + (uint8_t)lengthWord, 1.107 + (uint8_t)(lengthWord >> 8), 1.108 + (uint8_t)(lengthWord >> 16), 1.109 + (uint8_t)(lengthWord >> 24) 1.110 + }; 1.111 + 1.112 + int s = PacketizedTCPSocketBase::Send(lengthBytes, LENGTH_FIELD_BYTES); 1.113 + if (s > 0) 1.114 + { 1.115 + for (int i = 0; i < arrayCount; i++) 1.116 + { 1.117 + PacketizedTCPSocketBase::Send(pDataArray[i], dataLengthArray[i]); 1.118 + } 1.119 + } 1.120 + 1.121 + return s; 1.122 +} 1.123 + 1.124 +void PacketizedTCPSocket::OnRecv(SocketEvent_TCP* eventHandler, uint8_t* pData, int bytesRead) 1.125 +{ 1.126 + uint8_t* dataSource = NULL; 1.127 + int dataSourceSize = 0; 1.128 + 1.129 + recvBuffLock.DoLock(); 1.130 + 1.131 + if (pRecvBuff == NULL) 1.132 + { 1.133 + dataSource = pData; 1.134 + dataSourceSize = bytesRead; 1.135 + } 1.136 + else 1.137 + { 1.138 + uint8_t* pRecvBuffNew = (uint8_t*)OVR_REALLOC(pRecvBuff, bytesRead + pRecvBuffSize); 1.139 + if (!pRecvBuffNew) 1.140 + { 1.141 + OVR_FREE(pRecvBuff); 1.142 + pRecvBuff = NULL; 1.143 + pRecvBuffSize = 0; 1.144 + recvBuffLock.Unlock(); 1.145 + return; 1.146 + } 1.147 + else 1.148 + { 1.149 + pRecvBuff = pRecvBuffNew; 1.150 + 1.151 + memcpy(pRecvBuff + pRecvBuffSize, pData, bytesRead); 1.152 + 1.153 + dataSourceSize = pRecvBuffSize + bytesRead; 1.154 + dataSource = pRecvBuff; 1.155 + } 1.156 + } 1.157 + 1.158 + int bytesReadFromStream; 1.159 + while (bytesReadFromStream = BytesFromStream(dataSource, dataSourceSize), 1.160 + LENGTH_FIELD_BYTES + bytesReadFromStream <= dataSourceSize) 1.161 + { 1.162 + dataSource += LENGTH_FIELD_BYTES; 1.163 + dataSourceSize -= LENGTH_FIELD_BYTES; 1.164 + 1.165 + TCPSocket::OnRecv(eventHandler, dataSource, bytesReadFromStream); 1.166 + 1.167 + dataSource += bytesReadFromStream; 1.168 + dataSourceSize -= bytesReadFromStream; 1.169 + } 1.170 + 1.171 + if (dataSourceSize > 0) 1.172 + { 1.173 + if (dataSource != NULL) 1.174 + { 1.175 + if (pRecvBuff == NULL) 1.176 + { 1.177 + pRecvBuff = (uint8_t*)OVR_ALLOC(dataSourceSize); 1.178 + if (!pRecvBuff) 1.179 + { 1.180 + pRecvBuffSize = 0; 1.181 + recvBuffLock.Unlock(); 1.182 + return; 1.183 + } 1.184 + else 1.185 + { 1.186 + memcpy(pRecvBuff, dataSource, dataSourceSize); 1.187 + } 1.188 + } 1.189 + else 1.190 + { 1.191 + memmove(pRecvBuff, dataSource, dataSourceSize); 1.192 + } 1.193 + } 1.194 + } 1.195 + else 1.196 + { 1.197 + if (pRecvBuff != NULL) 1.198 + OVR_FREE(pRecvBuff); 1.199 + 1.200 + pRecvBuff = NULL; 1.201 + } 1.202 + pRecvBuffSize = dataSourceSize; 1.203 + 1.204 + recvBuffLock.Unlock(); 1.205 +} 1.206 + 1.207 +int PacketizedTCPSocket::BytesFromStream(uint8_t* pData, int bytesRead) 1.208 +{ 1.209 + if (pData != 0 && bytesRead >= LENGTH_FIELD_BYTES) 1.210 + { 1.211 + return pData[0] | ((uint32_t)pData[1] << 8) | ((uint32_t)pData[2] << 16) | ((uint32_t)pData[3] << 24); 1.212 + } 1.213 + 1.214 + return 0; 1.215 +} 1.216 + 1.217 + 1.218 +}} // OVR::Net