nl::Weave::TLV::TLVUpdater

#include <src/lib/core/WeaveTLV.h>

Provides a unified Reader/Writer interface for editing/adding/deleting elements in TLV encoding.

Summary

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 approximately enough free space to write the encoding. Note that GetRemainingFreeLength() only tells you the available free bytes and there is 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).

Public functions

CopyElement(TLVReader & reader)
CopyElement(uint64_t tag, TLVReader & reader)
DupBytes(uint8_t *& buf, uint32_t & dataLen)
DupString(char *& buf)
EndContainer(TLVType outerContainerType)
EnterContainer(TLVType & outerContainerType)
Prepares a TLVUpdater object for reading elements of a container.
ExitContainer(TLVType outerContainerType)
Completes the reading of a TLV container element and encodes an end of TLV element in the output TLV.
Finalize(void)
Get(bool & v)
Get(int8_t & v)
Get(int16_t & v)
Get(int32_t & v)
Get(int64_t & v)
Get(uint8_t & v)
Get(uint16_t & v)
Get(uint32_t & v)
Get(uint64_t & v)
Get(float & v)
Get(double & v)
GetBytes(uint8_t *buf, uint32_t bufSize)
GetContainerType(void) const
GetDataPtr(const uint8_t *& data)
GetImplicitProfileId(void)
uint32_t
GetLength(void) const
uint32_t
GetLengthRead(void) const
uint32_t
GetLengthWritten(void)
uint32_t
GetReader(TLVReader & containerReader)
void
GetRemainingFreeLength(void)
uint32_t
GetRemainingLength(void) const
uint32_t
GetString(char *buf, uint32_t bufSize)
GetTag(void) const
uint64_t
GetType(void) const
Init(uint8_t *buf, uint32_t dataLen, uint32_t maxLen)
Initialize a TLVUpdater object to edit a single input buffer.
Init(TLVReader & aReader, uint32_t freeLen)
Initialize a TLVUpdater object using a TLVReader.
Move(void)
Copies the current element from input TLV to output TLV.
MoveUntilEnd(void)
void
Move everything from the TLVUpdater's current read point till end of input TLV buffer over to output.
Next(void)
Skip the current element and advance the TLVUpdater object to the next element in the input TLV.
Put(uint64_t tag, int8_t v)
Put(uint64_t tag, int16_t v)
Put(uint64_t tag, int32_t v)
Put(uint64_t tag, int64_t v)
Put(uint64_t tag, uint8_t v)
Put(uint64_t tag, uint16_t v)
Put(uint64_t tag, uint32_t v)
Put(uint64_t tag, uint64_t v)
Put(uint64_t tag, int8_t v, bool preserveSize)
Put(uint64_t tag, int16_t v, bool preserveSize)
Put(uint64_t tag, int32_t v, bool preserveSize)
Put(uint64_t tag, int64_t v, bool preserveSize)
Put(uint64_t tag, uint8_t v, bool preserveSize)
Put(uint64_t tag, uint16_t v, bool preserveSize)
Put(uint64_t tag, uint32_t v, bool preserveSize)
Put(uint64_t tag, uint64_t v, bool preserveSize)
Put(uint64_t tag, float v)
Put(uint64_t tag, double v)
PutBoolean(uint64_t tag, bool v)
PutBytes(uint64_t tag, const uint8_t *buf, uint32_t len)
PutNull(uint64_t tag)
PutString(uint64_t tag, const char *buf)
PutString(uint64_t tag, const char *buf, uint32_t len)
SetImplicitProfileId(uint32_t profileId)
void
Set the Implicit Profile ID for the TLVUpdater object.
StartContainer(uint64_t tag, TLVType containerType, TLVType & outerContainerType)
VerifyEndOfContainer(void)

Public functions

CopyElement

WEAVE_ERROR CopyElement(
  TLVReader & reader
)

CopyElement

WEAVE_ERROR CopyElement(
  uint64_t tag,
  TLVReader & reader
)

DupBytes

WEAVE_ERROR DupBytes(
  uint8_t *& buf,
  uint32_t & dataLen
)

DupString

WEAVE_ERROR DupString(
  char *& buf
)

EndContainer

WEAVE_ERROR EndContainer(
  TLVType outerContainerType
)

EnterContainer

WEAVE_ERROR EnterContainer(
  TLVType & outerContainerType
)

Prepares a TLVUpdater object for reading elements of a container.

It also encodes a start of container object in the output TLV.

The EnterContainer() method prepares the current TLVUpdater 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 TLVUpdater's reader must be positioned on the container element. The method takes as an argument a reference to a TLVType value which will be used to save the context of the updater while it is reading the container.

When the EnterContainer() method returns, the updater is positioned immediately before the first member of the container. Repeatedly calling Next() will advance the updater through the members of the collection until the end is reached, at which point the updater 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.

Details
Parameters
[out] outerContainerType
A reference to a TLVType value that will receive the context of the updater.
Return Values
WEAVE_NO_ERROR
If the method succeeded.
WEAVE_ERROR_INCORRECT_STATE
If the TLVUpdater reader is not positioned on a container element.
other
Any other Weave or platform error code returned by TLVWriter::StartContainer() or TLVReader::EnterContainer().

