/*
 *
 *    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 contains definitions for working with data encoded in Weave TLV format.
 *
 *      Weave TLV (Tag-Length-Value) is a generalized encoding method for simple structured data. It
 *      shares many properties with the commonly used JSON serialization format while being considerably
 *      more compact over the wire.
 */

#ifndef WEAVETLV_H_
#define WEAVETLV_H_

#include <stdlib.h>
#include <stdarg.h>

#include <Weave/Support/NLDLLUtil.h>
#include <Weave/Core/WeaveError.h>
#include "WeaveTLVTags.h"
#include "WeaveTLVTypes.h"

// forward declaration of the PacketBuffer class used within the header.
namespace nl {
namespace Weave {
namespace System {

class PacketBuffer;

} // namespace System
} // namespace Weave
} // namespace nl

/**
 * @namespace nl::Weave::TLV
 *
 * Definitions for working with data encoded in Weave TLV format.
 *
 * Weave TLV is a generalized encoding method for simple structured data. It shares many properties
 * with the commonly used JSON serialization format while being considerably more compact over the wire.
 */

namespace nl {
namespace Weave {
namespace TLV {

using nl::Weave::System::PacketBuffer;

enum {
    kTLVControlByte_NotSpecified = 0xFFFF
};

/**
 * Provides a memory efficient parser for data encoded in Weave TLV format.
 *
 * TLVReader implements a forward-only, “pull-style” parser for Weave TLV data.  The TLVReader
 * object operates as a cursor that can be used to iterate over a sequence of TLV elements
 * and interpret their contents.  When positioned on an element, applications can make calls
 * to the reader's Get() methods to query the current element’s type and tag, and to extract
 * any associated value.  The reader’s Next() method is used to advance from element to element.
 *
 * A TLVReader object is always positioned either before, on or after a TLV element.  When first
 * initialized, a TLVReader is positioned immediately before the first element of the encoding.
 * To begin reading, an application must make an initial call to the Next() method to position
 * the reader on the first element.  When a container element is encountered--either a structure,
 * an array or a path--the OpenContainer() or EnterContainer() methods can be used to iterate
 * through the contents of the container.
 *
 * When the reader reaches the end of a TLV encoding, or the last element within a container,
 * it signals the application by returning a WEAVE_END_OF_TLV error from the Next() method.
 * The reader will continue to return WEAVE_END_OF_TLV until it is reinitialized, or the current
 * container is exited (via CloseContainer() / ExitContainer()).
 *
 * A TLVReader object can parse data directly from a fixed input buffer, or from a chain of one
 * or more PacketBuffers.  Additionally, applications can supply a @p GetNextBuffer function to
 * feed data to the reader from an arbitrary source, e.g. a socket or a serial port.
 *
 */
class NL_DLL_EXPORT TLVReader
{
friend class TLVWriter;
friend class TLVUpdater;

public:
    // *** See WeaveTLVReader.cpp file for API documentation ***

    void Init(const TLVReader &aReader);
    void Init(const uint8_t *data, uint32_t dataLen);
    void Init(PacketBuffer *buf, uint32_t maxLen = 0xFFFFFFFFUL);
    void Init(PacketBuffer *buf, uint32_t maxLen, bool allowDiscontiguousBuffers);

    WEAVE_ERROR Next(void);
    WEAVE_ERROR Next(TLVType expectedType, uint64_t expectedTag);

    TLVType GetType(void) const;
    uint64_t GetTag(void) const;
    uint32_t GetLength(void) const;
    uint16_t GetControlByte(void) const;

    WEAVE_ERROR Get(bool& v);
    WEAVE_ERROR Get(int8_t& v);
    WEAVE_ERROR Get(int16_t& v);
    WEAVE_ERROR Get(int32_t& v);
    WEAVE_ERROR Get(int64_t& v);
    WEAVE_ERROR Get(uint8_t& v);
    WEAVE_ERROR Get(uint16_t& v);
    WEAVE_ERROR Get(uint32_t& v);
    WEAVE_ERROR Get(uint64_t& v);
    WEAVE_ERROR Get(float& v);
    WEAVE_ERROR Get(double& v);
    WEAVE_ERROR GetBytes(uint8_t *buf, uint32_t bufSize);
    WEAVE_ERROR DupBytes(uint8_t *& buf, uint32_t& dataLen);
    WEAVE_ERROR GetString(char *buf, uint32_t bufSize);
    WEAVE_ERROR DupString(char *& buf);
    WEAVE_ERROR GetDataPtr(const uint8_t *& data);

