Matter SDK Coverage Report
Current view: top level - lib/core - TLVReader.h (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 86.5 % 37 32
Test Date: 2025-01-17 19:00:11 Functions: 87.5 % 32 28

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2020-2023 Project CHIP Authors
       4              :  *    Copyright (c) 2013-2017 Nest Labs, Inc.
       5              :  *
       6              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       7              :  *    you may not use this file except in compliance with the License.
       8              :  *    You may obtain a copy of the License at
       9              :  *
      10              :  *        http://www.apache.org/licenses/LICENSE-2.0
      11              :  *
      12              :  *    Unless required by applicable law or agreed to in writing, software
      13              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      14              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      15              :  *    See the License for the specific language governing permissions and
      16              :  *    limitations under the License.
      17              :  */
      18              : 
      19              : /**
      20              :  *    @file
      21              :  *      This file contains definitions for working with data encoded in CHIP TLV format.
      22              :  *
      23              :  *      CHIP TLV (Tag-Length-Value) is a generalized encoding method for simple structured data. It
      24              :  *      shares many properties with the commonly used JSON serialization format while being considerably
      25              :  *      more compact over the wire.
      26              :  */
      27              : #pragma once
      28              : 
      29              : #include <stddef.h>
      30              : #include <stdint.h>
      31              : #include <type_traits>
      32              : #include <utility>
      33              : 
      34              : #include <lib/core/CHIPError.h>
      35              : #include <lib/core/DataModelTypes.h>
      36              : #include <lib/core/Optional.h>
      37              : #include <lib/core/TLVBackingStore.h>
      38              : #include <lib/core/TLVTags.h>
      39              : #include <lib/core/TLVTypes.h>
      40              : #include <lib/support/BitFlags.h>
      41              : #include <lib/support/BitMask.h>
      42              : #include <lib/support/CodeUtils.h>
      43              : #include <lib/support/DLLUtil.h>
      44              : #include <lib/support/ScopedBuffer.h>
      45              : #include <lib/support/Span.h>
      46              : 
      47              : /**
      48              :  * @namespace chip::TLV
      49              :  *
      50              :  * Definitions for working with data encoded in CHIP TLV format.
      51              :  *
      52              :  * CHIP TLV is a generalized encoding method for simple structured data. It shares many properties
      53              :  * with the commonly used JSON serialization format while being considerably more compact over the wire.
      54              :  */
      55              : 
      56              : namespace chip {
      57              : namespace TLV {
      58              : 
      59              : /**
      60              :  * Provides a memory efficient parser for data encoded in CHIP TLV format.
      61              :  *
      62              :  * TLVReader implements a forward-only, “pull-style” parser for CHIP TLV data.  The TLVReader
      63              :  * object operates as a cursor that can be used to iterate over a sequence of TLV elements
      64              :  * and interpret their contents.  When positioned on an element, applications can make calls
      65              :  * to the reader's Get() methods to query the current element’s type and tag, and to extract
      66              :  * any associated value.  The reader’s Next() method is used to advance from element to element.
      67              :  *
      68              :  * A TLVReader object is always positioned either before, on or after a TLV element.  When first
      69              :  * initialized, a TLVReader is positioned immediately before the first element of the encoding.
      70              :  * To begin reading, an application must make an initial call to the Next() method to position
      71              :  * the reader on the first element.  When a container element is encountered--either a structure,
      72              :  * an array or a path--the OpenContainer() or EnterContainer() methods can be used to iterate
      73              :  * through the contents of the container.
      74              :  *
      75              :  * When the reader reaches the end of a TLV encoding, or the last element within a container,
      76              :  * it signals the application by returning a CHIP_END_OF_TLV error from the Next() method.
      77              :  * The reader will continue to return CHIP_END_OF_TLV until it is reinitialized, or the current
      78              :  * container is exited (via CloseContainer() / ExitContainer()).
      79              :  *
      80              :  * A TLVReader object can parse data directly from a fixed input buffer, or from memory provided
      81              :  * by a TLVBackingStore.
      82              :  */
      83              : class DLL_EXPORT TLVReader
      84              : {
      85              :     friend class TLVWriter;
      86              :     friend class TLVUpdater;
      87              : 
      88              : public:
      89              :     TLVReader();
      90              : 
      91              :     /**
      92              :      * Initializes a TLVReader object from another TLVReader object.
      93              :      *
      94              :      * @param[in]   aReader  A read-only reference to the TLVReader to initialize
      95              :      *                       this from.
      96              :      *
      97              :      */
      98              :     void Init(const TLVReader & aReader);
      99              : 
     100              :     /**
     101              :      * Initializes a TLVReader object to read from a single input buffer.
     102              :      *
     103              :      * @param[in]   data    A pointer to a buffer containing the TLV data to be parsed.
     104              :      * @param[in]   dataLen The length of the TLV data to be parsed.
     105              :      *
     106              :      */
     107              :     void Init(const uint8_t * data, size_t dataLen);
     108              : 
     109              :     /**
     110              :      * Initializes a TLVReader object to read from a single input buffer
     111              :      * represented as a span.
     112              :      *
     113              :      * @param[in]   data    A byte span to read from
     114              :      *
     115              :      */
     116         2241 :     void Init(const ByteSpan & data) { Init(data.data(), data.size()); }
     117              : 
     118              :     /**
     119              :      * Initializes a TLVReader object to read from a single input buffer
     120              :      * represented as byte array.
     121              :      *
     122              :      * @param[in]   data    A byte buffer to read from
     123              :      *
     124              :      */
     125              :     template <size_t N>
     126            2 :     void Init(const uint8_t (&data)[N])
     127              :     {
     128            2 :         Init(data, N);
     129            2 :     }
     130              : 
     131              :     /**
     132              :      * Initializes a TLVReader object to read from a TLVBackingStore.
     133              :      *
     134              :      * Parsing begins at the backing store's start position and continues until the
     135              :      * end of the data in the buffer, or maxLen bytes have been parsed.
     136              :      *
     137              :      * @param[in]   backingStore    A reference to a TLVBackingStore providing the TLV data to be parsed.
     138              :      * @param[in]   maxLen          The maximum number of bytes to parse. Defaults to the amount of data
     139              :      *                              in the input buffer.
     140              :      *
     141              :      * @retval #CHIP_NO_ERROR  If the method succeeded.
     142              :      * @retval other           Other error codes returned by TLVBackingStore::OnInit().
     143              :      */
     144              :     CHIP_ERROR Init(TLVBackingStore & backingStore, uint32_t maxLen = UINT32_MAX);
     145              : 
     146              :     /**
     147              :      * Advances the TLVReader object to the next TLV element to be read.
     148              :      *
     149              :      * The Next() method positions the reader object on the next element in a TLV encoding that resides
     150              :      * in the same containment context.  In particular, if the reader is positioned at the outer-most
     151              :      * level of a TLV encoding, calling Next() will advance the reader to the next, top-most element.
     152              :      * If the reader is positioned within a TLV container element (a structure, array or path), calling
     153              :      * Next() will advance the reader to the next member element of the container.
     154              :      *
     155              :      * Since Next() constrains reader motion to the current containment context, calling Next() when
     156              :      * the reader is positioned on a container element will advance @em over the container, skipping
     157              :      * its member elements (and the members of any nested containers) until it reaches the first element
     158              :      * after the container.
     159              :      *
     160              :      * When there are no further elements within a particular containment context the Next() method will
     161              :      * return a #CHIP_END_OF_TLV error and the position of the reader will remain unchanged.
     162              :      *
     163              :      * @retval #CHIP_NO_ERROR              If the reader was successfully positioned on a new element.
     164              :      * @retval #CHIP_END_OF_TLV            If no further elements are available.
     165              :      * @retval #CHIP_ERROR_TLV_UNDERRUN    If the underlying TLV encoding ended prematurely.
     166              :      * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT
     167              :      *                                      If the reader encountered an invalid or unsupported TLV element
     168              :      *                                      type.
     169              :      * @retval #CHIP_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context.
     170              :      * @retval #CHIP_ERROR_UNKNOWN_IMPLICIT_TLV_TAG
     171              :      *                                      If the reader encountered a implicitly-encoded TLV tag for which
     172              :      *                                      the corresponding profile id is unknown.
     173              :      * @retval other                        Other CHIP or platform error codes returned by the configured
     174              :      *                                      TLVBackingStore.
     175              :      *
     176              :      */
     177              :     CHIP_ERROR Next();
     178              : 
     179              :     /**
     180              :      * Advances the TLVReader object to the next TLV element to be read, asserting the tag of
     181              :      * the new element.
     182              :      *
     183              :      * This is a convenience method that combines the behavior of Next() and Expect(...).
     184              :      *
     185              :      * Note that if this method returns an error, the reader may or may not have been advanced already.
     186              :      * In use cases where this is important, separate calls to Next() and Expect(...) should be made.
     187              :      *
     188              :      * @retval #CHIP_NO_ERROR              If the reader was successfully positioned on a new element
     189              :      *                                     matching the expected parameters.
     190              :      * @retval other                       See return values of Next() and Expect().
     191              :      */
     192              :     CHIP_ERROR Next(Tag expectedTag);
     193              : 
     194              :     /**
     195              :      * Checks that the TLV reader is positioned at an element with the expected tag.
     196              :      *
     197              :      * @retval #CHIP_NO_ERROR              If the reader is positioned on the expected element.
     198              :      * @retval #CHIP_ERROR_WRONG_TLV_TYPE  If the reader is not positioned on an element.
     199              :      * @retval #CHIP_ERROR_UNEXPECTED_TLV_ELEMENT
     200              :      *                                      If the tag associated with the new element does not match the
     201              :      *                                      value of the @p expectedTag argument.
     202              :      */
     203              :     CHIP_ERROR Expect(Tag expectedTag);
     204              : 
     205              :     /**
     206              :      * Advances the TLVReader object to the next TLV element to be read, asserting the type and tag of
     207              :      * the new element.
     208              :      *
     209              :      * This is a convenience method that combines the behavior of Next() and Expect(...).
     210              :      *
     211              :      * Note that if this method returns an error, the reader may or may not have been advanced already.
     212              :      * In use cases where this is important, separate calls to Next() and Expect(...) should be made.
     213              :      *
     214              :      * @retval #CHIP_NO_ERROR              If the reader was successfully positioned on a new element
     215              :      *                                     matching the expected parameters.
     216              :      * @retval other                       See return values of Next() and Expect().
     217              :      */
     218              :     CHIP_ERROR Next(TLVType expectedType, Tag expectedTag);
     219              : 
     220              :     /**
     221              :      * Checks that the TLV reader is positioned at an element with the expected type and tag.
     222              :      *
     223              :      * @param[in] expectedType              The expected data type for the next element.
     224              :      * @param[in] expectedTag               The expected tag for the next element.
     225              :      *
     226              :      * @retval #CHIP_NO_ERROR              If the reader is positioned on the expected element.
     227              :      * @retval #CHIP_ERROR_WRONG_TLV_TYPE  If the type of the new element does not match the value
     228              :      *                                      of the @p expectedType argument.
     229              :      * @retval #CHIP_ERROR_UNEXPECTED_TLV_ELEMENT
     230              :      *                                      If the tag associated with the new element does not match the
     231              :      *                                      value of the @p expectedTag argument.
     232              :      */
     233              :     CHIP_ERROR Expect(TLVType expectedType, Tag expectedTag);
     234              : 
     235              :     /**
     236              :      * Returns the type of the current TLV element.
     237              :      *
     238              :      * @return      A TLVType value describing the data type of the current TLV element.  If the reader
     239              :      *              is not positioned on a TLV element, the return value will be kTLVType_NotSpecified.
     240              :      */
     241              :     TLVType GetType() const;
     242              : 
     243              :     /**
     244              :      * Returns the tag associated with current TLV element.
     245              :      *
     246              :      * The value returned by GetTag() can be used with the tag utility functions (IsProfileTag(),
     247              :      * IsContextTag(), ProfileIdFromTag(), etc.) to determine the type of tag and to extract various tag
     248              :      * field values.
     249              :      *
     250              :      * @note If the reader is not positioned on a TLV element when GetTag() is called, the return value
     251              :      * is undefined. Therefore whenever the position of the reader is uncertain applications should call
     252              :      * GetType() to determine if the reader is position on an element (GetType() != kTLVType_NotSpecified)
     253              :      * before calling GetTag().
     254              :      *
     255              :      * @return      An unsigned integer containing information about the tag associated with the current
     256              :      *              TLV element.
     257              :      */
     258      1246297 :     Tag GetTag() const { return mElemTag; }
     259              : 
     260              :     /**
     261              :      * Returns the length of data associated with current TLV element.
     262              :      *
     263              :      * Data length only applies to elements of type UTF8 string or byte string.  For UTF8 strings, the
     264              :      * value returned is the number of bytes in the string, not the number of characters.
     265              :      *
     266              :      * @return      The length (in bytes) of data associated with the current TLV element, or 0 if the
     267              :      *              current element is not a UTF8 string or byte string, or if the reader is not
     268              :      *              positioned on an element.
     269              :      */
     270              :     uint32_t GetLength() const;
     271              : 
     272              :     /**
     273              :      * Returns the control byte associated with current TLV element.
     274              :      *
     275              :      * Ideally, nobody ever needs to know about the control byte and only the
     276              :      * internal implementation of TLV should have access to it. But, nevertheless,
     277              :      * having access to the control byte is helpful for debugging purposes by the
     278              :      * TLV Debug Utilities (that try to decode the tag control byte when pretty
     279              :      * printing the TLV buffer contents).
     280              :      *
     281              :      * @note Unless you really know what you are doing, please refrain from using
     282              :      * this method and the associated control byte information.
     283              :      *
     284              :      * @return      An unsigned integer containing the control byte associated with
     285              :      *              the current TLV element. kTLVControlByte_NotSpecified is
     286              :      *              returned if the reader is not positioned @em on an element.
     287              :      */
     288         1390 :     uint16_t GetControlByte() const { return mControlByte; }
     289              : 
     290              :     /**
     291              :      * Get the value of the current element as a bool type.
     292              :      *
     293              :      * @param[out]  v                       Receives the value associated with current TLV element.
     294              :      *
     295              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
     296              :      * @retval #CHIP_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV boolean type, or the
     297              :      *                                      reader is not positioned on an element.
     298              :      */
     299              :     CHIP_ERROR Get(bool & v) const;
     300              : 
     301              :     /**
     302              :      * Get the value of the current element as an 8-bit signed integer.
     303              :      *
     304              :      * If the encoded integer value is larger than the output data type the resultant value will be
     305              :      * truncated.
     306              :      *
     307              :      * @param[out]  v                       Receives the value associated with current TLV element.
     308              :      *
     309              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
     310              :      * @retval #CHIP_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV integer type (signed or
     311              :      *                                      unsigned), or the reader is not positioned on an element.
     312              :      *
     313              :      */
     314              :     CHIP_ERROR Get(int8_t & v) const;
     315              : 
     316              :     /**
     317              :      * Get the value of the current element as a 16-bit signed integer.
     318              :      *
     319              :      * If the encoded integer value is larger than the output data type the resultant value will be
     320              :      * truncated.
     321              :      *
     322              :      * @param[out]  v                       Receives the value associated with current TLV element.
     323              :      *
     324              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
     325              :      * @retval #CHIP_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV integer type (signed or
     326              :      *                                      unsigned), or the reader is not positioned on an element.
     327              :      *
     328              :      */
     329              :     CHIP_ERROR Get(int16_t & v) const;
     330              : 
     331              :     /**
     332              :      * Get the value of the current element as a 32-bit signed integer.
     333              :      *
     334              :      * If the encoded integer value is larger than the output data type the resultant value will be
     335              :      * truncated.
     336              :      *
     337              :      * @param[out]  v                       Receives the value associated with current TLV element.
     338              :      *
     339              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
     340              :      * @retval #CHIP_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV integer type (signed or
     341              :      *                                      unsigned), or the reader is not positioned on an element.
     342              :      *
     343              :      */
     344              :     CHIP_ERROR Get(int32_t & v) const;
     345              : 
     346              :     /**
     347              :      * Get the value of the current element as a 64-bit signed integer.
     348              :      *
     349              :      * If the encoded integer value is larger than the output data type the resultant value will be
     350              :      * truncated.
     351              :      *
     352              :      * @param[out]  v                       Receives the value associated with current TLV element.
     353              :      *
     354              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
     355              :      * @retval #CHIP_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV integer type (signed or
     356              :      *                                      unsigned), or the reader is not positioned on an element.
     357              :      *
     358              :      */
     359              :     CHIP_ERROR Get(int64_t & v) const;
     360              : 
     361              :     /**
     362              :      * Get the value of the current element as an 8-bit unsigned integer.
     363              :      *
     364              :      * If the encoded integer value is larger than the output data type the resultant value will be
     365              :      * truncated.  Similarly, if the encoded integer value is negative, the value will be converted
     366              :      * to unsigned.
     367              :      *
     368              :      * @param[out]  v                       Receives the value associated with current TLV element.
     369              :      *
     370              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
     371              :      * @retval #CHIP_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV integer type (signed or
     372              :      *                                      unsigned), or the reader is not positioned on an element.
     373              :      *
     374              :      */
     375              :     CHIP_ERROR Get(uint8_t & v) const;
     376              : 
     377              :     /**
     378              :      * Get the value of the current element as a 16-bit unsigned integer.
     379              :      *
     380              :      * If the encoded integer value is larger than the output data type the resultant value will be
     381              :      * truncated.  Similarly, if the encoded integer value is negative, the value will be converted
     382              :      * to unsigned.
     383              :      *
     384              :      * @param[out]  v                       Receives the value associated with current TLV element.
     385              :      *
     386              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
     387              :      * @retval #CHIP_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV integer type (signed or
     388              :      *                                      unsigned), or the reader is not positioned on an element.
     389              :      *
     390              :      */
     391              :     CHIP_ERROR Get(uint16_t & v) const;
     392              : 
     393              :     /**
     394              :      * Get the value of the current element as a 32-bit unsigned integer.
     395              :      *
     396              :      * If the encoded integer value is larger than the output data type the resultant value will be
     397              :      * truncated.  Similarly, if the encoded integer value is negative, the value will be converted
     398              :      * to unsigned.
     399              :      *
     400              :      * @param[out]  v                       Receives the value associated with current TLV element.
     401              :      *
     402              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
     403              :      * @retval #CHIP_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV integer type (signed or
     404              :      unsigned), or the reader is not positioned on an element.
     405              :      *
     406              :      */
     407              :     CHIP_ERROR Get(uint32_t & v) const;
     408              : 
     409              :     /**
     410              :      * Get the value of the current element as a 64-bit unsigned integer.
     411              :      *
     412              :      * If the encoded integer value is negative, the value will be converted to unsigned.
     413              :      *
     414              :      * @param[out]  v                       Receives the value associated with current TLV element.
     415              :      *
     416              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
     417              :      * @retval #CHIP_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV integer type (signed or
     418              :      *                                      unsigned), or the reader is not positioned on an element.
     419              :      *
     420              :      */
     421              :     CHIP_ERROR Get(uint64_t & v) const;
     422              : 
     423              :     /**
     424              :      * Get the value of the current element as a double-precision floating point number.
     425              :      *
     426              :      * @param[out]  v                       Receives the value associated with current TLV element.
     427              :      *
     428              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
     429              :      * @retval #CHIP_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV floating point type, or
     430              :      *                                      the reader is not positioned on an element.
     431              :      *
     432              :      */
     433              :     CHIP_ERROR Get(double & v) const;
     434              : 
     435              :     /**
     436              :      * Get the value of the current element as a single-precision floating point number.
     437              :      *
     438              :      * @param[out]  v                       Receives the value associated with current TLV element.
     439              :      *
     440              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
     441              :      * @retval #CHIP_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV floating point type, or
     442              :      *                                      the reader is not positioned on an element.
     443              :      *
     444              :      */
     445              :     CHIP_ERROR Get(float & v) const;
     446              : 
     447              :     /**
     448              :      * Get the value of the current element as a ByteSpan
     449              :      *
     450              :      * @param[out]  v                       Receives the value associated with current TLV element.
     451              :      *
     452              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
     453              :      * @retval #CHIP_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV bytes array, or
     454              :      *                                      the reader is not positioned on an element.
     455              :      *
     456              :      */
     457              :     CHIP_ERROR Get(ByteSpan & v) const;
     458              : 
     459              :     /**
     460              :      * Get the value of the current element as a FixedByteSpan
     461              :      *
     462              :      * @param[out]  v                       Receives the value associated with current TLV element.
     463              :      *
     464              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
     465              :      * @retval #CHIP_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV bytes array, or
     466              :      *                                      the reader is not positioned on an element.
     467              :      *
     468              :      */
     469              :     template <size_t N>
     470        11094 :     CHIP_ERROR Get(FixedByteSpan<N> & v) const
     471              :     {
     472              :         const uint8_t * val;
     473        11094 :         ReturnErrorOnFailure(GetDataPtr(val));
     474        11094 :         VerifyOrReturnError(GetLength() == N, CHIP_ERROR_UNEXPECTED_TLV_ELEMENT);
     475        11076 :         v = FixedByteSpan<N>(val);
     476        11076 :         return CHIP_NO_ERROR;
     477              :     }
     478              : 
     479              :     /**
     480              :      * Get the value of the current element as a CharSpan
     481              :      *
     482              :      * @param[out]  v                       Receives the value associated with current TLV element.
     483              :      *
     484              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
     485              :      * @retval #CHIP_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV character string, or
     486              :      *                                      the reader is not positioned on an element.
     487              :      *
     488              :      */
     489              :     CHIP_ERROR Get(CharSpan & v) const;
     490              : 
     491              :     /**
     492              :      * Get the Localized String Identifier contained in the current element..
     493              :      *
     494              :      * The method takes what's after the first Information Separator 1 <IS1>, and until end of string
     495              :      * or second <IS1>, and return the hex-decoded string identifier, if one was there.
     496              :      *
     497              :      * @param[out]  lsid                       Optional Localized String Identifier. Returns empty
     498              :      *                                         if the value is not found or it was invalidly encoded.
     499              :      *
     500              :      * @retval #CHIP_NO_ERROR                  If the method succeeded.
     501              :      * @retval #CHIP_ERROR_WRONG_TLV_TYPE      If the current element is not a TLV character string, or
     502              :      *                                         the reader is not positioned on an element.
     503              :      * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT If the Localized String Identifier is malformed.
     504              :      */
     505              :     CHIP_ERROR Get(Optional<LocalizedStringIdentifier> & lsid);
     506              : 
     507              :     /**
     508              :      * Get the value of the current element as an enum value, if it's an integer
     509              :      * value that fits in the enum type.
     510              :      *
     511              :      * @param[out] v Receives the value associated with current TLV element.
     512              :      */
     513              :     template <typename T, typename = std::enable_if_t<std::is_enum<T>::value>>
     514         3100 :     CHIP_ERROR Get(T & v)
     515              :     {
     516              :         std::underlying_type_t<T> val;
     517         3100 :         ReturnErrorOnFailure(Get(val));
     518         3100 :         v = static_cast<T>(val);
     519         3100 :         return CHIP_NO_ERROR;
     520              :     }
     521              : 
     522              :     /**
     523              :      * Get the value of the current element as a BitFlags value, if it's an integer
     524              :      * value that fits in the BitFlags type.
     525              :      *
     526              :      * @param[out] v Receives the value associated with current TLV element.
     527              :      */
     528              :     template <typename T>
     529            0 :     CHIP_ERROR Get(BitFlags<T> & v)
     530              :     {
     531              :         std::underlying_type_t<T> val;
     532            0 :         ReturnErrorOnFailure(Get(val));
     533            0 :         v.SetRaw(val);
     534            0 :         return CHIP_NO_ERROR;
     535              :     }
     536              : 
     537              :     /**
     538              :      * Get the value of the current element as a BitMask value, if it's an integer
     539              :      * value that fits in the BitMask type.
     540              :      *
     541              :      * @param[out] v Receives the value associated with current TLV element.
     542              :      */
     543              :     template <typename T>
     544              :     CHIP_ERROR Get(BitMask<T> & v)
     545              :     {
     546              :         std::underlying_type_t<T> val;
     547              :         ReturnErrorOnFailure(Get(val));
     548              :         v.SetRaw(val);
     549              :         return CHIP_NO_ERROR;
     550              :     }
     551              : 
     552              :     /**
     553              :      * Get the value of the current byte or UTF8 string element.
     554              :      *
     555              :      * To determine the required input buffer size, call the GetLength() method before calling GetBytes().
     556              :      *
     557              :      * @note The data output by this method is NOT null-terminated.
     558              :      *
     559              :      * @param[in]  buf                      A pointer to a buffer to receive the string data.
     560              :      * @param[in]  bufSize                  The size in bytes of the buffer pointed to by @p buf.
     561              :      *
     562              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
     563              :      * @retval #CHIP_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV byte or UTF8 string, or
     564              :      *                                      the reader is not positioned on an element.
     565              :      * @retval #CHIP_ERROR_BUFFER_TOO_SMALL
     566              :      *                                      If the supplied buffer is too small to hold the data associated
     567              :      *                                      with the current element.
     568              :      * @retval #CHIP_ERROR_TLV_UNDERRUN    If the underlying TLV encoding ended prematurely.
     569              :      * @retval other                        Other CHIP or platform error codes returned by the configured
     570              :      *                                      TLVBackingStore.
     571              :      *
     572              :      */
     573              :     CHIP_ERROR GetBytes(uint8_t * buf, size_t bufSize);
     574              : 
     575              :     /**
     576              :      * Allocates and returns a buffer containing the value of the current byte or UTF8 string.
     577              :      *
     578              :      * This method creates a buffer for and returns a copy of the data associated with the byte
     579              :      * or UTF-8 string element at the current position. Memory for the buffer is obtained with
     580              :      * Platform::MemoryAlloc() and should be freed with Platform::MemoryFree() by the caller when
     581              :      * it is no longer needed.
     582              :      *
     583              :      * @note The data returned by this method is NOT null-terminated.
     584              :      *
     585              :      * @param[out] buf                      A reference to a pointer to which a heap-allocated buffer of
     586              :      *                                      @p dataLen bytes will be assigned on success.
     587              :      * @param[out] dataLen                  A reference to storage for the size, in bytes, of @p buf on
     588              :      *                                      success.
     589              :      *
     590              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
     591              :      * @retval #CHIP_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV byte or UTF8 string, or
     592              :      *                                      the reader is not positioned on an element.
     593              :      * @retval #CHIP_ERROR_NO_MEMORY       If memory could not be allocated for the output buffer.
     594              :      * @retval #CHIP_ERROR_TLV_UNDERRUN    If the underlying TLV encoding ended prematurely.
     595              :      * @retval other                        Other CHIP or platform error codes returned by the configured
     596              :      *                                      TLVBackingStore.
     597              :      *
     598              :      */
     599              :     CHIP_ERROR DupBytes(uint8_t *& buf, uint32_t & dataLen);
     600              : 
     601              :     /**
     602              :      * Get the value of the current byte or UTF8 string element as a null terminated string.
     603              :      *
     604              :      * To determine the required input buffer size, call the GetLength() method before calling GetBytes().
     605              :      * The input buffer should be at least one byte bigger than the string length to accommodate the null
     606              :      * character.
     607              :      *
     608              :      * @param[in]  buf                      A pointer to a buffer to receive the byte string data.
     609              :      * @param[in]  bufSize                  The size in bytes of the buffer pointed to by @p buf.
     610              :      *
     611              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
     612              :      * @retval #CHIP_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV byte or UTF8 string, or
     613              :      *                                      the reader is not positioned on an element.
     614              :      * @retval #CHIP_ERROR_BUFFER_TOO_SMALL
     615              :      *                                      If the supplied buffer is too small to hold the data associated
     616              :      *                                      with the current element.
     617              :      * @retval #CHIP_ERROR_TLV_UNDERRUN    If the underlying TLV encoding ended prematurely.
     618              :      * @retval other                        Other CHIP or platform error codes returned by the configured
     619              :      *                                      TLVBackingStore.
     620              :      *
     621              :      */
     622              :     CHIP_ERROR GetString(char * buf, size_t bufSize);
     623              : 
     624              :     /**
     625              :      * Allocates and returns a buffer containing the null-terminated value of the current byte or UTF8
     626              :      * string.
     627              :      *
     628              :      * This method creates a buffer for and returns a null-terminated copy of the data associated with
     629              :      * the byte or UTF-8 string element at the current position. Memory for the buffer is obtained with
     630              :      * Platform::MemoryAlloc() and should be freed with chip::Platform::MemoryFree() by the caller when
     631              :      * it is no longer needed.
     632              :      *
     633              :      * @param[out] buf                      A reference to a pointer to which a heap-allocated buffer of
     634              :      *                                      will be assigned on success.
     635              :      *
     636              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
     637              :      * @retval #CHIP_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV byte or UTF8 string, or
     638              :      *                                      the reader is not positioned on an element.
     639              :      * @retval #CHIP_ERROR_NO_MEMORY       If memory could not be allocated for the output buffer.
     640              :      * @retval #CHIP_ERROR_TLV_UNDERRUN    If the underlying TLV encoding ended prematurely.
     641              :      * @retval other                       Other CHIP or platform error codes returned by the configured
     642              :      *                                      TLVBackingStore.
     643              :      *
     644              :      */
     645              :     CHIP_ERROR DupString(char *& buf);
     646              : 
     647              :     /**
     648              :      * Get a pointer to the initial encoded byte of a TLV byte or UTF8 string element.
     649              :      *
     650              :      * This method returns a direct pointer to the encoded string value within the underlying input buffer
     651              :      * as fetched by `Next`. To succeed, the method requires that the entirety of the
     652              :      * string value be present in a single buffer.
     653              :      *
     654              :      * If no string data is present (i.e the length is zero), data shall be updated to point to null.
     655              :      *
     656              :      * @param[out] data                     A reference to a const pointer that will receive a pointer to
     657              :      *                                      the underlying string data.
     658              :      *
     659              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
     660              :      * @retval #CHIP_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV byte or UTF8 string, or the
     661              :      *                                      reader is not positioned on an element.
     662              :      * @retval #CHIP_ERROR_TLV_UNDERRUN    If the underlying TLV encoding ended prematurely or the value
     663              :      *                                      of the current string element is not contained within a single
     664              :      *                                      contiguous buffer.
     665              :      * @retval other                        Other CHIP or platform error codes returned by the configured
     666              :      *                                      TLVBackingStore.
     667              :      *
     668              :      */
     669              :     CHIP_ERROR GetDataPtr(const uint8_t *& data) const;
     670              : 
     671              :     /**
     672              :      * Prepares a TLVReader object for reading the members of TLV container element.
     673              :      *
     674              :      * The EnterContainer() method prepares the current TLVReader object to begin reading the member
     675              :      * elements of a TLV container (a structure, array or path). For every call to EnterContainer()
     676              :      * applications must make a corresponding call to ExitContainer().
     677              :      *
     678              :      * When EnterContainer() is called the TLVReader object must be positioned on the container element
     679              :      * to be read.  The method takes as an argument a reference to a TLVType value which will be used
     680              :      * to save the context of the reader while it is reading the container.
     681              :      *
     682              :      * When the EnterContainer() method returns, the reader is positioned immediately @em before the
     683              :      * first member of the container. Repeatedly calling Next() will advance the reader through the members
     684              :      * of the collection until the end is reached, at which point the reader will return CHIP_END_OF_TLV.
     685              :      *
     686              :      * Once the application has finished reading a container it can continue reading the elements after
     687              :      * the container by calling the ExitContainer() method.
     688              :      *
     689              :      * @param[out] outerContainerType       A reference to a TLVType value that will receive the context
     690              :      *                                      of the reader.
     691              :      *
     692              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
     693              :      * @retval #CHIP_ERROR_INCORRECT_STATE If the current element is not positioned on a container element.
     694              :      *
     695              :      */
     696              :     CHIP_ERROR EnterContainer(TLVType & outerContainerType);
     697              : 
     698              :     /**
     699              :      * Completes the reading of a TLV container and prepares a TLVReader object to read elements
     700              :      * after the container.
     701              :      *
     702              :      * The ExitContainer() method restores the state of a TLVReader object after a call to
     703              :      * EnterContainer().  For every call to EnterContainer() applications must make a corresponding
     704              :      * call to ExitContainer(), passing the context value returned by the EnterContainer() method.
     705              :      *
     706              :      * When ExitContainer() returns, the reader is positioned immediately before the first element that
     707              :      * follows the container.  From this point an application can use the Next() method to advance
     708              :      * through any remaining elements.
     709              :      *
     710              :      * Once EnterContainer() has been called, applications can call ExitContainer() on a reader at any
     711              :      * point in time, regardless of whether all elements in the underlying container have been read.
     712              :      *
     713              :      * @note Any changes made to the configuration of the reader between the calls to EnterContainer()
     714              :      * and ExitContainer() are NOT undone by the call to ExitContainer().  For example, a change to the
     715              :      * implicit profile id (@p ImplicitProfileId) will not be reversed when a container is exited.  Thus
     716              :      * it is the application's responsibility to adjust the configuration accordingly at the appropriate
     717              :      * times.
     718              :      *
     719              :      * @param[in] outerContainerType        The TLVType value that was returned by the EnterContainer() method.
     720              :      *
     721              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
     722              :      * @retval #CHIP_ERROR_INCORRECT_STATE If OpenContainer() has not been called on the reader, or if
     723              :      *                                      the container reader does not match the one passed to the
     724              :      *                                      OpenContainer() method.
     725              :      * @retval #CHIP_ERROR_TLV_UNDERRUN    If the underlying TLV encoding ended prematurely.
     726              :      * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT
     727              :      *                                      If the reader encountered an invalid or unsupported TLV element type.
     728              :      * @retval #CHIP_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context.
     729              :      * @retval other                        Other CHIP or platform error codes returned by the configured
     730              :      *                                      TLVBackingStore.
     731              :      *
     732              :      */
     733              :     CHIP_ERROR ExitContainer(TLVType outerContainerType);
     734              : 
     735              :     /**
     736              :      * Initializes a new TLVReader object for reading the members of a TLV container element.
     737              :      *
     738              :      * The OpenContainer() method initializes a new TLVReader object for reading the member elements of a
     739              :      * TLV container (a structure, array or path).  When OpenContainer() is called, the current TLVReader
     740              :      * object must be positioned on the container element to be read.  The method takes as its sole argument
     741              :      * a reference to a new reader that will be initialized to read the container.  This reader is known as
     742              :      * the <em>container reader</em> while the reader on which OpenContainer() is called is known as the <em>parent
     743              :      * reader</em>.
     744              :      *
     745              :      * When the OpenContainer() method returns, the container reader is positioned immediately before the
     746              :      * first member of the container. Calling Next() on the container reader will advance through the members
     747              :      * of the collection until the end is reached, at which point the reader will return CHIP_END_OF_TLV.
     748              :      *
     749              :      * While the container reader is open, applications must not make calls on or otherwise alter the state
     750              :      * of the parent reader.  Once an application has finished using the container reader it must close it
     751              :      * by calling CloseContainer() on the parent reader, passing the container reader as an argument.
     752              :      * Applications may close the container reader at any point, with or without reading all elements
     753              :      * contained in the underlying container. After the container reader is closed, applications may
     754              :      * continue their use of the parent reader.
     755              :      *
     756              :      * The container reader inherits various configuration properties from the parent reader.  These are:
     757              :      *
     758              :      * @li The implicit profile id (ImplicitProfileId)
     759              :      * @li The application data pointer (AppData)
     760              :      * @li The GetNextBuffer function pointer
     761              :      *
     762              :      * @note The EnterContainer() method can be used as an alternative to OpenContainer() to read a
     763              :      * container element without initializing a new reader object.
     764              :      *
     765              :      * @param[out] containerReader          A reference to a TLVReader object that will be initialized for
     766              :      *                                      reading the members of the current container element. Any data
     767              :      *                                      associated with the supplied object is overwritten.
     768              :      *
     769              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
     770              :      * @retval #CHIP_ERROR_INCORRECT_STATE If the current element is not positioned on a container element.
     771              :      *
     772              :      */
     773              :     CHIP_ERROR OpenContainer(TLVReader & containerReader);
     774              : 
     775              :     /**
     776              :      * Completes the reading of a TLV container after a call to OpenContainer().
     777              :      *
     778              :      * The CloseContainer() method restores the state of a parent TLVReader object after a call to
     779              :      * OpenContainer().  For every call to OpenContainer() applications must make a corresponding
     780              :      * call to CloseContainer(), passing a reference to the same container reader to both methods.
     781              :      *
     782              :      * When CloseContainer() returns, the parent reader is positioned immediately before the first
     783              :      * element that follows the container.  From this point an application can use the Next() method
     784              :      * to advance through any remaining elements.
     785              :      *
     786              :      * Applications can call close CloseContainer() on a parent reader at any point in time, regardless
     787              :      * of whether all elements in the underlying container have been read. After CloseContainer() has
     788              :      * been called, the application should consider the container reader 'de-initialized' and must not
     789              :      * use it further without re-initializing it.
     790              :      *
     791              :      * @param[in] containerReader           A reference to the TLVReader object that was supplied to the
     792              :      *                                      OpenContainer() method.
     793              :      *
     794              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
     795              :      * @retval #CHIP_ERROR_INCORRECT_STATE If OpenContainer() has not been called on the reader, or if
     796              :      *                                      the container reader does not match the one passed to the
     797              :      *                                      OpenContainer() method.
     798              :      * @retval #CHIP_ERROR_TLV_UNDERRUN    If the underlying TLV encoding ended prematurely.
     799              :      * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT
     800              :      *                                      If the reader encountered an invalid or unsupported TLV
     801              :      *                                      element type.
     802              :      * @retval #CHIP_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context.
     803              :      * @retval other                        Other CHIP or platform error codes returned by the configured
     804              :      *                                      TLVBackingStore.
     805              :      *
     806              :      */
     807              :     CHIP_ERROR CloseContainer(TLVReader & containerReader);
     808              : 
     809              :     /**
     810              :      * Returns the type of the container within which the TLVReader is currently reading.
     811              :      *
     812              :      * The GetContainerType() method returns the type of the TLV container within which the TLVReader
     813              :      * is reading.  If the TLVReader is positioned at the outer-most level of a TLV encoding (i.e. before,
     814              :      * on or after the outer-most TLV element), the method will return kTLVType_NotSpecified.
     815              :      *
     816              :      * @return  The TLVType of the current container, or kTLVType_NotSpecified if the TLVReader is not
     817              :      *          positioned within a container.
     818              :      */
     819            5 :     TLVType GetContainerType() const { return mContainerType; }
     820              : 
     821              :     /**
     822              :      * Verifies that the TLVReader object is at the end of a TLV container.
     823              :      *
     824              :      * The VerifyEndOfContainer() method verifies that there are no further TLV elements to be read
     825              :      * within the current TLV container.  This is a convenience method that is equivalent to calling
     826              :      * Next() and checking for a return value of CHIP_END_OF_TLV.
     827              :      *
     828              :      * @note When there are more TLV elements in the collection, this method will change the position
     829              :      * of the reader.
     830              :      *
     831              :      * @retval #CHIP_NO_ERROR              If there are no further TLV elements to be read.
     832              :      * @retval #CHIP_ERROR_UNEXPECTED_TLV_ELEMENT
     833              :      *                                      If another TLV element was found in the collection.
     834              :      * @retval #CHIP_ERROR_TLV_UNDERRUN    If the underlying TLV encoding ended prematurely.
     835              :      * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT
     836              :      *                                      If the reader encountered an invalid or unsupported TLV element
     837              :      *                                      type.
     838              :      * @retval #CHIP_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context.
     839              :      * @retval other                        Other CHIP or platform error codes returned by the configured
     840              :      *                                      TLVBackingStore.
     841              :      *
     842              :      */
     843              :     CHIP_ERROR VerifyEndOfContainer();
     844              : 
     845              :     /**
     846              :      * Returns the total number of bytes read since the reader was initialized.
     847              :      *
     848              :      * @return Total number of bytes read since the reader was initialized.
     849              :      */
     850        53126 :     uint32_t GetLengthRead() const { return mLenRead; }
     851              : 
     852              :     /**
     853              :      * Returns the total number of bytes that can be read until the max read length is reached.
     854              :      *
     855              :      * @return Total number of bytes that can be read until the max read length is reached.
     856              :      */
     857            0 :     uint32_t GetRemainingLength() const { return mMaxLen - mLenRead; }
     858              : 
     859              :     /**
     860              :      * Return the total number of bytes for the TLV data
     861              :      * @return the total number of bytes for the TLV data
     862              :      */
     863          106 :     uint32_t GetTotalLength() const { return mMaxLen; }
     864              : 
     865              :     /**
     866              :      * Returns the stored backing store.
     867              :      *
     868              :      * @return the stored backing store.
     869              :      */
     870            4 :     TLVBackingStore * GetBackingStore() { return mBackingStore; }
     871              : 
     872              :     /**
     873              :      * Returns true if the current TLV element type is a double.
     874              :      */
     875           53 :     bool IsElementDouble() { return ElementType() == TLVElementType::FloatingPointNumber64; }
     876              : 
     877              :     /**
     878              :      * Gets the point in the underlying input buffer that corresponds to the reader's current position.
     879              :      *
     880              :      * @note Depending on the type of the current element, GetReadPoint() will return a pointer that
     881              :      * is some number of bytes *after* the first byte of the element.  For string types (UTF8 and byte
     882              :      * strings), the pointer will point to the first byte of the string's value.  For container types
     883              :      * (structures, arrays and paths), the pointer will point to the first member element within the
     884              :      * container. For all other types, the pointer will point to the byte immediately after the element's
     885              :      * encoding.
     886              :      *
     887              :      * @return A pointer into underlying input buffer that corresponds to the reader's current position.
     888              :      */
     889         1530 :     const uint8_t * GetReadPoint() const { return mReadPoint; }
     890              : 
     891              :     /**
     892              :      * Advances the TLVReader object to immediately after the current TLV element.
     893              :      *
     894              :      * The Skip() method positions the reader object immediately @em after the current TLV element, such
     895              :      * that a subsequent call to Next() will advance the reader to the following element.  Like Next(),
     896              :      * if the reader is positioned on a container element at the time of the call, the members of the
     897              :      * container will be skipped.  If the reader is not positioned on any element, its position remains
     898              :      * unchanged.
     899              :      *
     900              :      * @retval #CHIP_NO_ERROR              If the reader was successfully positioned on a new element.
     901              :      * @retval #CHIP_END_OF_TLV            If no further elements are available.
     902              :      * @retval #CHIP_ERROR_TLV_UNDERRUN    If the underlying TLV encoding ended prematurely.
     903              :      * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT
     904              :      *                                      If the reader encountered an invalid or unsupported TLV
     905              :      *                                      element type.
     906              :      * @retval #CHIP_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context.
     907              :      * @retval other                        Other CHIP or platform error codes returned by the configured
     908              :      *                                      TLVBackingStore.
     909              :      *
     910              :      */
     911              :     CHIP_ERROR Skip();
     912              : 
     913              :     /**
     914              :      * Position the destination reader on the next element with the given tag within this reader's current container context
     915              :      *
     916              :      * @param[in] tagInApiForm             The destination context tag value
     917              :      * @param[in] destReader               The destination TLV reader value that was located by given tag
     918              :      *
     919              :      * @retval #CHIP_NO_ERROR              If the reader was successfully positioned at the given tag
     920              :      * @retval #CHIP_END_OF_TLV            If the given tag cannot be found
     921              :      * @retval other                       Other CHIP or platform error codes
     922              :      */
     923              :     CHIP_ERROR FindElementWithTag(Tag tagInApiForm, TLVReader & destReader) const;
     924              : 
     925              :     /**
     926              :      * Count how many elements remain in the currently-open container.  Will
     927              :      * fail with CHIP_ERROR_INCORRECT_STATE if not currently in a container.
     928              :      *
     929              :      * @param[out] size On success, set to the number of items following the
     930              :      *                  current reader position in the container.
     931              :      */
     932              :     CHIP_ERROR CountRemainingInContainer(size_t * size) const;
     933              : 
     934              :     /**
     935              :      * The profile id to be used for profile tags encoded in implicit form.
     936              :      *
     937              :      * When the reader encounters a profile-specific tag that has been encoded in implicit form, it
     938              :      * uses the value of the @p ImplicitProfileId property as the assumed profile id for the tag.
     939              :      *
     940              :      * By default, the @p ImplicitProfileId property is set to kProfileIdNotSpecified. When decoding
     941              :      * TLV that contains implicitly-encoded tags, applications must set @p ImplicitProfileId prior
     942              :      * to reading any TLV elements having such tags.  The appropriate profile id is usually dependent
     943              :      * on the context of the application or protocol being spoken.
     944              :      *
     945              :      * If an implicitly-encoded tag is encountered while @p ImplicitProfileId is set to
     946              :      * kProfileIdNotSpecified, the reader will return a #CHIP_ERROR_UNKNOWN_IMPLICIT_TLV_TAG error.
     947              :      */
     948              :     uint32_t ImplicitProfileId;
     949              : 
     950              :     /**
     951              :      * A pointer field that can be used for application-specific data.
     952              :      */
     953              :     void * AppData;
     954              : 
     955              : protected:
     956              :     Tag mElemTag;
     957              :     uint64_t mElemLenOrVal;
     958              :     TLVBackingStore * mBackingStore;
     959              :     const uint8_t * mReadPoint;
     960              :     const uint8_t * mBufEnd;
     961              :     uint32_t mLenRead;
     962              :     uint32_t mMaxLen;
     963              :     TLVType mContainerType;
     964              :     uint16_t mControlByte;
     965              : 
     966              : private:
     967              :     bool mContainerOpen;
     968              : 
     969              : protected:
     970       563390 :     bool IsContainerOpen() const { return mContainerOpen; }
     971      4219899 :     void SetContainerOpen(bool aContainerOpen) { mContainerOpen = aContainerOpen; }
     972              : 
     973              :     CHIP_ERROR ReadElement();
     974              :     void ClearElementState();
     975              :     CHIP_ERROR SkipData();
     976              :     CHIP_ERROR SkipToEndOfContainer();
     977              :     CHIP_ERROR VerifyElement();
     978              :     Tag ReadTag(TLVTagControl tagControl, const uint8_t *& p) const;
     979              :     CHIP_ERROR EnsureData(CHIP_ERROR noDataErr);
     980              :     CHIP_ERROR ReadData(uint8_t * buf, uint32_t len);
     981              :     CHIP_ERROR GetElementHeadLength(uint8_t & elemHeadBytes) const;
     982              :     TLVElementType ElementType() const;
     983              : };
     984              : 
     985              : /*
     986              :  * A TLVReader that is backed by a scoped memory buffer that is owned by the reader
     987              :  */
     988              : class ScopedBufferTLVReader : public TLVReader
     989              : {
     990              : public:
     991              :     /*
     992              :      * Construct and initialize the reader by taking ownership of the provided scoped buffer.
     993              :      */
     994          475 :     ScopedBufferTLVReader(Platform::ScopedMemoryBuffer<uint8_t> && buffer, size_t dataLen) { Init(std::move(buffer), dataLen); }
     995              : 
     996         1023 :     ScopedBufferTLVReader() {}
     997              : 
     998              :     /*
     999              :      * Initialize the reader by taking ownership of a passed in scoped buffer.
    1000              :      */
    1001         1517 :     void Init(Platform::ScopedMemoryBuffer<uint8_t> && buffer, size_t dataLen)
    1002              :     {
    1003         1517 :         mBuffer = std::move(buffer);
    1004         1517 :         TLVReader::Init(mBuffer.Get(), dataLen);
    1005         1517 :     }
    1006              : 
    1007              :     /*
    1008              :      * Take back the buffer owned by the reader and transfer its ownership to
    1009              :      * the provided buffer reference. This also re-initializes the reader with
    1010              :      * a null buffer to prevent further use of the reader.
    1011              :      */
    1012              :     void TakeBuffer(Platform::ScopedMemoryBuffer<uint8_t> & buffer)
    1013              :     {
    1014              :         buffer = std::move(mBuffer);
    1015              :         TLVReader::Init(nullptr, 0);
    1016              :     }
    1017              : 
    1018              : private:
    1019              :     Platform::ScopedMemoryBuffer<uint8_t> mBuffer;
    1020              : };
    1021              : 
    1022              : /**
    1023              :  * A TLVReader that is guaranteed to be backed by a single contiguous buffer.
    1024              :  * This allows it to expose some additional methods that allow consumers to
    1025              :  * directly access the data in that buffer in a safe way that is guaranteed to
    1026              :  * work as long as the reader object stays in scope.
    1027              :  */
    1028              : class ContiguousBufferTLVReader : public TLVReader
    1029              : {
    1030              : public:
    1031        14265 :     ContiguousBufferTLVReader() : TLVReader() {}
    1032              : 
    1033              :     /**
    1034              :      * Init with input buffer as ptr + length pair.
    1035              :      */
    1036        14255 :     void Init(const uint8_t * data, size_t dataLen) { TLVReader::Init(data, dataLen); }
    1037              : 
    1038              :     /**
    1039              :      * Init with input buffer as ByteSpan.
    1040              :      */
    1041          263 :     void Init(const ByteSpan & data) { Init(data.data(), data.size()); }
    1042              : 
    1043              :     /**
    1044              :      * Init with input buffer as byte array.
    1045              :      */
    1046              :     template <size_t N>
    1047              :     void Init(const uint8_t (&data)[N])
    1048              :     {
    1049              :         Init(data, N);
    1050              :     }
    1051              : 
    1052              :     /**
    1053              :      * Allow opening a container, with a new ContiguousBufferTLVReader reading
    1054              :      * that container.  See TLVReader::OpenContainer for details.
    1055              :      */
    1056              :     CHIP_ERROR OpenContainer(ContiguousBufferTLVReader & containerReader);
    1057              : 
    1058              :     /**
    1059              :      * Get the value of the current UTF8 string as a Span<const char> pointing
    1060              :      * into the TLV data.  Consumers may need to copy the data elsewhere as
    1061              :      * needed (e.g. before releasing the reader and its backing buffer if they
    1062              :      * plan to use the data after that point).
    1063              :      *
    1064              :      * @param[out] data                     A Span<const char> representing the string data.
    1065              :      *
    1066              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
    1067              :      * @retval #CHIP_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV UTF8 string, or
    1068              :      *                                      the reader is not positioned on an element.
    1069              :      * @retval #CHIP_ERROR_TLV_UNDERRUN    If the underlying TLV encoding ended prematurely (i.e. the string length was "too big").
    1070              :      *
    1071              :      */
    1072              :     CHIP_ERROR GetStringView(Span<const char> & data);
    1073              : 
    1074              :     /**
    1075              :      * Get the value of the current octet string as a ByteSpan pointing into the
    1076              :      * TLV data.  Consumers may need to copy the data elsewhere as needed
    1077              :      * (e.g. before releasing the reader and its backing buffer if they plan to
    1078              :      * use the data after that point).
    1079              :      *
    1080              :      * @param[out] data                     A ByteSpan representing the string data.
    1081              :      *
    1082              :      * @retval #CHIP_NO_ERROR              If the method succeeded.
    1083              :      * @retval #CHIP_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV octet string, or
    1084              :      *                                      the reader is not positioned on an element.
    1085              :      * @retval #CHIP_ERROR_TLV_UNDERRUN    If the underlying TLV encoding ended prematurely (i.e. the string length was "too big").
    1086              :      *
    1087              :      */
    1088              :     CHIP_ERROR GetByteView(ByteSpan & data);
    1089              : };
    1090              : 
    1091              : } // namespace TLV
    1092              : } // namespace chip
        

Generated by: LCOV version 2.0-1