int WaypointMessageHelper::readWaypointMessageForTarget (const void *pWaypointMsgPayload, uint32 ui32Offset, uint32 ui32TotalLen, PreviousMessageIds &previouMessagesSentToTargets, uint32 &ui32WaypointMsgPayloadLen) { ui32WaypointMsgPayloadLen = ui32TotalLen; BufferReader br (pWaypointMsgPayload, ui32TotalLen); br.setPosition (ui32Offset); uint32 ui32LatestMessageSentLen = 0; if (br.read32 (&ui32LatestMessageSentLen) < 0) { return -1; } ui32WaypointMsgPayloadLen -= 4; if (ui32LatestMessageSentLen > 0) { static const uint16 BUF_LEN = 1024; char buf[BUF_LEN]; if ((ui32LatestMessageSentLen + 1) > BUF_LEN) { return -2; } if (br.readBytes (buf, ui32LatestMessageSentLen) < 0) { return -3; } buf[ui32LatestMessageSentLen] = '\0'; previouMessagesSentToTargets = buf; ui32WaypointMsgPayloadLen -= ui32LatestMessageSentLen; } return 0; }
PtrLList<const char> * InformationPull::remoteSearchArrived (const void *pData, uint32 ui32DataLength, uint32 &ui32RcvdRemoteSeachQuery, const char *pszSenderNodeId) { // Read the message BufferReader br (pData, ui32DataLength); br.read32 (&ui32RcvdRemoteSeachQuery); uint16 ui16Len; br.read16 (&ui16Len); char *pszGroupName = new char[ui16Len+1]; br.readBytes (pszGroupName, ui16Len); pszGroupName[ui16Len] = '\0'; br.read16 (&ui16Len); char *pszQuery = new char[ui16Len+1]; br.readBytes (pszQuery, ui16Len); pszQuery[ui16Len] = '\0'; // Check the search seq id uint32 *pUI32PrevRcvdRemoteSeachQuery = _latestSearchIdRcvdByPeer.get (pszSenderNodeId); if (pUI32PrevRcvdRemoteSeachQuery == NULL) { pUI32PrevRcvdRemoteSeachQuery = new uint32; (*pUI32PrevRcvdRemoteSeachQuery) = ui32RcvdRemoteSeachQuery; _latestSearchIdRcvdByPeer.put (pszSenderNodeId, pUI32PrevRcvdRemoteSeachQuery); } else { if (SequentialArithmetic::lessThanOrEqual (ui32RcvdRemoteSeachQuery, (*pUI32PrevRcvdRemoteSeachQuery))) { // This is either a duplicate search or an old search. Either way // it must not be served! (Actually the "equal" case should never // happen). return NULL; } else { (*pUI32PrevRcvdRemoteSeachQuery) = ui32RcvdRemoteSeachQuery; } } // Get the IDs of the messages matching the query except the ones specified // in ppszFilters (because they have already been sent) char **ppszFilters = (char **) malloc (sizeof(char*) * 2); ppszFilters[0] = (char *) pszSenderNodeId; ppszFilters[1] = NULL; PtrLList<const char> *pRet = _pInformationStore->getMessageIDs (pszGroupName, pszQuery); ppszFilters[0] = NULL; delete ppszFilters; ppszFilters = NULL; return pRet; }
TEST(test_buffer, read_bytes_empty) { err_code_t err; DataBlock::setMinCapacity(5); BufferReader reader; TokenData td; reader.readBytes(err, 0, td); ASSERT_EQ(err, RET_OK); ASSERT_EQ(td.size(), 0); }
TEST(test_buffer, fuzzy) { err_code_t err; DataBlock::setMinCapacity(5); BufferReader reader; TokenData td; DataBlock* dbPtr = NULL; // VALUE foo 10 0 24\r\n // \r\n // END\r\n // [] char str_list[][6] = {"VALUE", " foo ", "10 0 ", "24\r\n\r", "\nEND\r", "\n"}; for (int i = 0; i < 6; i++) { reader.write(str_list[i], strlen(str_list[i])); } uint64_t val, nBytes; reader.readUntil(err, ' ', td); ASSERT_EQ(err, RET_OK); ASSERT_EQ(td.size(), 1); ASSERT_EQ(td.front().offset, 0); ASSERT_EQ(td.front().size, 5); dbPtr = &*(td.front().iterator); dbPtr->release(td.front().size); ASSERT_N_STREQ((*dbPtr)[td.front().offset], "VALUE", 5); TEST_SKIP_BYTES_NO_THROW(1); td.clear(); reader.readUntil(err, ' ', td); ASSERT_EQ(err, RET_OK); ASSERT_EQ(td.size(), 1); ASSERT_EQ(td.front().offset, 1); ASSERT_EQ(td.front().size, 3); dbPtr = &*(td.front().iterator); dbPtr->release(td.front().size); ASSERT_N_STREQ((*dbPtr)[td.front().offset], "foo", 3); TEST_SKIP_BYTES_NO_THROW(1); td.clear(); TEST_READ_UNSIGNED_NO_THROW(val); ASSERT_EQ(val, 10); TEST_SKIP_BYTES_NO_THROW(1); TEST_READ_UNSIGNED_NO_THROW(nBytes); ASSERT_EQ(nBytes, 0); TEST_SKIP_BYTES_NO_THROW(1); TEST_READ_UNSIGNED_NO_THROW(val); ASSERT_EQ(val, 24); reader.readBytes(err, nBytes + 4, td); ASSERT_EQ(err, RET_OK); dbPtr = &*(td.front().iterator); dbPtr->release(td.front().size); // td.pop_front(); td.erase(td.begin()); dbPtr = &*(td.front().iterator); dbPtr->release(td.front().size); ASSERT_EQ(reader.peek(err, 0), 'E'); ASSERT_EQ(err, RET_OK); TEST_SKIP_BYTES_NO_THROW(5); }
TEST(test_buffer, read_bytes) { err_code_t err; DataBlock::setMinCapacity(5); BufferReader reader; TokenData td; DataBlock* dbPtr = NULL; reader.write(CSTR("12345"), 5); reader.write(CSTR("68964"), 5); reader.write(CSTR("\r\n"), 2); reader.readBytes(err, 6, td); ASSERT_EQ(err, RET_OK); ASSERT_EQ(td.size(), 2); ASSERT_EQ(td.front().size, 5); ASSERT_EQ(td.front().offset, 0); dbPtr = &*(td.front().iterator); dbPtr->release(td.front().size); ASSERT_N_STREQ((*dbPtr)[td.front().offset], "12345", 5); // td.pop_front(); td.erase(td.begin()); ASSERT_EQ(td.front().size, 1); ASSERT_EQ(td.front().offset, 0); dbPtr = &*(td.front().iterator); dbPtr->release(td.front().size); ASSERT_N_STREQ((*dbPtr)[td.front().offset], "6", 1); td.clear(); reader.readBytes(err, 4, td); ASSERT_EQ(err, RET_OK); ASSERT_EQ(td.size(), 1); ASSERT_EQ(td.front().size, 4); ASSERT_EQ(td.front().offset, 1); dbPtr = &*(td.front().iterator); dbPtr->release(td.front().size); ASSERT_N_STREQ((*dbPtr)[td.front().offset], "8964", 4); td.clear(); reader.readBytes(err, 2, td); ASSERT_EQ(err, RET_OK); ASSERT_EQ(td.size(), 1); ASSERT_EQ(td.front().size, 2); ASSERT_EQ(td.front().offset, 0); dbPtr = &*(td.front().iterator); dbPtr->release(td.front().size); ASSERT_N_STREQ((*dbPtr)[td.front().offset], "\r\n", 2); td.clear(); reader.readBytes(err, 2, td); ASSERT_EQ(err, RET_INCOMPLETE_BUFFER_ERR); td.clear(); reader.write(CSTR("syyin"), 5); reader.readBytes(err, 5, td); ASSERT_EQ(err, RET_OK); ASSERT_EQ(td.size(), 2); ASSERT_EQ(td.front().size, 3); ASSERT_EQ(td.front().offset, 2); dbPtr = &*(td.front().iterator); dbPtr->release(td.front().size); ASSERT_N_STREQ((*dbPtr)[td.front().offset], "syy", 3); // td.pop_front(); td.erase(td.begin()); ASSERT_EQ(td.front().size, 2); ASSERT_EQ(td.front().offset, 0); dbPtr = &*(td.front().iterator); dbPtr->release(td.front().size); ASSERT_N_STREQ((*dbPtr)[td.front().offset], "in", 2); }