    WEAVE_ERROR EnterContainer(TLVType& outerContainerType);
    WEAVE_ERROR ExitContainer(TLVType outerContainerType);
    WEAVE_ERROR OpenContainer(TLVReader& containerReader);
    WEAVE_ERROR CloseContainer(TLVReader& containerReader);
    TLVType GetContainerType(void) const;
    WEAVE_ERROR VerifyEndOfContainer(void);

    uint32_t GetLengthRead(void) const { return mLenRead; }
    uint32_t GetRemainingLength(void) const { return mMaxLen - mLenRead; }

    const uint8_t *GetReadPoint(void) const { return mReadPoint; }

    WEAVE_ERROR Skip(void);

    uint32_t ImplicitProfileId;
    void *AppData;

    typedef WEAVE_ERROR (*GetNextBufferFunct)(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart,
            uint32_t& bufLen);
    GetNextBufferFunct GetNextBuffer;

protected:
    uint64_t mElemTag;
    uint64_t mElemLenOrVal;
    uintptr_t mBufHandle;
    const uint8_t *mReadPoint;
    const uint8_t *mBufEnd;
    uint32_t mLenRead;
    uint32_t mMaxLen;
    TLVType mContainerType;
    uint16_t mControlByte;

private:
    bool mContainerOpen;

protected:
    bool IsContainerOpen(void) const { return mContainerOpen; }
    void SetContainerOpen(bool aContainerOpen) { mContainerOpen = aContainerOpen; }

    WEAVE_ERROR ReadElement(void);
    void ClearElementState(void);
    WEAVE_ERROR SkipData(void);
    WEAVE_ERROR SkipToEndOfContainer(void);
    WEAVE_ERROR VerifyElement(void);
    uint64_t ReadTag(TLVTagControl tagControl, const uint8_t *& p);
    WEAVE_ERROR EnsureData(WEAVE_ERROR noDataErr);
    WEAVE_ERROR ReadData(uint8_t *buf, uint32_t len);
    WEAVE_ERROR GetElementHeadLength(uint8_t& elemHeadBytes) const;
    TLVElementType ElementType(void) const;

    static WEAVE_ERROR GetNextPacketBuffer(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart,
            uint32_t& bufLen);
    static WEAVE_ERROR FailGetNextBuffer(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart,
            uint32_t& bufLen);

#if INET_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES
    static WEAVE_ERROR GetNextInetBuffer(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart,
            uint32_t& bufLen);
#endif // INET_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES
};

#if INET_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES
inline WEAVE_ERROR TLVReader::GetNextInetBuffer(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart,
    uint32_t& bufLen)
{
    return GetNextPacketBuffer(reader, bufHandle, bufStart, bufLen);
}
#endif // INET_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES

/**
 * Provides a memory efficient encoder for writing data in Weave TLV format.
 *
 * TLVWriter implements a forward-only, stream-style encoder for Weave TLV data.  Applications
 * write data to an encoding by calling one of the writer's Put() methods, passing associated
 * tag and value information as necessary.  Similarly applications can encode TLV container types
 * (structures, arrays or paths) by calling the writer's OpenContainer() or EnterContainer()
 * methods.
 *
 * A TLVWriter object can write data directly to a fixed output buffer, or to a chain of one or
 * more PacketBuffer objects.  Additionally, applications can supply their own @p GetNewBuffer and
 * @p FinalizeBuffer functions to direct output to an arbitrary destination, e.g. a socket or an
 * event queue.
 *
 */
class NL_DLL_EXPORT TLVWriter
{
friend class TLVUpdater;
public:
    // *** See WeaveTLVWriter.cpp file for API documentation ***

