/*
 *
 *    Copyright (c) 2013-2017 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 *    @file
 *      This file implements a parser for the Weave TLV (Tag-Length-Value) encoding format.
 *
 */

#include <stdlib.h>

#include <Weave/Core/WeaveCore.h>
#include <Weave/Core/WeaveEncoding.h>
#include <Weave/Core/WeaveTLV.h>
#include <Weave/Support/CodeUtils.h>

namespace nl {
namespace Weave {
namespace TLV {

using namespace nl::Weave::Encoding;

static const uint8_t sTagSizes[] = { 0, 1, 2, 4, 2, 4, 6, 8 };

/**
 * @fn uint32_t TLVReader::GetLengthRead() const
 *
 * Returns the total number of bytes read since the reader was initialized.
 *
 * @return Total number of bytes read since the reader was initialized.
 */

/**
 * @fn uint32_t TLVReader::GetRemainingLength() const
 *
 * Returns the total number of bytes that can be read until the max read length is reached.
 *
 * @return Total number of bytes that can be read until the max read length is reached.
 */

/**
 * @fn const uint8_t *TLVReader::GetReadPoint() const
 *
 * Gets the point in the underlying input buffer that corresponds to the reader's current position.
 *
 * @note Depending on the type of the current element, GetReadPoint() will return a pointer that
 * is some number of bytes *after* the first byte of the element.  For string types (UTF8 and byte
 * strings), the pointer will point to the first byte of the string's value.  For container types
 * (structures, arrays and paths), the pointer will point to the first member element within the
 * container. For all other types, the pointer will point to the byte immediately after the element's
 * encoding.
 *
 * @return A pointer into underlying input buffer that corresponds to the reader's current position.
 */

/**
 *
 * @var uint32_t TLVReader::ImplicitProfileId
 *
 * The profile id to be used for profile tags encoded in implicit form.
 *
 * When the reader encounters a profile-specific tag that has been encoded in implicit form, it
 * uses the value of the @p ImplicitProfileId property as the assumed profile id for the tag.
 *
 * By default, the @p ImplicitProfileId property is set to kProfileIdNotSpecified. When decoding
 * TLV that contains implicitly-encoded tags, applications must set @p ImplicitProfileId prior
 * to reading any TLV elements having such tags.  The appropriate profile id is usually dependent
 * on the context of the application or protocol being spoken.
 *
 * If an implicitly-encoded tag is encountered while @p ImplicitProfileId is set to
 * kProfileIdNotSpecified, the reader will return a #WEAVE_ERROR_UNKNOWN_IMPLICIT_TLV_TAG error.
 */

/**
 * @var void *TLVReader::AppData
 *
 * A pointer field that can be used for application-specific data.
 */

/**
 * @typedef WEAVE_ERROR (*TLVReader::GetNextBufferFunct)(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart, uint32_t& bufLen)
 *
 * A function that can be used to retrieve additional TLV data to be parsed.
 *
 * Functions of this type are used to feed input data to a TLVReader. When called, the function is
 * expected to produce additional data for the reader to parse or signal the reader that no more
 * data is available.
 *
 * @param[in]       reader          A reference to the TLVReader object that is requesting input data.
 * @param[in,out]   bufHandle       A reference to a uintptr_t value that the function can use to store
 *                                  context data between calls.  This value is initialized to 0
 *                                  prior to the first call.
 * @param[in,out]   bufStart        A reference to a data pointer. On entry to the function, @p bufStart
 *                                  points to one byte beyond the last TLV data byte consumed by the
 *                                  reader.  On exit, bufStart is expected to point to the first byte
 *                                  of new TLV data to be parsed.  The new pointer value can be within
 *                                  the same buffer as the previously consumed data, or it can point
 *                                  to an entirely new buffer.
 * @param[out]      bufLen          A reference to an unsigned integer that the function must set to
 *                                  the number of TLV data bytes being returned.  If the end of the
 *                                  input TLV data has been reached, the function should set this value
 *                                  to 0.
 *
 * @retval #WEAVE_NO_ERROR          If the function successfully produced more TLV data, or the end of
 *                                  the input data was reached (@p bufLen should be set to 0 in this case).
 * @retval other                    Other Weave or platform-specific error codes indicating that an error
 *                                  occurred preventing the function from producing the requested data.
 *
 */

/**
 * @var GetNextBufferFunct TLVReader::GetNextBuffer
 *
 * A pointer to a function that will produce input data for the TLVReader object.  If set to NULL (the
 * default value), the reader will assume that no further input data is available.
 *
 * GetNextBuffer can be set by an application at any time, but is typically set when the reader
 * is initialized.
 *
 * See the GetNextBufferFunct type definition for additional information on implementing a
 * GetNextBuffer function.
 */

/**
 * Initializes a TLVReader object to read from a single input buffer.
 *
 * @param[in]   data    A pointer to a buffer containing the TLV data to be parsed.
 * @param[in]   dataLen The length of the TLV data to be parsed.
 *
 */
void TLVReader::Init(const uint8_t *data, uint32_t dataLen)
{
    mBufHandle = 0;
    mReadPoint = data;
    mBufEnd = data + dataLen;
    mLenRead = 0;
    mMaxLen = dataLen;
    ClearElementState();
    mContainerType = kTLVType_NotSpecified;
    SetContainerOpen(false);

    ImplicitProfileId = kProfileIdNotSpecified;
    AppData = NULL;
    GetNextBuffer = NULL;
}

/**
 * Initializes a TLVReader object to read from a single PacketBuffer.
 *
 * Parsing begins at the buffer's start position (buf->DataStart()) and continues until the
 * end of the data in the buffer (as denoted by buf->Datalen()), or maxLen bytes have been parsed.
 *
 * @param[in]   data    A pointer to an PacketBuffer containing the TLV data to be parsed.
 * @param[in]   maxLen  The maximum of bytes to parse.  Defaults to the amount of data
 *                      in the input buffer.
 */
void TLVReader::Init(PacketBuffer *buf, uint32_t maxLen)
{
    mBufHandle = (uintptr_t) buf;
    mReadPoint = buf->Start();
    mBufEnd = mReadPoint + buf->DataLength();
    mLenRead = 0;
    mMaxLen = maxLen;
    ClearElementState();
    mContainerType = kTLVType_NotSpecified;
    SetContainerOpen(false);

    ImplicitProfileId = kProfileIdNotSpecified;
    AppData = NULL;
    GetNextBuffer = NULL;
}

/**
 * Initializes a TLVReader object to read from a one or more PacketBuffers.
 *
 * Parsing begins at the initial buffer's start position (buf->DataStart()).  If
 * allowDiscontiguousBuffers is true, the reader will advance through the chain of buffers linked
 * by their Next() pointers. Parsing continues until all data in the buffer chain has been consumed
 * (as denoted by buf->Datalen()), or maxLen bytes have been parsed.
 *
 * @param[in]   data    A pointer to an PacketBuffer containing the TLV data to be parsed.
 * @param[in]   maxLen  The maximum of bytes to parse.  Defaults to the total amount of data
 *                      in the input buffer chain.
 * @param[in]   allowDiscontiguousBuffers
 *                      If true, advance to the next buffer in the chain once all data in the
 *                      current buffer has been consumed.  If false, stop parsing at the end
 *                      of the initial buffer.
 */
void TLVReader::Init(PacketBuffer *buf, uint32_t maxLen, bool allowDiscontiguousBuffers)
{
    mBufHandle = (uintptr_t) buf;
    mReadPoint = buf->Start();
    mBufEnd = mReadPoint + buf->DataLength();
    mLenRead = 0;
    mMaxLen = maxLen;
    ClearElementState();
    mContainerType = kTLVType_NotSpecified;
    SetContainerOpen(false);

    ImplicitProfileId = kProfileIdNotSpecified;
    AppData = NULL;

    if (allowDiscontiguousBuffers)
    {
        GetNextBuffer = GetNextPacketBuffer;
    }
    else
    {
        GetNextBuffer = NULL;
    }
}

/**
 * Initializes a TLVReader object from another TLVReader object.
 *
 * @param[in]   aReader  A read-only reference to the TLVReader to initialize
 *                       this from.
 *
 */
void TLVReader::Init(const TLVReader &aReader)
{
    // Initialize private data members

    mElemTag          = aReader.mElemTag;
    mElemLenOrVal     = aReader.mElemLenOrVal;
    mBufHandle        = aReader.mBufHandle;
    mReadPoint        = aReader.mReadPoint;
    mBufEnd           = aReader.mBufEnd;
    mLenRead          = aReader.mLenRead;
    mMaxLen           = aReader.mMaxLen;
    mControlByte      = aReader.mControlByte;
    mContainerType    = aReader.mContainerType;
    SetContainerOpen(aReader.IsContainerOpen());

    // Initialize public data members

    ImplicitProfileId = aReader.ImplicitProfileId;
    AppData           = aReader.AppData;
    GetNextBuffer     = aReader.GetNextBuffer;
}

/**
 * Returns the type of the current TLV element.
 *
 * @return      A TLVType value describing the data type of the current TLV element.  If the reader
 *              is not positioned on a TLV element, the return value will be kTLVType_NotSpecified.
 */
TLVType TLVReader::GetType() const
{
    TLVElementType elemType = ElementType();
    if (elemType == kTLVElementType_EndOfContainer)
        return kTLVType_NotSpecified;
    if (elemType == kTLVElementType_FloatingPointNumber32 || elemType == kTLVElementType_FloatingPointNumber64)
        return kTLVType_FloatingPointNumber;
    if (elemType == kTLVElementType_NotSpecified || elemType >= kTLVElementType_Null)
        return (TLVType) elemType;
    return (TLVType) (elemType & ~kTLVTypeSizeMask);
}

/**
 * Returns the control byte associated with current TLV element.
 *
 * Ideally, nobody ever needs to know about the control byte and only the
 * internal implementation of TLV should have access to it. But, nevertheless,
 * having access to the control byte is helpful for debugging purposes by the
 * TLV Debug Utilities (that try to decode the tag control byte when pretty
 * printing the TLV buffer contents).
 *
 * @note Unless you really know what you are doing, please refrain from using
 * this method and the associated control byte information.
 *
 * @return      An unsigned integer containing the control byte associated with
 *              the current TLV element. kTLVControlByte_NotSpecified is
 *              returned if the reader is not positioned @em on an element.
 */
uint16_t TLVReader::GetControlByte() const
{
    return mControlByte;
}

/**
 * Returns the tag associated with current TLV element.
 *
 * The value returned by GetTag() can be used with the tag utility functions (IsProfileTag(),
 * IsContextTag(), ProfileIdFromTag(), etc.) to determine the type of tag and to extract various tag
 * field values.
 *
 * @note If the reader is not positioned on a TLV element when GetTag() is called, the return value
 * is undefined. Therefore whenever the position of the reader is uncertain applications should call
 * GetType() to determine if the reader is position on an element (GetType() != kTLVType_NotSpecified)
 * before calling GetTag().
 *
 * @return      An unsigned integer containing information about the tag associated with the current
 *              TLV element.
 */
uint64_t TLVReader::GetTag() const
{
    return mElemTag;
}

/**
 * Returns the length of data associated with current TLV element.
 *
 * Data length only applies to elements of type UTF8 string or byte string.  For UTF8 strings, the
 * value returned is the number of bytes in the string, not the number of characters.
 *
 * @return      The length (in bytes) of data associated with the current TLV element, or 0 if the
 *              current element is not a UTF8 string or byte string, or if the reader is not
 *              positioned on an element.
 */
uint32_t TLVReader::GetLength() const
{
    if (TLVTypeHasLength(ElementType()))
        return (uint32_t) mElemLenOrVal;
    else
        return 0;
}

/**
 * Get the value of the current element as a bool type.
 *
 * @param[out]  v                       Receives the value associated with current TLV element.
 *
 * @retval #WEAVE_NO_ERROR              If the method succeeded.
 * @retval #WEAVE_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV boolean type, or the
 *                                      reader is not positioned on an element.
 *
 */
WEAVE_ERROR TLVReader::Get(bool& v)
{
    TLVElementType elemType = ElementType();
    if (elemType == kTLVElementType_BooleanFalse)
        v = false;
    else if (elemType == kTLVElementType_BooleanTrue)
        v = true;
    else
        return WEAVE_ERROR_WRONG_TLV_TYPE;
    return WEAVE_NO_ERROR;
}

/**
 * Get the value of the current element as an 8-bit signed integer.
 *
 * If the encoded integer value is larger than the output data type the resultant value will be
 * truncated.
 *
 * @param[out]  v                       Receives the value associated with current TLV element.
 *
 * @retval #WEAVE_NO_ERROR              If the method succeeded.
 * @retval #WEAVE_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV integer type (signed or
 *                                      unsigned), or the reader is not positioned on an element.
 *
 */
WEAVE_ERROR TLVReader::Get(int8_t& v)
{
    uint64_t v64 = 0;
    WEAVE_ERROR err = Get(v64);
    v = v64;
    return err;
}

/**
 * Get the value of the current element as a 16-bit signed integer.
 *
 * If the encoded integer value is larger than the output data type the resultant value will be
 * truncated.
 *
 * @param[out]  v                       Receives the value associated with current TLV element.
 *
 * @retval #WEAVE_NO_ERROR              If the method succeeded.
 * @retval #WEAVE_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV integer type (signed or
 *                                      unsigned), or the reader is not positioned on an element.
 *
 */
WEAVE_ERROR TLVReader::Get(int16_t& v)
{
    uint64_t v64 = 0;
    WEAVE_ERROR err = Get(v64);
    v = v64;
    return err;
}

/**
 * Get the value of the current element as a 32-bit signed integer.
 *
 * If the encoded integer value is larger than the output data type the resultant value will be
 * truncated.
 *
 * @param[out]  v                       Receives the value associated with current TLV element.
 *
 * @retval #WEAVE_NO_ERROR              If the method succeeded.
 * @retval #WEAVE_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV integer type (signed or
 *                                      unsigned), or the reader is not positioned on an element.
 *
 */
WEAVE_ERROR TLVReader::Get(int32_t& v)
{
    uint64_t v64 = 0;
    WEAVE_ERROR err = Get(v64);
    v = v64;
    return err;
}

/**
 * Get the value of the current element as a 64-bit signed integer.
 *
 * If the encoded integer value is larger than the output data type the resultant value will be
 * truncated.
 *
 * @param[out]  v                       Receives the value associated with current TLV element.
 *
 * @retval #WEAVE_NO_ERROR              If the method succeeded.
 * @retval #WEAVE_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV integer type (signed or
 *                                      unsigned), or the reader is not positioned on an element.
 *
 */
WEAVE_ERROR TLVReader::Get(int64_t& v)
{
    uint64_t v64 = 0;
    WEAVE_ERROR err = Get(v64);
    v = v64;
    return err;
}

/**
 * Get the value of the current element as an 8-bit unsigned integer.
 *
 * If the encoded integer value is larger than the output data type the resultant value will be
 * truncated.  Similarly, if the encoded integer value is negative, the value will be converted
 * to unsigned.
 *
 * @param[out]  v                       Receives the value associated with current TLV element.
 *
 * @retval #WEAVE_NO_ERROR              If the method succeeded.
 * @retval #WEAVE_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV integer type (signed or
 *                                      unsigned), or the reader is not positioned on an element.
 *
 */
WEAVE_ERROR TLVReader::Get(uint8_t& v)
{
    uint64_t v64 = 0;
    WEAVE_ERROR err = Get(v64);
    v = v64;
    return err;
}

/**
 * Get the value of the current element as a 16-bit unsigned integer.
 *
 * If the encoded integer value is larger than the output data type the resultant value will be
 * truncated.  Similarly, if the encoded integer value is negative, the value will be converted
 * to unsigned.
 *
 * @param[out]  v                       Receives the value associated with current TLV element.
 *
 * @retval #WEAVE_NO_ERROR              If the method succeeded.
 * @retval #WEAVE_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV integer type (signed or
 *                                      unsigned), or the reader is not positioned on an element.
 *
 */
WEAVE_ERROR TLVReader::Get(uint16_t& v)
{
    uint64_t v64 = 0;
    WEAVE_ERROR err = Get(v64);
    v = v64;
    return err;
}

/**
 * Get the value of the current element as a 32-bit unsigned integer.
 *
 * If the encoded integer value is larger than the output data type the resultant value will be
 * truncated.  Similarly, if the encoded integer value is negative, the value will be converted
 * to unsigned.
 *
 * @param[out]  v                       Receives the value associated with current TLV element.
 *
 * @retval #WEAVE_NO_ERROR              If the method succeeded.
 * @retval #WEAVE_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV integer type (signed or
                                        unsigned), or the reader is not positioned on an element.
 *
 */
WEAVE_ERROR TLVReader::Get(uint32_t& v)
{
    uint64_t v64 = 0;
    WEAVE_ERROR err = Get(v64);
    v = v64;
    return err;
}

/**
 * Get the value of the current element as a 64-bit unsigned integer.
 *
 * If the encoded integer value is negative, the value will be converted to unsigned.
 *
 * @param[out]  v                       Receives the value associated with current TLV element.
 *
 * @retval #WEAVE_NO_ERROR              If the method succeeded.
 * @retval #WEAVE_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV integer type (signed or
 *                                      unsigned), or the reader is not positioned on an element.
 *
 */
WEAVE_ERROR TLVReader::Get(uint64_t& v)
{
    switch (ElementType())
    {
    case kTLVElementType_Int8:
        v = (int64_t) (int8_t) mElemLenOrVal;
        break;
    case kTLVElementType_Int16:
        v = (int64_t) (int16_t) mElemLenOrVal;
        break;
    case kTLVElementType_Int32:
        v = (int64_t) (int32_t) mElemLenOrVal;
        break;
    case kTLVElementType_Int64:
    case kTLVElementType_UInt8:
    case kTLVElementType_UInt16:
    case kTLVElementType_UInt32:
    case kTLVElementType_UInt64:
        v = mElemLenOrVal;
        break;
    default:
        return WEAVE_ERROR_WRONG_TLV_TYPE;
    }
    return WEAVE_NO_ERROR;
}

/**
 * Get the value of the current element as a double-precision floating point number.
 *
 * @param[out]  v                       Receives the value associated with current TLV element.
 *
 * @retval #WEAVE_NO_ERROR              If the method succeeded.
 * @retval #WEAVE_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV floating point type, or
 *                                      the reader is not positioned on an element.
 *
 */
WEAVE_ERROR TLVReader::Get(double& v)
{
    switch (ElementType())
    {
    case kTLVElementType_FloatingPointNumber32:
    {
        union
        {
            uint32_t u32;
            float f;
        } cvt;
        cvt.u32 = (uint32_t)mElemLenOrVal;
        v = cvt.f;
        break;
    }
    case kTLVElementType_FloatingPointNumber64:
    {
        union
        {
            uint64_t u64;
            double d;
        } cvt;
        cvt.u64 = mElemLenOrVal;
        v = cvt.d;
        break;
    }
    default:
        return WEAVE_ERROR_WRONG_TLV_TYPE;
    }
    return WEAVE_NO_ERROR;
}

/**
 * Get the value of the current byte or UTF8 string element.
 *
 * To determine the required input buffer size, call the GetLength() method before calling GetBytes().
 *
 * @note The data output by this method is NOT null-terminated.
 *
 * @param[in]  buf                      A pointer to a buffer to receive the string data.
 * @param[in]  bufSize                  The size in bytes of the buffer pointed to by @p buf.
 *
 * @retval #WEAVE_NO_ERROR              If the method succeeded.
 * @retval #WEAVE_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV byte or UTF8 string, or
 *                                      the reader is not positioned on an element.
 * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL
 *                                      If the supplied buffer is too small to hold the data associated
 *                                      with the current element.
 * @retval #WEAVE_ERROR_TLV_UNDERRUN    If the underlying TLV encoding ended prematurely.
 * @retval other                        Other Weave or platform error codes returned by the configured
 *                                      GetNextBuffer() function. Only possible when GetNextBuffer is
 *                                      non-NULL.
 *
 */
WEAVE_ERROR TLVReader::GetBytes(uint8_t *buf, uint32_t bufSize)
{
    if (!TLVTypeIsString(ElementType()))
        return WEAVE_ERROR_WRONG_TLV_TYPE;

    if (mElemLenOrVal > bufSize)
        return WEAVE_ERROR_BUFFER_TOO_SMALL;

    WEAVE_ERROR err = ReadData(buf, (uint32_t) mElemLenOrVal);
    if (err != WEAVE_NO_ERROR)
        return err;

    mElemLenOrVal = 0;

    return WEAVE_NO_ERROR;
}

/**
 * Get the value of the current byte or UTF8 string element as a null terminated string.
 *
 * To determine the required input buffer size, call the GetLength() method before calling GetBytes().
 * The input buffer should be at least one byte bigger than the string length to accommodate the null
 * character.
 *
 * @param[in]  buf                      A pointer to a buffer to receive the byte string data.
 * @param[in]  bufSize                  The size in bytes of the buffer pointed to by @p buf.
 *
 * @retval #WEAVE_NO_ERROR              If the method succeeded.
 * @retval #WEAVE_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV byte or UTF8 string, or
 *                                      the reader is not positioned on an element.
 * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL
 *                                      If the supplied buffer is too small to hold the data associated
 *                                      with the current element.
 * @retval #WEAVE_ERROR_TLV_UNDERRUN    If the underlying TLV encoding ended prematurely.
 * @retval other                        Other Weave or platform error codes returned by the configured
 *                                      GetNextBuffer() function. Only possible when GetNextBuffer is
 *                                      non-NULL.
 *
 */
WEAVE_ERROR TLVReader::GetString(char *buf, uint32_t bufSize)
{
    if (!TLVTypeIsString(ElementType()))
        return WEAVE_ERROR_WRONG_TLV_TYPE;

    if ((mElemLenOrVal + 1) > bufSize)
        return WEAVE_ERROR_BUFFER_TOO_SMALL;

    buf[mElemLenOrVal] = 0;

    return GetBytes((uint8_t *) buf, bufSize - 1);
}

/**
 * Allocates and returns a buffer containing the value of the current byte or UTF8 string.
 *
 * This method creates a buffer for and returns a copy of the data associated with the byte
 * or UTF-8 string element at the current position. Memory for the buffer is obtained with
 * malloc() and should be freed with free() by the caller when it is no longer needed.
 *
 * @note The data returned by this method is NOT null-terminated.
 *
 * @param[out] buf                      A reference to a pointer to which a heap-allocated buffer of
 *                                      @p dataLen bytes will be assigned on success.
 * @param[out] dataLen                  A reference to storage for the size, in bytes, of @p buf on
 *                                      success.
 *
 * @retval #WEAVE_NO_ERROR              If the method succeeded.
 * @retval #WEAVE_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV byte or UTF8 string, or
 *                                      the reader is not positioned on an element.
 * @retval #WEAVE_ERROR_NO_MEMORY       If memory could not be allocated for the output buffer.
 * @retval #WEAVE_ERROR_TLV_UNDERRUN    If the underlying TLV encoding ended prematurely.
 * @retval #WEAVE_ERROR_UNSUPPORTED_WEAVE_FEATURE
 *                                      If the target platform does not support malloc() and free().
 * @retval other                        Other Weave or platform error codes returned by the configured
 *                                      GetNextBuffer() function. Only possible when GetNextBuffer
 *                                      is non-NULL.
 *
 */
WEAVE_ERROR TLVReader::DupBytes(uint8_t *& buf, uint32_t& dataLen)
{
#if HAVE_MALLOC && HAVE_FREE
    if (!TLVTypeIsString(ElementType()))
        return WEAVE_ERROR_WRONG_TLV_TYPE;

    buf = (uint8_t *) malloc(mElemLenOrVal);
    if (buf == NULL)
        return WEAVE_ERROR_NO_MEMORY;

    WEAVE_ERROR err = ReadData(buf, (uint32_t) mElemLenOrVal);
    if (err != WEAVE_NO_ERROR)
    {
        free(buf);
        return err;
    }

    dataLen = mElemLenOrVal;
    mElemLenOrVal = 0;

    return WEAVE_NO_ERROR;
#else
    return WEAVE_ERROR_UNSUPPORTED_WEAVE_FEATURE;
#endif // HAVE_MALLOC && HAVE_FREE
}

/**
 * Allocates and returns a buffer containing the null-terminated value of the current byte or UTF8
 * string.
 *
 * This method creates a buffer for and returns a null-terminated copy of the data associated with
 * the byte or UTF-8 string element at the current position. Memory for the buffer is obtained with
 * malloc() and should be freed with free() by the caller when it is no longer needed.
 *
 * @param[out] buf                      A reference to a pointer to which a heap-allocated buffer of
 *                                      will be assigned on success.
 *
 * @retval #WEAVE_NO_ERROR              If the method succeeded.
 * @retval #WEAVE_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV byte or UTF8 string, or
 *                                      the reader is not positioned on an element.
 * @retval #WEAVE_ERROR_NO_MEMORY       If memory could not be allocated for the output buffer.
 * @retval #WEAVE_ERROR_TLV_UNDERRUN    If the underlying TLV encoding ended prematurely.
 * @retval #WEAVE_ERROR_UNSUPPORTED_WEAVE_FEATURE
 *                                      If the target platform does not support malloc() and free().
 * @retval other                        Other Weave or platform error codes returned by the configured
 *                                      GetNextBuffer() function. Only possible when GetNextBuffer
 *                                      is non-NULL.
 *
 */
WEAVE_ERROR TLVReader::DupString(char *& buf)
{
#if HAVE_MALLOC && HAVE_FREE
    if (!TLVTypeIsString(ElementType()))
        return WEAVE_ERROR_WRONG_TLV_TYPE;

    buf = (char *) malloc(mElemLenOrVal + 1);
    if (buf == NULL)
        return WEAVE_ERROR_NO_MEMORY;

    WEAVE_ERROR err = ReadData((uint8_t *) buf, (uint32_t) mElemLenOrVal);
    if (err != WEAVE_NO_ERROR)
    {
        free(buf);
        return err;
    }

    buf[mElemLenOrVal] = 0;
    mElemLenOrVal = 0;

    return err;
#else
    return WEAVE_ERROR_UNSUPPORTED_WEAVE_FEATURE;
#endif // HAVE_MALLOC && HAVE_FREE
}

/**
 * Get a pointer to the initial encoded byte of a TLV byte or UTF8 string element.
 *
 * This method returns a direct pointer the encoded string value within the underlying input buffer.
 * To succeed, the method requires that the entirety of the string value be present in a single buffer.
 * Otherwise the method returns #WEAVE_ERROR_TLV_UNDERRUN.  This makes the method of limited use when
 * reading data from multiple discontiguous buffers.
 *
 * @param[out] data                     A reference to a const pointer that will receive a pointer to
 *                                      the underlying string data.
 *
 * @retval #WEAVE_NO_ERROR              If the method succeeded.
 * @retval #WEAVE_ERROR_WRONG_TLV_TYPE  If the current element is not a TLV byte or UTF8 string, or the
 *                                      reader is not positioned on an element.
 * @retval #WEAVE_ERROR_TLV_UNDERRUN    If the underlying TLV encoding ended prematurely or the value
 *                                      of the current string element is not contained within a single
 *                                      contiguous buffer.
 * @retval other                        Other Weave or platform error codes returned by the configured
 *                                      GetNextBuffer() function. Only possible when GetNextBuffer is
 *                                      non-NULL.
 *
 */
WEAVE_ERROR TLVReader::GetDataPtr(const uint8_t *& data)
{
    WEAVE_ERROR err;

    if (!TLVTypeIsString(ElementType()))
        return WEAVE_ERROR_WRONG_TLV_TYPE;

    err = EnsureData(WEAVE_ERROR_TLV_UNDERRUN);
    if (err != WEAVE_NO_ERROR)
        return err;

    uint32_t remainingLen = 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 < (uint32_t)mElemLenOrVal)
        return WEAVE_ERROR_TLV_UNDERRUN;

