From 4a339e21181c9afdf46b351b20c5d1ab68206fea Mon Sep 17 00:00:00 2001 From: Marcus Liotta Date: Tue, 17 Oct 2023 20:20:00 +0200 Subject: [PATCH] adds support for little endian --- src/data_structures/Scarb.toml | 2 + src/data_structures/src/byte_array_ext.cairo | 240 +++++++++++++++++- .../src/tests/byte_array_ext_test.cairo | 201 +++++++++++++++ 3 files changed, 429 insertions(+), 14 deletions(-) diff --git a/src/data_structures/Scarb.toml b/src/data_structures/Scarb.toml index 2a1e3f0d..a164c240 100644 --- a/src/data_structures/Scarb.toml +++ b/src/data_structures/Scarb.toml @@ -4,3 +4,5 @@ version = "0.1.0" description = "A set of Cairo data structure libraries and algorithms" homepage = "https://github.com/keep-starknet-strange/alexandria/tree/main/src/data_structures" +[dependencies] +alexandria_encoding = { path = "../encoding" } \ No newline at end of file diff --git a/src/data_structures/src/byte_array_ext.cairo b/src/data_structures/src/byte_array_ext.cairo index 7418f44c..465f23bc 100644 --- a/src/data_structures/src/byte_array_ext.cairo +++ b/src/data_structures/src/byte_array_ext.cairo @@ -1,4 +1,5 @@ use alexandria_data_structures::byte_array_reader::{ByteArrayReader, ByteArrayReaderTrait}; +use alexandria_encoding::reversible::ArrayReversibleBytes; use array::{serialize_array_helper, deserialize_array_helper}; use byte_array::ByteArray; use bytes_31::{one_shift_left_bytes_felt252, one_shift_left_bytes_u128, BYTES_IN_BYTES31}; @@ -7,74 +8,138 @@ use traits::DivRem; use core::serde::into_felt252_based::SerdeImpl; trait ByteArrayTraitExt { - /// Appends an unsigned 16 bit integer + /// Appends an unsigned 16 bit integer encoded in big endian /// # Arguments /// * `word` - a 16 bit unsigned integer typed as u16 fn append_u16(ref self: ByteArray, word: u16); - /// Appends an unsigned 32 bit integer + /// Appends an unsigned 16 bit integer encoded in little endian + /// # Arguments + /// * `word` - a 16 bit unsigned integer typed as u16 + fn append_u16_le(ref self: ByteArray, word: u16); + /// Appends an unsigned 32 bit integer encoded in big endian /// # Arguments /// * `word` - a 32 bit unsigned integer typed as u32 fn append_u32(ref self: ByteArray, word: u32); - /// Appends an unsigned 64 bit integer + /// Appends an unsigned 32 bit integer encoded in little endian + /// # Arguments + /// * `word` - a 32 bit unsigned integer typed as u32 + fn append_u32_le(ref self: ByteArray, word: u32); + /// Appends an unsigned 64 bit integer encoded in big endian /// # Arguments /// * `word` - a 64 bit unsigned integer typed as u64 fn append_u64(ref self: ByteArray, word: u64); - /// Appends an unsigned 128 bit integer + /// Appends an unsigned 64 bit integer encoded in little endian + /// # Arguments + /// * `word` - a 64 bit unsigned integer typed as u64 + fn append_u64_le(ref self: ByteArray, word: u64); + /// Appends an unsigned 128 bit integer encoded in big endian /// # Arguments /// * `word` - a 128 bit unsigned integer typed as u128 fn append_u128(ref self: ByteArray, word: u128); - /// Appends an unsigned 256 bit integer + /// Appends an unsigned 128 bit integer encoded in little endian + /// # Arguments + /// * `word` - a 128 bit unsigned integer typed as u128 + fn append_u128_le(ref self: ByteArray, word: u128); + /// Appends an unsigned 256 bit integer encoded in big endian /// # Arguments /// * `word` - a 256 bit unsigned integer typed as u256 fn append_u256(ref self: ByteArray, word: u256); - /// Appends an unsigned 512 bit integer + /// Appends an unsigned 256 bit integer encoded in little endian + /// # Arguments + /// * `word` - a 256 bit unsigned integer typed as u256 + fn append_u256_le(ref self: ByteArray, word: u256); + /// Appends an unsigned 512 bit integer encoded in big endian /// # Arguments /// * `word` - a 512 bit unsigned integer typed as u32 fn append_u512(ref self: ByteArray, word: u512); + /// Appends an unsigned 512 bit integer encoded in little endian + /// # Arguments + /// * `word` - a 512 bit unsigned integer typed as u32 + fn append_u512_le(ref self: ByteArray, word: u512); /// Appends a signed 8 bit integer /// # Arguments /// * `word` - an 8 bit signed integer typed as i8 fn append_i8(ref self: ByteArray, word: i8); - /// Appends a signed 16 bit integer + /// Appends a signed 16 bit integer encoded in big endian /// # Arguments /// * `word` - a 16 bit signed integer typed as i16 fn append_i16(ref self: ByteArray, word: i16); - /// Appends a signed 32 bit integer + /// Appends a signed 16 bit integer encoded in little endian + /// # Arguments + /// * `word` - a 16 bit signed integer typed as i16 + fn append_i16_le(ref self: ByteArray, word: i16); + /// Appends a signed 32 bit integer encoded in big endian /// # Arguments /// * `word` - a 32 bit signed integer typed as i32 fn append_i32(ref self: ByteArray, word: i32); - /// Appends a signed 64 bit integer + /// Appends a signed 32 bit integer encoded in little endian + /// # Arguments + /// * `word` - a 32 bit signed integer typed as i32 + fn append_i32_le(ref self: ByteArray, word: i32); + /// Appends a signed 64 bit integer encoded in big endian /// # Arguments /// * `word` - a 64 bit signed integer typed as i64 fn append_i64(ref self: ByteArray, word: i64); - /// Appends a signed 128 bit integer + /// Appends a signed 64 bit integer encoded in little endian + /// # Arguments + /// * `word` - a 64 bit signed integer typed as i64 + fn append_i64_le(ref self: ByteArray, word: i64); + /// Appends a signed 128 bit integer encoded in big endian /// # Arguments /// * `word` - a 128 bit signed integer typed as i128 fn append_i128(ref self: ByteArray, word: i128); - /// Reads consecutive bytes from a specified offset as an unsigned integer + /// Appends a signed 128 bit integer encoded in little endian + /// # Arguments + /// * `word` - a 128 bit signed integer typed as i128 + fn append_i128_le(ref self: ByteArray, word: i128); + /// Reads consecutive bytes from a specified offset as an unsigned integer in big endian /// # Arguments /// * `offset` - the start location of the consecutive bytes to read /// # Returns /// * `Option` - Returns an integer if there are enough consecutive bytes available in the ByteArray fn word_u16(self: @ByteArray, offset: usize) -> Option; - /// Reads consecutive bytes from a specified offset as an unsigned integer + /// Reads consecutive bytes from a specified offset as an unsigned integer in little endian + /// # Arguments + /// * `offset` - the start location of the consecutive bytes to read + /// # Returns + /// * `Option` - Returns an integer if there are enough consecutive bytes available in the ByteArray + fn word_u16_le(self: @ByteArray, offset: usize) -> Option; + /// Reads consecutive bytes from a specified offset as an unsigned integer in big endian /// # Arguments /// * `offset` - the start location of the consecutive bytes to read /// # Returns /// * `Option` - Returns an integer if there are enough consecutive bytes available in the ByteArray fn word_u32(self: @ByteArray, offset: usize) -> Option; - /// Reads consecutive bytes from a specified offset as an unsigned integer + /// Reads consecutive bytes from a specified offset as an unsigned integer in little endian + /// # Arguments + /// * `offset` - the start location of the consecutive bytes to read + /// # Returns + /// * `Option` - Returns an integer if there are enough consecutive bytes available in the ByteArray + fn word_u32_le(self: @ByteArray, offset: usize) -> Option; + /// Reads consecutive bytes from a specified offset as an unsigned integer in big endian /// # Arguments /// * `offset` - the start location of the consecutive bytes to read /// # Returns /// * `Option` - Returns an integer if there are enough consecutive bytes available in the ByteArray fn word_u64(self: @ByteArray, offset: usize) -> Option; - /// Reads consecutive bytes from a specified offset as an unsigned integer + /// Reads consecutive bytes from a specified offset as an unsigned integer in little endian + /// # Arguments + /// * `offset` - the start location of the consecutive bytes to read + /// # Returns + /// * `Option` - Returns an integer if there are enough consecutive bytes available in the ByteArray + fn word_u64_le(self: @ByteArray, offset: usize) -> Option; + /// Reads consecutive bytes from a specified offset as an unsigned integer in big endian /// # Arguments /// * `offset` - the start location of the consecutive bytes to read /// # Returns /// * `Option` - Returns an integer if there are enough consecutive bytes available in the ByteArray fn word_u128(self: @ByteArray, offset: usize) -> Option; + /// Reads consecutive bytes from a specified offset as an unsigned integer in little endian + /// # Arguments + /// * `offset` - the start location of the consecutive bytes to read + /// # Returns + /// * `Option` - Returns an integer if there are enough consecutive bytes available in the ByteArray + fn word_u128_le(self: @ByteArray, offset: usize) -> Option; /// Wraps the ByteArray in a ByteArrayReader for sequential consumption of integers and/or bytes /// # Returns /// * `ByteArrayReader` - The reader struct wrapping a read-only snapshot of this ByteArray @@ -86,24 +151,46 @@ impl ByteArrayImpl of ByteArrayTraitExt { self.append_word(word.into(), 2); } + fn append_u16_le(ref self: ByteArray, word: u16) { + self.append_word(word.reverse_bytes().into(), 2); + } + fn append_u32(ref self: ByteArray, word: u32) { self.append_word(word.into(), 4); } + fn append_u32_le(ref self: ByteArray, word: u32) { + self.append_word(word.reverse_bytes().into(), 4); + } + fn append_u64(ref self: ByteArray, word: u64) { self.append_word(word.into(), 8); } + fn append_u64_le(ref self: ByteArray, word: u64) { + self.append_word(word.reverse_bytes().into(), 8); + } + fn append_u128(ref self: ByteArray, word: u128) { self.append_word(word.into(), 16); } + fn append_u128_le(ref self: ByteArray, word: u128) { + self.append_word(word.reverse_bytes().into(), 16); + } + fn append_u256(ref self: ByteArray, word: u256) { let u256{low, high } = word; self.append_u128(high); self.append_u128(low); } + fn append_u256_le(ref self: ByteArray, word: u256) { + let u256{low, high } = word; + self.append_u128_le(low); + self.append_u128_le(high); + } + fn append_u512(ref self: ByteArray, word: u512) { let u512{limb0, limb1, limb2, limb3 } = word; self.append_u128(limb3); @@ -112,6 +199,14 @@ impl ByteArrayImpl of ByteArrayTraitExt { self.append_u128(limb0); } + fn append_u512_le(ref self: ByteArray, word: u512) { + let u512{limb0, limb1, limb2, limb3 } = word; + self.append_u128_le(limb0); + self.append_u128_le(limb1); + self.append_u128_le(limb2); + self.append_u128_le(limb3); + } + fn append_i8(ref self: ByteArray, word: i8) { if word >= 0_i8 { self.append_word(word.into(), 1); @@ -128,6 +223,16 @@ impl ByteArrayImpl of ByteArrayTraitExt { } } + fn append_i16_le(ref self: ByteArray, word: i16) { + let felt: felt252 = if word >= 0_i16 { + word.into() + } else { + word.into() + one_shift_left_bytes_felt252(2) + }; + let unsigned: u16 = felt.try_into().unwrap(); + self.append_word(unsigned.reverse_bytes().into(), 2); + } + fn append_i32(ref self: ByteArray, word: i32) { if word >= 0_i32 { self.append_word(word.into(), 4); @@ -136,6 +241,16 @@ impl ByteArrayImpl of ByteArrayTraitExt { } } + fn append_i32_le(ref self: ByteArray, word: i32) { + let felt: felt252 = if word >= 0_i32 { + word.into() + } else { + word.into() + one_shift_left_bytes_felt252(4) + }; + let unsigned: u32 = felt.try_into().unwrap(); + self.append_word(unsigned.reverse_bytes().into(), 4); + } + fn append_i64(ref self: ByteArray, word: i64) { if word >= 0_i64 { self.append_word(word.into(), 8); @@ -144,6 +259,16 @@ impl ByteArrayImpl of ByteArrayTraitExt { } } + fn append_i64_le(ref self: ByteArray, word: i64) { + let felt: felt252 = if word >= 0_i64 { + word.into() + } else { + word.into() + one_shift_left_bytes_felt252(8) + }; + let unsigned: u64 = felt.try_into().unwrap(); + self.append_word(unsigned.reverse_bytes().into(), 8); + } + fn append_i128(ref self: ByteArray, word: i128) { if word >= 0_i128 { self.append_word(word.into(), 16); @@ -152,12 +277,28 @@ impl ByteArrayImpl of ByteArrayTraitExt { } } + fn append_i128_le(ref self: ByteArray, word: i128) { + let felt: felt252 = if word >= 0_i128 { + word.into() + } else { + word.into() + one_shift_left_bytes_felt252(16) + }; + let unsigned: u128 = felt.try_into().unwrap(); + self.append_word(unsigned.reverse_bytes().into(), 16); + } + fn word_u16(self: @ByteArray, offset: usize) -> Option { let b1 = self.at(offset)?; let b2 = self.at(offset + 1)?; Option::Some(b1.into() * one_shift_left_bytes_u128(1).try_into().unwrap() + b2.into()) } + fn word_u16_le(self: @ByteArray, offset: usize) -> Option { + let b1 = self.at(offset)?; + let b2 = self.at(offset + 1)?; + Option::Some(b1.into() + b2.into() * one_shift_left_bytes_u128(1).try_into().unwrap()) + } + fn word_u32(self: @ByteArray, offset: usize) -> Option { let b1 = self.at(offset)?; let b2 = self.at(offset + 1)?; @@ -171,6 +312,19 @@ impl ByteArrayImpl of ByteArrayTraitExt { ) } + fn word_u32_le(self: @ByteArray, offset: usize) -> Option { + let b1 = self.at(offset)?; + let b2 = self.at(offset + 1)?; + let b3 = self.at(offset + 2)?; + let b4 = self.at(offset + 3)?; + Option::Some( + b1.into() + + b2.into() * one_shift_left_bytes_u128(1).try_into().unwrap() + + b3.into() * one_shift_left_bytes_u128(2).try_into().unwrap() + + b4.into() * one_shift_left_bytes_u128(3).try_into().unwrap() + ) + } + fn word_u64(self: @ByteArray, offset: usize) -> Option { let b1 = self.at(offset)?; let b2 = self.at(offset + 1)?; @@ -192,6 +346,27 @@ impl ByteArrayImpl of ByteArrayTraitExt { ) } + fn word_u64_le(self: @ByteArray, offset: usize) -> Option { + let b1 = self.at(offset)?; + let b2 = self.at(offset + 1)?; + let b3 = self.at(offset + 2)?; + let b4 = self.at(offset + 3)?; + let b5 = self.at(offset + 4)?; + let b6 = self.at(offset + 5)?; + let b7 = self.at(offset + 6)?; + let b8 = self.at(offset + 7)?; + Option::Some( + b1.into() + + b2.into() * one_shift_left_bytes_u128(1).try_into().unwrap() + + b3.into() * one_shift_left_bytes_u128(2).try_into().unwrap() + + b4.into() * one_shift_left_bytes_u128(3).try_into().unwrap() + + b5.into() * one_shift_left_bytes_u128(4).try_into().unwrap() + + b6.into() * one_shift_left_bytes_u128(5).try_into().unwrap() + + b7.into() * one_shift_left_bytes_u128(6).try_into().unwrap() + + b8.into() * one_shift_left_bytes_u128(7).try_into().unwrap() + ) + } + fn word_u128(self: @ByteArray, offset: usize) -> Option { let b01 = self.at(offset)?; let b02 = self.at(offset + 1)?; @@ -229,6 +404,43 @@ impl ByteArrayImpl of ByteArrayTraitExt { ) } + fn word_u128_le(self: @ByteArray, offset: usize) -> Option { + let b01 = self.at(offset)?; + let b02 = self.at(offset + 1)?; + let b03 = self.at(offset + 2)?; + let b04 = self.at(offset + 3)?; + let b05 = self.at(offset + 4)?; + let b06 = self.at(offset + 5)?; + let b07 = self.at(offset + 6)?; + let b08 = self.at(offset + 7)?; + let b09 = self.at(offset + 8)?; + let b10 = self.at(offset + 9)?; + let b11 = self.at(offset + 10)?; + let b12 = self.at(offset + 11)?; + let b13 = self.at(offset + 12)?; + let b14 = self.at(offset + 13)?; + let b15 = self.at(offset + 14)?; + let b16 = self.at(offset + 15)?; + Option::Some( + b01.into() + + b02.into() * one_shift_left_bytes_u128(01).try_into().unwrap() + + b03.into() * one_shift_left_bytes_u128(02).try_into().unwrap() + + b04.into() * one_shift_left_bytes_u128(03).try_into().unwrap() + + b05.into() * one_shift_left_bytes_u128(04).try_into().unwrap() + + b06.into() * one_shift_left_bytes_u128(05).try_into().unwrap() + + b07.into() * one_shift_left_bytes_u128(06).try_into().unwrap() + + b08.into() * one_shift_left_bytes_u128(07).try_into().unwrap() + + b09.into() * one_shift_left_bytes_u128(08).try_into().unwrap() + + b10.into() * one_shift_left_bytes_u128(09).try_into().unwrap() + + b11.into() * one_shift_left_bytes_u128(10).try_into().unwrap() + + b12.into() * one_shift_left_bytes_u128(11).try_into().unwrap() + + b13.into() * one_shift_left_bytes_u128(12).try_into().unwrap() + + b14.into() * one_shift_left_bytes_u128(13).try_into().unwrap() + + b15.into() * one_shift_left_bytes_u128(14).try_into().unwrap() + + b16.into() * one_shift_left_bytes_u128(15).try_into().unwrap() + ) + } + fn reader(self: @ByteArray) -> ByteArrayReader { ByteArrayReaderTrait::new(self) } diff --git a/src/data_structures/src/tests/byte_array_ext_test.cairo b/src/data_structures/src/tests/byte_array_ext_test.cairo index 361bef86..fc932229 100644 --- a/src/data_structures/src/tests/byte_array_ext_test.cairo +++ b/src/data_structures/src/tests/byte_array_ext_test.cairo @@ -12,6 +12,17 @@ fn test_append_u16() { assert(ba == test_byte_array_8(), 'u16 differs'); } +#[test] +#[available_gas(1000000)] +fn test_append_u16_le() { + let mut ba: ByteArray = Default::default(); + ba.append_u16_le(0x0201_u16); + ba.append_u16_le(0x0403_u16); + ba.append_u16_le(0x0605_u16); + ba.append_u16_le(0x0807_u16); + assert(ba == test_byte_array_8(), 'u16 differs'); +} + #[test] #[available_gas(1000000)] fn test_append_u32() { @@ -21,6 +32,15 @@ fn test_append_u32() { assert(ba == test_byte_array_8(), 'u32 differs'); } +#[test] +#[available_gas(1000000)] +fn test_append_u32_le() { + let mut ba: ByteArray = Default::default(); + ba.append_u32_le(0x04030201_u32); + ba.append_u32_le(0x08070605_u32); + assert(ba == test_byte_array_8(), 'u32 differs'); +} + #[test] #[available_gas(1000000)] fn test_append_u64() { @@ -30,6 +50,15 @@ fn test_append_u64() { assert(ba == test_byte_array_16(), 'u64 differs'); } +#[test] +#[available_gas(1000000)] +fn test_append_u64_le() { + let mut ba: ByteArray = Default::default(); + ba.append_u64_le(0x0807060504030201_u64); + ba.append_u64_le(0x100f0e0d0c0b0a09_u64); + assert(ba == test_byte_array_16(), 'u64 differs'); +} + #[test] #[available_gas(1000000)] fn test_append_u128() { @@ -39,6 +68,15 @@ fn test_append_u128() { assert(ba == test_byte_array_32(), 'u128 differs'); } +#[test] +#[available_gas(1000000)] +fn test_append_u128_le() { + let mut ba: ByteArray = Default::default(); + ba.append_u128_le(0x100f0e0d0c0b0a090807060504030201_u128); + ba.append_u128_le(0x201f1e1d1c1b1a191817161514131211_u128); + assert(ba == test_byte_array_32(), 'u128 differs'); +} + #[test] #[available_gas(1000000)] fn test_append_u256() { @@ -50,6 +88,17 @@ fn test_append_u256() { assert(ba == test_byte_array_32(), 'u256 differs'); } +#[test] +#[available_gas(1000000)] +fn test_append_u256_le() { + let mut ba: ByteArray = Default::default(); + let word = u256 { + low: 0x100f0e0d0c0b0a090807060504030201_u128, high: 0x201f1e1d1c1b1a191817161514131211_u128, + }; + ba.append_u256_le(word); + assert(ba == test_byte_array_32(), 'u256 differs'); +} + #[test] #[available_gas(1000000)] fn test_append_u512() { @@ -65,6 +114,21 @@ fn test_append_u512() { assert(ba == test_byte_array_64(), 'test64 differs'); } +#[test] +#[available_gas(10000000)] +fn test_append_u512_le() { + let test64 = u512 { + limb0: 0x100f0e0d0c0b0a090807060504030201_u128, + limb1: 0x201f1e1d1c1b1a191817161514131211_u128, + limb2: 0x302f2e2d2c2b2a292827262524232221_u128, + limb3: 0x403f3e3d3c3b3a393837363534333231_u128, + }; + + let mut ba: ByteArray = Default::default(); + ba.append_u512_le(test64); + assert(ba == test_byte_array_64(), 'test64 differs'); +} + #[test] #[available_gas(1000000)] fn test_append_i8() { @@ -96,6 +160,17 @@ fn test_append_i16() { assert(ba1 == test_byte_array_8(), 'i16 differs'); } +#[test] +#[available_gas(1000000)] +fn test_append_i16_le() { + let mut ba1 = Default::default(); + ba1.append_i16_le(0x0201_i16); + ba1.append_i16_le(0x0403_i16); + ba1.append_i16_le(0x0605_i16); + ba1.append_i16_le(0x0807_i16); + assert(ba1 == test_byte_array_8(), 'i16 differs'); +} + #[test] #[available_gas(1000000)] fn test_append_i16_neg() { @@ -111,6 +186,21 @@ fn test_append_i16_neg() { assert(ba1 == test_byte_array_16_neg(), 'negative i16 differs'); } +#[test] +#[available_gas(1000000)] +fn test_append_i16_le_neg() { + let mut ba1 = Default::default(); + ba1.append_i16_le(-1_i16); + ba1.append_i16_le(-1_i16); + ba1.append_i16_le(-1_i16); + ba1.append_i16_le(-1_i16); + ba1.append_i16_le(-1_i16); + ba1.append_i16_le(-1_i16); + ba1.append_i16_le(-1_i16); + ba1.append_i16_le(-257_i16); + assert(ba1 == test_byte_array_16_neg(), 'negative i16 differs'); +} + #[test] #[available_gas(1000000)] fn test_append_i32() { @@ -120,6 +210,15 @@ fn test_append_i32() { assert(ba == test_byte_array_8(), 'i32 differs'); } +#[test] +#[available_gas(1000000)] +fn test_append_i32_le() { + let mut ba = Default::default(); + ba.append_i32_le(0x04030201_i32); + ba.append_i32_le(0x08070605_i32); + assert(ba == test_byte_array_8(), 'i32 differs'); +} + #[test] #[available_gas(1000000)] fn test_append_i32_neg() { @@ -131,6 +230,17 @@ fn test_append_i32_neg() { assert(ba == test_byte_array_16_neg(), 'negative i32 differs'); } +#[test] +#[available_gas(1000000)] +fn test_append_i32_le_neg() { + let mut ba = Default::default(); + ba.append_i32_le(-1_i32); + ba.append_i32_le(-1_i32); + ba.append_i32_le(-1_i32); + ba.append_i32_le(-16777217_i32); + assert(ba == test_byte_array_16_neg(), 'negative i32 differs'); +} + #[test] #[available_gas(1000000)] fn test_append_i64() { @@ -140,6 +250,15 @@ fn test_append_i64() { assert(ba == test_byte_array_16(), 'i64 differs'); } +#[test] +#[available_gas(1000000)] +fn test_append_i64_le() { + let mut ba: ByteArray = Default::default(); + ba.append_i64_le(0x0807060504030201_i64); + ba.append_i64_le(0x100f0e0d0c0b0a09_i64); + assert(ba == test_byte_array_16(), 'i64 differs'); +} + #[test] #[available_gas(1000000)] fn test_append_i64_neg() { @@ -149,6 +268,15 @@ fn test_append_i64_neg() { assert(ba == test_byte_array_16_neg(), 'negative i64 differs'); } +#[test] +#[available_gas(1000000)] +fn test_append_i64_le_neg() { + let mut ba: ByteArray = Default::default(); + ba.append_i64_le(-1_i64); + ba.append_i64_le(-72057594037927937_i64); + assert(ba == test_byte_array_16_neg(), 'negative i64 differs'); +} + #[test] #[available_gas(1000000)] fn test_append_i128() { @@ -158,6 +286,15 @@ fn test_append_i128() { assert(ba == test_byte_array_32(), 'i128 differs'); } +#[test] +#[available_gas(1000000)] +fn test_append_i128_le() { + let mut ba: ByteArray = Default::default(); + ba.append_i128_le(0x100f0e0d0c0b0a090807060504030201_i128); + ba.append_i128_le(0x201f1e1d1c1b1a191817161514131211_i128); + assert(ba == test_byte_array_32(), 'i128 differs'); +} + #[test] #[available_gas(1000000)] fn test_append_i128_neg() { @@ -166,6 +303,14 @@ fn test_append_i128_neg() { assert(ba == test_byte_array_16_neg(), 'negative i128 differs'); } +#[test] +#[available_gas(1000000)] +fn test_append_i128_le_neg() { + let mut ba: ByteArray = Default::default(); + ba.append_i128_le(-1329227995784915872903807060280344577_i128); + assert(ba == test_byte_array_16_neg(), 'negative i128 differs'); +} + #[test] #[available_gas(1000000)] fn test_word_u16() { @@ -173,6 +318,13 @@ fn test_word_u16() { assert(word == 0x3f40_u16, 'word u16 differs'); } +#[test] +#[available_gas(1000000)] +fn test_word_u16_le() { + let word = test_byte_array_64().word_u16_le(62).unwrap(); + assert(word == 0x403f_u16, 'word u16 differs'); +} + #[test] #[available_gas(1000000)] fn test_word_u16_none() { @@ -180,6 +332,13 @@ fn test_word_u16_none() { assert(is_none, 'word u16 should be empty'); } +#[test] +#[available_gas(1000000)] +fn test_word_u16_le_none() { + let is_none = test_byte_array_64().word_u16_le(63).is_none(); + assert(is_none, 'word u16 should be empty'); +} + #[test] #[available_gas(1000000)] fn test_word_u32() { @@ -187,6 +346,13 @@ fn test_word_u32() { assert(word == 0x3d3e3f40_u32, 'word u32 differs'); } +#[test] +#[available_gas(1000000)] +fn test_word_u32_le() { + let word = test_byte_array_64().word_u32_le(60).unwrap(); + assert(word == 0x403f3e3d_u32, 'word u32 differs'); +} + #[test] #[available_gas(1000000)] fn test_word_u32_none() { @@ -194,6 +360,13 @@ fn test_word_u32_none() { assert(is_none, 'word u32 should be empty'); } +#[test] +#[available_gas(1000000)] +fn test_word_u32_le_none() { + let is_none = test_byte_array_64().word_u32_le(61).is_none(); + assert(is_none, 'word u32 should be empty'); +} + #[test] #[available_gas(1000000)] fn test_word_u64() { @@ -201,6 +374,13 @@ fn test_word_u64() { assert(word == 0x393a3b3c3d3e3f40_u64, 'word u64 differs'); } +#[test] +#[available_gas(1000000)] +fn test_word_u64_le() { + let word = test_byte_array_64().word_u64_le(56).unwrap(); + assert(word == 0x403f3e3d3c3b3a39_u64, 'word u64 differs'); +} + #[test] #[available_gas(1000000)] fn test_word_u64_none() { @@ -208,6 +388,13 @@ fn test_word_u64_none() { assert(is_none, 'word u64 should be empty'); } +#[test] +#[available_gas(1000000)] +fn test_word_u64_le_none() { + let is_none = test_byte_array_64().word_u64_le(57).is_none(); + assert(is_none, 'word u64 should be empty'); +} + #[test] #[available_gas(2000000)] fn test_word_u128() { @@ -215,6 +402,13 @@ fn test_word_u128() { assert(word == 0x3132333435363738393a3b3c3d3e3f40_u128, 'word u128 differs'); } +#[test] +#[available_gas(2000000)] +fn test_word_u128_le() { + let word = test_byte_array_64().word_u128_le(48).unwrap(); + assert(word == 0x403f3e3d3c3b3a393837363534333231_u128, 'word u128 differs'); +} + #[test] #[available_gas(2000000)] fn test_word_u128_none() { @@ -222,6 +416,13 @@ fn test_word_u128_none() { assert(is_none, 'word u128 should be empty'); } +#[test] +#[available_gas(2000000)] +fn test_word_u128_le_none() { + let is_none = test_byte_array_64().word_u128_le(49).is_none(); + assert(is_none, 'word u128 should be empty'); +} + #[test] #[available_gas(2000000)] fn test_reader_helper() {