    void Init(uint8_t *buf, uint32_t maxLen);
    void Init(PacketBuffer *buf, uint32_t maxLen = 0xFFFFFFFFUL);
    void Init(PacketBuffer *buf, uint32_t maxLen, bool allowDiscontiguousBuffers);

    WEAVE_ERROR Finalize(void);

    WEAVE_ERROR Put(uint64_t tag, int8_t v);
    WEAVE_ERROR Put(uint64_t tag, int8_t v, bool preserveSize);
    WEAVE_ERROR Put(uint64_t tag, int16_t v);
    WEAVE_ERROR Put(uint64_t tag, int16_t v, bool preserveSize);
    WEAVE_ERROR Put(uint64_t tag, int32_t v);
    WEAVE_ERROR Put(uint64_t tag, int32_t v, bool preserveSize);
    WEAVE_ERROR Put(uint64_t tag, int64_t v);
    WEAVE_ERROR Put(uint64_t tag, int64_t v, bool preserveSize);
    WEAVE_ERROR Put(uint64_t tag, uint8_t v);
    WEAVE_ERROR Put(uint64_t tag, uint8_t v, bool preserveSize);
    WEAVE_ERROR Put(uint64_t tag, uint16_t v);
    WEAVE_ERROR Put(uint64_t tag, uint16_t v, bool preserveSize);
    WEAVE_ERROR Put(uint64_t tag, uint32_t v);
    WEAVE_ERROR Put(uint64_t tag, uint32_t v, bool preserveSize);
    WEAVE_ERROR Put(uint64_t tag, uint64_t v);
    WEAVE_ERROR Put(uint64_t tag, uint64_t v, bool preserveSize);
    WEAVE_ERROR Put(uint64_t tag, float v);
    WEAVE_ERROR Put(uint64_t tag, double v);
    WEAVE_ERROR PutBoolean(uint64_t tag, bool v);
    WEAVE_ERROR PutBytes(uint64_t tag, const uint8_t *buf, uint32_t len);
    WEAVE_ERROR PutString(uint64_t tag, const char *buf);
    WEAVE_ERROR PutString(uint64_t tag, const char *buf, uint32_t len);
    WEAVE_ERROR PutStringF(uint64_t tag, const char *fmt, ...);
    WEAVE_ERROR VPutStringF(uint64_t tag, const char *fmt, va_list ap);
    WEAVE_ERROR PutNull(uint64_t tag);
    WEAVE_ERROR CopyElement(TLVReader& reader);
    WEAVE_ERROR CopyElement(uint64_t tag, TLVReader& reader);

    WEAVE_ERROR StartContainer(uint64_t tag, TLVType containerType, TLVType& outerContainerType);
    WEAVE_ERROR EndContainer(TLVType outerContainerType);
    WEAVE_ERROR OpenContainer(uint64_t tag, TLVType containerType, TLVWriter& containerWriter);
    WEAVE_ERROR CloseContainer(TLVWriter& containerWriter);
    WEAVE_ERROR PutPreEncodedContainer(uint64_t tag, TLVType containerType, const uint8_t *data, uint32_t dataLen);
    WEAVE_ERROR CopyContainer(TLVReader& container);
    WEAVE_ERROR CopyContainer(uint64_t tag, TLVReader& container);
    TLVType GetContainerType(void) const;

    uint32_t GetLengthWritten(void);

    uint32_t ImplicitProfileId;
    void *AppData;

    typedef WEAVE_ERROR (*GetNewBufferFunct)(TLVWriter& writer, uintptr_t& bufHandle, uint8_t *& bufStart,
            uint32_t& bufLen);
    GetNewBufferFunct GetNewBuffer;

    typedef WEAVE_ERROR (*FinalizeBufferFunct)(TLVWriter& writer, uintptr_t bufHandle, uint8_t *bufStart,
            uint32_t bufLen);
    FinalizeBufferFunct FinalizeBuffer;

