mirror of
https://github.com/espressif/openthread.git
synced 2026-08-06 10:47:46 +00:00
[message] add clone methods to MessageAllocator (#12704)
This commit adds `CloneMessage()`, `CloneMessageWithoutFooter()`, and `CloneMessageWithout<Footer>()` methods to the `MessageAllocator` class. These methods simplify creating copies of messages by automatically applying the correct `kReservedHeader` size. It also updates existing code in `CoapBase`, `Dns::Client`, `Sntp::Client`, and `Mle` to utilize these new methods. Additionally, this commit updates the `Clone()` method in `Message` to be a template method, accepting a `CloneMode` to specify whether the cloned message should retain the reserved header or have no reserved header. The documentation for the clone methods has also been updated to clarify which message fields are copied during the cloning process.
This commit is contained in:
@@ -122,7 +122,7 @@ int otMessageWrite(otMessage *aMessage, uint16_t aOffset, const void *aBuf, uint
|
||||
return aLength;
|
||||
}
|
||||
|
||||
otMessage *otMessageClone(const otMessage *aMessage) { return AsCoreType(aMessage).Clone(); }
|
||||
otMessage *otMessageClone(const otMessage *aMessage) { return AsCoreType(aMessage).Clone<kNoReservedHeader>(); }
|
||||
|
||||
void otMessageQueueInit(otMessageQueue *aQueue) { AsCoreType(aQueue).Clear(); }
|
||||
|
||||
|
||||
@@ -1018,7 +1018,7 @@ Error CoapBase::CacheLastBlockResponse(Message *aResponse)
|
||||
|
||||
FreeLastBlockResponse();
|
||||
|
||||
mLastResponse = AsCoapMessagePtr(aResponse->Clone());
|
||||
mLastResponse = AsCoapMessagePtr(aResponse->Clone<kNoReservedHeader>());
|
||||
VerifyOrExit(mLastResponse != nullptr, error = kErrorNoBufs);
|
||||
|
||||
exit:
|
||||
@@ -1549,7 +1549,7 @@ Error CoapBase::PendingRequests::Add(const Msg &aTxMsg,
|
||||
|
||||
cloneLength = aTxMsg.IsConfirmable() ? aTxMsg.mMessage.GetLength() : aTxMsg.GetHeaderSize();
|
||||
|
||||
aRequest.mMessage = AsCoapMessagePtr(aTxMsg.mMessage.Clone(cloneLength));
|
||||
aRequest.mMessage = AsCoapMessagePtr(aTxMsg.mMessage.Clone<kNoReservedHeader>(cloneLength));
|
||||
VerifyOrExit(aRequest.HasMessage(), error = kErrorNoBufs);
|
||||
|
||||
SuccessOrExit(error = aRequest.AppendMetadataToMessage());
|
||||
@@ -1688,7 +1688,7 @@ void CoapBase::PendingRequests::RetransmitRequest(const Request &aRequest)
|
||||
Message *clone;
|
||||
Ip6::MessageInfo messageInfo;
|
||||
|
||||
clone = AsCoapMessagePtr(aRequest.mMessage->Clone(aRequest.mMessage->GetLength() - sizeof(Request::Metadata)));
|
||||
clone = mCoapBase.CloneMessageWithout<Request::Metadata>(aRequest.GetMessage());
|
||||
VerifyOrExit(clone != nullptr, error = kErrorNoBufs);
|
||||
|
||||
aRequest.mMetadata.CopyInfoTo(messageInfo);
|
||||
@@ -1802,7 +1802,7 @@ Error CoapBase::ResponseCache::SendCachedResponse(const Msg &aRxMsg, CoapBase &a
|
||||
|
||||
VerifyOrExit(match != nullptr, error = kErrorNotFound);
|
||||
|
||||
response = AsCoapMessagePtr(match->Clone(match->GetLength() - sizeof(ResponseMetadata)));
|
||||
response = aCoapBase.CloneMessageWithout<ResponseMetadata>(*match);
|
||||
VerifyOrExit(response != nullptr, error = kErrorNoBufs);
|
||||
|
||||
error = aCoapBase.Transmit(*response, aRxMsg.mMessageInfo);
|
||||
@@ -1848,7 +1848,7 @@ void CoapBase::ResponseCache::Add(const Msg &aTxMsg, uint32_t aExchangeLifetime)
|
||||
|
||||
MaintainCacheSize();
|
||||
|
||||
responseClone = AsCoapMessagePtr(aTxMsg.mMessage.Clone());
|
||||
responseClone = AsCoapMessagePtr(aTxMsg.mMessage.Clone<kNoReservedHeader>());
|
||||
VerifyOrExit(responseClone != nullptr);
|
||||
|
||||
metadata.mExpireTime = TimerMilli::GetNow() + aExchangeLifetime;
|
||||
|
||||
@@ -785,10 +785,6 @@ void Message::WriteBytesFromMessage(uint16_t aWriteOffset,
|
||||
}
|
||||
}
|
||||
|
||||
Message *Message::Clone(void) const { return Clone(GetLength()); }
|
||||
|
||||
Message *Message::Clone(uint16_t aLength) const { return Clone(aLength, GetReserved()); }
|
||||
|
||||
Message *Message::Clone(uint16_t aLength, uint16_t aReserveHeader) const
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
@@ -824,6 +820,17 @@ exit:
|
||||
return clone;
|
||||
}
|
||||
|
||||
template <> Message *Message::Clone<kNoReservedHeader>(void) const { return Clone(GetLength(), 0); }
|
||||
|
||||
template <> Message *Message::Clone<kSameReservedHeader>(void) const { return Clone(GetLength(), GetReserved()); }
|
||||
|
||||
template <> Message *Message::Clone<kNoReservedHeader>(uint16_t aLength) const { return Clone(aLength, 0); }
|
||||
|
||||
template <> Message *Message::Clone<kSameReservedHeader>(uint16_t aLength) const
|
||||
{
|
||||
return Clone(aLength, GetReserved());
|
||||
}
|
||||
|
||||
Error Message::GetLinkInfo(ThreadLinkInfo &aLinkInfo) const
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
+42
-26
@@ -156,6 +156,15 @@ enum LinkSecurityMode : bool
|
||||
kWithLinkSecurity = true, ///< Link security enabled.
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents the clone mode indicating how the reserved header should be configured on the cloned message.
|
||||
*/
|
||||
enum CloneMode : uint8_t
|
||||
{
|
||||
kNoReservedHeader, ///< The clone message will have no reserved header.
|
||||
kSameReservedHeader ///< The clone message will have the same reserved header size as the original `Message`.
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a Message buffer.
|
||||
*/
|
||||
@@ -1099,35 +1108,12 @@ public:
|
||||
WriteBytes(aOffset, aData.GetBytes(), aData.GetLength());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of the message.
|
||||
*
|
||||
* It allocates the new message from the same message pool as the original one and copies the entire payload. The
|
||||
* `Type`, `SubType`, `LinkSecurity`, `Offset`, and `Priority` fields on the cloned message are also
|
||||
* copied from the original one.
|
||||
*
|
||||
* @returns A pointer to the message or `nullptr` if insufficient message buffers are available.
|
||||
*/
|
||||
Message *Clone(void) const;
|
||||
|
||||
/**
|
||||
* Creates a copy of the message.
|
||||
*
|
||||
* It allocates the new message from the same message pool as the original one and copies @p aLength octets
|
||||
* of the payload. The `Type`, `SubType`, `LinkSecurity`, `Offset`, and `Priority` fields on the cloned message
|
||||
* are also copied from the original one.
|
||||
*
|
||||
* @param[in] aLength Number of message bytes to copy.
|
||||
*
|
||||
* @returns A pointer to the message or nullptr if insufficient message buffers are available.
|
||||
*/
|
||||
Message *Clone(uint16_t aLength) const;
|
||||
|
||||
/**
|
||||
* Creates a copy of the message using a given configuration.
|
||||
*
|
||||
* It allocates the new message from the same message pool as the original one. The `Type`, `SubType`,
|
||||
* `LinkSecurity`, `Offset`, and `Priority` fields on the cloned message are copied from the original one.
|
||||
* The `Type`, `SubType`, `LinkSecurity`, `Offset`, `Priority`, `LoopbackToHostAllowed`, `Origin`, `Timestamp`,
|
||||
* `MeshDest`, `PanId`, `Channel`, `RssAverager`, `LqiAverager`, and `TimeSync` fields on the cloned message are
|
||||
* also copied from the original one.
|
||||
*
|
||||
* @param[in] aLength Number of message bytes to copy.
|
||||
* @param[in] aReserveHeader Number of header bytes to reserve in the new cloned message.
|
||||
@@ -1136,6 +1122,30 @@ public:
|
||||
*/
|
||||
Message *Clone(uint16_t aLength, uint16_t aReserveHeader) const;
|
||||
|
||||
/**
|
||||
* Creates a copy of the message.
|
||||
*
|
||||
* @tparam kMode Specifies the clone mode (whether to keep the same reserved header size or have none).
|
||||
*
|
||||
* See the non-templated `Clone()` method for details on which message fields are also copied.
|
||||
*
|
||||
* @returns A pointer to the message or `nullptr` if insufficient message buffers are available.
|
||||
*/
|
||||
template <CloneMode kMode> Message *Clone(void) const;
|
||||
|
||||
/**
|
||||
* Creates a copy of the message.
|
||||
*
|
||||
* @tparam kMode Specifies the clone mode (whether to keep the same reserved header size or have none).
|
||||
*
|
||||
* See the non-templated `Clone()` method for details on which message fields are also copied.
|
||||
*
|
||||
* @param[in] aLength Number of message bytes to copy.
|
||||
*
|
||||
* @returns A pointer to the message or `nullptr` if insufficient message buffers are available.
|
||||
*/
|
||||
template <CloneMode kMode> Message *Clone(uint16_t aLength) const;
|
||||
|
||||
/**
|
||||
* Returns the datagram tag used for 6LoWPAN fragmentation or the identification used for IPv6
|
||||
* fragmentation.
|
||||
@@ -1996,6 +2006,12 @@ private:
|
||||
uint16_t mMaxAllocated;
|
||||
};
|
||||
|
||||
// Declare specializations of `Message::Clone<CloneMode>()` (implemented in `message.cpp`).
|
||||
template <> Message *Message::Clone<kNoReservedHeader>(void) const;
|
||||
template <> Message *Message::Clone<kSameReservedHeader>(void) const;
|
||||
template <> Message *Message::Clone<kNoReservedHeader>(uint16_t aLength) const;
|
||||
template <> Message *Message::Clone<kSameReservedHeader>(uint16_t aLength) const;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#include "common/message.hpp"
|
||||
#include "common/type_traits.hpp"
|
||||
#include "net/ip6_headers.hpp"
|
||||
|
||||
namespace ot {
|
||||
@@ -126,6 +127,53 @@ public:
|
||||
*/
|
||||
MessageType *NewNetPriorityMessage(void) { return NewMessage(Message::Settings(Message::kPriorityNet)); }
|
||||
|
||||
/**
|
||||
* Creates a copy of a given message.
|
||||
*
|
||||
* The new message will be allocated with the `kReservedHeader` reserved header size.
|
||||
*
|
||||
* @param[in] aMessage The message to copy.
|
||||
*
|
||||
* @returns A pointer to the message or `nullptr` if no buffers are available.
|
||||
*/
|
||||
MessageType *CloneMessage(const MessageType &aMessage)
|
||||
{
|
||||
return AsMessageType(aMessage.Clone(aMessage.GetLength(), kReservedHeader));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of a given message without a footer.
|
||||
*
|
||||
* The new message will be allocated with the `kReservedHeader` reserved header size.
|
||||
*
|
||||
* @param[in] aMessage The message to copy.
|
||||
* @param[in] aFooterLength The size of the footer to omit from the cloned message.
|
||||
*
|
||||
* @returns A pointer to the message or `nullptr` if no buffers are available.
|
||||
*/
|
||||
MessageType *CloneMessageWithoutFooter(const MessageType &aMessage, uint16_t aFooterLength)
|
||||
{
|
||||
return AsMessageType(aMessage.Clone(aMessage.GetLength() - aFooterLength, kReservedHeader));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of a given message without a given footer type.
|
||||
*
|
||||
* The new message will be allocated with the `kReservedHeader` reserved header size.
|
||||
*
|
||||
* @tparam FooterType The footer type to omit from the cloned message.
|
||||
*
|
||||
* @param[in] aMessage The message to copy.
|
||||
*
|
||||
* @returns A pointer to the message or `nullptr` if no buffers are available.
|
||||
*/
|
||||
template <typename FooterType> MessageType *CloneMessageWithout(const MessageType &aMessage)
|
||||
{
|
||||
static_assert(!TypeTraits::IsPointer<FooterType>::kValue, "FooterType must not be a pointer");
|
||||
|
||||
return AsMessageType(aMessage.Clone(aMessage.GetLength() - sizeof(FooterType), kReservedHeader));
|
||||
}
|
||||
|
||||
protected:
|
||||
MessageAllocator(void) = default;
|
||||
|
||||
|
||||
@@ -1584,8 +1584,8 @@ void Client::SaveQueryResponse(Query &aQuery, const Message &aResponseMessage)
|
||||
info.ReadFrom(aQuery);
|
||||
VerifyOrExit(info.mSavedResponse == nullptr);
|
||||
|
||||
// If `Clone()` fails we let retry or timeout handle the error.
|
||||
info.mSavedResponse = aResponseMessage.Clone();
|
||||
// If clone fails we let retry or timeout handle the error.
|
||||
info.mSavedResponse = aResponseMessage.Clone<kNoReservedHeader>();
|
||||
|
||||
UpdateQuery(aQuery, info);
|
||||
|
||||
@@ -1823,7 +1823,7 @@ Error Client::ReplaceWithSeparateSrvTxtQueries(Query &aQuery)
|
||||
|
||||
RecordServerAsLimitedToSingleQuestion(info.mConfig.GetServerSockAddr().GetAddress());
|
||||
|
||||
secondQuery = aQuery.Clone();
|
||||
secondQuery = mSocket.CloneMessage(aQuery);
|
||||
VerifyOrExit(secondQuery != nullptr);
|
||||
|
||||
info.mQueryType = kServiceQueryTxt;
|
||||
|
||||
@@ -184,7 +184,7 @@ Error Ip6::PrepareMulticastToLargerThanRealmLocal(Message &aMessage, const Heade
|
||||
if (aHeader.GetDestination().IsMulticastLargerThanRealmLocal() &&
|
||||
Get<ChildTable>().HasSleepyChildWithAddress(aHeader.GetDestination()))
|
||||
{
|
||||
Message *messageCopy = aMessage.Clone();
|
||||
Message *messageCopy = aMessage.Clone<kSameReservedHeader>();
|
||||
|
||||
if (messageCopy != nullptr)
|
||||
{
|
||||
@@ -855,7 +855,7 @@ Error Ip6::TakeOrCopyMessagePtr(OwnedPtr<Message> &aTargetPtr,
|
||||
break;
|
||||
|
||||
case kCopyMessageToUse:
|
||||
aTargetPtr.Reset(aMessagePtr->Clone());
|
||||
aTargetPtr.Reset(aMessagePtr->Clone<kNoReservedHeader>());
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -342,7 +342,7 @@ void Mpl::AddBufferedMessage(Message &aMessage, uint16_t aSeedId, uint8_t aSeque
|
||||
#endif
|
||||
|
||||
VerifyOrExit(DetermineMaxRetransmissions() > 0);
|
||||
VerifyOrExit((messageCopy = aMessage.Clone()) != nullptr, error = kErrorNoBufs);
|
||||
VerifyOrExit((messageCopy = aMessage.Clone<kSameReservedHeader>()) != nullptr, error = kErrorNoBufs);
|
||||
|
||||
if (aMessage.IsOriginThreadNetif())
|
||||
{
|
||||
@@ -413,7 +413,7 @@ void Mpl::HandleRetransmissionTimer(void)
|
||||
|
||||
nextTime.UpdateIfEarlier(metadata.mTransmissionTime);
|
||||
|
||||
messageCopy = message.Clone();
|
||||
messageCopy = message.Clone<kSameReservedHeader>();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -128,7 +128,7 @@ Message *Client::CopyAndEnqueueMessage(const Message &aMessage, const QueryMetad
|
||||
Message *messageCopy = nullptr;
|
||||
|
||||
// Create a message copy for further retransmissions.
|
||||
VerifyOrExit((messageCopy = aMessage.Clone()) != nullptr, error = kErrorNoBufs);
|
||||
VerifyOrExit((messageCopy = aMessage.Clone<kNoReservedHeader>()) != nullptr, error = kErrorNoBufs);
|
||||
|
||||
// Append the copy with retransmission data and add it to the queue.
|
||||
SuccessOrExit(error = aQueryMetadata.AppendTo(*messageCopy));
|
||||
@@ -160,13 +160,11 @@ Error Client::SendMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInf
|
||||
void Client::SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
Error error;
|
||||
Message *messageCopy = nullptr;
|
||||
Message *messageCopy;
|
||||
|
||||
// Create a message copy for lower layers.
|
||||
VerifyOrExit((messageCopy = aMessage.Clone(aMessage.GetLength() - sizeof(QueryMetadata))) != nullptr,
|
||||
error = kErrorNoBufs);
|
||||
messageCopy = mSocket.CloneMessageWithout<QueryMetadata>(aMessage);
|
||||
VerifyOrExit(messageCopy != nullptr, error = kErrorNoBufs);
|
||||
|
||||
// Send the copy.
|
||||
SuccessOrExit(error = SendMessage(*messageCopy, aMessageInfo));
|
||||
|
||||
exit:
|
||||
|
||||
@@ -4945,8 +4945,9 @@ void Mle::Attacher::SendParentRequest(ParentRequestType aType)
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE
|
||||
if (aType == kToSelectedRouter)
|
||||
{
|
||||
TxMessage *messageToCurParent = static_cast<TxMessage *>(message->Clone());
|
||||
TxMessage *messageToCurParent;
|
||||
|
||||
messageToCurParent = static_cast<TxMessage *>(Get<Mle>().mSocket.CloneMessage(*message));
|
||||
VerifyOrExit(messageToCurParent != nullptr, error = kErrorNoBufs);
|
||||
|
||||
destination.SetToLinkLocalAddress(Get<Mle>().mParent.GetExtAddress());
|
||||
|
||||
@@ -335,7 +335,7 @@ void InfraIf::SendUdp(const Ip6::Address &aSrcAddress,
|
||||
|
||||
if (aDestAddress.IsMulticast())
|
||||
{
|
||||
Message *loopbackMessage = aPayload.Clone();
|
||||
Message *loopbackMessage = aPayload.Clone<kNoReservedHeader>();
|
||||
|
||||
VerifyOrQuit(loopbackMessage != nullptr);
|
||||
Receive(GetNode(), *loopbackMessage);
|
||||
@@ -396,7 +396,7 @@ void InfraIf::Receive(Node &aSrcNode, Message &aMessage)
|
||||
if (headers.GetDestinationAddress().IsMulticast() || node.mInfraIf.HasAddress(headers.GetDestinationAddress()))
|
||||
{
|
||||
Mdns::AddressInfo senderAddress;
|
||||
Message *payload = aMessage.Clone();
|
||||
Message *payload = aMessage.Clone<kNoReservedHeader>();
|
||||
|
||||
VerifyOrQuit(payload != nullptr);
|
||||
payload->RemoveHeader(sizeof(Ip6::Header) + sizeof(Ip6::Udp::Header));
|
||||
@@ -432,7 +432,7 @@ void InfraIf::Receive(Node &aSrcNode, Message &aMessage)
|
||||
VerifyOrExit(updatedHeader.GetHopLimit() > 1);
|
||||
updatedHeader.SetHopLimit(updatedHeader.GetHopLimit() - 1);
|
||||
|
||||
messagePtr.Reset(aMessage.Clone());
|
||||
messagePtr.Reset(aMessage.Clone<kNoReservedHeader>());
|
||||
VerifyOrQuit(messagePtr != nullptr);
|
||||
|
||||
messagePtr->Write(0, updatedHeader);
|
||||
|
||||
@@ -140,7 +140,7 @@ void Mdns::Receive(Instance &aInstance, Message &aMessage, bool aIsUnicast, cons
|
||||
VerifyOrExit(aSenderAddress.mPort == kUdpPort);
|
||||
}
|
||||
|
||||
message = aMessage.Clone();
|
||||
message = aMessage.Clone<kNoReservedHeader>();
|
||||
VerifyOrQuit(message != nullptr);
|
||||
|
||||
otPlatMdnsHandleReceive(&aInstance, message, aIsUnicast, &aSenderAddress);
|
||||
|
||||
@@ -361,14 +361,14 @@ bool HandleResource(void *aContext, Uri aUri, Coap::Msg &aMsg)
|
||||
SuccessOrQuit(Tlv::Find<MeshCoP::JoinerIidTlv>(aMsg.mMessage, joinerIid));
|
||||
Log(" Received `RelayRx` from joiner - port:%u iid:%s", joinerPort, joinerIid.ToString().AsCString());
|
||||
|
||||
msgClone = aMsg.mMessage.Clone();
|
||||
msgClone = aMsg.mMessage.Clone<kNoReservedHeader>();
|
||||
VerifyOrQuit(msgClone != nullptr);
|
||||
recvContext->mRelayRxMsgs.Enqueue(*msgClone);
|
||||
break;
|
||||
|
||||
case kUriProxyRx:
|
||||
Log(" Received `ProxyRx`");
|
||||
msgClone = aMsg.mMessage.Clone();
|
||||
msgClone = aMsg.mMessage.Clone<kNoReservedHeader>();
|
||||
VerifyOrQuit(msgClone != nullptr);
|
||||
recvContext->mProxyRxMsgs.Enqueue(*msgClone);
|
||||
break;
|
||||
|
||||
@@ -333,7 +333,7 @@ void TestDtlsSingleSession(void)
|
||||
{
|
||||
OwnedPtr<Message> msg(PrepareMessage(node0));
|
||||
|
||||
SuccessOrQuit(dtls0.Send(*msg->Clone()));
|
||||
SuccessOrQuit(dtls0.Send(*msg->Clone<kNoReservedHeader>()));
|
||||
nexus.AdvanceTime(100);
|
||||
|
||||
VerifyOrQuit(sDtlsLastReceive[node1.GetId()].GetLength() == msg->GetLength());
|
||||
@@ -347,7 +347,7 @@ void TestDtlsSingleSession(void)
|
||||
{
|
||||
OwnedPtr<Message> msg(PrepareMessage(node1));
|
||||
|
||||
SuccessOrQuit(dtls1.Send(*msg->Clone()));
|
||||
SuccessOrQuit(dtls1.Send(*msg->Clone<kNoReservedHeader>()));
|
||||
nexus.AdvanceTime(100);
|
||||
|
||||
VerifyOrQuit(sDtlsLastReceive[node0.GetId()].GetLength() == msg->GetLength());
|
||||
|
||||
@@ -218,7 +218,7 @@ void TestInPlaceAesCcmProcessing(void)
|
||||
SuccessOrQuit(message->Append<uint8_t>(i & 0xff));
|
||||
}
|
||||
|
||||
messageClone = message->Clone();
|
||||
messageClone = message->Clone<kNoReservedHeader>();
|
||||
VerifyOrQuit(messageClone != nullptr);
|
||||
VerifyOrQuit(messageClone->GetLength() == msgLength);
|
||||
|
||||
|
||||
@@ -379,7 +379,7 @@ public:
|
||||
message->SetOrigin(Message::kOriginHostUntrusted);
|
||||
|
||||
// Test 1: Default cloning
|
||||
clone = message->Clone();
|
||||
clone = message->Clone<kSameReservedHeader>();
|
||||
VerifyOrQuit(clone != nullptr);
|
||||
|
||||
VerifyOrQuit(clone->GetLength() == message->GetLength());
|
||||
@@ -397,7 +397,7 @@ public:
|
||||
clone->Free();
|
||||
|
||||
// Test 2: Cloning with shorter length
|
||||
clone = message->Clone(kLength / 2);
|
||||
clone = message->Clone<kSameReservedHeader>(kLength / 2);
|
||||
VerifyOrQuit(clone != nullptr);
|
||||
|
||||
VerifyOrQuit(clone->GetLength() == kLength / 2);
|
||||
@@ -411,12 +411,12 @@ public:
|
||||
// Test 3: Cloning with shorter length, offset change
|
||||
message->SetOffset(80);
|
||||
|
||||
clone = message->Clone(kLength / 2);
|
||||
clone = message->Clone<kNoReservedHeader>(kLength / 2);
|
||||
VerifyOrQuit(clone != nullptr);
|
||||
|
||||
VerifyOrQuit(clone->GetLength() == kLength / 2);
|
||||
VerifyOrQuit(clone->GetPriority() == message->GetPriority());
|
||||
VerifyOrQuit(clone->GetReserved() == message->GetReserved());
|
||||
VerifyOrQuit(clone->GetReserved() == 0);
|
||||
VerifyOrQuit(clone->GetOffset() == 50); // Offset should be updated
|
||||
VerifyOrQuit(clone->CompareBytes(0, buffer, kLength / 2));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user