bytes.rs
1 // Copyright (c) 2019-2025 Alpha-Delta Network Inc. 2 // This file is part of the alphavm library. 3 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at: 7 8 // http://www.apache.org/licenses/LICENSE-2.0 9 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 use super::*; 17 18 impl<E: Environment> FromBytes for StringType<E> { 19 /// Reads the string from a buffer. 20 #[inline] 21 fn read_le<R: Read>(mut reader: R) -> IoResult<Self> { 22 // Read the number of bytes. 23 let num_bytes = u16::read_le(&mut reader)?; 24 // Ensure the number of bytes is within the allowed bounds. 25 if num_bytes as u32 > E::MAX_STRING_BYTES { 26 return Err(error(format!("String literal exceeds maximum length of {} bytes.", E::MAX_STRING_BYTES))); 27 } 28 // Read the bytes. 29 let mut bytes = vec![0u8; num_bytes as usize]; 30 reader.read_exact(&mut bytes)?; 31 // Return the string. 32 Ok(Self::new(&String::from_utf8(bytes).map_err(error)?)) 33 } 34 } 35 36 impl<E: Environment> ToBytes for StringType<E> { 37 /// Writes the string to a buffer. 38 #[inline] 39 fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> { 40 // Ensure the number of bytes is within the allowed bounds. 41 if self.string.len() > E::MAX_STRING_BYTES as usize { 42 return Err(error(format!("String literal exceeds maximum length of {} bytes.", E::MAX_STRING_BYTES))); 43 } 44 // Write the number of bytes. 45 u16::try_from(self.string.len()).or_halt_with::<E>("String exceeds u16::MAX bytes").write_le(&mut writer)?; 46 // Write the bytes. 47 self.string.as_bytes().write_le(&mut writer) 48 } 49 } 50 51 #[cfg(test)] 52 mod tests { 53 use super::*; 54 use alphavm_console_network_environment::Console; 55 56 type CurrentEnvironment = Console; 57 58 const ITERATIONS: u64 = 10_000; 59 60 #[test] 61 fn test_bytes() -> Result<()> { 62 let mut rng = TestRng::default(); 63 64 for _ in 0..ITERATIONS { 65 // Sample a new string. 66 let expected = StringType::<CurrentEnvironment>::rand(&mut rng); 67 68 // Check the byte representation. 69 let expected_bytes = expected.to_bytes_le()?; 70 assert_eq!(expected, StringType::read_le(&expected_bytes[..])?); 71 } 72 Ok(()) 73 } 74 }