    // Implementations of GetNewBufferFunct/FinalizeBufferFunct that support writing into one or more
    // PacketBuffers.
    static WEAVE_ERROR GetNewPacketBuffer(TLVWriter& writer, uintptr_t& bufHandle, uint8_t *& bufStart, uint32_t& bufLen);
    static WEAVE_ERROR FinalizePacketBuffer(TLVWriter& writer, uintptr_t bufHandle, uint8_t *bufStart, uint32_t dataLen);

#if INET_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES
    static WEAVE_ERROR GetNewInetBuffer(TLVWriter& writer, uintptr_t& bufHandle, uint8_t *& bufStart, uint32_t& bufLen);
    static WEAVE_ERROR FinalizeInetBuffer(TLVWriter& writer, uintptr_t bufHandle, uint8_t *bufStart, uint32_t dataLen);
#endif // INET_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES

protected:
    uintptr_t mBufHandle;
    uint8_t *mBufStart;
    uint8_t *mWritePoint;
    uint32_t mRemainingLen;
    uint32_t mLenWritten;
    uint32_t mMaxLen;
    TLVType mContainerType;

private:
    bool mContainerOpen;
    bool mCloseContainerReserved;

protected:
    bool IsContainerOpen(void) const { return mContainerOpen; }
    void SetContainerOpen(bool aContainerOpen) { mContainerOpen = aContainerOpen; }

    enum {
        kEndOfContainerMarkerSize = 1, /**< Size of the EndOfContainer marker, used in reserving space. */
    };

    /**
     * @brief
     *   Determine whether the container should reserve space for the
     *   CloseContainer symbol at the point of starting / opening the
     *   container.
     */
    bool IsCloseContainerReserved(void) const { return mCloseContainerReserved; }

    /**
     * @brief
     * Set whether the container should reserve the space for the
     * CloseContainer symbol at the point of starting / opening the
     * container.
     */
    void SetCloseContainerReserved(bool aCloseContainerReserved) { mCloseContainerReserved = aCloseContainerReserved; }

#if CONFIG_HAVE_VCBPRINTF
    static void WeaveTLVWriterPutcharCB(uint8_t c, void *appState);
#endif
    WEAVE_ERROR WriteElementHead(TLVElementType elemType, uint64_t tag, uint64_t lenOrVal);
    WEAVE_ERROR WriteElementWithData(TLVType type, uint64_t tag, const uint8_t *data, uint32_t dataLen);
    WEAVE_ERROR WriteData(const uint8_t *p, uint32_t len);
};

#if INET_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES
inline WEAVE_ERROR TLVWriter::GetNewInetBuffer(TLVWriter& writer, uintptr_t& bufHandle, uint8_t *& bufStart, uint32_t& bufLen)
{
    return GetNewPacketBuffer(writer, bufHandle, bufStart, bufLen);
}

inline WEAVE_ERROR TLVWriter::FinalizeInetBuffer(TLVWriter& writer, uintptr_t bufHandle, uint8_t *bufStart, uint32_t dataLen)
{
    return FinalizePacketBuffer(writer, bufHandle, bufStart, dataLen);
}
#endif // INET_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES

/**
 * Provides a unified Reader/Writer interface for editing/adding/deleting elements in TLV encoding.
 *
 * The TLVUpdater is a union of the TLVReader and TLVWriter objects and provides interface methods
 * for editing/deleting data in an encoding as well as adding new elements to the TLV encoding. The
 * TLVUpdater object essentially acts like two cursors, one for reading existing encoding and
 * another for writing (either for copying over existing data or writing new data).
 *
 * Semantically, the TLVUpdater object functions like a union of the TLVReader and TLVWriter. The
 * TLVUpdater methods have more or less similar meanings as similarly named counterparts in
 * TLVReader/TLVWriter. Where there are differences in the semantics, the differences are clearly
 * documented in the function's comment section in WeaveTLVUpdater.cpp.
 *
 * One particularly important note about the TLVUpdater's PutBytes() and PutString() methods is that
 * it can leave the encoding in a corrupt state with only the element header written when an
 * overflow occurs. Applications can call GetRemainingFreeLength() to make sure there is
 * @em approximately enough free space to write the encoding. Note that GetRemainingFreeLength()
 * only tells you the available free bytes and there is @em no way for the application to know the
 * length of encoded data that gets written. In the event of an overflow, both PutBytes() and
 * PutString() will return WEAVE_ERROR_BUFFER_TOO_SMALL to the caller.
 *
 * Also, note that Next() method is overloaded to both skip the current element and also advance the
 * internal reader to the next element. Because skipping already encoded elements requires changing
 * the internal writer's free space state variables to account for the new freed space (made
 * available by skipping), the application is expected to call Next() on the updater after a Get()
 * method whose value it doesn't wish to write back (which is equivalent to skipping the current
 * element).
 *
 * @note The application is expected to use the TLVUpdater object atomically from the time it calls
 * Init() till it calls Finalize(). The same buffer should NOT be used with other TLVWriter objects.
 *
 * @note The TLVUpdater currently only supports single static buffers. Support for chain of buffers
 * (PacketBuffer) is NOT supported.
 */
class NL_DLL_EXPORT TLVUpdater
{
public:
    WEAVE_ERROR Init(uint8_t *buf, uint32_t dataLen, uint32_t maxLen);
    WEAVE_ERROR Init(TLVReader& aReader, uint32_t freeLen);
    WEAVE_ERROR Finalize(void) { return mUpdaterWriter.Finalize(); }

