diff --git a/src/data_structures/src/byte_array_reader.cairo b/src/data_structures/src/byte_array_reader.cairo index 53c58260..a97d0d5a 100644 --- a/src/data_structures/src/byte_array_reader.cairo +++ b/src/data_structures/src/byte_array_reader.cairo @@ -25,50 +25,90 @@ trait ByteArrayReaderTrait { /// # Returns /// `Option` - If there are enough bytes remaining an optional integer is returned fn read_u8(ref self: ByteArrayReader) -> Option; - /// Reads a u16 unsigned integer + /// Reads a u16 unsigned integer in big endian byte order /// # Returns /// `Option` - If there are enough bytes remaining an optional integer is returned fn read_u16(ref self: ByteArrayReader) -> Option; - /// Reads a u32 unsigned integer + /// Reads a u16 unsigned integer in little endian byte order + /// # Returns + /// `Option` - If there are enough bytes remaining an optional integer is returned + fn read_u16_le(ref self: ByteArrayReader) -> Option; + /// Reads a u32 unsigned integer in big endian byte order /// # Returns /// `Option` - If there are enough bytes remaining an optional integer is returned fn read_u32(ref self: ByteArrayReader) -> Option; - /// Reads a u64 unsigned integer + /// Reads a u32 unsigned integer in little endian byte order + /// # Returns + /// `Option` - If there are enough bytes remaining an optional integer is returned + fn read_u32_le(ref self: ByteArrayReader) -> Option; + /// Reads a u64 unsigned integer in big endian byte order /// # Returns /// `Option` - If there are enough bytes remaining an optional integer is returned fn read_u64(ref self: ByteArrayReader) -> Option; - /// Reads a u128 unsigned integer + /// Reads a u64 unsigned integer in little endian byte order + /// # Returns + /// `Option` - If there are enough bytes remaining an optional integer is returned + fn read_u64_le(ref self: ByteArrayReader) -> Option; + /// Reads a u128 unsigned integer in big endian byte order /// # Returns /// `Option` - If there are enough bytes remaining an optional integer is returned fn read_u128(ref self: ByteArrayReader) -> Option; - /// Reads a u256 unsigned integer + /// Reads a u128 unsigned integer in little endian byte order + /// # Returns + /// `Option` - If there are enough bytes remaining an optional integer is returned + fn read_u128_le(ref self: ByteArrayReader) -> Option; + /// Reads a u256 unsigned integer in big endian byte order /// # Returns /// `Option` - If there are enough bytes remaining an optional integer is returned fn read_u256(ref self: ByteArrayReader) -> Option; - /// Reads a u512 unsigned integer + /// Reads a u256 unsigned integer in little endian byte order + /// # Returns + /// `Option` - If there are enough bytes remaining an optional integer is returned + fn read_u256_le(ref self: ByteArrayReader) -> Option; + /// Reads a u512 unsigned integer in big endian byte order /// # Returns /// `Option` - If there are enough bytes remaining an optional integer is returned fn read_u512(ref self: ByteArrayReader) -> Option; + /// Reads a u512 unsigned integer in little endian byte order + /// # Returns + /// `Option` - If there are enough bytes remaining an optional integer is returned + fn read_u512_le(ref self: ByteArrayReader) -> Option; /// Reads an i8 signed integer in two's complement encoding from the ByteArray /// # Returns /// `Option` - If there are enough bytes remaining an optional integer is returned fn read_i8(ref self: ByteArrayReader) -> Option; - /// Reads an i16 signed integer in two's complement encoding from the ByteArray + /// Reads an i16 signed integer in two's complement encoding from the ByteArray in big endian byte order /// # Returns /// `Option` - If there are enough bytes remaining an optional integer is returned fn read_i16(ref self: ByteArrayReader) -> Option; - /// Reads an i32 signed integer in two's complement encoding from the ByteArray + /// Reads an i16 signed integer in two's complement encoding from the ByteArray in little endian byte order + /// # Returns + /// `Option` - If there are enough bytes remaining an optional integer is returned + fn read_i16_le(ref self: ByteArrayReader) -> Option; + /// Reads an i32 signed integer in two's complement encoding from the ByteArray in big endian byte order /// # Returns /// `Option` - If there are enough bytes remaining an optional integer is returned fn read_i32(ref self: ByteArrayReader) -> Option; - /// Reads an i64 signed integer in two's complement encoding from the ByteArray + /// Reads an i32 signed integer in two's complement encoding from the ByteArray in little endian byte order + /// # Returns + /// `Option` - If there are enough bytes remaining an optional integer is returned + fn read_i32_le(ref self: ByteArrayReader) -> Option; + /// Reads an i64 signed integer in two's complement encoding from the ByteArray in big endian byte order /// # Returns /// `Option` - If there are enough bytes remaining an optional integer is returned fn read_i64(ref self: ByteArrayReader) -> Option; - /// Reads an i128 signed integer in two's complement encoding from the ByteArray + /// Reads an i64 signed integer in two's complement encoding from the ByteArray in little endian byte order + /// # Returns + /// `Option` - If there are enough bytes remaining an optional integer is returned + fn read_i64_le(ref self: ByteArrayReader) -> Option; + /// Reads an i128 signed integer in two's complement encoding from the ByteArray in big endian byte order /// # Returns /// `Option` - If there are enough bytes remaining an optional integer is returned fn read_i128(ref self: ByteArrayReader) -> Option; + /// Reads an i128 signed integer in two's complement encoding from the ByteArray in little endian byte order + /// # Returns + /// `Option` - If there are enough bytes remaining an optional integer is returned + fn read_i128_le(ref self: ByteArrayReader) -> Option; /// Returns the remaining length of the ByteArrayReader /// # Returns /// `usize` - The number of bytes remaining, considering the number of bytes that have already been consumed @@ -92,24 +132,48 @@ impl ByteArrayReaderImpl of ByteArrayReaderTrait { Option::Some(result) } + fn read_u16_le(ref self: ByteArrayReader) -> Option { + let result = self.data.word_u16_le(self.reader_index)?; + self.reader_index += 2; + Option::Some(result) + } + fn read_u32(ref self: ByteArrayReader) -> Option { let result = self.data.word_u32(self.reader_index)?; self.reader_index += 4; Option::Some(result) } + fn read_u32_le(ref self: ByteArrayReader) -> Option { + let result = self.data.word_u32_le(self.reader_index)?; + self.reader_index += 4; + Option::Some(result) + } + fn read_u64(ref self: ByteArrayReader) -> Option { let result = self.data.word_u64(self.reader_index)?; self.reader_index += 8; Option::Some(result) } + fn read_u64_le(ref self: ByteArrayReader) -> Option { + let result = self.data.word_u64_le(self.reader_index)?; + self.reader_index += 8; + Option::Some(result) + } + fn read_u128(ref self: ByteArrayReader) -> Option { let result = self.data.word_u128(self.reader_index)?; self.reader_index += 16; Option::Some(result) } + fn read_u128_le(ref self: ByteArrayReader) -> Option { + let result = self.data.word_u128_le(self.reader_index)?; + self.reader_index += 16; + Option::Some(result) + } + fn read_u256(ref self: ByteArrayReader) -> Option { let result = u256 { high: self.data.word_u128(self.reader_index)?, @@ -119,6 +183,15 @@ impl ByteArrayReaderImpl of ByteArrayReaderTrait { Option::Some(result) } + fn read_u256_le(ref self: ByteArrayReader) -> Option { + let result = u256 { + low: self.data.word_u128_le(self.reader_index)?, + high: self.data.word_u128_le(self.reader_index + 16)? + }; + self.reader_index += 32; + Option::Some(result) + } + fn read_u512(ref self: ByteArrayReader) -> Option { let result = u512 { limb3: self.data.word_u128(self.reader_index)?, @@ -130,6 +203,17 @@ impl ByteArrayReaderImpl of ByteArrayReaderTrait { Option::Some(result) } + fn read_u512_le(ref self: ByteArrayReader) -> Option { + let result = u512 { + limb0: self.data.word_u128_le(self.reader_index)?, + limb1: self.data.word_u128_le(self.reader_index + 16)?, + limb2: self.data.word_u128_le(self.reader_index + 32)?, + limb3: self.data.word_u128_le(self.reader_index + 48)? + }; + self.reader_index += 64; + Option::Some(result) + } + fn read_i8(ref self: ByteArrayReader) -> Option { let felt: felt252 = self.read_u8()?.into(); Option::Some(parse_signed(felt, 1).unwrap()) @@ -140,21 +224,41 @@ impl ByteArrayReaderImpl of ByteArrayReaderTrait { Option::Some(parse_signed(felt, 2).unwrap()) } + fn read_i16_le(ref self: ByteArrayReader) -> Option { + let felt: felt252 = self.read_u16_le()?.into(); + Option::Some(parse_signed(felt, 2).unwrap()) + } + fn read_i32(ref self: ByteArrayReader) -> Option { let felt: felt252 = self.read_u32()?.into(); Option::Some(parse_signed(felt, 4).unwrap()) } + fn read_i32_le(ref self: ByteArrayReader) -> Option { + let felt: felt252 = self.read_u32_le()?.into(); + Option::Some(parse_signed(felt, 4).unwrap()) + } + fn read_i64(ref self: ByteArrayReader) -> Option { let felt: felt252 = self.read_u64()?.into(); Option::Some(parse_signed(felt, 8).unwrap()) } + fn read_i64_le(ref self: ByteArrayReader) -> Option { + let felt: felt252 = self.read_u64_le()?.into(); + Option::Some(parse_signed(felt, 8).unwrap()) + } + fn read_i128(ref self: ByteArrayReader) -> Option { let felt: felt252 = self.read_u128()?.into(); Option::Some(parse_signed(felt, 16).unwrap()) } + fn read_i128_le(ref self: ByteArrayReader) -> Option { + let felt: felt252 = self.read_u128_le()?.into(); + Option::Some(parse_signed(felt, 16).unwrap()) + } + fn len(self: @ByteArrayReader) -> usize { let byte_array = *self.data; let byte_array_len = byte_array.len(); diff --git a/src/data_structures/src/tests/byte_array_reader_test.cairo b/src/data_structures/src/tests/byte_array_reader_test.cairo index 82709c42..3fffb9e6 100644 --- a/src/data_structures/src/tests/byte_array_reader_test.cairo +++ b/src/data_structures/src/tests/byte_array_reader_test.cairo @@ -43,7 +43,6 @@ fn test_read() { let ba = test_byte_array_64(); let mut rd = ba.reader(); assert(rd.read_i8() == Option::Some(1), 'expected 1'); - // rd.read_i128().unwrap().print(); assert( rd.read_i128() == Option::Some(0x02030405060708090a0b0c0d0e0f1011), 'not 0x0203040506...' ); @@ -60,6 +59,28 @@ fn test_read() { assert(rd.read_u8().is_none(), 'expected none'); } +#[test] +#[available_gas(20000000)] +fn test_read_le() { + let ba = test_byte_array_64(); + let mut rd = ba.reader(); + assert(rd.read_i8() == Option::Some(1), 'expected 1'); + assert( + rd.read_i128_le() == Option::Some(0x11100f0e0d0c0b0a0908070605040302), 'not 0x11100f0e0...' + ); + assert( + rd.read_u128_le() == Option::Some(0x21201f1e1d1c1b1a1918171615141312), 'not 0x21201f1e1d...' + ); + assert(rd.read_i64_le() == Option::Some(0x2928272625242322), 'not 0x29282726...'); + assert( + rd.read_u128_le() == Option::Some(0x393837363534333231302f2e2d2c2b2a), 'not 0x3938373635...' + ); + assert(rd.read_u32_le() == Option::Some(0x3d3c3b3a), 'not 0x3d3c3b3a'); + assert(rd.read_i16_le() == Option::Some(0x3f3e), 'not 0x3f3e'); + assert(rd.read_u8() == Option::Some(0x40), 'not 0x40'); + assert(rd.read_u8().is_none(), 'expected none'); +} + #[test] #[available_gas(20000000)] fn test_read_u256() { @@ -70,6 +91,16 @@ fn test_read_u256() { assert(low1 == 0x1112131415161718191a1b1c1d1e1f20_u128, 'wrong value for low1'); } +#[test] +#[available_gas(20000000)] +fn test_read_u256_le() { + let ba = test_byte_array_64(); + let mut rd = ba.reader(); + let u256{low: low1, high: high1 } = rd.read_u256_le().unwrap(); + assert(high1 == 0x201f1e1d1c1b1a191817161514131211_u128, 'wrong value for high1'); + assert(low1 == 0x100f0e0d0c0b0a090807060504030201_u128, 'wrong value for low1'); +} + #[test] #[available_gas(20000000)] fn test_read_u512() { @@ -82,3 +113,15 @@ fn test_read_u512() { assert(limb1 == 0x2122232425262728292a2b2c2d2e2f30_u128, 'wrong value for limb1'); assert(limb0 == 0x3132333435363738393a3b3c3d3e3f40_u128, 'wrong value for limb0'); } + +#[test] +#[available_gas(20000000)] +fn test_read_u512_le() { + let ba = test_byte_array_64(); + let mut rd = ba.reader(); + let u512{limb0, limb1, limb2, limb3 } = rd.read_u512_le().unwrap(); + assert(limb0 == 0x100f0e0d0c0b0a090807060504030201_u128, 'wrong value for limb0'); + assert(limb1 == 0x201f1e1d1c1b1a191817161514131211_u128, 'wrong value for limb1'); + assert(limb2 == 0x302f2e2d2c2b2a292827262524232221_u128, 'wrong value for limb2'); + assert(limb3 == 0x403f3e3d3c3b3a393837363534333231_u128, 'wrong value for limb3'); +}