ExitContainer

WEAVE_ERROR ExitContainer(
  TLVType outerContainerType
)

Completes the reading of a TLV container element and encodes an end of TLV element in the output TLV.

The ExitContainer() method restores the state of a TLVUpdater 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 TLVUpdater reader is positioned immediately before the first element that follows the container in the input TLV. From this point applications can call Next() to advance through any remaining elements.

Once EnterContainer() has been called, applications can call ExitContainer() on the updater at any point in time, regardless of whether all elements in the underlying container have been read. Also, note that calling ExitContainer() before reading all the elements in the container, will result in the updated container getting truncated in the output TLV.

Details
Parameters
[in] outerContainerType
The TLVType value that was returned by the EnterContainer() method.
Return Values
WEAVE_NO_ERROR
If the method succeeded.
WEAVE_ERROR_TLV_UNDERRUN
If the underlying TLV encoding ended prematurely.
WEAVE_ERROR_INVALID_TLV_ELEMENT
If the updater encountered an invalid or unsupported TLV element type.
WEAVE_ERROR_INVALID_TLV_TAG
If the updater encountered a TLV tag in an invalid context.
other
Any other Weave or platform error code returned by TLVWriter::EndContainer() or TLVReader::ExitContainer().

Finalize

WEAVE_ERROR Finalize(
  void
)

Get

WEAVE_ERROR Get(
  bool & v
)

Get

WEAVE_ERROR Get(
  int8_t & v
)

Get

WEAVE_ERROR Get(
  int16_t & v
)

Get

WEAVE_ERROR Get(
  int32_t & v
)

Get

WEAVE_ERROR Get(
  int64_t & v
)

Get

WEAVE_ERROR Get(
  uint8_t & v
)

Get

WEAVE_ERROR Get(
  uint16_t & v
)

Get

WEAVE_ERROR Get(
  uint32_t & v
)

Get

WEAVE_ERROR Get(
  uint64_t & v
)

Get

WEAVE_ERROR Get(
  float & v
)

Get

WEAVE_ERROR Get(
  double & v
)

GetBytes

WEAVE_ERROR GetBytes(
  uint8_t *buf,
  uint32_t bufSize
)

GetContainerType

TLVType GetContainerType(
  void
) const 

GetDataPtr

WEAVE_ERROR GetDataPtr(
  const uint8_t *& data
)

GetImplicitProfileId

uint32_t GetImplicitProfileId(
  void
)

GetLength

uint32_t GetLength(
  void
) const 

GetLengthRead

uint32_t GetLengthRead(
  void
) const 

GetLengthWritten

uint32_t GetLengthWritten(
  void
)

GetReader

void GetReader(
  TLVReader & containerReader
)

GetRemainingFreeLength

uint32_t GetRemainingFreeLength(
  void
)

GetRemainingLength

uint32_t GetRemainingLength(
  void
) const 

GetString

WEAVE_ERROR GetString(
  char *buf,
  uint32_t bufSize
)

GetTag

uint64_t GetTag(
  void
) const 

GetType

TLVType GetType(
  void
) const 

Init

WEAVE_ERROR Init(
  uint8_t *buf,
  uint32_t dataLen,
  uint32_t maxLen
)

Initialize a TLVUpdater object to edit a single input buffer.

On calling this method, the TLV data in the buffer is moved to the end of the buffer and a private TLVReader object is initialized on this relocated buffer. A private TLVWriter object is also initialized on the free space that is now available at the beginning. Applications can use the TLVUpdater object to parse the TLV data and modify/delete existing elements or add new elements to the encoding.

Details
Parameters
[in] buf
A pointer to a buffer containing the TLV data to be edited.
[in] dataLen
The length of the TLV data in the buffer.
[in] maxLen
The total length of the buffer.
Return Values
WEAVE_NO_ERROR
If the method succeeded.
WEAVE_ERROR_INVALID_ARGUMENT
If the buffer address is invalid.
WEAVE_ERROR_BUFFER_TOO_SMALL
If the buffer is too small.

Init

WEAVE_ERROR Init(
  TLVReader & aReader,
  uint32_t freeLen
)

Initialize a TLVUpdater object using a TLVReader.

On calling this method, TLV data in the buffer pointed to by the TLVReader is moved from the current read point to the end of the buffer. A new private TLVReader object is initialized to read from this new location, while a new private TLVWriter object is initialized to write to the freed up buffer space.

Note that if the TLVReader is already positioned "on" an element, it is first backed-off to the start of that element. Also note that this backing off works well with container elements, i.e., if the TLVReader was already used to call EnterContainer(), then there is nothing to back-off. But if the TLVReader was positioned on the container element and EnterContainer() was not yet called, then the TLVReader object is backed-off to the start of the container head.

The input TLVReader object will be destroyed before returning and the application must not make use of the same on return.

