nl:: Weave:: TLV:: TLVReader
#include <src/lib/core/WeaveTLV.h>
为以 Weave TLV 格式编码的数据提供内存高效的解析器。
摘要
TLVReader 为 Weave TLV 数据实现了仅限前向的“拉取式”解析器。TLVReader 对象作为光标运行,可用于遍历一系列 TLV 元素并解读其内容。当位于某个元素上时,应用可调用读取器的 Get() 方法,以查询当前元素的类型和标记,并提取任何关联值。读取器的 Next() 方法用于从一个元素前进到另一个元素。
TLVReader 对象始终位于 TLV 元素的前面、上方或后面。首次初始化时,TLVReader 会紧挨着编码的第一个元素之前。如需开始读取,应用必须对 Next() 方法进行初始调用,以将读取器放置在第一个元素上。当容器元素遇到结构、数组或路径时,可以使用 OpenContainer() 或 EnterContainer() 方法遍历容器的内容。
当读取器到达 TLV 编码的结尾或容器内的最后一个元素时,它会从 Next() 方法返回 WEAVE_END_OF_TLV 错误,向应用发出信号。读取器将继续返回 WEAVE_END_OF_TLV,直到其重新初始化或退出当前容器(通过 CloseContainer() / ExitContainer())。
TLVReader 对象可以直接解析固定输入缓冲区中的数据,也可以解析由一个或多个 PacketBuffer 组成的链中的数据。此外,应用可以提供 GetNextBuffer
函数,将任意来源(例如套接字或串行端口)的数据馈送到读取器。
继承
已知直接子类:nl::Weave::Profiles::DataManagement_Current::CircularEventReader
nl::Weave::TLV::CircularTLVReader
公共类型 |
|
---|---|
GetNextBufferFunct)(TLVReader &reader, uintptr_t &bufHandle, const uint8_t *&bufStart, uint32_t &bufLen)
|
WEAVE_ERROR(* 一个函数,可用于检索要解析的其他 TLV 数据。 |
公共属性 |
|
---|---|
AppData
|
void *
可用于应用特定数据的指针字段。
|
GetNextBuffer
|
指向将为 TLVReader 对象生成输入数据的函数的指针。
|
ImplicitProfileId
|
uint32_t
用于以隐式形式编码的配置文件标记的配置文件 ID。
|
受保护的属性 |
|
---|---|
mBufEnd
|
const uint8_t *
|
mBufHandle
|
uintptr_t
|
mContainerType
|
|
mControlByte
|
uint16_t
|
mElemLenOrVal
|
uint64_t
|
mElemTag
|
uint64_t
|
mLenRead
|
uint32_t
|
mMaxLen
|
uint32_t
|
mReadPoint
|
const uint8_t *
|
公共函数 |
|
---|---|
CloseContainer(TLVReader & containerReader)
|
调用 OpenContainer() 后,完成对 TLV 容器的读取。
|
DupBytes(uint8_t *& buf, uint32_t & dataLen)
|
分配并返回包含当前字节或 UTF8 字符串值的缓冲区。
|
DupString(char *& buf)
|
分配并返回缓冲区,其中包含当前字节或 UTF8 字符串的以 null 结尾的值。
|
EnterContainer(TLVType & outerContainerType)
|
|
ExitContainer(TLVType outerContainerType)
|
|
Get(bool & v)
|
获取当前元素的值(布尔值类型)。
|
Get(int8_t & v)
|
获取当前元素的值(8 位有符号整数)。
|
Get(int16_t & v)
|
获取当前元素的值(16 位带符号整数)。
|
Get(int32_t & v)
|
获取当前元素的值(32 位带符号整数)。
|
Get(int64_t & v)
|
获取当前元素的值(64 位有符号整数)。
|
Get(uint8_t & v)
|
获取当前元素的值(8 位无符号整数)。
|
Get(uint16_t & v)
|
获取当前元素的值(16 位无符号整数)。
|
Get(uint32_t & v)
|
获取当前元素的值(32 位无符号整数)。
|
Get(uint64_t & v)
|
获取当前元素的值(64 位无符号整数)。
|
Get(float & v)
|
|
Get(double & v)
|
获取当前元素的值(采用双精度浮点数)。
|
GetBufHandle(void) const
|
uintptr_t
|
GetBytes(uint8_t *buf, uint32_t bufSize)
|
获取当前字节或 UTF8 字符串元素的值。
|
GetContainerType(void) const
|
返回 TLVReader 当前从中读取数据的容器类型。
|
GetControlByte(void) const
|
uint16_t
返回与当前 TLV 元素关联的控制字节。
|
GetDataPtr(const uint8_t *& data)
|
获取指向 TLV 字节或 UTF8 字符串元素的初始编码字节的指针。
|
GetLength(void) const
|
uint32_t
返回与当前 TLV 元素关联的数据长度。
|
GetLengthRead(void) const
|
uint32_t
返回自读取器初始化以来读取的总字节数。
|
GetReadPoint(void) const
|
const uint8_t *
获取底层输入缓冲区中对应于读取器当前位置的点。
|
GetRemainingLength(void) const
|
uint32_t
返回在达到读取长度上限之前可以读取的总字节数。
|
GetString(char *buf, uint32_t bufSize)
|
获取当前字节或 UTF8 字符串元素的值(以 null 终止的字符串形式)。
|
GetTag(void) const
|
uint64_t
返回与当前 TLV 元素关联的代码。
|
GetType(void) const
|
返回当前 TLV 元素的类型。
|
Init(const TLVReader & aReader)
|
void
|
Init(const uint8_t *data, uint32_t dataLen)
|
void
初始化要从单个输入缓冲区读取数据的 TLVReader 对象。
|
Init(PacketBuffer *buf, uint32_t maxLen)
|
void
初始化 TLVReader 对象,以便从单个 PacketBuffer 中读取数据。
|
Init(PacketBuffer *buf, uint32_t maxLen, bool allowDiscontiguousBuffers)
|
void
初始化 TLVReader 对象,以从一个或多个 PacketBuffer 读取数据。
|
Next(void)
|
|
Next(TLVType expectedType, uint64_t expectedTag)
|
|
OpenContainer(TLVReader & containerReader)
|
|
Skip(void)
|
|
VerifyEndOfContainer(void)
|
验证 TVLReader 对象是否位于 TLV 容器的末尾。
|
受保护的函数 |
|
---|---|
ClearElementState(void)
|
void
清除 TLVReader 的状态。
|
ElementType(void) const
|
TLVElementType
这是一种从 mControlByte 返回 TLVElementType 的私有方法。
|
EnsureData(WEAVE_ERROR noDataErr)
|
|
GetElementHeadLength(uint8_t & elemHeadBytes) const
|
这是一种私有方法,用于计算 TLV 元素头部的长度。
|
IsContainerOpen(void) const
|
bool
|
ReadData(uint8_t *buf, uint32_t len)
|
|
ReadElement(void)
|
|
ReadTag(TLVTagControl tagControl, const uint8_t *& p)
|
uint64_t
|
SetContainerOpen(bool aContainerOpen)
|
void
|
SkipData(void)
|
在没有目标缓冲区的情况下读取当前 TLV 中包含的任何数据。
|
SkipToEndOfContainer(void)
|
|
VerifyElement(void)
|
受保护的静态函数 |
|
---|---|
FailGetNextBuffer(TLVReader & reader, uintptr_t & bufHandle, const uint8_t *& bufStart, uint32_t & bufLen)
|
|
GetNextPacketBuffer(TLVReader & reader, uintptr_t & bufHandle, const uint8_t *& bufStart, uint32_t & bufLen)
|
公共类型
GetNextBufferFunct
WEAVE_ERROR(* GetNextBufferFunct)(TLVReader &reader, uintptr_t &bufHandle, const uint8_t *&bufStart, uint32_t &bufLen)
一个函数,可用于检索要解析的其他 TLV 数据。
此类型的函数用于向 TLVReader 提供输入数据。被调用时,该函数应生成额外的数据供读取器解析,或向读取器发出信号以表明已没有更多数据。
具体说明 | |||||||||
---|---|---|---|---|---|---|---|---|---|
参数 |
|
||||||||
返回值 |
|
公共属性
AppData
void * AppData
可用于应用特定数据的指针字段。
GetNextBuffer
GetNextBufferFunct GetNextBuffer
指向将为 TLVReader 对象生成输入数据的函数的指针。
如果设置为 NULL(默认值),读取器将假定没有更多输入数据可用。
应用可以随时设置 GetNextBuffer,但一般是在初始化读取器时进行设置。
如需详细了解如何实现 GetNextBuffer 函数,请参阅 GetNextBufferFunct 类型定义。
ImplicitProfileId
uint32_t ImplicitProfileId
用于以隐式形式编码的配置文件标记的配置文件 ID。
当读取器遇到以隐式形式编码的配置文件专用标记时,它会使用 ImplicitProfileId
属性的值作为该标记的假定配置文件 ID。
默认情况下,ImplicitProfileId
属性设置为 kProfileIdNotSpecified。解码包含隐式编码标记的 TLV 时,应用必须在读取具有此类标记的 TLV 元素之前设置 ImplicitProfileId
。适当的配置文件 ID 通常取决于应用的上下文或所用协议的上下文。
如果在 ImplicitProfileId
设置为 kProfileIdNotSpecified 时遇到隐式编码标记,读取器将返回 WEAVE_ERROR_UNKNOWN_IMPLICIT_TLV_TAG 错误。
受保护的属性
mBufEnd
const uint8_t * mBufEnd
mBufHandle
uintptr_t mBufHandle
mContainerType
TLVType mContainerType
mControlByte
uint16_t mControlByte
mElemLenOrVal
uint64_t mElemLenOrVal
mElemTag
uint64_t mElemTag
mLenRead
uint32_t mLenRead
mMaxLen
uint32_t mMaxLen
mReadPoint
const uint8_t * mReadPoint
公共函数
CloseContainer
WEAVE_ERROR CloseContainer( TLVReader & containerReader )
调用 OpenContainer() 后,完成对 TLV 容器的读取。
调用 OpenContainer() 后,CloseContainer() 方法会恢复父 TLVReader 对象的状态。对于 OpenContainer() 的每次调用,应用都必须对 CloseContainer() 进行相应的调用,并将对同一容器读取器的引用传递给这两个方法。
当 CloseContainer() 返回时,父级读取器会紧挨着紧跟容器后面的第一个元素放置。从此时开始,应用可以使用 Next() 方法遍历所有剩余元素。
无论底层容器中的所有元素是否已读取,应用都可以随时对父级读取器调用关闭 CloseContainer()。调用 CloseContainer() 之后,应用应将容器读取器视为“已解除初始化”,并且不得在没有重新初始化的情况下继续使用它。
具体说明 | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
参数 |
|
||||||||||||
返回值 |
|
DupBytes
WEAVE_ERROR DupBytes( uint8_t *& buf, uint32_t & dataLen )
分配并返回包含当前字节或 UTF8 字符串值的缓冲区。
此方法为与当前位置的字节或 UTF-8 字符串元素相关联的数据创建缓冲区,并返回副本。缓冲区内存通过 malloc() 获取,当不再需要该缓冲区时,应由调用方使用 free() 将其释放。
具体说明 | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
参数 |
|
||||||||||||
返回值 |
|
DupString
WEAVE_ERROR DupString( char *& buf )
分配并返回缓冲区,其中包含当前字节或 UTF8 字符串的以 null 结尾的值。
此方法为与当前位置的字节或 UTF-8 字符串元素关联的数据创建以空字符结尾的副本,并返回以空字符结尾的副本。缓冲区内存通过 malloc() 获取,当不再需要该缓冲区时,应由调用方使用 free() 将其释放。
具体说明 | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
参数 |
|
||||||||||||
返回值 |
|
EnterContainer
WEAVE_ERROR EnterContainer( TLVType & outerContainerType )
准备 TLVReader 对象,以读取 TLV 容器元素的成员。
EnterContainer() 方法会准备当前的 TLVReader 对象,以便开始读取 TLV 容器的成员元素(结构、数组或路径)。每次调用 EnterContainer() 时,应用都必须对 ExitContainer() 进行相应的调用。
调用 EnterContainer() 时,TLVReader 对象必须放置在要读取的容器元素上。该方法将对 TLVType 值的引用作为参数,该值将用于在读取器读取容器时保存其上下文。
当 EnterContainer() 方法返回时,读取器将放置在容器的第一个成员之前且紧邻该元素的位置。重复调用 Next() 会使读取器遍历集合的所有成员,直到到达末尾,此时读取器将返回 WEAVE_END_OF_TLV。
应用完成对容器的读取后,可调用 ExitContainer() 方法,在容器之后继续读取元素。
具体说明 | |||||
---|---|---|---|---|---|
参数 |
|
||||
返回值 |
|
ExitContainer
WEAVE_ERROR ExitContainer( TLVType outerContainerType )
完成对 TLV 容器的读取,并准备 TLVReader 对象,以便在该容器之后读取元素。
调用 EnterContainer() 后,ExitContainer() 方法会恢复 TLVReader 对象的状态。每次调用 EnterContainer() 时,应用都必须对 ExitContainer() 进行相应的调用,并传递 EnterContainer() 方法返回的上下文值。
当 ExitContainer() 返回时,读取器将放置在紧接容器后面的第一个元素的前面。从此时开始,应用可以使用 Next() 方法遍历所有剩余元素。
调用 EnterContainer() 之后,无论底层容器中的所有元素是否已读取,应用都可以随时对读取器调用 ExitContainer()。
具体说明 | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
参数 |
|
||||||||||||
返回值 |
|
获取
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 )
GetBufHandle
uintptr_t GetBufHandle( void ) const
GetBytes
WEAVE_ERROR GetBytes( uint8_t *buf, uint32_t bufSize )
获取当前字节或 UTF8 字符串元素的值。
要确定所需的输入缓冲区空间,请先调用 GetLength() 方法,然后再调用 GetBytes()。
具体说明 | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
参数 |
|
||||||||||
返回值 |
|
GetContainerType
TLVType GetContainerType( void ) const
GetControlByte
uint16_t GetControlByte( void ) const
GetDataPtr
WEAVE_ERROR GetDataPtr( const uint8_t *& data )
获取指向 TLV 字节或 UTF8 字符串元素的初始编码字节的指针。
此方法会返回一个直接指针,该指针指向底层输入缓冲区中的编码字符串值。要成功,该方法要求整个字符串值都存在于单个缓冲区中。否则,该方法会返回 WEAVE_ERROR_TLV_UNDERRUN。这样,在从多个不连续的缓冲区读取数据时,该方法的使用就会受到限制。
具体说明 | |||||||||
---|---|---|---|---|---|---|---|---|---|
参数 |
|
||||||||
返回值 |
|
GetLength
uint32_t GetLength( void ) const
GetLengthRead
uint32_t GetLengthRead( void ) const
返回自读取器初始化以来读取的总字节数。
具体说明 | |
---|---|
返回值 |
自读取器初始化以来读取的总字节数。
|
GetReadPoint
const uint8_t * GetReadPoint( void ) const
获取底层输入缓冲区中对应于读取器当前位置的点。
具体说明 | |
---|---|
返回值 |
指向与读取器当前位置对应的底层输入缓冲区的指针。
|
GetRemainingLength
uint32_t GetRemainingLength( void ) const
返回在达到读取长度上限之前可以读取的总字节数。
具体说明 | |
---|---|
返回值 |
在达到读取长度上限之前可以读取的总字节数。
|
GetString
WEAVE_ERROR GetString( char *buf, uint32_t bufSize )
获取当前字节或 UTF8 字符串元素的值(以 null 终止的字符串形式)。
要确定所需的输入缓冲区大小,请先调用 GetLength() 方法,然后再调用 GetBytes()。输入缓冲区至少应比字符串长度大一个字节,才能容纳 null 字符。
具体说明 | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
参数 |
|
||||||||||
返回值 |
|
GetTag
uint64_t GetTag( void ) const
返回与当前 TLV 元素关联的代码。
GetTag() 返回的值可与标签实用函数(IsProfileTag()、IsContextTag()、ProfileIdFromTag() 等)结合使用,以便确定标签类型并提取各种标签字段值。
具体说明 | |
---|---|
返回值 |
一个无符号整数,包含与当前 TLV 元素关联的标记的相关信息。
|
GetType
TLVType GetType( void ) const
Init
void Init( const TLVReader & aReader )
Init
void Init( const uint8_t *data, uint32_t dataLen )
Init
void Init( PacketBuffer *buf, uint32_t maxLen )
Init
void Init( PacketBuffer *buf, uint32_t maxLen, bool allowDiscontiguousBuffers )
初始化 TLVReader 对象,以从一个或多个 PacketBuffer 读取数据。
解析从初始缓冲区的起始位置 (buf->DataStart()) 开始。如果 allowDiscontiguousBuffers 为 true,读取器将遍历由其 Next() 指针关联的缓冲区链。一直解析,直到缓冲区链中的所有数据都已使用(用 buf->Datalen() 表示),或 maxLen 字节已解析完成。
具体说明 | |||||||
---|---|---|---|---|---|---|---|
参数 |
|
下一个
WEAVE_ERROR Next( void )
将 TLVReader 对象前进到下一个要读取的 TLV 元素。
Next() 方法会将 Reader 对象放置在 TLV 编码中位于同一包含上下文的下一个元素上。特别是,如果读取器位于 TLV 编码的最外层,调用 Next() 会使读取器转到下一个最顶层的元素。如果读取器位于 TLV 容器元素(结构、数组或路径)内,调用 Next() 会使读取器转到容器的下一个成员元素。
由于 Next() 会将读者移动限制到当前的包含上下文,因此当读取器位于容器元素上时,调用 Next() 将跳过该容器,跳过该容器的成员元素(以及任何嵌套容器的成员),直到到达容器后的第一个元素。
当特定包含上下文中没有其他元素时,Next() 方法将返回 WEAVE_END_OF_TLV 错误,并且读取器的位置将保持不变。
具体说明 | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
返回值 |
|
下一个
WEAVE_ERROR Next( TLVType expectedType, uint64_t expectedTag )
将 TLVReader 对象推进到要读取的下一个 TLV 元素,并断言新元素的类型和标记。
Next(TLVTypeexpectedType, uint64_texpectedTag) 方法是一种便捷方法,其行为与 Next() 相同,但也会验证新 TLV 元素的类型和标记是否与所提供的参数匹配。
具体说明 | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
参数 |
|
||||||||||||||||
返回值 |
|
OpenContainer
WEAVE_ERROR OpenContainer( TLVReader & containerReader )
初始化新的 TLVReader 对象,用于读取 TLV 容器元素的成员。
OpenContainer() 方法会初始化一个新的 TLVReader 对象,用于读取 TLV 容器的成员元素(结构、数组或路径)。调用 OpenContainer() 时,必须将当前的 TLVReader 对象放置在要读取的容器元素上。该方法将对将被初始化为读取容器的新读取器的引用作为其唯一参数。此读取器称为“容器读取器”,而调用 OpenContainer() 的读取器称为“父级读取器”。
当 OpenContainer() 方法返回时,容器读取器会紧邻容器的第一个成员之前。对容器读取器调用 Next() 将遍历集合的各个成员,直到到达末尾,此时读取器将返回 WEAVE_END_OF_TLV。
当容器读取器处于打开状态时,应用不得调用或以其他方式更改父级读取器的状态。当应用使用完容器读取器后,应用必须通过对父级读取器调用 CloseContainer() 并传递容器读取器作为参数来将其关闭。应用可以随时关闭容器读取器,无论是否读取底层容器中的所有元素。容器读取器关闭后,应用可以继续使用父级读取器。
容器读取器会从父级读取器继承各种配置属性。它们是:
- 隐式个人资料 ID (ImplicitProfileId)
- 应用数据指针 (AppData)
- GetNextBuffer 函数指针
具体说明 | |||||
---|---|---|---|---|---|
参数 |
|
||||
返回值 |
|
跳过
WEAVE_ERROR Skip( void )
将 TLVReader 对象移到当前 TLV 元素之后,且紧邻该元素。
Skip() 方法将读取器对象放置在当前 TLV 元素之后紧跟着的位置,这样一来,在后续调用 Next() 时,读者便可以跳转到下一个元素。与 Next() 一样,如果读取器在调用时位于某个容器元素上,则会跳过该容器的成员。如果读取器未放置在任何元素上,则其位置将保持不变。
具体说明 | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
返回值 |
|
VerifyEndOfContainer
WEAVE_ERROR VerifyEndOfContainer( void )
验证 TVLReader 对象是否位于 TLV 容器的末尾。
VerifyEndOfContainer() 方法可验证当前 TLV 容器中没有其他 TLV 元素可供读取。该方法非常便捷,等同于调用 Next() 并检查返回值是否为 WEAVE_END_OF_TLV。
具体说明 | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
返回值 |
|
受保护的函数
ClearElementState
void ClearElementState( void )
ElementType
TLVElementType ElementType( void ) const
这是一种从 mControlByte 返回 TLVElementType 的私有方法。
EnsureData
WEAVE_ERROR EnsureData( WEAVE_ERROR noDataErr )
GetElementHeadLength
WEAVE_ERROR GetElementHeadLength( uint8_t & elemHeadBytes ) const
这是一种私有方法,用于计算 TLV 元素头部的长度。
IsContainerOpen
bool IsContainerOpen( void ) const
ReadData
WEAVE_ERROR ReadData( uint8_t *buf, uint32_t len )
ReadElement
WEAVE_ERROR ReadElement( void )
ReadTag
uint64_t ReadTag( TLVTagControl tagControl, const uint8_t *& p )
SetContainerOpen
void SetContainerOpen( bool aContainerOpen )
SkipData
WEAVE_ERROR SkipData( void )
在没有目标缓冲区的情况下读取当前 TLV 中包含的任何数据。
具体说明 | |||||
---|---|---|---|---|---|
返回值 |
|
SkipToEndOfContainer
WEAVE_ERROR SkipToEndOfContainer( void )
VerifyElement
WEAVE_ERROR VerifyElement( void )
受保护的静态函数
FailGetNextBuffer
WEAVE_ERROR FailGetNextBuffer( TLVReader & reader, uintptr_t & bufHandle, const uint8_t *& bufStart, uint32_t & bufLen )
GetNextPacketBuffer
WEAVE_ERROR GetNextPacketBuffer( TLVReader & reader, uintptr_t & bufHandle, const uint8_t *& bufStart, uint32_t & bufLen )