[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:
Abtin Keshavarzian
2021-09-20 19:13:00 -07:00
committed by GitHub
parent 0bb0896c98
commit d14acd4324
7 changed files with 71 additions and 45 deletions
+24 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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));
} }
+1 -1
View File
@@ -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);
} }
} }
+1 -1
View File
@@ -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);
} }
} }
+1 -1
View File
@@ -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);
} }
} }
+5 -1
View File
@@ -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));