@@ -28,12 +28,9 @@ pub fn check_remaining(bytes: &[u8], offset: usize, num_bytes: usize) -> Result<
2828pub fn read_byte ( bytes : & [ u8 ] , offset : & mut usize ) -> Result < u8 > {
2929 // Implicitly checks that the offset is within bounds, no need
3030 // to call `check_remaining` explicitly here.
31- let value = bytes
32- . get ( * offset)
33- . copied ( )
34- . ok_or ( TransactionViewError :: ParseError ) ;
35- * offset = offset. wrapping_add ( 1 ) ;
36- value
31+ let value = bytes. get ( * offset) . copied ( ) . ok_or ( TransactionViewError :: ParseError ) ?;
32+ * offset = offset. checked_add ( 1 ) . ok_or ( TransactionViewError :: ParseError ) ?;
33+ Ok ( value)
3734}
3835
3936/// Read a byte and advance the offset without any bounds checks.
@@ -69,9 +66,8 @@ pub fn read_compressed_u16(bytes: &[u8], offset: &mut usize) -> Result<u16> {
6966 for i in 0 ..3 {
7067 // Implicitly checks that the offset is within bounds, no need
7168 // to call check_remaining explicitly here.
72- let byte = * bytes
73- . get ( offset. wrapping_add ( i) )
74- . ok_or ( TransactionViewError :: ParseError ) ?;
69+ let index = offset. checked_add ( i) . ok_or ( TransactionViewError :: ParseError ) ?;
70+ let byte = * bytes. get ( index) . ok_or ( TransactionViewError :: ParseError ) ?;
7571 // non-minimal encoding or overflow
7672 if ( i > 0 && byte == 0 ) || ( i == 2 && byte > 3 ) {
7773 return Err ( TransactionViewError :: ParseError ) ;
@@ -85,46 +81,7 @@ pub fn read_compressed_u16(bytes: &[u8], offset: &mut usize) -> Result<u16> {
8581 }
8682
8783 // if we reach here, it means that all 3 bytes were used
88- * offset = offset. wrapping_add ( 3 ) ;
89- Ok ( result)
90- }
91-
92- /// Domain-specific optimization for reading a compressed u16.
93- ///
94- /// The compressed u16's are only used for array-lengths in our transaction
95- /// format. The transaction packet has a maximum size of 1232 bytes.
96- /// This means that the maximum array length within a **valid** transaction is
97- /// 1232. This has a minimally encoded length of 2 bytes.
98- /// Although the encoding scheme allows for more, any arrays with this length
99- /// would be too large to fit in a packet. This function optimizes for this
100- /// case, and reads a maximum of 2 bytes.
101- /// If the buffer is too short or the encoding is invalid, return Err.
102- /// `offset` is updated to point to the byte after the compressed u16.
103- ///
104- /// * `bytes` - Slice of bytes to read from.
105- /// * `offset` - Current offset into `bytes`.
106- #[ inline( always) ]
107- pub fn optimized_read_compressed_u16 ( bytes : & [ u8 ] , offset : & mut usize ) -> Result < u16 > {
108- let mut result = 0u16 ;
109-
110- // First byte
111- let byte1 = * bytes. get ( * offset) . ok_or ( TransactionViewError :: ParseError ) ?;
112- result |= ( byte1 & 0x7F ) as u16 ;
113- if byte1 & 0x80 == 0 {
114- * offset = offset. wrapping_add ( 1 ) ;
115- return Ok ( result) ;
116- }
117-
118- // Second byte
119- let byte2 = * bytes
120- . get ( offset. wrapping_add ( 1 ) )
121- . ok_or ( TransactionViewError :: ParseError ) ?;
122- if byte2 == 0 || byte2 & 0x80 != 0 {
123- return Err ( TransactionViewError :: ParseError ) ; // non-minimal encoding or overflow
124- }
125- result |= ( ( byte2 & 0x7F ) as u16 ) << 7 ;
126- * offset = offset. wrapping_add ( 2 ) ;
127-
84+ * offset = offset. checked_add ( 3 ) . ok_or ( TransactionViewError :: ParseError ) ?;
12885 Ok ( result)
12986}
13087
@@ -313,9 +270,8 @@ mod tests {
313270 serialize_into ( & mut buffer[ ..] , & short_u16) . expect ( "Serialization failed" ) ;
314271
315272 // Use bincode's size calculation to determine the length of the serialized data
316- let serialized_len = options
317- . serialized_size ( & short_u16)
318- . expect ( "Failed to get serialized size" ) ;
273+ let serialized_len =
274+ options. serialized_size ( & short_u16) . expect ( "Failed to get serialized size" ) ;
319275
320276 // Reset offset
321277 offset = 0 ;
@@ -351,55 +307,6 @@ mod tests {
351307 assert ! ( read_compressed_u16( & [ 0x81 , 0x80 , 0x00 ] , & mut 0 ) . is_err( ) ) ;
352308 }
353309
354- #[ test]
355- fn test_optimized_read_compressed_u16 ( ) {
356- let mut buffer = [ 0u8 ; 1024 ] ;
357- let options = DefaultOptions :: new ( ) . with_fixint_encoding ( ) ; // Ensure fixed-int encoding
358-
359- // Test all possible u16 values under the packet length
360- for value in 0 ..=PACKET_DATA_SIZE as u16 {
361- let mut offset;
362- let short_u16 = ShortU16 ( value) ;
363-
364- // Serialize the value into the buffer
365- serialize_into ( & mut buffer[ ..] , & short_u16) . expect ( "Serialization failed" ) ;
366-
367- // Use bincode's size calculation to determine the length of the serialized data
368- let serialized_len = options
369- . serialized_size ( & short_u16)
370- . expect ( "Failed to get serialized size" ) ;
371-
372- // Reset offset
373- offset = 0 ;
374-
375- // Read the value back using unchecked_read_u16_compressed
376- let read_value = optimized_read_compressed_u16 ( & buffer, & mut offset) ;
377-
378- // Assert that the read value matches the original value
379- assert_eq ! ( read_value, Ok ( value) , "Value mismatch for: {value}" ) ;
380-
381- // Assert that the offset matches the serialized length
382- assert_eq ! (
383- offset, serialized_len as usize ,
384- "Offset mismatch for: {value}"
385- ) ;
386- }
387-
388- // Test bounds.
389- // All 0s => 0
390- assert_eq ! ( Ok ( 0 ) , optimized_read_compressed_u16( & [ 0 ; 3 ] , & mut 0 ) ) ;
391- // Overflow
392- assert ! ( optimized_read_compressed_u16( & [ 0xFF , 0xFF , 0x04 ] , & mut 0 ) . is_err( ) ) ;
393- assert ! ( optimized_read_compressed_u16( & [ 0xFF , 0x80 ] , & mut 0 ) . is_err( ) ) ;
394-
395- // overflow errors
396- assert ! ( optimized_read_compressed_u16( & [ u8 :: MAX ; 1 ] , & mut 0 ) . is_err( ) ) ;
397- assert ! ( optimized_read_compressed_u16( & [ u8 :: MAX ; 2 ] , & mut 0 ) . is_err( ) ) ;
398-
399- // Minimal encoding checks
400- assert ! ( optimized_read_compressed_u16( & [ 0x81 , 0x00 ] , & mut 0 ) . is_err( ) ) ;
401- }
402-
403310 #[ test]
404311 fn test_advance_offset_for_array ( ) {
405312 #[ repr( C ) ]
0 commit comments