@@ -293,11 +293,17 @@ impl fmt::Display for DecodedValue {
293293/// PVD Decoder state
294294pub struct PvdDecoder {
295295 is_be : bool ,
296+ /// IntrospectionRegistry: maps int16 keys to previously seen FieldTypes.
297+ /// Populated when parsing `0xFD` (full-with-id) entries, looked up on `0xFE` (only-id).
298+ registry : std:: cell:: RefCell < std:: collections:: HashMap < u16 , FieldType > > ,
296299}
297300
298301impl PvdDecoder {
299302 pub fn new ( is_be : bool ) -> Self {
300- Self { is_be }
303+ Self {
304+ is_be,
305+ registry : std:: cell:: RefCell :: new ( std:: collections:: HashMap :: new ( ) ) ,
306+ }
301307 }
302308
303309 /// Decode a size value (PVA variable-length encoding)
@@ -382,24 +388,36 @@ impl PvdDecoder {
382388 // Full-with-id from IntrospectionRegistry:
383389 // 0xFD + int16 key + type descriptor payload.
384390 if type_byte == 0xFD {
385- if data. len ( ) < 4 {
391+ if data. len ( ) < 3 {
386392 return None ;
387393 }
388- // Preferred parsing path: skip tag + int16 key.
394+ let key = if self . is_be {
395+ u16:: from_be_bytes ( [ data[ 1 ] , data[ 2 ] ] )
396+ } else {
397+ u16:: from_le_bytes ( [ data[ 1 ] , data[ 2 ] ] )
398+ } ;
389399 if let Some ( ( field_type, consumed) ) = self . parse_type_desc ( & data[ 3 ..] ) {
400+ self . registry . borrow_mut ( ) . insert ( key, field_type. clone ( ) ) ;
390401 return Some ( ( field_type, 3 + consumed) ) ;
391402 }
392- // Legacy fallback for older non-keyed streams.
393- if let Some ( ( field_type, consumed) ) = self . parse_type_desc ( & data[ 1 ..] ) {
394- return Some ( ( field_type, 1 + consumed) ) ;
395- }
396403 return None ;
397404 }
398405
399406 // Only-id from IntrospectionRegistry:
400- // 0xFE + int16 key, requires connection-level registry state .
407+ // 0xFE + int16 key — reference to a previously seen type .
401408 if type_byte == 0xFE {
402- debug ! ( "Type descriptor uses ONLY_ID (0xFE) without registry context" ) ;
409+ if data. len ( ) < 3 {
410+ return None ;
411+ }
412+ let key = if self . is_be {
413+ u16:: from_be_bytes ( [ data[ 1 ] , data[ 2 ] ] )
414+ } else {
415+ u16:: from_le_bytes ( [ data[ 1 ] , data[ 2 ] ] )
416+ } ;
417+ if let Some ( ft) = self . registry . borrow ( ) . get ( & key) {
418+ return Some ( ( ft. clone ( ) , 3 ) ) ;
419+ }
420+ debug ! ( "Type descriptor ONLY_ID (0xFE) key={} not found in registry" , key) ;
403421 return None ;
404422 }
405423
@@ -549,26 +567,49 @@ impl PvdDecoder {
549567 // Full-with-id from IntrospectionRegistry:
550568 // 0xFD + int16 key + field type descriptor payload.
551569 if type_byte == 0xFD {
552- if data. len ( ) < 4 {
570+ if data. len ( ) < 3 {
553571 return None ;
554572 }
555- // Preferred parsing path: skip tag + int16 key.
573+ let key = if self . is_be {
574+ u16:: from_be_bytes ( [ data[ 1 ] , data[ 2 ] ] )
575+ } else {
576+ u16:: from_le_bytes ( [ data[ 1 ] , data[ 2 ] ] )
577+ } ;
556578 if let Some ( ( desc, consumed) ) = self . parse_introspection_with_len ( & data[ 3 ..] ) {
579+ // Register this structure type for later 0xFE references
580+ if !desc. fields . is_empty ( ) {
581+ self . registry . borrow_mut ( ) . insert (
582+ key,
583+ FieldType :: Structure ( desc. clone ( ) ) ,
584+ ) ;
585+ } else {
586+ self . registry . borrow_mut ( ) . insert (
587+ key,
588+ FieldType :: Structure ( desc. clone ( ) ) ,
589+ ) ;
590+ }
557591 return Some ( ( desc, 3 + consumed) ) ;
558592 }
559- // Legacy fallback for older non-keyed streams.
560- if let Some ( ( desc, consumed) ) = self . parse_introspection_with_len ( & data[ 1 ..] ) {
561- return Some ( ( desc, 1 + consumed) ) ;
562- }
563593 return None ;
564594 }
565595
566596 // Only-id from IntrospectionRegistry:
567- // 0xFE + int16 key, requires connection-level registry state .
597+ // 0xFE + int16 key — reference to a previously seen type .
568598 if type_byte == 0xFE {
569- debug ! (
570- "Introspection uses ONLY_ID (0xFE), but no registry is available in this decoder"
571- ) ;
599+ if data. len ( ) < 3 {
600+ return None ;
601+ }
602+ let key = if self . is_be {
603+ u16:: from_be_bytes ( [ data[ 1 ] , data[ 2 ] ] )
604+ } else {
605+ u16:: from_le_bytes ( [ data[ 1 ] , data[ 2 ] ] )
606+ } ;
607+ if let Some ( ft) = self . registry . borrow ( ) . get ( & key) {
608+ if let FieldType :: Structure ( desc) = ft {
609+ return Some ( ( desc. clone ( ) , 3 ) ) ;
610+ }
611+ }
612+ debug ! ( "Introspection ONLY_ID (0xFE) key={} not found in registry" , key) ;
572613 return None ;
573614 }
574615
0 commit comments