@@ -106,10 +106,15 @@ impl Header {
106106
107107 /// Extracts the next payload from the given buffer, advancing it.
108108 ///
109+ /// The returned `PayloadView` provides a structured view of the payload, allowing for efficient
110+ /// parsing of nested items without unnecessary allocations.
111+ ///
109112 /// # Errors
110113 ///
111- /// Returns an error if the buffer is too short, the header is invalid or one of the headers one
112- /// level deeper is invalid.
114+ /// Returns an error if:
115+ /// - The buffer is too short
116+ /// - The header is invalid
117+ /// - Any nested headers (for list items) are invalid
113118 #[ inline]
114119 pub fn decode_raw < ' a > ( buf : & mut & ' a [ u8 ] ) -> Result < PayloadView < ' a > > {
115120 let Self { list, payload_length } = Self :: decode ( buf) ?;
@@ -122,17 +127,18 @@ impl Header {
122127
123128 let mut items = alloc:: vec:: Vec :: new ( ) ;
124129 while !payload. is_empty ( ) {
125- // decode the next header without advancing in the payload
126- let Self { payload_length, .. } = Self :: decode ( & mut & payload[ ..] ) ?;
127- // the length of the RLP encoding is the length of the header plus its payload length
128- // if payload length is 1 and the first byte is in [0x00, 0x7F], then there is no header
129- let rlp_length = if payload_length == 1 && payload[ 0 ] <= 0x7F {
130- 1
131- } else {
132- payload_length + crate :: length_of_length ( payload_length)
133- } ;
134- items. push ( & payload[ ..rlp_length] ) ;
135- payload. advance ( rlp_length) ;
130+ // store the start of the current item for later slice creation
131+ let item_start = payload;
132+
133+ // decode the header of the next RLP item, advancing the payload
134+ let Self { payload_length, .. } = Self :: decode ( & mut payload) ?;
135+ // SAFETY: this is already checked in `decode`
136+ unsafe { advance_unchecked ( & mut payload, payload_length) } ;
137+
138+ // calculate the total length of the item (header + payload) by subtracting the
139+ // remaining payload length from the initial length
140+ let item_length = item_start. len ( ) - payload. len ( ) ;
141+ items. push ( & item_start[ ..item_length] ) ;
136142 }
137143
138144 Ok ( PayloadView :: List ( items) )
0 commit comments