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 对象,以从一个或多个 PacketBuffers 读取数据。
|
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 进行解码时,应用必须先设置 ImplicitProfileId
,然后才能读取具有此类标记的 TLV 元素。TLV合适的个人资料 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() 后,应用应将容器读取器视为“de-initialized”并且不得在未重新初始化它的情况下进一步使用它。
详细信息 | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
参数 |
|
||||||||||||
返回值 |
|
DupBytes
WEAVE_ERROR DupBytes( uint8_t *& buf, uint32_t & dataLen )
分配并返回包含当前字节或 UTF8 字符串值的缓冲区。
该方法会为与当前位置的 byte 或 UTF-8 字符串元素关联的数据创建缓冲区,并传回数据副本。缓冲区的内存通过 malloc() 获取,并且当不再需要时应由调用方通过 free() 释放。
详细信息 | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
参数 |
|
||||||||||||
返回值 |
|
DupString
WEAVE_ERROR DupString( char *& buf )
分配并返回一个包含当前字节或 UTF8 字符串的以 null 结尾的值的缓冲区。
该方法会为与当前位置的字节或 UTF-8 字符串元素关联的数据创建缓冲区,并返回以 null 结尾的数据副本。缓冲区的内存通过 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 对象以读取容器之后的元素。
ExitContainer() 方法会在调用 EnterContainer() 后恢复 TLVReader 对象的状态。每次调用 EnterContainer() 时,应用都必须对 ExitContainer() 进行相应的调用,并传递 EnterContainer() 方法返回的上下文值。
当 ExitContainer() 返回时,读取器将被放置在容器之后的第一个元素之前,且紧邻该元素。从此时开始,应用可以使用 Next() 方法遍历所有剩余元素。
调用 EnterContainer() 后,应用可以随时对读取器调用 ExitContainer(),无论底层容器中的所有元素是否已读取。
详细信息 | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
参数 |
|
||||||||||||
返回值 |
|
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 )
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()。输入缓冲区应至少比字符串长度大一个字节,以容纳空字符。
详细信息 | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
参数 |
|
||||||||||
返回值 |
|
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 对象,以从一个或多个 PacketBuffers 读取数据。
从初始缓冲区的起始位置 (buf->DataStart()) 开始解析。如果 allowDiscontiguousBuffers 为 true,则读取器会前进到通过其 Next() 指针关联的缓冲区链。解析会一直持续,直到缓冲区链中的所有数据都被耗尽(用 buf->Datalen() 表示)或 maxLen 字节完成解析。
详细信息 | |||||||
---|---|---|---|---|---|---|---|
参数 |
|
下一步
WEAVE_ERROR Next( void )
将 TLVReader 对象推进到要读取的下一个 TLV 元素。
Next() 方法将读取器对象放置在位于同一包含上下文的 TLV 编码中的下一个元素上。特别是,如果读取器位于 TLV 编码的最外层,调用 Next() 会将读取器前进到下一个最顶层的元素。如果读取器位于 TLV 容器元素(结构、数组或路径)内,调用 Next() 会将读取器前进到容器的下一个成员元素。
由于 Next() 将读取器的动作限制在当前的包含上下文内,因此,当读取器位于容器元素上时,调用 Next() 会使读取器移到容器之上,并跳过其成员元素(以及任何嵌套容器的成员),直到它到达容器之后的第一个元素。
当特定包含内容上下文中没有其他元素时,Next() 方法将返回 WEAVE_END_OF_TLV 错误,并且 Reader 的位置将保持不变。
详细信息 | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
返回值 |
|
下一步
WEAVE_ERROR Next( TLVType expectedType, uint64_t expectedTag )
将 TLVReader 对象推进到要读取的下一个 TLV 元素,并断言新元素的类型和标记。
Next(TLVType expectedType, uint64_t expectedTag) 方法是一种便捷方法,它的行为与 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 )
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 )