bool SimpleMessage::init(ByteArray & msg) { int dataSize = 0; bool rtn = false; if (msg.getBufferSize() >= this->getHeaderSize()) { // Check to see if the message is larger than the standard header // If so, copy out the data portion. if (msg.getBufferSize() > this->getHeaderSize()) { dataSize = msg.getBufferSize() - this->getHeaderSize(); LOG_COMM("Unloading data portion of message: %d bytes", dataSize); msg.unload(this->data_, dataSize); } LOG_COMM("Unloading header data"); msg.unload(this->reply_code_); msg.unload(this->comm_type_); msg.unload(this->message_type_); LOG_COMM("SimpleMessage::init(type: %d, comm: %d, reply: %d, data[%d]...)", this->message_type_, this->comm_type_, this->reply_code_, this->data_.getBufferSize()); rtn = this->validateMessage(); } else { LOG_ERROR("Failed to init message, buffer size too small: %u", msg.getBufferSize()); rtn = false; } return rtn; }
TEST(ByteArraySuite, copy) { const shared_int SIZE = 100; char buffer[SIZE]; // Copy ByteArray copyFrom; ByteArray copyTo; EXPECT_TRUE(copyFrom.init(&buffer[0], SIZE)); EXPECT_TRUE(copyTo.load(copyFrom)); EXPECT_EQ((shared_int)copyTo.getBufferSize(), SIZE); EXPECT_TRUE(copyTo.load(copyFrom)); EXPECT_EQ((shared_int)copyTo.getBufferSize(), 2*SIZE); // Copy too large ByteArray tooBig; if (tooBig.getMaxBufferSize()-1 <= std::numeric_limits<shared_int>::max()) { shared_int TOO_BIG = tooBig.getMaxBufferSize()-1; char bigBuffer[TOO_BIG]; EXPECT_TRUE(tooBig.init(&bigBuffer[0], TOO_BIG)); EXPECT_FALSE(copyTo.load(tooBig)); // A failed load should not change the buffer. EXPECT_EQ((shared_int)copyTo.getBufferSize(), 2*SIZE); } else std::cout << std::string(15, ' ') << "ByteArray.MaxSize==INT_MAX. Skipping TOO_BIG tests" << std::endl; }
TEST(ByteArraySuite, byteSwapping) { if(ByteArray::isByteSwapEnabled()) { ASSERT_TRUE(ByteArray::isByteSwapEnabled()); ByteArray swapped; unsigned char buffer[] = { 0x00, 0x00, 0x00, 0x38, // be: 56 0x00, 0x00, 0x00, 0x0a, // be: 10 0x00, 0x00, 0x00, 0x01, // be: 1 0x3e, 0x81, 0x32, 0x64, // be: 0.25233757495880127 0x3f, 0x30, 0x4b, 0x75, // be: 0.68865138292312622 0x3f, 0xa8, 0x9d, 0xd2, // be: 1.3173162937164307 0x3f, 0x85, 0x93, 0xdd, // be: 1.0435749292373657 0xbf, 0xf4, 0x8c, 0xc5, // be: -1.9105459451675415 }; const unsigned int bufferLength = 32; shared_int tempInt; shared_real tempReal; swapped.init((const char*) buffer, bufferLength); ASSERT_EQ(swapped.getBufferSize(), bufferLength); ASSERT_TRUE(swapped.unload(tempReal)); EXPECT_FLOAT_EQ(tempReal, -1.9105459451675415); ASSERT_TRUE(swapped.unload(tempReal)); EXPECT_FLOAT_EQ(tempReal, 1.0435749292373657); ASSERT_TRUE(swapped.unload(tempReal)); EXPECT_FLOAT_EQ(tempReal, 1.3173162937164307); ASSERT_TRUE(swapped.unload(tempReal)); EXPECT_FLOAT_EQ(tempReal, 0.68865138292312622); ASSERT_TRUE(swapped.unload(tempReal)); EXPECT_FLOAT_EQ(tempReal, 0.25233757495880127); ASSERT_TRUE(swapped.unload(tempInt)); EXPECT_EQ(tempInt, 1); ASSERT_TRUE(swapped.unload(tempInt)); EXPECT_EQ(tempInt, 10); ASSERT_TRUE(swapped.unload(tempInt)); EXPECT_EQ(tempInt, 56); ASSERT_EQ(swapped.getBufferSize(), 0); } }
void ByteArray::copyFrom(ByteArray & buffer) { if (buffer.getBufferSize() != 0) { this->setBufferSize(buffer.getBufferSize()); memcpy(this->getRawDataPtr(), buffer.getRawDataPtr(), this->buffer_size_); } else { LOG_WARN("Byte array copy not performed, buffer to copy is empty"); } }
TEST(SocketSuite, splitPackets) { const int port = TEST_PORT_BASE + 1; char ipAddr[] = "127.0.0.1"; const int RECV_LENGTH = 64; TestClient client; TestServer server; ByteArray recv; // Construct server ASSERT_TRUE(server.init(port)); // Construct a client ASSERT_TRUE(client.init(&ipAddr[0], port)); pthread_t serverConnectThrd; pthread_create(&serverConnectThrd, NULL, connectServerFunc, &server); ASSERT_TRUE(client.makeConnect()); pthread_join(serverConnectThrd, NULL); pthread_t senderThrd; pthread_create(&senderThrd, NULL, spinSender, &client); ASSERT_TRUE(server.receiveBytes(recv, RECV_LENGTH)); ASSERT_EQ(RECV_LENGTH, recv.getBufferSize()); pthread_cancel(senderThrd); pthread_join(senderThrd, NULL); }
bool SimpleSocket::sendBytes(ByteArray & buffer) { int rc = this->SOCKET_FAIL; bool rtn = false; if (this->isConnected()) { // Nothing restricts the ByteArray from being larger than the what the socket // can handle. if (this->MAX_BUFFER_SIZE > (int)buffer.getBufferSize()) { rc = rawSendBytes(buffer.getRawDataPtr(), buffer.getBufferSize()); if (this->SOCKET_FAIL != rc) { rtn = true; } else { rtn = false; logSocketError("Socket sendBytes failed", rc); } } else { LOG_ERROR("Buffer size: %u, is greater than max socket size: %u", buffer.getBufferSize(), this->MAX_BUFFER_SIZE); rtn = false; } } else { rtn = false; LOG_WARN("Not connected, bytes not sent"); } if (!rtn) { this->setConnected(false); } return rtn; }
void ByteArray::copyFrom(ByteArray & buffer) { if (buffer.getBufferSize() != 0) { this->buffer_ = buffer.buffer_; } else { LOG_WARN("Byte array copy not performed, buffer to copy is empty"); } }
bool SimpleMessage::init(int msgType, int commType, int replyCode, ByteArray & data ) { LOG_COMM("SimpleMessage::init(type: %d, comm: %d, reply: %d, data[%d]...)", msgType, commType, replyCode, data.getBufferSize()); this->setMessageType(msgType); this->setCommType(commType); this->setReplyCode(replyCode); this->data_.copyFrom(data); return this->validateMessage(); }
bool UdpServer::makeConnect() { ByteArray send; char sendHS = this->CONNECT_HANDSHAKE; char recvHS = 0; int bytesRcvd = 0; const int timeout = 1000; // Time (ms) between handshake sends bool rtn = false; send.load((void*)&sendHS, sizeof(sendHS)); if (!this->isConnected()) { this->setConnected(false); // Listen for handshake. Once received, break // listen loop. do { ByteArray recv; recvHS = 0; if (this->isReadyReceive(timeout)) { bytesRcvd = this->rawReceiveBytes(this->buffer_, 0); if (bytesRcvd > 0) { LOG_DEBUG("UDP server received %d bytes while waiting for handshake", bytesRcvd); recv.init(&this->buffer_[0], bytesRcvd); recv.unload((void*)&recvHS, sizeof(recvHS)); } } } while(recvHS != sendHS); // Send a reply handshake this->rawSendBytes(send.getRawDataPtr(), send.getBufferSize()); this->setConnected(true); rtn = true; } else { LOG_WARN("Tried to connect when socket already in connected state"); rtn = true; } return rtn; }
bool ByteArray::load(ByteArray &value) { LOG_COMM("Executing byte array load through byte array"); std::deque<char>& src = value.buffer_; std::deque<char>& dest = this->buffer_; if (this->getBufferSize()+value.getBufferSize() > this->getMaxBufferSize()) { LOG_ERROR("Additional data would exceed buffer size"); return false; } dest.insert(dest.end(), src.begin(), src.end()); return true; }
bool UdpClient::makeConnect() { ByteArray send; char sendHS = this->CONNECT_HANDSHAKE; char recvHS = 0; bool rtn = false; const int timeout = 1000; // Time (ms) between handshake sends int bytesRcvd = 0; if (!this->isConnected()) { this->setConnected(false); send.load((void*)&sendHS, sizeof(sendHS)); do { ByteArray recv; recvHS = 0; LOG_DEBUG("UDP client sending handshake"); this->rawSendBytes(send.getRawDataPtr(), send.getBufferSize()); if (this->isReadyReceive(timeout)) { bytesRcvd = this->rawReceiveBytes(this->buffer_, 0); LOG_DEBUG("UDP client received possible handshake"); recv.init(&this->buffer_[0], bytesRcvd); recv.unload((void*)&recvHS, sizeof(recvHS)); } } while(recvHS != sendHS); LOG_INFO("UDP client connected"); rtn = true; this->setConnected(true); } else { rtn = true; LOG_WARN("Tried to connect when socket already in connected state"); } return rtn; }
bool SmplMsgConnection::sendMsg(SimpleMessage & message) { bool rtn; ByteArray sendBuffer; ByteArray msgData; if (message.validateMessage()) { message.toByteArray(msgData); sendBuffer.load((int)msgData.getBufferSize()); sendBuffer.load(msgData); rtn = this->sendBytes(sendBuffer); } else { rtn = false; LOG_ERROR("Message validation failed, message not sent"); } return rtn; }
TEST(ByteArraySuite, init) { const shared_int SIZE = 100; ByteArray bytes; char buffer[SIZE]; // Valid byte arrays EXPECT_TRUE(bytes.init(&buffer[0], SIZE)); EXPECT_EQ((shared_int)bytes.getBufferSize(), SIZE); // Invalid init (too big) if (bytes.getMaxBufferSize() < std::numeric_limits<shared_int>::max()) { shared_int TOO_BIG = bytes.getMaxBufferSize()+1; char bigBuffer[TOO_BIG]; EXPECT_FALSE(bytes.init(&bigBuffer[0], TOO_BIG)); } else std::cout << std::string(15, ' ') << "ByteArray.MaxSize==INT_MAX. Skipping TOO_BIG tests" << std::endl; }
bool ByteArray::load(ByteArray &value) { LOG_COMM("Executing byte array load through byte array"); return this->load(value.getRawDataPtr(), value.getBufferSize()); }
TEST(ByteArraySuite, loading) { const shared_int SIZE = 100; char buffer[SIZE]; ByteArray bytes; ByteArray empty; ASSERT_TRUE(bytes.init(&buffer[0], SIZE)); shared_bool bIN = true, bOUT = false; shared_int iIN = 999, iOUT = 0; shared_real rIN = 9999.9999, rOUT = 0; // Boolean loading EXPECT_TRUE(bytes.load(bIN)); EXPECT_EQ(bytes.getBufferSize(), SIZE+sizeof(shared_bool)); EXPECT_TRUE(bytes.unload(bOUT)); EXPECT_EQ((shared_int)bytes.getBufferSize(), SIZE); EXPECT_EQ(bOUT, bIN); // Integer loading EXPECT_TRUE(bytes.load(iIN)); EXPECT_EQ(bytes.getBufferSize(), SIZE+sizeof(shared_int)); EXPECT_TRUE(bytes.unload(iOUT)); EXPECT_EQ((shared_int)bytes.getBufferSize(), SIZE); EXPECT_EQ(iOUT, iIN); // Real loading EXPECT_TRUE(bytes.load(rIN)); EXPECT_EQ(bytes.getBufferSize(), SIZE+sizeof(shared_real)); EXPECT_TRUE(bytes.unload(rOUT)); EXPECT_EQ((shared_int)bytes.getBufferSize(), SIZE); EXPECT_EQ(rOUT, rIN); // Unloading a single member (down to an empty buffer size) EXPECT_TRUE(empty.load(bIN)); EXPECT_EQ(empty.getBufferSize(), sizeof(shared_bool)); EXPECT_TRUE(empty.unload(bOUT)); EXPECT_EQ((int)empty.getBufferSize(), 0); EXPECT_EQ(bOUT, bIN); // Loading two members (unloading the first) and then checking the value of the second rOUT = 0.0; iOUT = 0; EXPECT_TRUE(empty.load(rIN)); EXPECT_EQ(empty.getBufferSize(), sizeof(shared_real)); EXPECT_TRUE(empty.load(iIN)); EXPECT_EQ(empty.getBufferSize(), sizeof(shared_real)+sizeof(shared_int)); EXPECT_TRUE(empty.unloadFront(rOUT)); EXPECT_EQ(rOUT, rIN); EXPECT_TRUE(empty.unload(iOUT)); EXPECT_EQ((int)empty.getBufferSize(), 0); EXPECT_EQ(iOUT, iIN); }