From 0e0fd72befb24759347c43c5eca2d88fc03d89d1 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 24 Jul 2023 10:35:58 -0400 Subject: [PATCH] Make TLVReader getter const for ByteSpan and CharSpan (#28169) * Move some TLV reader get methods to const (integers and bools) * Move floating point getters to const * Make use of new newly const support in protocol decoder printers * Restyled by clang-format * Another minor simplification --------- Co-authored-by: Andrei Litvin Co-authored-by: Restyled.io --- src/lib/core/TLVReader.cpp | 41 +++++++++++------------------ src/lib/core/TLVReader.h | 13 +++++---- src/lib/format/protocol_decoder.cpp | 4 +-- 3 files changed, 23 insertions(+), 35 deletions(-) diff --git a/src/lib/core/TLVReader.cpp b/src/lib/core/TLVReader.cpp index 95d7f7c880fef3..c44d0947d87d1c 100644 --- a/src/lib/core/TLVReader.cpp +++ b/src/lib/core/TLVReader.cpp @@ -290,7 +290,7 @@ CHIP_ERROR TLVReader::Get(double & v) const return CHIP_NO_ERROR; } -CHIP_ERROR TLVReader::Get(ByteSpan & v) +CHIP_ERROR TLVReader::Get(ByteSpan & v) const { const uint8_t * val; ReturnErrorOnFailure(GetDataPtr(val)); @@ -304,7 +304,7 @@ constexpr int kUnicodeInformationSeparator1 = 0x1F; constexpr size_t kMaxLocalizedStringIdentifierLen = 2 * sizeof(LocalizedStringIdentifier); } // namespace -CHIP_ERROR TLVReader::Get(CharSpan & v) +CHIP_ERROR TLVReader::Get(CharSpan & v) const { if (!TLVTypeIsUTF8String(ElementType())) { @@ -460,12 +460,9 @@ CHIP_ERROR TLVReader::DupString(char *& buf) return err; } -CHIP_ERROR TLVReader::GetDataPtr(const uint8_t *& data) +CHIP_ERROR TLVReader::GetDataPtr(const uint8_t *& data) const { - CHIP_ERROR err; - - if (!TLVTypeIsString(ElementType())) - return CHIP_ERROR_WRONG_TLV_TYPE; + VerifyOrReturnError(TLVTypeIsString(ElementType()), CHIP_ERROR_WRONG_TLV_TYPE); if (GetLength() == 0) { @@ -473,19 +470,12 @@ CHIP_ERROR TLVReader::GetDataPtr(const uint8_t *& data) return CHIP_NO_ERROR; } - err = EnsureData(CHIP_ERROR_TLV_UNDERRUN); - if (err != CHIP_NO_ERROR) - return err; - uint32_t remainingLen = static_cast(mBufEnd - mReadPoint); // Verify that the entirety of the data is available in the buffer. // Note that this may not be possible if the reader is reading from a chain of buffers. - if (remainingLen < static_cast(mElemLenOrVal)) - return CHIP_ERROR_TLV_UNDERRUN; - + VerifyOrReturnError(remainingLen >= static_cast(mElemLenOrVal), CHIP_ERROR_TLV_UNDERRUN); data = mReadPoint; - return CHIP_NO_ERROR; } @@ -576,20 +566,19 @@ CHIP_ERROR TLVReader::VerifyEndOfContainer() CHIP_ERROR TLVReader::Next() { - CHIP_ERROR err; - TLVElementType elemType = ElementType(); + ReturnErrorOnFailure(Skip()); + ReturnErrorOnFailure(ReadElement()); - err = Skip(); - if (err != CHIP_NO_ERROR) - return err; + TLVElementType elemType = ElementType(); - err = ReadElement(); - if (err != CHIP_NO_ERROR) - return err; + VerifyOrReturnError(elemType != TLVElementType::EndOfContainer, CHIP_END_OF_TLV); - elemType = ElementType(); - if (elemType == TLVElementType::EndOfContainer) - return CHIP_END_OF_TLV; + // Ensure that GetDataPtr calls can be called immediately after Next, so + // that `Get(ByteSpan&)` does not need to advance buffers and just works + if (TLVTypeIsString(elemType) && (GetLength() != 0)) + { + ReturnErrorOnFailure(EnsureData(CHIP_ERROR_TLV_UNDERRUN)); + } return CHIP_NO_ERROR; } diff --git a/src/lib/core/TLVReader.h b/src/lib/core/TLVReader.h index 69aed99f3eabac..caf56332762e79 100644 --- a/src/lib/core/TLVReader.h +++ b/src/lib/core/TLVReader.h @@ -440,7 +440,7 @@ class DLL_EXPORT TLVReader * the reader is not positioned on an element. * */ - CHIP_ERROR Get(ByteSpan & v); + CHIP_ERROR Get(ByteSpan & v) const; /** * Get the value of the current element as a FixedByteSpan @@ -453,7 +453,7 @@ class DLL_EXPORT TLVReader * */ template - CHIP_ERROR Get(FixedByteSpan & v) + CHIP_ERROR Get(FixedByteSpan & v) const { const uint8_t * val; ReturnErrorOnFailure(GetDataPtr(val)); @@ -472,7 +472,7 @@ class DLL_EXPORT TLVReader * the reader is not positioned on an element. * */ - CHIP_ERROR Get(CharSpan & v); + CHIP_ERROR Get(CharSpan & v) const; /** * Get the Localized String Identifier contained in the current element.. @@ -634,9 +634,8 @@ class DLL_EXPORT TLVReader * Get a pointer to the initial encoded byte of a TLV byte or UTF8 string element. * * This method returns a direct pointer to the encoded string value within the underlying input buffer - * if a non-zero length string payload is present. To succeed, the method requires that the entirety of the - * string value be present in a single buffer. Otherwise the method returns #CHIP_ERROR_TLV_UNDERRUN. - * This makes the method of limited use when reading data from multiple discontiguous buffers. + * as fetched by `Next`. To succeed, the method requires that the entirety of the + * string value be present in a single buffer. * * If no string data is present (i.e the length is zero), data shall be updated to point to null. * @@ -653,7 +652,7 @@ class DLL_EXPORT TLVReader * TLVBackingStore. * */ - CHIP_ERROR GetDataPtr(const uint8_t *& data); + CHIP_ERROR GetDataPtr(const uint8_t *& data) const; /** * Prepares a TLVReader object for reading the members of TLV container element. diff --git a/src/lib/format/protocol_decoder.cpp b/src/lib/format/protocol_decoder.cpp index 4752dfaee9c8b4..5f787a9982b286 100644 --- a/src/lib/format/protocol_decoder.cpp +++ b/src/lib/format/protocol_decoder.cpp @@ -45,7 +45,7 @@ class ByTag const Tag mTag; }; -CHIP_ERROR FormatCurrentValue(TLVReader & reader, chip::StringBuilderBase & out) +CHIP_ERROR FormatCurrentValue(const TLVReader & reader, chip::StringBuilderBase & out) { switch (reader.GetType()) { @@ -105,7 +105,7 @@ CHIP_ERROR FormatCurrentValue(TLVReader & reader, chip::StringBuilderBase & out) } // Returns a null terminated string containing the current reader value -void PrettyPrintCurrentValue(TLVReader & reader, chip::StringBuilderBase & out, PayloadDecoderBase::DecodePosition & position) +void PrettyPrintCurrentValue(const TLVReader & reader, chip::StringBuilderBase & out, PayloadDecoderBase::DecodePosition & position) { CHIP_ERROR err = FormatCurrentValue(reader, out);