    data = mReadPoint;

    return WEAVE_NO_ERROR;
}

/**
 * Initializes a new TLVReader object for reading the members of a TLV container element.
 *
 * The OpenContainer() method initializes a new TLVReader object for reading the member elements of a
 * TLV container (a structure, array or path).  When OpenContainer() is called, the current TLVReader
 * object must be positioned on the container element to be read.  The method takes as its sole argument
 * a reference to a new reader that will be initialized to read the container.  This reader is known as
 * the <em>container reader</em> while the reader on which OpenContainer() is called is known as the <em>parent
 * reader</em>.
 *
 * When the OpenContainer() method returns, the container reader is positioned immediately before the
 * first member of the container. Calling Next() on the container reader will advance through the members
 * of the collection until the end is reached, at which point the reader will return WEAVE_END_OF_TLV.
 *
 * While the container reader is open, applications must not make calls on or otherwise alter the state
 * of the parent reader.  Once an application has finished using the container reader it must close it
 * by calling CloseContainer() on the parent reader, passing the container reader as an argument.
 * Applications may close the container reader at any point, with or without reading all elements
 * contained in the underlying container. After the container reader is closed, applications may
 * continue their use of the parent reader.
 *
 * The container reader inherits various configuration properties from the parent reader.  These are:
 *
 * @li The implicit profile id (ImplicitProfileId)
 * @li The application data pointer (AppData)
 * @li The GetNextBuffer function pointer
 *
 * @note The EnterContainer() method can be used as an alternative to OpenContainer() to read a
 * container element without initializing a new reader object.
 *
 * @param[out] containerReader          A reference to a TLVReader object that will be initialized for
 *                                      reading the members of the current container element. Any data
 *                                      associated with the supplied object is overwritten.
 *
 * @retval #WEAVE_NO_ERROR              If the method succeeded.
 * @retval #WEAVE_ERROR_INCORRECT_STATE If the current element is not positioned on a container element.
 *
 */
WEAVE_ERROR TLVReader::OpenContainer(TLVReader& containerReader)
{
    TLVElementType elemType = ElementType();
    if (!TLVTypeIsContainer(elemType))
        return WEAVE_ERROR_INCORRECT_STATE;

    containerReader.mBufHandle = mBufHandle;
    containerReader.mReadPoint = mReadPoint;
    containerReader.mBufEnd = mBufEnd;
    containerReader.mLenRead = mLenRead;
    containerReader.mMaxLen = mMaxLen;
    containerReader.ClearElementState();
    containerReader.mContainerType = (TLVType) elemType;
    containerReader.SetContainerOpen(false);
    containerReader.ImplicitProfileId = ImplicitProfileId;
    containerReader.AppData = AppData;
    containerReader.GetNextBuffer = GetNextBuffer;

    SetContainerOpen(true);

    return WEAVE_NO_ERROR;
}

/**
 * Completes the reading of a TLV container after a call to OpenContainer().
 *
 * The CloseContainer() method restores the state of a parent TLVReader object after a call to
 * OpenContainer().  For every call to OpenContainer() applications must make a corresponding
 * call to CloseContainer(), passing a reference to the same container reader to both methods.
 *
 * When CloseContainer() returns, the parent reader is positioned immediately before the first
 * element that follows the container.  From this point an application can use the Next() method
 * to advance through any remaining elements.
 *
 * Applications can call close CloseContainer() on a parent reader at any point in time, regardless
 * of whether all elements in the underlying container have been read. After CloseContainer() has
 * been called, the application should consider the container reader 'de-initialized' and must not
 * use it further without re-initializing it.
 *
 * @param[in] containerReader           A reference to the TLVReader object that was supplied to the
 *                                      OpenContainer() method.
 *
 * @retval #WEAVE_NO_ERROR              If the method succeeded.
 * @retval #WEAVE_ERROR_INCORRECT_STATE If OpenContainer() has not been called on the reader, or if
 *                                      the container reader does not match the one passed to the
 *                                      OpenContainer() method.
 * @retval #WEAVE_ERROR_TLV_UNDERRUN    If the underlying TLV encoding ended prematurely.
 * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT
 *                                      If the reader encountered an invalid or unsupported TLV
 *                                      element type.
 * @retval #WEAVE_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context.
 * @retval other                        Other Weave or platform error codes returned by the configured
 *                                      GetNextBuffer() function. Only possible when GetNextBuffer is
 *                                      non-NULL.
 *
 */
WEAVE_ERROR TLVReader::CloseContainer(TLVReader& containerReader)
{
    WEAVE_ERROR err;

    if (!IsContainerOpen())
        return WEAVE_ERROR_INCORRECT_STATE;

    if ((TLVElementType) containerReader.mContainerType != ElementType())
        return WEAVE_ERROR_INCORRECT_STATE;

    err = containerReader.SkipToEndOfContainer();
    if (err != WEAVE_NO_ERROR)
        return err;

    mBufHandle = containerReader.mBufHandle;
    mReadPoint = containerReader.mReadPoint;
    mBufEnd = containerReader.mBufEnd;
    mLenRead = containerReader.mLenRead;
    mMaxLen = containerReader.mMaxLen;
    ClearElementState();

    return WEAVE_NO_ERROR;
}

/**
 * Prepares a TLVReader object for reading the members of TLV container element.
 *
 * The EnterContainer() method prepares the current TLVReader object to begin reading the member
 * elements of a TLV container (a structure, array or path). For every call to EnterContainer()
 * applications must make a corresponding call to ExitContainer().
 *
 * When EnterContainer() is called the TLVReader object must be positioned on the container element
 * to be read.  The method takes as an argument a reference to a TLVType value which will be used
 * to save the context of the reader while it is reading the container.
 *
 * When the EnterContainer() method returns, the reader is positioned immediately @em before the
 * first member of the container. Repeatedly calling Next() will advance the reader through the members
 * of the collection until the end is reached, at which point the reader will return WEAVE_END_OF_TLV.
 *
 * Once the application has finished reading a container it can continue reading the elements after
 * the container by calling the ExitContainer() method.
 *
 * @param[out] outerContainerType       A reference to a TLVType value that will receive the context
 *                                      of the reader.
 *
 * @retval #WEAVE_NO_ERROR              If the method succeeded.
 * @retval #WEAVE_ERROR_INCORRECT_STATE If the current element is not positioned on a container element.
 *
 */
WEAVE_ERROR TLVReader::EnterContainer(TLVType& outerContainerType)
{
    TLVElementType elemType = ElementType();
    if (!TLVTypeIsContainer(elemType))
        return WEAVE_ERROR_INCORRECT_STATE;

    outerContainerType = mContainerType;
    mContainerType = (TLVType) elemType;

    ClearElementState();
    SetContainerOpen(false);

    return WEAVE_NO_ERROR;
}

/**
 * Completes the reading of a TLV container and prepares a TLVReader object to read elements
 * after the container.
 *
 * The ExitContainer() method restores the state of a TLVReader object after a call to
 * EnterContainer().  For every call to EnterContainer() applications must make a corresponding
 * call to ExitContainer(), passing the context value returned by the EnterContainer() method.
 *
 * When ExitContainer() returns, the reader is positioned immediately before the first element that
 * follows the container.  From this point an application can use the Next() method to advance
 * through any remaining elements.
 *
 * Once EnterContainer() has been called, applications can call ExitContainer() on a reader at any
 * point in time, regardless of whether all elements in the underlying container have been read.
 *
 * @note Any changes made to the configuration of the reader between the calls to EnterContainer()
 * and ExitContainer() are NOT undone by the call to ExitContainer().  For example, a change to the
 * implicit profile id (@p ImplicitProfileId) will not be reversed when a container is exited.  Thus
 * it is the application's responsibility to adjust the configuration accordingly at the appropriate
 * times.
 *
 * @param[in] outerContainerType        The TLVType value that was returned by the EnterContainer() method.
 *
 * @retval #WEAVE_NO_ERROR              If the method succeeded.
 * @retval #WEAVE_ERROR_INCORRECT_STATE If OpenContainer() has not been called on the reader, or if
 *                                      the container reader does not match the one passed to the
 *                                      OpenContainer() method.
 * @retval #WEAVE_ERROR_TLV_UNDERRUN    If the underlying TLV encoding ended prematurely.
 * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT
 *                                      If the reader encountered an invalid or unsupported TLV element type.
 * @retval #WEAVE_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context.
 * @retval other                        Other Weave or platform error codes returned by the configured
 *                                      GetNextBuffer() function. Only possible when GetNextBuffer is
 *                                      non-NULL.
 *
 */
WEAVE_ERROR TLVReader::ExitContainer(TLVType outerContainerType)
{
    WEAVE_ERROR err;

    err = SkipToEndOfContainer();
    if (err != WEAVE_NO_ERROR)
        return err;

    mContainerType = outerContainerType;
    ClearElementState();

    return WEAVE_NO_ERROR;
}

/**
 * Verifies that the TVLReader object is at the end of a TLV container.
 *
 * The VerifyEndOfContainer() method verifies that there are no further TLV elements to be read
 * within the current TLV container.  This is a convenience method that is equivalent to calling
 * Next() and checking for a return value of WEAVE_END_OF_TLV.
 *
 * @note When there are more TLV elements in the collection, this method will change the position
 * of the reader.
 *
 * @retval #WEAVE_NO_ERROR              If there are no further TLV elements to be read.
 * @retval #WEAVE_ERROR_UNEXPECTED_TLV_ELEMENT
 *                                      If another TLV element was found in the collection.
 * @retval #WEAVE_ERROR_TLV_UNDERRUN    If the underlying TLV encoding ended prematurely.
 * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT
 *                                      If the reader encountered an invalid or unsupported TLV element
 *                                      type.
 * @retval #WEAVE_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context.
 * @retval other                        Other Weave or platform error codes returned by the configured
 *                                      GetNextBuffer() function. Only possible when GetNextBuffer is
 *                                      non-NULL.
 *
 */
WEAVE_ERROR TLVReader::VerifyEndOfContainer()
{
    WEAVE_ERROR err = Next();
    if (err == WEAVE_END_OF_TLV)
        return WEAVE_NO_ERROR;
    if (err == WEAVE_NO_ERROR)
        return WEAVE_ERROR_UNEXPECTED_TLV_ELEMENT;
    return err;
}

/**
 * Returns the type of the container within which the TLVReader is currently reading.
 *
 * The GetContainerType() method returns the type of the TLV container within which the TLVReader
 * is reading.  If the TLVReader is positioned at the outer-most level of a TLV encoding (i.e. before,
 * on or after the outer-most TLV element), the method will return kTLVType_NotSpecified.
 *
 * @return  The TLVType of the current container, or kTLVType_NotSpecified if the TLVReader is not
 *          positioned within a container.
 */
TLVType TLVReader::GetContainerType() const
{
    return mContainerType;
}

/**
 * Advances the TLVReader object to the next TLV element to be read.
 *
 * The Next() method positions the reader object on the next element in a TLV encoding that resides
 * in the same containment context.  In particular, if the reader is positioned at the outer-most
 * level of a TLV encoding, calling Next() will advance the reader to the next, top-most element.
 * If the reader is positioned within a TLV container element (a structure, array or path), calling
 * Next() will advance the reader to the next member element of the container.
 *
 * Since Next() constrains reader motion to the current containment context, calling Next() when
 * the reader is positioned on a container element will advance @em over the container, skipping
 * its member elements (and the members of any nested containers) until it reaches the first element
 * after the container.
 *
 * When there are no further elements within a particular containment context the Next() method will
 * return a #WEAVE_END_OF_TLV error and the position of the reader will remain unchanged.
 *
 * @retval #WEAVE_NO_ERROR              If the reader was successfully positioned on a new element.
 * @retval #WEAVE_END_OF_TLV            If no further elements are available.
 * @retval #WEAVE_ERROR_TLV_UNDERRUN    If the underlying TLV encoding ended prematurely.
 * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT
 *                                      If the reader encountered an invalid or unsupported TLV element
 *                                      type.
 * @retval #WEAVE_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context.
 * @retval #WEAVE_ERROR_UNKNOWN_IMPLICIT_TLV_TAG
 *                                      If the reader encountered a implicitly-encoded TLV tag for which
 *                                      the corresponding profile id is unknown.
 * @retval other                        Other Weave or platform error codes returned by the configured
 *                                      GetNextBuffer() function. Only possible when GetNextBuffer is
 *                                      non-NULL.
 *
 */
WEAVE_ERROR TLVReader::Next()
{
    WEAVE_ERROR err;
    TLVElementType elemType = ElementType();

    err = Skip();
    if (err != WEAVE_NO_ERROR)
        return err;

    err = ReadElement();
    if (err != WEAVE_NO_ERROR)
        return err;

    elemType = ElementType();
    if (elemType == kTLVElementType_EndOfContainer)
        return WEAVE_END_OF_TLV;

    return WEAVE_NO_ERROR;
}

/**
 * Advances the TLVReader object to the next TLV element to be read, asserting the type and tag of
 * the new element.
 *
 * The Next(TLVType expectedType, uint64_t expectedTag) method is a convenience method that has the
 * same behavior as Next(), but also verifies that the type and tag of the new TLV element match
 * the supplied arguments.
 *
 * @param[in] expectedType              The expected data type for the next element.
 * @param[in] exceptedTag               The expected tag for the next element.
 *
 * @retval #WEAVE_NO_ERROR              If the reader was successfully positioned on a new element.
 * @retval #WEAVE_END_OF_TLV            If no further elements are available.
 * @retval #WEAVE_ERROR_WRONG_TLV_TYPE  If the type of the new element does not match the value
 *                                      of the @p expectedType argument.
 * @retval #WEAVE_ERROR_UNEXPECTED_TLV_ELEMENT
 *                                      If the tag associated with the new element does not match the
 *                                      value of the @p expectedTag argument.
 * @retval #WEAVE_ERROR_TLV_UNDERRUN    If the underlying TLV encoding ended prematurely.
 * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT
 *                                      If the reader encountered an invalid or unsupported TLV
 *                                      element type.
 * @retval #WEAVE_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context.
 * @retval other                        Other Weave or platform error codes returned by the configured
 *                                      GetNextBuffer() function. Only possible when GetNextBuffer is
 *                                      non-NULL.
 *
 */
WEAVE_ERROR TLVReader::Next(TLVType expectedType, uint64_t expectedTag)
{
    WEAVE_ERROR err = Next();
    if (err != WEAVE_NO_ERROR)
        return err;
    if (GetType() != expectedType)
        return WEAVE_ERROR_WRONG_TLV_TYPE;
    if (mElemTag != expectedTag)
        return WEAVE_ERROR_UNEXPECTED_TLV_ELEMENT;
    return WEAVE_NO_ERROR;
}

/**
 * Advances the TLVReader object to immediately after the current TLV element.
 *
 * The Skip() method positions the reader object immediately @em after the current TLV element, such
 * that a subsequent call to Next() will advance the reader to the following element.  Like Next(),
 * if the reader is positioned on a container element at the time of the call, the members of the
 * container will be skipped.  If the reader is not positioned on any element, its position remains
 * unchanged.
 *
 * @retval #WEAVE_NO_ERROR              If the reader was successfully positioned on a new element.
 * @retval #WEAVE_END_OF_TLV            If no further elements are available.
 * @retval #WEAVE_ERROR_TLV_UNDERRUN    If the underlying TLV encoding ended prematurely.
 * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT
 *                                      If the reader encountered an invalid or unsupported TLV
 *                                      element type.
 * @retval #WEAVE_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context.
 * @retval other                        Other Weave or platform error codes returned by the configured
 *                                      GetNextBuffer() function. Only possible when GetNextBuffer is
 *                                      non-NULL.
 *
 */
WEAVE_ERROR TLVReader::Skip()
{
    WEAVE_ERROR err;
    TLVElementType elemType = ElementType();

    if (elemType == kTLVElementType_EndOfContainer)
        return WEAVE_END_OF_TLV;

    if (TLVTypeIsContainer(elemType))
    {
        TLVType outerContainerType;
        err = EnterContainer(outerContainerType);
        if (err != WEAVE_NO_ERROR)
            return err;
        err = ExitContainer(outerContainerType);
        if (err != WEAVE_NO_ERROR)
            return err;
    }

    else
    {
        err = SkipData();
        if (err != WEAVE_NO_ERROR)
            return err;

        ClearElementState();
    }

    return WEAVE_NO_ERROR;
}

/**
 * Clear the state of the TLVReader.
 * This method is used to position the reader before the first TLV,
 * between TLVs or after the last TLV.
 */
void TLVReader::ClearElementState(void)
{
    mElemTag = AnonymousTag;
    mControlByte = kTLVControlByte_NotSpecified;
    mElemLenOrVal = 0;
}

/**
 * Skip any data contained in the current TLV by reading over it without
 * a destination buffer.
 *
 * @retval #WEAVE_NO_ERROR              If the reader was successfully positioned at the end of the
 *                                      data.
 * @retval other                        Other Weave or platform error codes returned by the configured
 *                                      GetNextBuffer() function. Only possible when GetNextBuffer is
 *                                      non-NULL.
 */
WEAVE_ERROR TLVReader::SkipData(void)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    TLVElementType elemType = ElementType();

