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 錯誤,以指示應用程式。除非持續重新啟動或結束目前的容器 (透過 CloseContainer() / ExitContainer()) 結束,否則讀取器會繼續傳回 WEAVE_END_OF_TLV。
TLVreader 物件可以直接從固定的輸入緩衝區,或從一或多個 PacketBuffers 鏈結剖析資料。此外,應用程式可提供 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 字串的空值結尾的緩衝區。
|
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 字串元素的值,以空值終止的字串。
|
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
初始化從單一 PacketBuffer 讀取的 TLVReader 物件。
|
Init(PacketBuffer *buf, uint32_t maxLen, bool allowDiscontiguousBuffers)
|
void
初始化從一或多個 PacketBuffers 讀取的 TLVReader 物件。
|
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 解碼時,應用程式必須先設定 ImplicitProfileId
,才能讀取含有這類標記的任何 TLV 元素。適當的設定檔 ID 通常取決於所說的應用程式或通訊協定內容。
如果在 ImplicitProfileId
設為 kProfileIdNotSpecified 時隱式編碼標記,讀取工具會傳回 WEAVE_ERROR_UNKNOWN_IMPLICIT_TLV_TAG 錯誤。
受保護的屬性
mBufEnd (無線)
const uint8_t * mBufEnd
mBufHandle
uintptr_t mBufHandle
mContainer 類型
TLVType mContainerType
mControlByte
uint16_t mControlByte
mElemLenOrVal
uint64_t mElemLenOrVal
mElemTag
uint64_t mElemTag
mLenRead
uint32_t mLenRead
行動裝置最大
uint32_t mMaxLen
m 讀取點
const uint8_t * mReadPoint
公用函式
關閉容器
WEAVE_ERROR CloseContainer( TLVReader & containerReader )
呼叫 OpenContainer() 後,完成 TLV 容器的讀取作業。
CloseContainer() 方法會在呼叫 OpenContainer() 後還原父項 TLVReader 物件的狀態。每次對 OpenContainer() 應用程式發出呼叫時,都必須對 CloseContainer() 發出相應的呼叫,並將同一個容器讀取器的參照傳遞至這兩個方法。
CloseContainer() 傳回時,上層讀取器緊接在容器後方的第一個元素之前。在這個模式下,應用程式可以使用 Next() 方法繼續瀏覽任何其餘元素。
無論何時,基礎容器中的所有元素是否已讀取,應用程式都可隨時在父項讀取器上關閉 CloseContainer()。呼叫 CloseContainer() 後,應用程式應考量容器讀取者 'de-initd',在不重新初始化的情況下,必須進一步使用容器。
詳情 | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
參數 |
|
||||||||||||
傳回值 |
|
DupBytes
WEAVE_ERROR DupBytes( uint8_t *& buf, uint32_t & dataLen )
分配並傳回包含目前位元組或 UTF8 字串值的緩衝區。
這個方法會建立一個緩衝區,並傳回與目前位置的位元組或 UTF-8 字串元素相關聯的資料副本。緩衝區的記憶體是透過 malloc() 取得,如果呼叫端不需要,則應使用 free() 釋出。
詳情 | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
參數 |
|
||||||||||||
傳回值 |
|
DupString
WEAVE_ERROR DupString( char *& buf )
分配並傳回包含目前位元組或 UTF8 字串的空值結尾的緩衝區。
這個方法會建立一個緩衝區,並傳回與目前位置的位元組或 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 物件,以便在容器結束後讀取元素。
ExitContainer() 方法會在呼叫 EnterContainer() 後還原 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 字串元素的值。
如要判斷所需的輸入緩衝區大小,請在呼叫 GetBytes() 之前呼叫 GetLength() 方法。
詳情 | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
參數 |
|
||||||||||
傳回值 |
|
取得容器類型
TLVType GetContainerType( void ) const
GetControlByte
uint16_t GetControlByte( void ) const
取得資料
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
傳回讀取器初始化後已讀取的位元組總數。
詳情 | |
---|---|
傳回 |
自讀者初始化後已讀取的位元組總數。
|
讀取點
const uint8_t * GetReadPoint( void ) const
取得基礎輸入緩衝區中與讀者目前位置相符的點。
詳情 | |
---|---|
傳回 |
指向讀者目前位置的基本輸入緩衝區指標。
|
取得長度
uint32_t GetRemainingLength( void ) const
傳回可讀取的位元組總數 (以位元組為單位),直到達到長度上限為止。
詳情 | |
---|---|
傳回 |
已達讀取長度上限前的可讀取位元組總數。
|
GetString
WEAVE_ERROR GetString( char *buf, uint32_t bufSize )
取得目前位元組或 UTF8 字串元素的值,以空值終止的字串。
如要判斷所需的輸入緩衝區大小,請在呼叫 GetBytes() 之前呼叫 GetLength() 方法。輸入緩衝區必須至少比字串長度大於 1 個位元組,以容納空值字元。
詳情 | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
參數 |
|
||||||||||
傳回值 |
|
GetTag
uint64_t GetTag( void ) const
傳回與目前 TLV 元素相關聯的標記。
GetTag() 傳回的值可以與代碼公用程式函式 (IsProfileTag()、IsContextTag()、ProfileIdFromTag() 等) 搭配使用,以判斷代碼類型並擷取各種代碼欄位值。
詳情 | |
---|---|
傳回 |
未簽署的整數,包含與目前 TLV 元素相關聯的標記相關資訊。
|
GetType
TLVType GetType( void ) const
初始
void Init( const TLVReader & aReader )
初始
void Init( const uint8_t *data, uint32_t dataLen )
初始
void Init( PacketBuffer *buf, uint32_t maxLen )
初始
void Init( PacketBuffer *buf, uint32_t maxLen, bool allowDiscontiguousBuffers )
初始化從一或多個 PacketBuffers 讀取的 TLVReader 物件。
剖析作業是從初始緩衝區的起始位置 (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 預期的 Type, uint64_t 預期 Tag) 方法是便利方法,其行為與 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 傳回值。
詳情 | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
傳回值 |
|
受保護的函式
ClearElementState (清除元素狀態)
void ClearElementState( void )
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 )
設定 ContainerOpen
void SetContainerOpen( bool aContainerOpen )
略過資料
WEAVE_ERROR SkipData( void )
略過目的地緩衝區中的資料,藉此略過目前 TLV 中包含的任何資料。
詳情 | |||||
---|---|---|---|---|---|
傳回值 |
|
略過至結尾容器
WEAVE_ERROR SkipToEndOfContainer( void )
驗證元素
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 )