nl:: 编织: 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 馈送输入数据。调用后,该函数应生成额外的数据供读取者解析或告知读取者没有更多可用数据。
详情 | |||||||||
---|---|---|---|---|---|---|---|---|---|
参数 |
|
||||||||
返回值 |
|
公共属性
应用数据
void * AppData
可用于应用专用数据的指针字段。
GetNextBuffer
GetNextBufferFunct GetNextBuffer
指向将为 TLVReader 对象生成输入数据的函数的指针。
如果设置为 NULL(默认值),读取器会假定没有其他输入数据可用。
应用可以随时设置 GetNextBuffer,但通常在读取器初始化时进行设置。
如需详细了解如何实现 GetNextBuffer 函数,请参阅 GetNextBufferFunct 类型定义。
隐式配置文件 ID
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
马克斯·伦
uint32_t mMaxLen
mReadPoint
const uint8_t * mReadPoint
公共函数
关闭容器
WEAVE_ERROR CloseContainer( TLVReader & containerReader )
在调用 OpenContainer() 后完成 TLV 容器的读取。
CloseContainer() 方法会在调用 OpenContainer() 后恢复父级 TLVReader 对象的状态。每次调用 OpenContainer() 时,应用都必须对 CloseContainer() 进行相应的调用,将对同一容器读取器的引用传递给这两种方法。
当 CloseContainer() 返回时,父阅读器将紧跟在容器后的第一个元素之前。从此时起,应用可以使用 Next() 方法遍历所有剩余元素。
无论底层容器中的所有元素是否已读取,应用都可以随时在父阅读器上调用关闭 CloseContainer()。调用 CloseContainer() 后,应用应考虑容器读取器 (de#-initialized),并且不得在未重新初始化的情况下再使用容器读取器。
详情 | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
参数 |
|
||||||||||||
返回值 |
|
杜比字节
WEAVE_ERROR DupBytes( uint8_t *& buf, uint32_t & dataLen )
分配并返回包含当前字节或 UTF8 字符串值的缓冲区。
此方法会为 创建缓冲区,并返回与当前位置上的字节或 UTF-8 字符串元素相关联的数据副本。该缓冲区的内存是通过 malloc() 获取的,并且在不再需要时应由调用方使用 free() 释放。
详情 | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
参数 |
|
||||||||||||
返回值 |
|
重复字符串
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 值的引用,TLVType 值用于在读取容器时保存读取器的上下文。
返回 EnterContainer() 方法后,读取器会紧跟在容器第一个成员之前的位置。重复调用 Next() 会让读取器遍历集合成员,直到到达末尾,最终返回 WEAVE_END_OF_TLV。
当应用读取完容器后,它可以通过调用 ExitContainer() 方法继续读取容器之后的元素。
详情 | |||||
---|---|---|---|---|---|
参数 |
|
||||
返回值 |
|
退出容器
WEAVE_ERROR ExitContainer( TLVType outerContainerType )
完成 TLV 容器的读取,并准备 TLVReader 对象以读取容器之后的元素。
调用 EnterContainer() 后,ExitContainer() 方法会恢复 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()。输入缓冲区应至少比字符串长度多一个字节,以适应 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() 方法会将读取器对象放在位于同一封闭环境的 TLV 编码的下一个元素上。特别是,如果读取器位于 TLV 编码的最外层,调用 Next() 会让读取器前进到最靠上的元素。如果读取器位于 TLV 容器元素(结构、数组或路径)中,调用 Next() 会将读取器前进到容器中的下一个成员元素。
由于 Next() 将读取器动作限制为当前的包含上下文,因此在将读取器置于容器元素上时调用 Next() 会使容器向前移动,跳过其成员元素(以及任何嵌套容器的成员),直到到达容器后的第一个元素为止。
当特定包含上下文中没有其他元素时,Next() 方法将返回 WEAVE_END_OF_TLV 错误,读取器的位置将保持不变。
详情 | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
返回值 |
|
下一步
WEAVE_ERROR Next( TLVType expectedType, uint64_t expectedTag )
将 TLVReader 对象前进到要读取的下一个 TLV 元素,并声明新元素的类型和标记。
Next(TLVType expectedType, uint64_t expectedTag) 方法是一种与 Next() 行为相同的便捷方法,也会验证新 TLV 元素的类型和标记是否与提供的参数匹配。
详情 | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
参数 |
|
||||||||||||||||
返回值 |
|
OpenContainer
WEAVE_ERROR OpenContainer( TLVReader & containerReader )
初始化用于读取 TLV 容器元素成员的新 TLVReader 对象。
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() 一样,如果读取器在调用时位于容器元素上,则系统会跳过容器的成员。如果读取器不在任何元素上,则其位置保持不变。
详情 | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
返回值 |
|
验证容器结束状态
WEAVE_ERROR VerifyEndOfContainer( void )
验证 TVLReader 对象是否位于 TLV 容器的末尾。
VerifyEndOfContainer() 方法可验证当前 TLV 容器中没有要读取的其他 TLV 元素。这种便捷方法相当于调用 Next() 并检查返回值 WEAVE_END_OF_TLV。
详情 | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
返回值 |
|
受保护的函数
ElementType
TLVElementType ElementType( void ) const
这是一个私有方法,用于从 mControlByte 返回 TLVElementType。
确保数据
WEAVE_ERROR EnsureData( WEAVE_ERROR noDataErr )
GetElementHeadLength
WEAVE_ERROR GetElementHeadLength( uint8_t & elemHeadBytes ) const
这是一个私有方法,用于计算 TLV 元素头的长度。
IsContainerOpen
bool IsContainerOpen( void ) const
读取数据
WEAVE_ERROR ReadData( uint8_t *buf, uint32_t len )
读取元素
WEAVE_ERROR ReadElement( void )
读取标记
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 )
验证元素
WEAVE_ERROR VerifyElement( void )
受保护的静态函数
FailureGetNextBuffer
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 )