    if (TLVTypeHasLength(elemType))
    {
        err = ReadData(NULL, mElemLenOrVal);
        if (err != WEAVE_NO_ERROR)
            return err;
    }

    return err;
}

WEAVE_ERROR TLVReader::SkipToEndOfContainer()
{
    WEAVE_ERROR err;
    TLVType outerContainerType = mContainerType;
    uint32_t nestLevel = 0;

    // If the user calls Next() after having called OpenContainer() but before calling
    // CloseContainer() they're effectively doing a close container by skipping over
    // the container element.  So reset the 'container open' flag here to prevent them
    // from calling CloseContainer() with the now orphaned container reader.
    SetContainerOpen(false);

    while (true)
    {
        TLVElementType elemType = ElementType();

        if (elemType == kTLVElementType_EndOfContainer)
        {
            if (nestLevel == 0)
                return WEAVE_NO_ERROR;

            nestLevel--;
            mContainerType = (nestLevel == 0) ? outerContainerType : kTLVType_UnknownContainer;
        }

        else if (TLVTypeIsContainer(elemType))
        {
            nestLevel++;
            mContainerType = (TLVType)elemType;
        }

        err = SkipData();
        if (err != WEAVE_NO_ERROR)
            return err;

        err = ReadElement();
        if (err != WEAVE_NO_ERROR)
            return err;
    }
}

WEAVE_ERROR TLVReader::ReadElement()
{
    WEAVE_ERROR err;
    uint8_t stagingBuf[17]; // 17 = 1 control byte + 8 tag bytes + 8 length/value bytes
    const uint8_t *p;
    TLVElementType elemType;

    // Make sure we have input data. Return WEAVE_END_OF_TLV if no more data is available.
    err = EnsureData(WEAVE_END_OF_TLV);
    if (err != WEAVE_NO_ERROR)
        return err;

    // Get the element's control byte.
    mControlByte = *mReadPoint;

    // Extract the element type from the control byte. Fail if it's invalid.
    elemType = ElementType();
    if (!IsValidTLVType(elemType))
        return WEAVE_ERROR_INVALID_TLV_ELEMENT;

    // Extract the tag control from the control byte.
    TLVTagControl tagControl = (TLVTagControl)(mControlByte & kTLVTagControlMask);

    // Determine the number of bytes in the element's tag, if any.
    uint8_t tagBytes = sTagSizes[tagControl >> kTLVTagControlShift];

    // Extract the size of length/value field from the control byte.
    TLVFieldSize lenOrValFieldSize = GetTLVFieldSize(elemType);

    // Determine the number of bytes in the length/value field.
    uint8_t valOrLenBytes = TLVFieldSizeToBytes(lenOrValFieldSize);

    // Determine the number of bytes in the element's 'head'. This includes: the control byte, the tag bytes (if present), the
    // length bytes (if present), and for elements that don't have a length (e.g. integers), the value bytes.
    uint8_t elemHeadBytes = 1 + tagBytes + valOrLenBytes;

    // If the head of the element overlaps the end of the input buffer, read the bytes into the staging buffer
    // and arrange to parse them from there. Otherwise read them directly from the input buffer.
    if (elemHeadBytes > (mBufEnd - mReadPoint))
    {
        err = ReadData(stagingBuf, elemHeadBytes);
        if (err != WEAVE_NO_ERROR)
            return err;
        p = stagingBuf;
    }
    else
    {
        p = mReadPoint;
        mReadPoint += elemHeadBytes;
        mLenRead += elemHeadBytes;
    }

    // Skip over the control byte.
    p++;

    // Read the tag field, if present.
    mElemTag = ReadTag(tagControl, p);

    // Read the length/value field, if present.
    switch (lenOrValFieldSize)
    {
    case kTLVFieldSize_0Byte:
        mElemLenOrVal = 0;
        break;
    case kTLVFieldSize_1Byte:
        mElemLenOrVal = Read8(p);
        break;
    case kTLVFieldSize_2Byte:
        mElemLenOrVal = LittleEndian::Read16(p);
        break;
    case kTLVFieldSize_4Byte:
        mElemLenOrVal = LittleEndian::Read32(p);
        break;
    case kTLVFieldSize_8Byte:
        mElemLenOrVal = LittleEndian::Read64(p);
        break;
    }

    return VerifyElement();
}

WEAVE_ERROR TLVReader::VerifyElement()
{
    if (ElementType() == kTLVElementType_EndOfContainer)
    {
        if (mContainerType == kTLVType_NotSpecified)
            return WEAVE_ERROR_INVALID_TLV_ELEMENT;
        if (mElemTag != AnonymousTag)
            return WEAVE_ERROR_INVALID_TLV_TAG;
    }
    else
    {
        if (mElemTag == UnknownImplicitTag)
            return WEAVE_ERROR_UNKNOWN_IMPLICIT_TLV_TAG;
        switch (mContainerType)
        {
        case kTLVType_NotSpecified:
            if (IsContextTag(mElemTag))
                return WEAVE_ERROR_INVALID_TLV_TAG;
            break;
        case kTLVType_Structure:
        case kTLVType_Path:
            if (mElemTag == AnonymousTag)
                return WEAVE_ERROR_INVALID_TLV_TAG;
            break;
        case kTLVType_Array:
            if (mElemTag != AnonymousTag)
                return WEAVE_ERROR_INVALID_TLV_TAG;
            break;
        case kTLVType_UnknownContainer:
            break;
        default:
            return WEAVE_ERROR_INCORRECT_STATE;
        }
    }

    // If the current element encodes a specific length (e.g. a UTF8 string or a byte string), verify
    // that the purported length fits within the remaining bytes of the encoding (as delineated by mMaxLen).
    //
    // Note that this check is not strictly necessary to prevent runtime errors, as any attempt to access
    // the data of an element with an invalid length will result in an error.  However checking the length
    // here catches the error earlier, and ensures that the application will never see the erroneous length
    // value.
    //
    if (TLVTypeHasLength(ElementType()))
    {
        uint32_t overallLenRemaining = mMaxLen - mLenRead;
        if (overallLenRemaining < (uint32_t)mElemLenOrVal)
            return WEAVE_ERROR_TLV_UNDERRUN;
    }

    return WEAVE_NO_ERROR;
}

uint64_t TLVReader::ReadTag(TLVTagControl tagControl, const uint8_t *& p)
{
    uint16_t vendorId;
    uint16_t profileNum;

    switch (tagControl)
    {
    case kTLVTagControl_ContextSpecific:
        return ContextTag(Read8(p));
    case kTLVTagControl_CommonProfile_2Bytes:
        return CommonTag(LittleEndian::Read16(p));
    case kTLVTagControl_CommonProfile_4Bytes:
        return CommonTag(LittleEndian::Read32(p));
    case kTLVTagControl_ImplicitProfile_2Bytes:
        if (ImplicitProfileId == kProfileIdNotSpecified)
            return UnknownImplicitTag;
        return ProfileTag(ImplicitProfileId, LittleEndian::Read16(p));
    case kTLVTagControl_ImplicitProfile_4Bytes:
        if (ImplicitProfileId == kProfileIdNotSpecified)
            return UnknownImplicitTag;
        return ProfileTag(ImplicitProfileId, LittleEndian::Read32(p));
    case kTLVTagControl_FullyQualified_6Bytes:
        vendorId = LittleEndian::Read16(p);
        profileNum = LittleEndian::Read16(p);
        return ProfileTag(vendorId, profileNum, LittleEndian::Read16(p));
    case kTLVTagControl_FullyQualified_8Bytes:
        vendorId = LittleEndian::Read16(p);
        profileNum = LittleEndian::Read16(p);
        return ProfileTag(vendorId, profileNum, LittleEndian::Read32(p));
    case kTLVTagControl_Anonymous:
    default:
        return AnonymousTag;
    }
}

WEAVE_ERROR TLVReader::ReadData(uint8_t *buf, uint32_t len)
{
    WEAVE_ERROR err;

    while (len > 0)
    {
        err = EnsureData(WEAVE_ERROR_TLV_UNDERRUN);
        if (err != WEAVE_NO_ERROR)
            return err;

        uint32_t remainingLen = mBufEnd - mReadPoint;

        uint32_t readLen = len;
        if (readLen > remainingLen)
            readLen = remainingLen;

        if (buf != NULL)
        {
            memcpy(buf, mReadPoint, readLen);
            buf += readLen;
        }
        mReadPoint += readLen;
        mLenRead += readLen;
        len -= readLen;
    }

    return WEAVE_NO_ERROR;
}

WEAVE_ERROR TLVReader::EnsureData(WEAVE_ERROR noDataErr)
{
    WEAVE_ERROR err;

    if (mReadPoint == mBufEnd)
    {
        if (mLenRead == mMaxLen)
            return noDataErr;

        if (GetNextBuffer == NULL)
            return noDataErr;

        uint32_t bufLen;
        err = GetNextBuffer(*this, mBufHandle, mReadPoint, bufLen);
        if (err != WEAVE_NO_ERROR)
            return err;
        if (bufLen == 0)
            return noDataErr;

        // Cap mBufEnd so that we don't read beyond the user's specified maximum length, even
        // if the underlying buffer is larger.
        uint32_t overallLenRemaining = mMaxLen - mLenRead;
        if (overallLenRemaining < bufLen)
            bufLen = overallLenRemaining;

        mBufEnd = mReadPoint + bufLen;
    }

    return WEAVE_NO_ERROR;
}

/**
 * This is a private method used to compute the length of a TLV element head.
 */
WEAVE_ERROR TLVReader::GetElementHeadLength(uint8_t& elemHeadBytes) const
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    uint8_t tagBytes;
    uint8_t valOrLenBytes;
    TLVTagControl tagControl;
    TLVFieldSize lenOrValFieldSize;
    TLVElementType elemType = ElementType();