Details
Parameters
[in,out] aReader
Reference to a TLVReader object that will be destroyed before returning.
[in] freeLen
The length of free space (in bytes) available in the pre-encoded data buffer.
Return Values
WEAVE_NO_ERROR
If the method succeeded.
WEAVE_ERROR_INVALID_ARGUMENT
If the buffer address is invalid.
WEAVE_ERROR_NOT_IMPLEMENTED
If reader was initialized on a chain of buffers.

Move

WEAVE_ERROR Move(
  void
)

Copies the current element from input TLV to output TLV.

The Move() method copies the current element on which the TLVUpdater's reader is positioned on, to the TLVUpdater's writer. The application should call Next() and position the TLVUpdater's reader on an element before calling this method. Just like the TLVReader::Next() method, if the reader is positioned on a container element at the time of the call, all the members of the container will be copied. If the reader is not positioned on any element, nothing changes on calling this method.

Details
Return Values
WEAVE_NO_ERROR
If the TLVUpdater reader was successfully positioned on a new element.
WEAVE_END_OF_TLV
If the TLVUpdater's reader is pointing to end of container.
WEAVE_ERROR_INVALID_TLV_ELEMENT
If the TLVIpdater's reader is not positioned on a valid TLV element.
other
Returns other error codes returned by TLVReader::Skip() method.

MoveUntilEnd

void MoveUntilEnd(
  void
)

Move everything from the TLVUpdater's current read point till end of input TLV buffer over to output.

This method supports moving everything from the TLVUpdater's current read point till the end of the reader buffer over to the TLVUpdater's writer.

Next

WEAVE_ERROR Next(
  void
)

Skip the current element and advance the TLVUpdater object to the next element in the input TLV.

The Next() method skips the current element in the input TLV and advances the TLVUpdater's reader to the next element 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 it 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 it 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 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.

Details
Return Values
WEAVE_NO_ERROR
If the TLVUpdater reader was successfully positioned on a new element.
other
Returns the Weave or platform error codes returned by the TLVReader::Skip() and TLVReader::Next() method.

Put

WEAVE_ERROR Put(
  uint64_t tag,
  int8_t v
)

Put

WEAVE_ERROR Put(
  uint64_t tag,
  int16_t v
)

Put

WEAVE_ERROR Put(
  uint64_t tag,
  int32_t v
)

Put

WEAVE_ERROR Put(
  uint64_t tag,
  int64_t v
)

Put

WEAVE_ERROR Put(
  uint64_t tag,
  uint8_t v
)

Put

WEAVE_ERROR Put(
  uint64_t tag,
  uint16_t v
)

Put

WEAVE_ERROR Put(
  uint64_t tag,
  uint32_t v
)

Put

WEAVE_ERROR Put(
  uint64_t tag,
  uint64_t v
)

Put

WEAVE_ERROR Put(
  uint64_t tag,
  int8_t v,
  bool preserveSize
)

Put

WEAVE_ERROR Put(
  uint64_t tag,
  int16_t v,
  bool preserveSize
)

Put

WEAVE_ERROR Put(
  uint64_t tag,
  int32_t v,
  bool preserveSize
)

Put

WEAVE_ERROR Put(
  uint64_t tag,
  int64_t v,
  bool preserveSize
)

Put

WEAVE_ERROR Put(
  uint64_t tag,
  uint8_t v,
  bool preserveSize
)

Put

WEAVE_ERROR Put(
  uint64_t tag,
  uint16_t v,
  bool preserveSize
)

Put

WEAVE_ERROR Put(
  uint64_t tag,
  uint32_t v,
  bool preserveSize
)

Put

WEAVE_ERROR Put(
  uint64_t tag,
  uint64_t v,
  bool preserveSize
)

Put

WEAVE_ERROR Put(
  uint64_t tag,
  float v
)

Put

WEAVE_ERROR Put(
  uint64_t tag,
  double v
)

PutBoolean

WEAVE_ERROR PutBoolean(
  uint64_t tag,
  bool v
)

PutBytes

WEAVE_ERROR PutBytes(
  uint64_t tag,
  const uint8_t *buf,
  uint32_t len
)

PutNull

WEAVE_ERROR PutNull(
  uint64_t tag
)

PutString

WEAVE_ERROR PutString(
  uint64_t tag,
  const char *buf
)

PutString

WEAVE_ERROR PutString(
  uint64_t tag,
  const char *buf,
  uint32_t len
)

SetImplicitProfileId

void SetImplicitProfileId(
  uint32_t profileId
)

Set the Implicit Profile ID for the TLVUpdater object.

This method sets the implicit profile ID for the TLVUpdater object. When the updater is asked to encode a new element, if the profile ID of the tag associated with the new element matches the value of the profileId, the updater will encode the tag in implicit form, thereby omitting the profile ID in the process.

Details
Parameters
[in] profileId
The profile id of tags that should be encoded in implicit form.

StartContainer

WEAVE_ERROR StartContainer(
  uint64_t tag,
  TLVType containerType,
  TLVType & outerContainerType
)

VerifyEndOfContainer

WEAVE_ERROR VerifyEndOfContainer(
  void
)