mirror of
https://github.com/espressif/openthread.git
synced 2026-10-08 16:57:39 +00:00
[message] update Message::Chunk definitions to use Data (#7019)
This commit updates the `Message::Chunk` type to use `Data` as its base class (thus inheriting the common helper methods from it) which helps simplify its use. This commit also adds couple of new methods in `Data` class (method `SetLength()` to change the `Data` length, and `MatchesBytesIn()` to compare the `Data` content with bytes from a given buffer). The `test_data` unit test is also updated to check the newly added `Data` methods.
This commit is contained in:
@@ -145,6 +145,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
LengthType GetLength(void) const { return mLength; }
|
LengthType GetLength(void) const { return mLength; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the data length.
|
||||||
|
*
|
||||||
|
* @param[in] aLength The data length (number of bytes).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetLength(LengthType aLength) { mLength = aLength; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method copies the `Data` bytes to a given buffer.
|
* This method copies the `Data` bytes to a given buffer.
|
||||||
*
|
*
|
||||||
@@ -153,7 +161,20 @@ public:
|
|||||||
* @param[out] aBuffer The buffer to copy the bytes into.
|
* @param[out] aBuffer The buffer to copy the bytes into.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void CopyBytesTo(uint8_t *aBuffer) const { memcpy(aBuffer, mBuffer, mLength); }
|
void CopyBytesTo(void *aBuffer) const { memcpy(aBuffer, mBuffer, mLength); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method compares the `Data` content with the bytes from a given buffer.
|
||||||
|
*
|
||||||
|
* It is up to the caller to ensure that @p aBuffer has enough bytes to compare with the current data length.
|
||||||
|
*
|
||||||
|
* @param[in] aBuffer A pointer to a buffer to compare with the data.
|
||||||
|
*
|
||||||
|
* @retval TRUE The `Data` content matches the bytes in @p aBuffer.
|
||||||
|
* @retval FALSE The `Data` content does not match the byes in @p aBuffer.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool MatchesBytesIn(const void *aBuffer) const { return memcmp(mBuffer, aBuffer, mLength) == 0; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method overloads operator `==` to compare the `Data` content with the content from another one.
|
* This method overloads operator `==` to compare the `Data` content with the content from another one.
|
||||||
@@ -166,7 +187,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool operator==(const Data &aOtherData) const
|
bool operator==(const Data &aOtherData) const
|
||||||
{
|
{
|
||||||
return (mLength == aOtherData.mLength) && (memcmp(mBuffer, aOtherData.mBuffer, mLength) == 0);
|
return (mLength == aOtherData.mLength) && MatchesBytesIn(aOtherData.mBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -183,7 +204,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool StartsWith(const Data &aOtherData) const
|
bool StartsWith(const Data &aOtherData) const
|
||||||
{
|
{
|
||||||
return (mLength >= aOtherData.mLength) && (memcmp(mBuffer, aOtherData.mBuffer, aOtherData.mLength) == 0);
|
return (mLength >= aOtherData.mLength) && aOtherData.MatchesBytesIn(mBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
+26
-27
@@ -410,7 +410,7 @@ Error Message::AppendBytesFromMessage(const Message &aMessage, uint16_t aOffset,
|
|||||||
|
|
||||||
while (chunk.GetLength() > 0)
|
while (chunk.GetLength() > 0)
|
||||||
{
|
{
|
||||||
WriteBytes(writeOffset, chunk.GetData(), chunk.GetLength());
|
WriteBytes(writeOffset, chunk.GetBytes(), chunk.GetLength());
|
||||||
writeOffset += chunk.GetLength();
|
writeOffset += chunk.GetLength();
|
||||||
aMessage.GetNextChunk(aLength, chunk);
|
aMessage.GetNextChunk(aLength, chunk);
|
||||||
}
|
}
|
||||||
@@ -475,12 +475,12 @@ void Message::GetFirstChunk(uint16_t aOffset, uint16_t &aLength, Chunk &aChunk)
|
|||||||
{
|
{
|
||||||
// This method gets the first message chunk (contiguous data
|
// This method gets the first message chunk (contiguous data
|
||||||
// buffer) corresponding to a given offset and length. On exit
|
// buffer) corresponding to a given offset and length. On exit
|
||||||
// `aChunk` is updated such that `aChunk.GetData()` gives the
|
// `aChunk` is updated such that `aChunk.GetBytes()` gives the
|
||||||
// pointer to the start of chunk and `aChunk.GetLength()` gives
|
// pointer to the start of chunk and `aChunk.GetLength()` gives
|
||||||
// its length. The `aLength` is also decreased by the chunk
|
// its length. The `aLength` is also decreased by the chunk
|
||||||
// length.
|
// length.
|
||||||
|
|
||||||
VerifyOrExit(aOffset < GetLength(), aChunk.mLength = 0);
|
VerifyOrExit(aOffset < GetLength(), aChunk.SetLength(0));
|
||||||
|
|
||||||
if (aOffset + aLength >= GetLength())
|
if (aOffset + aLength >= GetLength())
|
||||||
{
|
{
|
||||||
@@ -489,14 +489,13 @@ void Message::GetFirstChunk(uint16_t aOffset, uint16_t &aLength, Chunk &aChunk)
|
|||||||
|
|
||||||
aOffset += GetReserved();
|
aOffset += GetReserved();
|
||||||
|
|
||||||
aChunk.mBuffer = this;
|
aChunk.SetBuffer(this);
|
||||||
|
|
||||||
// Special case for the first buffer
|
// Special case for the first buffer
|
||||||
|
|
||||||
if (aOffset < kHeadBufferDataSize)
|
if (aOffset < kHeadBufferDataSize)
|
||||||
{
|
{
|
||||||
aChunk.mData = GetFirstData() + aOffset;
|
aChunk.Init(GetFirstData() + aOffset, kHeadBufferDataSize - aOffset);
|
||||||
aChunk.mLength = kHeadBufferDataSize - aOffset;
|
|
||||||
ExitNow();
|
ExitNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -506,13 +505,13 @@ void Message::GetFirstChunk(uint16_t aOffset, uint16_t &aLength, Chunk &aChunk)
|
|||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
aChunk.mBuffer = aChunk.mBuffer->GetNextBuffer();
|
aChunk.SetBuffer(aChunk.GetBuffer()->GetNextBuffer());
|
||||||
OT_ASSERT(aChunk.mBuffer != nullptr);
|
|
||||||
|
OT_ASSERT(aChunk.GetBuffer() != nullptr);
|
||||||
|
|
||||||
if (aOffset < kBufferDataSize)
|
if (aOffset < kBufferDataSize)
|
||||||
{
|
{
|
||||||
aChunk.mData = aChunk.mBuffer->GetData() + aOffset;
|
aChunk.Init(aChunk.GetBuffer()->GetData() + aOffset, kBufferDataSize - aOffset);
|
||||||
aChunk.mLength = kBufferDataSize - aOffset;
|
|
||||||
ExitNow();
|
ExitNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -520,12 +519,12 @@ void Message::GetFirstChunk(uint16_t aOffset, uint16_t &aLength, Chunk &aChunk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (aChunk.mLength > aLength)
|
if (aChunk.GetLength() > aLength)
|
||||||
{
|
{
|
||||||
aChunk.mLength = aLength;
|
aChunk.SetLength(aLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
aLength -= aChunk.mLength;
|
aLength -= aChunk.GetLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Message::GetNextChunk(uint16_t &aLength, Chunk &aChunk) const
|
void Message::GetNextChunk(uint16_t &aLength, Chunk &aChunk) const
|
||||||
@@ -536,20 +535,20 @@ void Message::GetNextChunk(uint16_t &aLength, Chunk &aChunk) const
|
|||||||
// is decreased by the chunk length. If there is no more
|
// is decreased by the chunk length. If there is no more
|
||||||
// chunk, `aChunk.GetLength()` would be zero.
|
// chunk, `aChunk.GetLength()` would be zero.
|
||||||
|
|
||||||
VerifyOrExit(aLength > 0, aChunk.mLength = 0);
|
VerifyOrExit(aLength > 0, aChunk.SetLength(0));
|
||||||
|
|
||||||
aChunk.mBuffer = aChunk.mBuffer->GetNextBuffer();
|
aChunk.SetBuffer(aChunk.GetBuffer()->GetNextBuffer());
|
||||||
OT_ASSERT(aChunk.mBuffer != nullptr);
|
|
||||||
|
|
||||||
aChunk.mData = aChunk.mBuffer->GetData();
|
OT_ASSERT(aChunk.GetBuffer() != nullptr);
|
||||||
aChunk.mLength = kBufferDataSize;
|
|
||||||
|
|
||||||
if (aChunk.mLength > aLength)
|
aChunk.Init(aChunk.GetBuffer()->GetData(), kBufferDataSize);
|
||||||
|
|
||||||
|
if (aChunk.GetLength() > aLength)
|
||||||
{
|
{
|
||||||
aChunk.mLength = aLength;
|
aChunk.SetLength(aLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
aLength -= aChunk.mLength;
|
aLength -= aChunk.GetLength();
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
return;
|
return;
|
||||||
@@ -564,7 +563,7 @@ uint16_t Message::ReadBytes(uint16_t aOffset, void *aBuf, uint16_t aLength) cons
|
|||||||
|
|
||||||
while (chunk.GetLength() > 0)
|
while (chunk.GetLength() > 0)
|
||||||
{
|
{
|
||||||
memcpy(bufPtr, chunk.GetData(), chunk.GetLength());
|
chunk.CopyBytesTo(bufPtr);
|
||||||
bufPtr += chunk.GetLength();
|
bufPtr += chunk.GetLength();
|
||||||
GetNextChunk(aLength, chunk);
|
GetNextChunk(aLength, chunk);
|
||||||
}
|
}
|
||||||
@@ -587,7 +586,7 @@ bool Message::CompareBytes(uint16_t aOffset, const void *aBuf, uint16_t aLength)
|
|||||||
|
|
||||||
while (chunk.GetLength() > 0)
|
while (chunk.GetLength() > 0)
|
||||||
{
|
{
|
||||||
VerifyOrExit(memcmp(bufPtr, chunk.GetData(), chunk.GetLength()) == 0);
|
VerifyOrExit(chunk.MatchesBytesIn(bufPtr));
|
||||||
bufPtr += chunk.GetLength();
|
bufPtr += chunk.GetLength();
|
||||||
bytesToCompare -= chunk.GetLength();
|
bytesToCompare -= chunk.GetLength();
|
||||||
GetNextChunk(aLength, chunk);
|
GetNextChunk(aLength, chunk);
|
||||||
@@ -609,7 +608,7 @@ bool Message::CompareBytes(uint16_t aOffset,
|
|||||||
|
|
||||||
while (chunk.GetLength() > 0)
|
while (chunk.GetLength() > 0)
|
||||||
{
|
{
|
||||||
VerifyOrExit(aOtherMessage.CompareBytes(aOtherOffset, chunk.GetData(), chunk.GetLength()));
|
VerifyOrExit(aOtherMessage.CompareBytes(aOtherOffset, chunk.GetBytes(), chunk.GetLength()));
|
||||||
aOtherOffset += chunk.GetLength();
|
aOtherOffset += chunk.GetLength();
|
||||||
bytesToCompare -= chunk.GetLength();
|
bytesToCompare -= chunk.GetLength();
|
||||||
GetNextChunk(aLength, chunk);
|
GetNextChunk(aLength, chunk);
|
||||||
@@ -622,7 +621,7 @@ exit:
|
|||||||
void Message::WriteBytes(uint16_t aOffset, const void *aBuf, uint16_t aLength)
|
void Message::WriteBytes(uint16_t aOffset, const void *aBuf, uint16_t aLength)
|
||||||
{
|
{
|
||||||
const uint8_t *bufPtr = reinterpret_cast<const uint8_t *>(aBuf);
|
const uint8_t *bufPtr = reinterpret_cast<const uint8_t *>(aBuf);
|
||||||
WritableChunk chunk;
|
MutableChunk chunk;
|
||||||
|
|
||||||
OT_ASSERT(aOffset + aLength <= GetLength());
|
OT_ASSERT(aOffset + aLength <= GetLength());
|
||||||
|
|
||||||
@@ -630,7 +629,7 @@ void Message::WriteBytes(uint16_t aOffset, const void *aBuf, uint16_t aLength)
|
|||||||
|
|
||||||
while (chunk.GetLength() > 0)
|
while (chunk.GetLength() > 0)
|
||||||
{
|
{
|
||||||
memmove(chunk.GetData(), bufPtr, chunk.GetLength());
|
memmove(chunk.GetBytes(), bufPtr, chunk.GetLength());
|
||||||
bufPtr += chunk.GetLength();
|
bufPtr += chunk.GetLength();
|
||||||
GetNextChunk(aLength, chunk);
|
GetNextChunk(aLength, chunk);
|
||||||
}
|
}
|
||||||
@@ -652,7 +651,7 @@ uint16_t Message::CopyTo(uint16_t aSourceOffset, uint16_t aDestinationOffset, ui
|
|||||||
|
|
||||||
while (chunk.GetLength() > 0)
|
while (chunk.GetLength() > 0)
|
||||||
{
|
{
|
||||||
aMessage.WriteBytes(aDestinationOffset, chunk.GetData(), chunk.GetLength());
|
aMessage.WriteBytes(aDestinationOffset, chunk.GetBytes(), chunk.GetLength());
|
||||||
aDestinationOffset += chunk.GetLength();
|
aDestinationOffset += chunk.GetLength();
|
||||||
bytesCopied += chunk.GetLength();
|
bytesCopied += chunk.GetLength();
|
||||||
GetNextChunk(aLength, chunk);
|
GetNextChunk(aLength, chunk);
|
||||||
|
|||||||
+13
-11
@@ -43,6 +43,7 @@
|
|||||||
|
|
||||||
#include "common/code_utils.hpp"
|
#include "common/code_utils.hpp"
|
||||||
#include "common/const_cast.hpp"
|
#include "common/const_cast.hpp"
|
||||||
|
#include "common/data.hpp"
|
||||||
#include "common/encoding.hpp"
|
#include "common/encoding.hpp"
|
||||||
#include "common/linked_list.hpp"
|
#include "common/linked_list.hpp"
|
||||||
#include "common/locator.hpp"
|
#include "common/locator.hpp"
|
||||||
@@ -1208,30 +1209,31 @@ protected:
|
|||||||
void SetReserved(uint16_t aReservedHeader) { GetMetadata().mReserved = aReservedHeader; }
|
void SetReserved(uint16_t aReservedHeader) { GetMetadata().mReserved = aReservedHeader; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Chunk
|
class Chunk : public Data<kWithUint16Length>
|
||||||
{
|
{
|
||||||
const uint8_t *GetData(void) const { return mData; }
|
public:
|
||||||
uint16_t GetLength(void) const { return mLength; }
|
const Buffer *GetBuffer(void) const { return mBuffer; }
|
||||||
|
void SetBuffer(const Buffer *aBuffer) { mBuffer = aBuffer; }
|
||||||
|
|
||||||
const uint8_t *mData; // Pointer to start of chunk data buffer.
|
private:
|
||||||
uint16_t mLength; // Length of chunk data (in bytes).
|
const Buffer *mBuffer; // Buffer containing the chunk
|
||||||
const Buffer * mBuffer; // Buffer containing the chunk
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WritableChunk : public Chunk
|
class MutableChunk : public Chunk
|
||||||
{
|
{
|
||||||
uint8_t *GetData(void) const { return AsNonConst(mData); }
|
public:
|
||||||
|
uint8_t *GetBytes(void) { return AsNonConst(Chunk::GetBytes()); }
|
||||||
};
|
};
|
||||||
|
|
||||||
void GetFirstChunk(uint16_t aOffset, uint16_t &aLength, Chunk &chunk) const;
|
void GetFirstChunk(uint16_t aOffset, uint16_t &aLength, Chunk &aChunk) const;
|
||||||
void GetNextChunk(uint16_t &aLength, Chunk &aChunk) const;
|
void GetNextChunk(uint16_t &aLength, Chunk &aChunk) const;
|
||||||
|
|
||||||
void GetFirstChunk(uint16_t aOffset, uint16_t &aLength, WritableChunk &aChunk)
|
void GetFirstChunk(uint16_t aOffset, uint16_t &aLength, MutableChunk &aChunk)
|
||||||
{
|
{
|
||||||
AsConst(this)->GetFirstChunk(aOffset, aLength, static_cast<Chunk &>(aChunk));
|
AsConst(this)->GetFirstChunk(aOffset, aLength, static_cast<Chunk &>(aChunk));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetNextChunk(uint16_t &aLength, WritableChunk &aChunk)
|
void GetNextChunk(uint16_t &aLength, MutableChunk &aChunk)
|
||||||
{
|
{
|
||||||
AsConst(this)->GetNextChunk(aLength, static_cast<Chunk &>(aChunk));
|
AsConst(this)->GetNextChunk(aLength, static_cast<Chunk &>(aChunk));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ void HmacSha256::Update(const Message &aMessage, uint16_t aOffset, uint16_t aLen
|
|||||||
|
|
||||||
while (chunk.GetLength() > 0)
|
while (chunk.GetLength() > 0)
|
||||||
{
|
{
|
||||||
Update(chunk.GetData(), chunk.GetLength());
|
Update(chunk.GetBytes(), chunk.GetLength());
|
||||||
aMessage.GetNextChunk(aLength, chunk);
|
aMessage.GetNextChunk(aLength, chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ void Sha256::Update(const Message &aMessage, uint16_t aOffset, uint16_t aLength)
|
|||||||
|
|
||||||
while (chunk.GetLength() > 0)
|
while (chunk.GetLength() > 0)
|
||||||
{
|
{
|
||||||
Update(chunk.GetData(), chunk.GetLength());
|
Update(chunk.GetBytes(), chunk.GetLength());
|
||||||
aMessage.GetNextChunk(aLength, chunk);
|
aMessage.GetNextChunk(aLength, chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ void Checksum::Calculate(const Ip6::Address &aSource,
|
|||||||
|
|
||||||
while (chunk.GetLength() > 0)
|
while (chunk.GetLength() > 0)
|
||||||
{
|
{
|
||||||
AddData(chunk.GetData(), chunk.GetLength());
|
AddData(chunk.GetBytes(), chunk.GetLength());
|
||||||
aMessage.GetNextChunk(length, chunk);
|
aMessage.GetNextChunk(length, chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ template <DataLengthType kDataLengthType> void TestData(void)
|
|||||||
data.CopyBytesTo(buffer);
|
data.CopyBytesTo(buffer);
|
||||||
VerifyOrQuit(memcmp(buffer, kData, sizeof(kData)) == 0);
|
VerifyOrQuit(memcmp(buffer, kData, sizeof(kData)) == 0);
|
||||||
VerifyOrQuit(buffer[sizeof(kData)] == 0);
|
VerifyOrQuit(buffer[sizeof(kData)] == 0);
|
||||||
|
VerifyOrQuit(data.MatchesBytesIn(buffer));
|
||||||
|
|
||||||
data2.InitFrom(kDataCopy);
|
data2.InitFrom(kDataCopy);
|
||||||
VerifyOrQuit(data2.GetLength() == sizeof(kDataCopy));
|
VerifyOrQuit(data2.GetLength() == sizeof(kDataCopy));
|
||||||
@@ -74,7 +75,10 @@ template <DataLengthType kDataLengthType> void TestData(void)
|
|||||||
VerifyOrQuit(data.StartsWith(data2));
|
VerifyOrQuit(data.StartsWith(data2));
|
||||||
VerifyOrQuit(data2.StartsWith(data));
|
VerifyOrQuit(data2.StartsWith(data));
|
||||||
|
|
||||||
data2.Init(kDataCopy, sizeof(kDataCopy) - 1);
|
data2.SetLength(sizeof(kDataCopy) - 1);
|
||||||
|
VerifyOrQuit(data2.GetLength() == sizeof(kDataCopy) - 1);
|
||||||
|
VerifyOrQuit(data2.GetBytes() == &kDataCopy[0]);
|
||||||
|
VerifyOrQuit(data2.MatchesBytesIn(kDataCopy));
|
||||||
VerifyOrQuit(data != data2);
|
VerifyOrQuit(data != data2);
|
||||||
VerifyOrQuit(data.StartsWith(data2));
|
VerifyOrQuit(data.StartsWith(data2));
|
||||||
VerifyOrQuit(!data2.StartsWith(data));
|
VerifyOrQuit(!data2.StartsWith(data));
|
||||||
|
|||||||
Reference in New Issue
Block a user