From e0f593bc2e5aeacabcaf508dcb472d5931a66d84 Mon Sep 17 00:00:00 2001 From: HomeSpan Date: Sat, 20 Apr 2024 19:50:46 -0500 Subject: [PATCH] Update TLV8.md --- docs/TLV8.md | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/docs/TLV8.md b/docs/TLV8.md index 436348b..a225a13 100644 --- a/docs/TLV8.md +++ b/docs/TLV8.md @@ -22,13 +22,13 @@ Fortunately, HomeSpan includes a dedicated TLV8 library (see below) that automat ## *TLV8()* -Creating an instance of HomeSpan's TLV8 **class** using the above constructor builds an empty TLV8 object into which you can add and process TLV8 records. TLV8 objects are instantiated as standard C++ linked-list containers derived from `std::list`, where *tlv8_t* is an opaque structure used to store individual TLV8 records.[^1] +Creating an instance of HomeSpan's TLV8 **class** using the above constructor builds an empty TLV8 object into which you can add and process TLV8 records. TLV8 objects are instantiated as standard C++ linked-list containers derived from `std::list`, where *tlv8_t* is an opaque structure used to store individual TLV8 records.[^opaque] -Also, as shown below, many of the TLV8 methods utilize linked-list iterators. These are represented by the typedef *TLV8_it*.[^2] +Also, as shown below, many of the TLV8 methods utilize linked-list iterators. These are represented by the typedef *TLV8_it*.[^iterators] -[^1]:The *tlv8_t* structure is opaque because in general you will not have to create or interact directly with the structure or its data. Note that in addition to the above TLV8-specific methods, you can use any `std::list` method with a TLV8 object if desired. +[^opaque]:The *tlv8_t* structure is opaque because in general you will not have to create or interact directly with the structure or its data. Note that in addition to the above TLV8-specific methods, you can use any `std::list` method with a TLV8 object if desired. -[^2]:You do not need expert knowledge of C++ containers and iterators in order to use the TLV8 library, but a basic understanding of containers and iterators will make the library much easier to learn and enjoyable to use. +[^iterators]:You do not need expert knowledge of C++ containers and iterators in order to use the TLV8 library, but a basic understanding of containers and iterators will make the library much easier to learn and enjoyable to use. The method for adding a generic TLV8 record to a TLV8 object is as follows: @@ -115,6 +115,18 @@ To restrict the the printing range to a limited set of records, add optional sta * if *it2* is unspecified, prints only the record pointed to by *it1* * note `myTLV.print()` is equivalent to `myTLV.print(myTLV.begin(), myTLV.end())` +The output generated by `print()` can contain some very long lines, especially if the VALUE of some of the TLV8 records represents other complete TLV8 objects (known as sub-TLVs or "nested" TLVs). To recursively print all sub-TLV objects, use the following method: + +* `void printAll()` + * recursively prints all TLV8 records, one per line, to the Serial Monitor + * inspects each TLV8 record and tries to parse as if the record represented a sub-TLV object + * if parsing is successful, prints the record and then calls `printAll()` on the sub-TLV + * if not, prints the record and ends this branch of the recursion + * the format of each line is the same as that of `print()` except that TAG displays the full path of all TAGs through the branch + * note that the output can be very voluminous if your TLV8 object contains many levels of nested sub-TLVs + * warning: some care is required when interpretating the output[^subTLVs] + +[^subTLVs]:The `printAll()` method assumes that any VALUE that is consistent with the format of a sub-TLV must be a sub-TLV, even if its just a simple numeric value. For example, `add(10,65536)` yields a record with a TAG identifer of 10 and a 4-byte VALUE of 0x00000100. The `printAll()` method will display this record along with NUMERIC=65536, but it will also then interpret (and thus display) this VALUE as a sub-TLV containing one zero-length record with TAG identifier=0 and another zero-length record with TAG identifer=1, since the VALUE can be successfully parsed as such. Once you have the iterator *myIT* pointing to the desired TLV8 record, you can then use any of the methods below to access the VALUE stored in the TLV8 record: