@@ -1008,7 +1008,13 @@ bool canardTableDecodeMessage(const CanardCodingTable* table,
10081008 uint32_t bit_ofs = 0 ;
10091009 const CanardCodingTableEntry * entry = & table -> entries [0 ];
10101010 const CanardCodingTableEntry * entry_last = & table -> entries [table -> entries_max ];
1011- if (tableDecodeCore (entry , entry_last , transfer , & bit_ofs , msg )) {
1011+ if (tableDecodeCore (entry , entry_last , transfer , & bit_ofs , msg ,
1012+ #if CANARD_ENABLE_TAO_OPTION
1013+ transfer -> tao
1014+ #else
1015+ true
1016+ #endif
1017+ )) {
10121018 return true; // decode failure
10131019 }
10141020
@@ -1038,7 +1044,13 @@ uint32_t canardTableEncodeMessage(const CanardCodingTable* table,
10381044 uint32_t bit_ofs = 0 ;
10391045 const CanardCodingTableEntry * entry = & table -> entries [0 ];
10401046 const CanardCodingTableEntry * entry_last = & table -> entries [table -> entries_max ];
1041- tableEncodeCore (entry , entry_last , buffer , & bit_ofs , msg );
1047+ tableEncodeCore (entry , entry_last , buffer , & bit_ofs , msg ,
1048+ #if CANARD_ENABLE_TAO_OPTION
1049+ tao
1050+ #else
1051+ true
1052+ #endif
1053+ );
10421054
10431055 return ((bit_ofs + 7 )/8 );
10441056}
@@ -1883,7 +1895,8 @@ CANARD_INTERNAL bool tableDecodeCore(const CanardCodingTableEntry* entry,
18831895 const CanardCodingTableEntry * entry_last ,
18841896 const CanardRxTransfer * transfer ,
18851897 uint32_t * bit_ofs ,
1886- void * msg )
1898+ void * msg ,
1899+ bool tao )
18871900{
18881901 do {
18891902 void * p = (char * )msg + entry -> offset ;
@@ -1914,7 +1927,7 @@ CANARD_INTERNAL bool tableDecodeCore(const CanardCodingTableEntry* entry,
19141927
19151928 uint16_t elems = aux -> type | ((uint16_t )aux -> bitlen << 8 );
19161929 while (elems -- ) {
1917- if (tableDecodeCore (array_entry , array_entry_last , transfer , bit_ofs , p )) {
1930+ if (tableDecodeCore (array_entry , array_entry_last , transfer , bit_ofs , p , ! elems && tao )) {
19181931 return true;
19191932 }
19201933 p = (char * )p + aux -> offset ;
@@ -1923,6 +1936,60 @@ CANARD_INTERNAL bool tableDecodeCore(const CanardCodingTableEntry* entry,
19231936 break ;
19241937 }
19251938
1939+ case CANARD_TABLE_CODING_ARRAY_DYNAMIC :
1940+ case CANARD_TABLE_CODING_ARRAY_DYNAMIC_TAO : {
1941+ const CanardCodingTableEntry * aux = ++ entry ;
1942+ const CanardCodingTableEntry * aux2 = ++ entry ;
1943+ const CanardCodingTableEntry * array_entry = ++ entry ;
1944+ const CanardCodingTableEntry * array_entry_last = array_entry + bitlen ;
1945+ entry = array_entry_last ; // point entry to last for ++entry at end of loop
1946+
1947+ uint16_t max_len = aux -> type | ((uint16_t )aux -> bitlen << 8 );
1948+ void * len_p = ((char * )msg + aux2 -> offset );
1949+ uint8_t len_bitlen = aux2 -> bitlen ;
1950+ if (type != CANARD_TABLE_CODING_ARRAY_DYNAMIC_TAO || !tao ) {
1951+ // not using TAO
1952+ canardDecodeScalar (transfer , * bit_ofs , len_bitlen , false, len_p );
1953+ * bit_ofs += len_bitlen ;
1954+
1955+ uint16_t elems ;
1956+ if (len_bitlen <= 8 ) {
1957+ elems = * (uint8_t * )len_p ;
1958+ } else { // 16 bits is max supported len
1959+ elems = * (uint16_t * )len_p ;
1960+ }
1961+ if (elems > max_len ) {
1962+ return true; // invalid value
1963+ }
1964+
1965+ while (elems -- ) {
1966+ if (tableDecodeCore (array_entry , array_entry_last , transfer , bit_ofs , p , !elems && tao )) {
1967+ return true;
1968+ }
1969+ p = (char * )p + aux -> offset ;
1970+ }
1971+ } else {
1972+ // TAO optimization in play
1973+ uint16_t elems = 0 ;
1974+ // TAO requires the element size to be at least 8 bits so if we have less we know we are done
1975+ uint32_t max_bits = (transfer -> payload_len * 8 )- 7 ;
1976+ while (max_bits > * bit_ofs ) {
1977+ if (!max_len -- || tableDecodeCore (array_entry , array_entry_last , transfer , bit_ofs , p , false)) {
1978+ return true;
1979+ }
1980+ p = (char * )p + aux -> offset ;
1981+ elems ++ ;
1982+ }
1983+ if (len_bitlen <= 8 ) {
1984+ * (uint8_t * )len_p = (uint8_t )elems ;
1985+ } else { // 16 bits is max supported len
1986+ * (uint16_t * )len_p = elems ;
1987+ }
1988+ }
1989+
1990+ break ;
1991+ }
1992+
19261993 default :
19271994 return true; // invalid type
19281995 }
@@ -1937,7 +2004,8 @@ CANARD_INTERNAL void tableEncodeCore(const CanardCodingTableEntry* entry,
19372004 const CanardCodingTableEntry * entry_last ,
19382005 uint8_t * buffer ,
19392006 uint32_t * bit_ofs ,
1940- const void * msg )
2007+ const void * msg ,
2008+ bool tao )
19412009{
19422010 do {
19432011 const void * p = (const char * )msg + entry -> offset ;
@@ -1969,7 +2037,51 @@ CANARD_INTERNAL void tableEncodeCore(const CanardCodingTableEntry* entry,
19692037
19702038 uint16_t elems = aux -> type | ((uint16_t )aux -> bitlen << 8 );
19712039 while (elems -- ) {
1972- tableEncodeCore (array_entry , array_entry_last , buffer , bit_ofs , p );
2040+ tableEncodeCore (array_entry , array_entry_last , buffer , bit_ofs , p , !elems && tao );
2041+ p = (const char * )p + aux -> offset ;
2042+ }
2043+
2044+ break ;
2045+ }
2046+
2047+ case CANARD_TABLE_CODING_ARRAY_DYNAMIC :
2048+ case CANARD_TABLE_CODING_ARRAY_DYNAMIC_TAO : {
2049+ const CanardCodingTableEntry * aux = ++ entry ;
2050+ const CanardCodingTableEntry * aux2 = ++ entry ;
2051+ const CanardCodingTableEntry * array_entry = ++ entry ;
2052+ const CanardCodingTableEntry * array_entry_last = array_entry + bitlen ;
2053+ entry = array_entry_last ; // point entry to last for ++entry at end of loop
2054+
2055+ uint16_t max_len = aux -> type | ((uint16_t )aux -> bitlen << 8 );
2056+ const void * len_p = (const char * )msg + aux2 -> offset ;
2057+ uint8_t len_bitlen = aux2 -> bitlen ;
2058+
2059+ uint16_t elems ;
2060+ if (len_bitlen <= 8 ) {
2061+ elems = * (const uint8_t * )len_p ;
2062+ } else { // 16 bits is max supported len
2063+ elems = * (const uint16_t * )len_p ;
2064+ }
2065+ if (elems > max_len ) {
2066+ elems = max_len ;
2067+ }
2068+
2069+ if (type != CANARD_TABLE_CODING_ARRAY_DYNAMIC_TAO || !tao ) {
2070+ // encode the length value we have clamped to the maximum
2071+ uint8_t elems_8 ;
2072+ if (len_bitlen <= 8 ) {
2073+ elems_8 = (uint8_t )elems ;
2074+ len_p = & elems_8 ;
2075+ } else { // 16 bits is max supported len
2076+ len_p = & elems ;
2077+ }
2078+ canardEncodeScalar (buffer , * bit_ofs , len_bitlen , len_p );
2079+ * bit_ofs += len_bitlen ;
2080+ }
2081+
2082+ int element_tao = type != CANARD_TABLE_CODING_ARRAY_DYNAMIC_TAO && tao ;
2083+ while (elems -- ) {
2084+ tableEncodeCore (array_entry , array_entry_last , buffer , bit_ofs , p , !elems && element_tao );
19732085 p = (const char * )p + aux -> offset ;
19742086 }
19752087
0 commit comments