bool BSCLib::decompressData(uint8 *& out, size_t & outSize, const uint8 * in, const size_t inSize) { Stream::MemoryBlockStream inStream(in, inSize); if (out == 0) { Stream::NullOutputStream outStream; if (!decompressStream(outStream, inStream)) return false; if (outSize) { outSize = (size_t)outStream.fullSize(); return setError(UnexpectedEOD); } // Then allocate the output buffer size out = new uint8[outStream.fullSize()]; outSize = (size_t)outStream.fullSize(); inStream.setPosition(0); } // Compress the stream now Stream::MemoryBlockOutStream finalStream(out, (uint64)outSize); return decompressStream(finalStream, inStream); }
BitStreamReader* Connection::receive(void) { if (state != CONNECTED) { throw Exception(NSL_EXCEPTION_USAGE_ERROR, "NSL: trying to receive data when not connected."); } // if there is some buffered message, first return it if (bufferedMessage != NULL) { BitStreamReader* response = bufferedMessage; bufferedMessage = NULL; return response; } // accept relevant packets Address sender; int size; while (size = socket.receive(sender,buffer,NSL_MAX_UDP_PACKET_SIZE)) { if (size < 7) { continue; } bufferStream->resetStream(size); if (bufferStream->read<uint16>() != applicationId) { continue; } if (bufferStream->read<uint32>() != connectionId) { continue; } // process payoad switch (bufferStream->readByte()) { case NSL_CONNECTION_FLAG_DISCONNECT: state = CLOSED; return NULL; case NSL_CONNECTION_FLAG_UPDATE: return bufferStream;//->createSubreader(size - 7, true); case NSL_CONNECTION_FLAG_COMPRESSED_UPDATE: #ifdef NSL_COMPRESS return decompressStream(bufferStream); #else throw Exception(NSL_EXCEPTION_LIBRARY_ERROR, "NSL: Compressed update was received from server, but compression is turned of on client"); #endif default: throw Exception(NSL_EXCEPTION_LIBRARY_ERROR, "NSL: protocol error, received not expected data."); } } return NULL; }
ConnectionState Connection::update(double time) { // if CLOSED or CONNECTED, nothing happens // if CONNECTING or HANDSHAKING, incomming packets are proccessed for update Address sender; int size; switch(state) { case CONNECTING: // accept only connectionResponse (and get its connectionId) while (size = socket.receive(sender,buffer, NSL_MAX_UDP_PACKET_SIZE)) { if (size != 6) { continue; } // reset buffer stream bufferStream->resetStream(size); if (bufferStream->read<uint16>() != applicationId) { continue; } connectionId = bufferStream->read<int32>(); state = HANDSHAKING; sendHandshake(time); return state; } if (lastRequest + NSL_TIMEOUT_CLIENT_CONNECTION_REQUEST < time) { sendConnectionRequest(time); } break; case HANDSHAKING: // accept only handshakeResponse (and get its status) while (size = socket.receive(sender,buffer,NSL_MAX_UDP_PACKET_SIZE)) { if (size < 7) { continue; } // reset buffer stream bufferStream->resetStream(size); if (bufferStream->read<uint16>() != applicationId) { continue; } if (bufferStream->read<uint32>() != connectionId) { continue; } // process handshake response switch (bufferStream->readByte()) { case NSL_CONNECTION_FLAG_DISCONNECT: state = CLOSED; return state; case NSL_CONNECTION_FLAG_UPDATE: state = CONNECTED; bufferedMessage = bufferStream->createSubreader(size - 7, true); return state; case NSL_CONNECTION_FLAG_COMPRESSED_UPDATE: state = CONNECTED; #ifdef NSL_COMPRESS bufferedMessage = decompressStream(bufferStream); #else throw Exception(NSL_EXCEPTION_LIBRARY_ERROR, "NSL: Compressed update was received from server, but compression is turned of on client"); #endif return state; default: throw Exception(NSL_EXCEPTION_LIBRARY_ERROR, "NSL: protocol error, received not expected data."); } } if (lastRequest + NSL_TIMEOUT_CLIENT_HANDSHAKE < time) { sendHandshake(time); } break; case CLOSED: // throw away all incomming packets so they will not mess later while (size = socket.receive(sender,buffer,NSL_MAX_UDP_PACKET_SIZE)) {} default: break; } return state; }