    // Verify element is of valid TLVType.
    VerifyOrExit(IsValidTLVType(elemType), err = WEAVE_ERROR_INVALID_TLV_ELEMENT);

    // Extract the tag control from the control byte.
    tagControl = (TLVTagControl)(mControlByte & kTLVTagControlMask);

    // Determine the number of bytes in the element's tag, if any.
    tagBytes = sTagSizes[tagControl >> kTLVTagControlShift];

    // Extract the size of length/value field from the control byte.
    lenOrValFieldSize = GetTLVFieldSize(elemType);

    // Determine the number of bytes in the length/value field.
    valOrLenBytes = TLVFieldSizeToBytes(lenOrValFieldSize);

    // Determine the number of bytes in the element's 'head'. This includes: the
    // control byte, the tag bytes (if present), the length bytes (if present),
    // and for elements that don't have a length (e.g. integers), the value
    // bytes.
    elemHeadBytes = 1 + tagBytes + valOrLenBytes;

exit:
    return err;
}

/**
 * This is a private method that returns the TLVElementType from mControlByte
 */
TLVElementType TLVReader::ElementType() const
{
    if (mControlByte == (uint16_t) kTLVControlByte_NotSpecified)
        return kTLVElementType_NotSpecified;
    else
        return (TLVElementType) (mControlByte & kTLVTypeMask);
}

WEAVE_ERROR TLVReader::GetNextPacketBuffer(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart,
        uint32_t& bufLen)
{
    PacketBuffer *& buf = (PacketBuffer *&) bufHandle;

    if (buf != NULL)
        buf = buf->Next();
    if (buf != NULL)
    {
        bufStart = buf->Start();
        bufLen = buf->DataLength();
    }
    else
    {
        bufStart = NULL;
        bufLen = 0;
    }

    return WEAVE_NO_ERROR;
}

} // namespace TLV
} // namespace Weave
} // namespace nl
