mirror of
https://github.com/espressif/openthread.git
synced 2026-07-31 08:07:47 +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; }
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
@@ -153,7 +161,20 @@ public:
|
||||
* @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.
|
||||
@@ -166,7 +187,7 @@ public:
|
||||
*/
|
||||
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
|
||||
{
|
||||
return (mLength >= aOtherData.mLength) && (memcmp(mBuffer, aOtherData.mBuffer, aOtherData.mLength) == 0);
|
||||
return (mLength >= aOtherData.mLength) && aOtherData.MatchesBytesIn(mBuffer);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
+26
-27
@@ -410,7 +410,7 @@ Error Message::AppendBytesFromMessage(const Message &aMessage, uint16_t aOffset,
|
||||
|
||||
while (chunk.GetLength() > 0)
|
||||
{
|
||||
WriteBytes(writeOffset, chunk.GetData(), chunk.GetLength());
|
||||
WriteBytes(writeOffset, chunk.GetBytes(), chunk.GetLength());
|
||||
writeOffset += chunk.GetLength();
|
||||
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
|
||||
// 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
|
||||
// its length. The `aLength` is also decreased by the chunk
|
||||
// length.
|
||||
|
||||
VerifyOrExit(aOffset < GetLength(), aChunk.mLength = 0);
|
||||
VerifyOrExit(aOffset < GetLength(), aChunk.SetLength(0));
|
||||
|
||||
if (aOffset + aLength >= GetLength())
|
||||
{
|
||||
@@ -489,14 +489,13 @@ void Message::GetFirstChunk(uint16_t aOffset, uint16_t &aLength, Chunk &aChunk)
|
||||
|
||||
aOffset += GetReserved();
|
||||
|
||||
aChunk.mBuffer = this;
|
||||
aChunk.SetBuffer(this);
|
||||
|
||||
// Special case for the first buffer
|
||||
|
||||
if (aOffset < kHeadBufferDataSize)
|
||||
{
|
||||
aChunk.mData = GetFirstData() + aOffset;
|
||||
aChunk.mLength = kHeadBufferDataSize - aOffset;
|
||||
aChunk.Init(GetFirstData() + aOffset, kHeadBufferDataSize - aOffset);
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
@@ -506,13 +505,13 @@ void Message::GetFirstChunk(uint16_t aOffset, uint16_t &aLength, Chunk &aChunk)
|
||||
|
||||
while (true)
|
||||
{
|
||||
aChunk.mBuffer = aChunk.mBuffer->GetNextBuffer();
|
||||
OT_ASSERT(aChunk.mBuffer != nullptr);
|
||||
aChunk.SetBuffer(aChunk.GetBuffer()->GetNextBuffer());
|
||||
|
||||
OT_ASSERT(aChunk.GetBuffer() != nullptr);
|
||||
|
||||
if (aOffset < kBufferDataSize)
|
||||
{
|
||||
aChunk.mData = aChunk.mBuffer->GetData() + aOffset;
|
||||
aChunk.mLength = kBufferDataSize - aOffset;
|
||||
aChunk.Init(aChunk.GetBuffer()->GetData() + aOffset, kBufferDataSize - aOffset);
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
@@ -520,12 +519,12 @@ void Message::GetFirstChunk(uint16_t aOffset, uint16_t &aLength, Chunk &aChunk)
|
||||
}
|
||||
|
||||
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
|
||||
@@ -536,20 +535,20 @@ void Message::GetNextChunk(uint16_t &aLength, Chunk &aChunk) const
|
||||
// is decreased by the chunk length. If there is no more
|
||||
// chunk, `aChunk.GetLength()` would be zero.
|
||||
|
||||
VerifyOrExit(aLength > 0, aChunk.mLength = 0);
|
||||
VerifyOrExit(aLength > 0, aChunk.SetLength(0));
|
||||
|
||||
aChunk.mBuffer = aChunk.mBuffer->GetNextBuffer();
|
||||
OT_ASSERT(aChunk.mBuffer != nullptr);
|
||||
aChunk.SetBuffer(aChunk.GetBuffer()->GetNextBuffer());
|
||||
|
||||
aChunk.mData = aChunk.mBuffer->GetData();
|
||||
aChunk.mLength = kBufferDataSize;
|
||||
OT_ASSERT(aChunk.GetBuffer() != nullptr);
|
||||
|
||||
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:
|
||||
return;
|
||||
@@ -564,7 +563,7 @@ uint16_t Message::ReadBytes(uint16_t aOffset, void *aBuf, uint16_t aLength) cons
|
||||
|
||||
while (chunk.GetLength() > 0)
|
||||
{
|
||||
memcpy(bufPtr, chunk.GetData(), chunk.GetLength());
|
||||
chunk.CopyBytesTo(bufPtr);
|
||||
bufPtr += chunk.GetLength();
|
||||
GetNextChunk(aLength, chunk);
|
||||
}
|
||||
@@ -587,7 +586,7 @@ bool Message::CompareBytes(uint16_t aOffset, const void *aBuf, uint16_t aLength)
|
||||
|
||||
while (chunk.GetLength() > 0)
|
||||
{
|
||||
VerifyOrExit(memcmp(bufPtr, chunk.GetData(), chunk.GetLength()) == 0);
|
||||
VerifyOrExit(chunk.MatchesBytesIn(bufPtr));
|
||||
bufPtr += chunk.GetLength();
|
||||
bytesToCompare -= chunk.GetLength();
|
||||
GetNextChunk(aLength, chunk);
|
||||
@@ -609,7 +608,7 @@ bool Message::CompareBytes(uint16_t aOffset,
|
||||
|
||||
while (chunk.GetLength() > 0)
|
||||
{
|
||||
VerifyOrExit(aOtherMessage.CompareBytes(aOtherOffset, chunk.GetData(), chunk.GetLength()));
|
||||
VerifyOrExit(aOtherMessage.CompareBytes(aOtherOffset, chunk.GetBytes(), chunk.GetLength()));
|
||||
aOtherOffset += chunk.GetLength();
|
||||
bytesToCompare -= chunk.GetLength();
|
||||
GetNextChunk(aLength, chunk);
|
||||
@@ -622,7 +621,7 @@ exit:
|
||||
void Message::WriteBytes(uint16_t aOffset, const void *aBuf, uint16_t aLength)
|
||||
{
|
||||
const uint8_t *bufPtr = reinterpret_cast<const uint8_t *>(aBuf);
|
||||
WritableChunk chunk;
|
||||
MutableChunk chunk;
|
||||
|
||||
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)
|
||||
{
|
||||
memmove(chunk.GetData(), bufPtr, chunk.GetLength());
|
||||
memmove(chunk.GetBytes(), bufPtr, chunk.GetLength());
|
||||
bufPtr += chunk.GetLength();
|
||||
GetNextChunk(aLength, chunk);
|
||||
}
|
||||
@@ -652,7 +651,7 @@ uint16_t Message::CopyTo(uint16_t aSourceOffset, uint16_t aDestinationOffset, ui
|
||||
|
||||
while (chunk.GetLength() > 0)
|
||||
{
|
||||
aMessage.WriteBytes(aDestinationOffset, chunk.GetData(), chunk.GetLength());
|
||||
aMessage.WriteBytes(aDestinationOffset, chunk.GetBytes(), chunk.GetLength());
|
||||
aDestinationOffset += chunk.GetLength();
|
||||
bytesCopied += chunk.GetLength();
|
||||
GetNextChunk(aLength, chunk);
|
||||
|
||||
+13
-11
@@ -43,6 +43,7 @@
|
||||
|
||||
#include "common/code_utils.hpp"
|
||||
#include "common/const_cast.hpp"
|
||||
#include "common/data.hpp"
|
||||
#include "common/encoding.hpp"
|
||||
#include "common/linked_list.hpp"
|
||||
#include "common/locator.hpp"
|
||||
@@ -1208,30 +1209,31 @@ protected:
|
||||
void SetReserved(uint16_t aReservedHeader) { GetMetadata().mReserved = aReservedHeader; }
|
||||
|
||||
private:
|
||||
struct Chunk
|
||||
class Chunk : public Data<kWithUint16Length>
|
||||
{
|
||||
const uint8_t *GetData(void) const { return mData; }
|
||||
uint16_t GetLength(void) const { return mLength; }
|
||||
public:
|
||||
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.
|
||||
uint16_t mLength; // Length of chunk data (in bytes).
|
||||
const Buffer * mBuffer; // Buffer containing the chunk
|
||||
private:
|
||||
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 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));
|
||||
}
|
||||
|
||||
void GetNextChunk(uint16_t &aLength, WritableChunk &aChunk)
|
||||
void GetNextChunk(uint16_t &aLength, MutableChunk &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)
|
||||
{
|
||||
Update(chunk.GetData(), chunk.GetLength());
|
||||
Update(chunk.GetBytes(), chunk.GetLength());
|
||||
aMessage.GetNextChunk(aLength, chunk);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ void Sha256::Update(const Message &aMessage, uint16_t aOffset, uint16_t aLength)
|
||||
|
||||
while (chunk.GetLength() > 0)
|
||||
{
|
||||
Update(chunk.GetData(), chunk.GetLength());
|
||||
Update(chunk.GetBytes(), chunk.GetLength());
|
||||
aMessage.GetNextChunk(aLength, chunk);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ void Checksum::Calculate(const Ip6::Address &aSource,
|
||||
|
||||
while (chunk.GetLength() > 0)
|
||||
{
|
||||
AddData(chunk.GetData(), chunk.GetLength());
|
||||
AddData(chunk.GetBytes(), chunk.GetLength());
|
||||
aMessage.GetNextChunk(length, chunk);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ template <DataLengthType kDataLengthType> void TestData(void)
|
||||
data.CopyBytesTo(buffer);
|
||||
VerifyOrQuit(memcmp(buffer, kData, sizeof(kData)) == 0);
|
||||
VerifyOrQuit(buffer[sizeof(kData)] == 0);
|
||||
VerifyOrQuit(data.MatchesBytesIn(buffer));
|
||||
|
||||
data2.InitFrom(kDataCopy);
|
||||
VerifyOrQuit(data2.GetLength() == sizeof(kDataCopy));
|
||||
@@ -74,7 +75,10 @@ template <DataLengthType kDataLengthType> void TestData(void)
|
||||
VerifyOrQuit(data.StartsWith(data2));
|
||||
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.StartsWith(data2));
|
||||
VerifyOrQuit(!data2.StartsWith(data));
|
||||
|
||||
Reference in New Issue
Block a user