    // Common methods
    void SetImplicitProfileId(uint32_t profileId);
    uint32_t GetImplicitProfileId(void) { return mUpdaterReader.ImplicitProfileId; }
    WEAVE_ERROR Move(void);
    void MoveUntilEnd(void);
    WEAVE_ERROR EnterContainer(TLVType& outerContainerType);
    WEAVE_ERROR ExitContainer(TLVType outerContainerType);
    void GetReader(TLVReader& containerReader) { containerReader = mUpdaterReader; }

    // Reader methods
    WEAVE_ERROR Next(void);

    WEAVE_ERROR Get(bool& v) { return mUpdaterReader.Get(v); }
    WEAVE_ERROR Get(int8_t& v) { return mUpdaterReader.Get(v); }
    WEAVE_ERROR Get(int16_t& v) { return mUpdaterReader.Get(v); }
    WEAVE_ERROR Get(int32_t& v) { return mUpdaterReader.Get(v); }
    WEAVE_ERROR Get(int64_t& v) { return mUpdaterReader.Get(v); }
    WEAVE_ERROR Get(uint8_t& v) { return mUpdaterReader.Get(v); }
    WEAVE_ERROR Get(uint16_t& v) { return mUpdaterReader.Get(v); }
    WEAVE_ERROR Get(uint32_t& v) { return mUpdaterReader.Get(v); }
    WEAVE_ERROR Get(uint64_t& v) { return mUpdaterReader.Get(v); }
    WEAVE_ERROR Get(float& v) { return mUpdaterReader.Get(v); }
    WEAVE_ERROR Get(double& v) { return mUpdaterReader.Get(v); }
    WEAVE_ERROR GetBytes(uint8_t *buf, uint32_t bufSize) { return mUpdaterReader.GetBytes(buf, bufSize); }
    WEAVE_ERROR DupBytes(uint8_t *& buf, uint32_t& dataLen) { return mUpdaterReader.DupBytes(buf, dataLen); }
    WEAVE_ERROR GetString(char *buf, uint32_t bufSize) { return mUpdaterReader.GetString(buf, bufSize); }
    WEAVE_ERROR DupString(char *& buf) { return mUpdaterReader.DupString(buf); }

    TLVType GetType(void) const { return mUpdaterReader.GetType(); }
    uint64_t GetTag(void) const { return mUpdaterReader.GetTag(); }
    uint32_t GetLength(void) const { return mUpdaterReader.GetLength(); }
    WEAVE_ERROR GetDataPtr(const uint8_t *& data) { return mUpdaterReader.GetDataPtr(data); }
    WEAVE_ERROR VerifyEndOfContainer(void) { return mUpdaterReader.VerifyEndOfContainer(); }
    TLVType GetContainerType(void) const { return mUpdaterReader.GetContainerType(); }
    uint32_t GetLengthRead(void) const { return mUpdaterReader.GetLengthRead(); }
    uint32_t GetRemainingLength(void) const { return mUpdaterReader.GetRemainingLength(); }

