mirror of
https://github.com/espressif/openthread.git
synced 2026-07-24 04:54:06 +00:00
[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:
committed by
GitHub
parent
bbbeee17fb
commit
fa7b012da9
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user