[message] add method to append bytes read from another/same message (#6364)

This commit adds `Message::AppendBytesFromMessage()` which appends
bytes to a message read from another or potentially the same message
at a given offset. The bytes are read and copied directly (chunk by
chunk) without requiring an intermediate buffer. This commit also
updates `test_message` unit test to cover the behavior of the newly
added method (for both cases where the source and the destination
messages are the same or different).
This commit is contained in:
Abtin Keshavarzian
2021-03-30 11:56:00 -07:00
committed by GitHub
parent bbbeee17fb
commit fa7b012da9
3 changed files with 82 additions and 0 deletions
+22
View File
@@ -388,6 +388,28 @@ exit:
return error;
}
Error Message::AppendBytesFromMessage(const Message &aMessage, uint16_t aOffset, uint16_t aLength)
{
Error error = kErrorNone;
uint16_t writeOffset = GetLength();
Chunk chunk;
VerifyOrExit(aMessage.GetLength() >= aOffset + aLength, error = kErrorParse);
SuccessOrExit(error = SetLength(GetLength() + aLength));
aMessage.GetFirstChunk(aOffset, aLength, chunk);
while (chunk.GetLength() > 0)
{
WriteBytes(writeOffset, chunk.GetData(), chunk.GetLength());
writeOffset += chunk.GetLength();
aMessage.GetNextChunk(aLength, chunk);
}
exit:
return error;
}
Error Message::PrependBytes(const void *aBuf, uint16_t aLength)
{
Error error = kErrorNone;
+16
View File
@@ -658,6 +658,22 @@ public:
*/
Error AppendBytes(const void *aBuf, uint16_t aLength);
/**
* This method appends bytes read from another or potentially the same message to the end of the current message.
*
* On success, this method grows the message by @p aLength bytes.
*
* @param[in] aMessage The message to read the bytes from (it can be the same as the current message).
* @param[in] aOffset The offset in @p aMessage to start reading the bytes from.
* @param[in] aLength The number of bytes to read from @p aMessage and append.
*
* @retval kErrorNone Successfully appended the bytes.
* @retval kErrorNoBufs Insufficient available buffers to grow the message.
* @retval kErrorParse Not enough bytes in @p aMessage to read @p aLength bytes from @p aOffset.
*
*/
Error AppendBytesFromMessage(const Message &aMessage, uint16_t aOffset, uint16_t aLength);
/**
* This method appends an object to the end of the message.
*
+44
View File
@@ -193,6 +193,50 @@ void TestMessage(void)
"CopyTo() write error");
}
// Verify `AppendBytesFromMessage()` with two different messages as source and destination.
message->WriteBytes(0, writeBuffer, kMaxSize);
for (uint16_t srcOffset = 0; srcOffset < kMaxSize; srcOffset += kOffsetStep)
{
for (uint16_t dstOffset = 0; dstOffset < kMaxSize; dstOffset += kOffsetStep)
{
for (uint16_t length = 0; length <= kMaxSize - srcOffset; length += kLengthStep)
{
IgnoreError(message2->SetLength(0));
SuccessOrQuit(message2->AppendBytes(zeroBuffer, dstOffset), "AppendBytes() failed");
SuccessOrQuit(message2->AppendBytesFromMessage(*message, srcOffset, length),
"AppendBytesFromMessage() failed");
VerifyOrQuit(message2->CompareBytes(dstOffset, *message, srcOffset, length),
"CompareBytes failed after AppendBytesFromMessage()");
}
VerifyOrQuit(message2->AppendBytesFromMessage(*message, srcOffset, kMaxSize - srcOffset + 1) == kErrorParse,
"AppendBytesFromMessage() did not fail with invalid length");
}
}
// Verify `AppendBytesFromMessage()` with the same message as source and destination.
for (uint16_t srcOffset = 0; srcOffset < kMaxSize; srcOffset += kOffsetStep)
{
uint16_t size = kMaxSize;
for (uint16_t length = 0; length <= kMaxSize - srcOffset; length++)
{
// Reset the `message` to its original size.
IgnoreError(message->SetLength(size));
SuccessOrQuit(message->AppendBytesFromMessage(*message, srcOffset, length),
"AppendBytesFromMessage() failed");
VerifyOrQuit(message->CompareBytes(size, *message, srcOffset, length),
"CompareBytes failed after AppendBytesFromMessage()");
}
}
message->Free();
message2->Free();