    // Writer methods
    WEAVE_ERROR Put(uint64_t tag, int8_t v) { return mUpdaterWriter.Put(tag, v); }
    WEAVE_ERROR Put(uint64_t tag, int16_t v) { return mUpdaterWriter.Put(tag, v); }
    WEAVE_ERROR Put(uint64_t tag, int32_t v) { return mUpdaterWriter.Put(tag, v); }
    WEAVE_ERROR Put(uint64_t tag, int64_t v) { return mUpdaterWriter.Put(tag, v); }
    WEAVE_ERROR Put(uint64_t tag, uint8_t v) { return mUpdaterWriter.Put(tag, v); }
    WEAVE_ERROR Put(uint64_t tag, uint16_t v) { return mUpdaterWriter.Put(tag, v); }
    WEAVE_ERROR Put(uint64_t tag, uint32_t v) { return mUpdaterWriter.Put(tag, v); }
    WEAVE_ERROR Put(uint64_t tag, uint64_t v) { return mUpdaterWriter.Put(tag, v); }
    WEAVE_ERROR Put(uint64_t tag, int8_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); }
    WEAVE_ERROR Put(uint64_t tag, int16_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); }
    WEAVE_ERROR Put(uint64_t tag, int32_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); }
    WEAVE_ERROR Put(uint64_t tag, int64_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); }
    WEAVE_ERROR Put(uint64_t tag, uint8_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); }
    WEAVE_ERROR Put(uint64_t tag, uint16_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); }
    WEAVE_ERROR Put(uint64_t tag, uint32_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); }
    WEAVE_ERROR Put(uint64_t tag, uint64_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); }
    WEAVE_ERROR Put(uint64_t tag, float v) { return mUpdaterWriter.Put(tag, v); }
    WEAVE_ERROR Put(uint64_t tag, double v) { return mUpdaterWriter.Put(tag, v); }
    WEAVE_ERROR PutBoolean(uint64_t tag, bool v) { return mUpdaterWriter.PutBoolean(tag, v); }
    WEAVE_ERROR PutNull(uint64_t tag) { return mUpdaterWriter.PutNull(tag); }
    WEAVE_ERROR PutBytes(uint64_t tag, const uint8_t *buf, uint32_t len) { return mUpdaterWriter.PutBytes(tag, buf, len); }
    WEAVE_ERROR PutString(uint64_t tag, const char *buf) { return mUpdaterWriter.PutString(tag, buf); }
    WEAVE_ERROR PutString(uint64_t tag, const char *buf, uint32_t len) { return mUpdaterWriter.PutString(tag, buf, len); }
    WEAVE_ERROR CopyElement(TLVReader& reader) { return mUpdaterWriter.CopyElement(reader); }
    WEAVE_ERROR CopyElement(uint64_t tag, TLVReader& reader) { return mUpdaterWriter.CopyElement(tag, reader); }
    WEAVE_ERROR StartContainer(uint64_t tag, TLVType containerType, TLVType& outerContainerType) { return mUpdaterWriter.StartContainer(tag, containerType, outerContainerType); }
    WEAVE_ERROR EndContainer(TLVType outerContainerType) { return mUpdaterWriter.EndContainer(outerContainerType); }
    uint32_t GetLengthWritten(void) { return mUpdaterWriter.GetLengthWritten(); }
    uint32_t GetRemainingFreeLength(void) { return mUpdaterWriter.mRemainingLen; }

private:
    void AdjustInternalWriterFreeSpace(void);

private:
    TLVWriter       mUpdaterWriter;
    TLVReader       mUpdaterReader;
    const uint8_t * mElementStartAddr;
};

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

#endif /* WEAVETLV_H_ */
