From f279e44efcd7f09374f5b4e19ff9f1daaf613225 Mon Sep 17 00:00:00 2001 From: ismail Date: Fri, 7 Nov 2025 10:49:43 +0300 Subject: [PATCH 1/5] organized binary --- src/lib.rs | 447 ++++++++++++++++++++++++----------------------------- 1 file changed, 202 insertions(+), 245 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 13db39c..69a397d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,373 +5,323 @@ pub mod binary { } impl Stream { + #[inline] pub fn new(buffer: Vec, offset: u32) -> Self { - Self {buffer, offset} + Self { buffer, offset } } + #[inline] + pub fn with_capacity(capacity: usize) -> Self { + Self { + buffer: Vec::with_capacity(capacity), + offset: 0, + } + } + + #[inline] pub fn rewind(&mut self) { self.offset = 0; } + #[inline] pub fn set_offset(&mut self, offset: u32) { - self.offset = offset + if offset <= self.buffer.len() as u32 { + self.offset = offset; + } else { + panic!("Offset out of bounds"); + } } + #[inline] pub fn get_offset(&self) -> u32 { self.offset } - pub fn get_buffer(&self) -> Vec { - self.buffer.to_vec() + #[inline] + pub fn get_buffer(&self) -> &[u8] { + &self.buffer } - pub fn get(&mut self, length: u32) -> Result, String> { + pub fn get(&mut self, length: u32) -> Vec { let end_index: usize = (self.offset + length) as usize; if end_index <= self.buffer.len() { let start_index: usize = self.offset as usize; self.offset += length; - Ok(self.buffer[start_index..end_index].to_vec()) + self.buffer[start_index..end_index].to_vec() } else { - Err(String::from("The specified range is invalid.")) + panic!("The specified range is invalid."); } } - - pub fn get_remaining(&self) -> Result, String> { - let buff_len = self.buffer.len() as u32; - if self.offset >= buff_len { - return Err(String::from("No bytes left to read")).expect("No bytes left to read"); + pub fn get_remaining(&self) -> Vec { + if self.offset >= self.buffer.len() as u32 { + panic!("Error get_remaining(): No bytes left to read"); + } else { + self.buffer[self.offset..].to_vec() } - Ok(self.buffer[(self.offset as usize)..].to_vec()) } + #[inline] pub fn put(&mut self, value: Vec) { self.buffer.extend(value); } + #[inline] pub fn get_bool(&mut self) -> bool { - let byte = self.get(1); - match byte { - Ok(b) => { - b[0] != 0 - } + match self.get(1) { + Ok(bytes) => bytes[0] != 0, Err(err) => { - println!("Error get_bool(): {}", err); - false + panic!("Error get_bool(): Not enough bytes, Error: {:?}", err); } } } + #[inline] pub fn put_bool(&mut self, value: bool) { - let byte = if value { 0x01 } else { 0x00 }; - self.buffer.push(byte); + self.buffer.push(if value { 0x01 } else { 0x00 }); } + #[inline] pub fn get_byte(&mut self) -> u8 { - let byte = self.get(1); - match byte { - Ok(b) => { - b[0] - } + match self.get(1) { + Ok(bytes) => bytes[0], Err(err) => { - println!("Error get_byte(): {}", err); - 0 + panic!("Error get_byte(): Not enough bytes, Error: {:?}", err); } } } + #[inline] pub fn put_byte(&mut self, value: u8) { self.buffer.push(value); } - pub fn get_short(&mut self) -> u16 { - let bytes = self.get(2); - - - match bytes { - Ok(byte) => { - let high_byte = byte[0] as u16; - let low_byte = byte[1] as u16; - (high_byte << 8) | low_byte - } + // Big-endian (network byte order) + #[inline] + pub fn get_be_unsigned_short(&mut self) -> u16 { + match self.get(2) { + Ok(bytes) => u16::from_be_bytes([bytes[0], bytes[1]]), Err(err) => { - println!("Error get_short(): {}", err); - 0 + panic!("Error get_short(): Not enough bytes, Error: {:?}", err); } } } - pub fn get_signed_short(&mut self) -> i16 { - let bytes = self.get(2); - match bytes { - Ok(byte) => { - i16::from_le_bytes([byte[0], byte[1]]) - } + #[inline] + pub fn get_be_signed_short(&mut self) -> i16 { + match self.get(2) { + Ok(bytes) => i16::from_be_bytes([bytes[0], bytes[1]]), Err(err) => { - println!("Error get_signed_short(): {}", err); - 0 + panic!("Error get_signed_short(): Not enough bytes, Error: {:?}", err); } } } - pub fn put_short(&mut self, value: u16) { - self.buffer.push((value >> 8) as u8); - self.buffer.push((value & 0xFF) as u8); + #[inline] + pub fn put_be_unsigned_short(&mut self, value: u16) { + self.buffer.extend_from_slice(&value.to_be_bytes()); } - pub fn get_l_short(&mut self) -> u16 { - let bytes = self.get(2); + #[inline] + pub fn put_be_signed_short(&mut self, value: i16) { + self.buffer.extend_from_slice(&value.to_be_bytes()); + } - match bytes { - Ok(byte) => { - let low_byte = byte[0] as u16; - let high_byte = byte[1] as u16; - low_byte | (high_byte << 8) - } + // Little-endian + #[inline] + pub fn get_le_unsigned_short(&mut self) -> u16 { + match self.get(2) { + Ok(bytes) => u16::from_le_bytes([bytes[0], bytes[1]]), Err(err) => { - println!("Error get_l_short(): {}", err); - 0 + panic!("Error get_l_short(): Not enough bytes, Error: {:?}", err); } } } - pub fn get_signed_l_short(&mut self) -> i16 { - let bytes = self.get(2); - - match bytes { - Ok(byte) => { - let low_byte = byte[0] as i16; - let high_byte = byte[1] as i16; - (high_byte << 8) | low_byte - } + #[inline] + pub fn get_le_signed_short(&mut self) -> i16 { + match self.get(2) { + Ok(bytes) => i16::from_le_bytes([bytes[0], bytes[1]]), Err(err) => { - println!("Error get_signed_l_short(): {}", err); - 0 + panic!("Error get_signed_l_short(): Not enough bytes, Error: {:?}", err); } } } - pub fn put_l_short(&mut self, value: u16) { - self.buffer.push((value & 0xFF) as u8); // Low byte - self.buffer.push((value >> 8) as u8); // High byte + #[inline] + pub fn put_le_unsigned_short(&mut self, value: u16) { + self.buffer.extend_from_slice(&value.to_le_bytes()); } - pub fn put_signed_l_short(&mut self, value: i16) { - self.buffer.push((value & 0xFF) as u8); // Low byte - self.buffer.push(((value >> 8) & 0xFF) as u8); // High byte + #[inline] + pub fn put_le_signed_short(&mut self, value: i16) { + self.buffer.extend_from_slice(&value.to_le_bytes()); } - pub fn get_triad(&mut self) -> i32 { - let bytes = self.get(3); - - match bytes { - Ok(byte) => { - ((byte[0] as i32) << 16) | ((byte[1] as i32) << 8) | (byte[2] as i32) - } + // 24-bit integers (Triad) - Big-endian + #[inline] + pub fn get_be_triad(&mut self) -> i32 { + match self.get(3) { + Ok(bytes) => i32::from_be_bytes([0, bytes[0], bytes[1], bytes[2]]), Err(err) => { - println!("Error get_triad(): {}", err); - 0 + panic!("Error get_triad(): Not enough bytes, Error: {:?}", err); } } } - pub fn put_triad(&mut self, value: i32) { - self.buffer.push(((value >> 16) & 0xFF) as u8); - self.buffer.push(((value >> 8) & 0xFF) as u8); - self.buffer.push((value & 0xFF) as u8); + #[inline] + pub fn put_be_triad(&mut self, value: i32) { + let bytes = value.to_be_bytes(); + self.buffer.extend_from_slice(&bytes[1..4]); } - pub fn get_l_triad(&mut self) -> i32 { - let bytes = self.get(3); - - match bytes { - Ok(byte) => { - (byte[0] as i32) | ((byte[1] as i32) << 8) | ((byte[2] as i32) << 16) - } + // 24-bit integers (Triad) - Little-endian + #[inline] + pub fn get_le_triad(&mut self) -> i32 { + match self.get(3) { + Ok(bytes) => i32::from_le_bytes([bytes[0], bytes[1], bytes[2], 0]), Err(err) => { - println!("Error get_l_triad(): {}", err); - 0 + panic!("Error get_l_triad(): Not enough bytes, Error: {:?}", err); } } } - pub fn put_l_triad(&mut self, value: i32) { - self.buffer.push((value & 0xFF) as u8); - self.buffer.push(((value >> 8) & 0xFF) as u8); - self.buffer.push(((value >> 16) & 0xFF) as u8); + #[inline] + pub fn put_le_triad(&mut self, value: i32) { + let bytes = value.to_le_bytes(); + self.buffer.extend_from_slice(&bytes[0..3]); } - pub fn get_int(&mut self) -> u32 { - let bytes = self.get(4); - match bytes { - Ok(byte) => { - u32::from_be_bytes([byte[0], byte[1], byte[2], byte[3]]) - } + // 32-bit integers - Big-endian + #[inline] + pub fn get_be_unsigned_int(&mut self) -> u32 { + match self.get(4) { + Ok(bytes) => u32::from_be_bytes(bytes.try_into().unwrap()), Err(err) => { - println!("Error get_int(): {}", err); - 0 + panic!("Error get_int(): Not enough bytes, Error: {:?}", err); } } } - pub fn put_int(&mut self, value: u32) { - let bytes: [u8; 4] = value.to_be_bytes(); - self.buffer.extend_from_slice(&bytes); + #[inline] + pub fn put_be_unsigned_int(&mut self, value: u32) { + self.buffer.extend_from_slice(&value.to_be_bytes()); } - pub fn get_l_int(&mut self) -> u32 { - let bytes = self.get(4); - match bytes { - Ok(byte) => { - u32::from_le_bytes([byte[0], byte[1], byte[2], byte[3]]) - } + // 32-bit integers - Little-endian + #[inline] + pub fn get_le_unsigned_int(&mut self) -> u32 { + match self.get(4) { + Ok(bytes) => u32::from_le_bytes(bytes.try_into().unwrap()), Err(err) => { - println!("Error get_l_int(): {}", err); - 0 + panic!("Error get_l_int(): Not enough bytes, Error: {:?}", err); } } } - pub fn put_l_int(&mut self, value: u32) { - let bytes: [u8; 4] = value.to_le_bytes(); - self.buffer.extend_from_slice(&bytes); + #[inline] + pub fn put_le_unsigned_int(&mut self, value: u32) { + self.buffer.extend_from_slice(&value.to_le_bytes()); } - pub fn get_float(&mut self) -> f32 { - let bytes = self.get(4); - - match bytes { - Ok(byte) => { - f32::from_be_bytes([byte[0], byte[1], byte[2], byte[3]]) - } + // 32-bit floats - Big-endian + #[inline] + pub fn get_be_float(&mut self) -> f32 { + match self.get(4) { + Ok(bytes) => f32::from_be_bytes(bytes.try_into().unwrap()), Err(err) => { - println!("Error get_float(): {}", err); - 0.0 + panic!("Error get_float(): Not enough bytes, Error: {:?}", err); } } } - /*pub fn get_rounded_float(&mut self, accuracy: usize) -> Result { - let bytes = self.get(4); - - match bytes { - Ok(byte) => { - f32::from_be_bytes([byte[0], byte[1], byte[2], byte[3]]) - } - Err(err) => { - println!("Error get_int(): {}", err); - 0.0 - } - } - Self::read_rounded_float(&bytes, accuracy) - }*/ - /* fn get_rounded_l_float(&mut self, accuracy: usize) -> f32 { - let bytes = self.get(4)?; // Get 4 bytes from the stream - let value = Self::read_lfloat(bytes)?; - Ok((value * 10f32.powf(accuracy as f32)).round() / 10f32.powf(accuracy as f32)) - }*/ - - pub fn put_float(&mut self, value: f32) { - let bytes: [u8; 4] = value.to_be_bytes(); - self.buffer.extend_from_slice(&bytes); + #[inline] + pub fn put_be_float(&mut self, value: f32) { + self.buffer.extend_from_slice(&value.to_be_bytes()); } - pub fn get_l_float(&mut self) -> f32 { - let bytes = self.get(4); - - match bytes { - Ok(byte) => { - f32::from_le_bytes([byte[0], byte[1], byte[2], byte[3]]) - } + // 32-bit floats - Little-endian + #[inline] + pub fn get_le_float(&mut self) -> f32 { + match self.get(4) { + Ok(bytes) => f32::from_le_bytes(bytes.try_into().unwrap()), Err(err) => { - println!("Error get_l_float(): {}", err); - 0.0 + panic!("Error get_l_float(): Not enough bytes, Error: {:?}", err); } } } - pub fn put_l_float(&mut self, value: f32) { - let bytes: [u8; 4] = value.to_le_bytes(); - self.buffer.extend_from_slice(&bytes); + #[inline] + pub fn put_le_float(&mut self, value: f32) { + self.buffer.extend_from_slice(&value.to_le_bytes()); } - pub fn get_double(&mut self) -> f64 { - let bytes = self.get(8); - - match bytes { - Ok(byte) => { - f64::from_be_bytes([byte[0], byte[1], byte[2], byte[3], byte[4], byte[5], byte[6], byte[7]]) - } + // 64-bit floats - Big-endian + #[inline] + pub fn get_be_double(&mut self) -> f64 { + match self.get(8) { + Ok(bytes) => f64::from_be_bytes(bytes.try_into().unwrap()), Err(err) => { - println!("Error get_double(): {}", err); - 0.0 + panic!("Error get_double(): Not enough bytes, Error: {:?}", err); } } } - pub fn put_double(&mut self, value: f64) { - let bytes: [u8; 8] = value.to_be_bytes(); - self.buffer.extend_from_slice(&bytes); + #[inline] + pub fn put_be_double(&mut self, value: f64) { + self.buffer.extend_from_slice(&value.to_be_bytes()); } - pub fn get_l_double(&mut self) -> f64 { - let bytes = self.get(8); - - match bytes { - Ok(byte) => { - f64::from_le_bytes([byte[0], byte[1], byte[2], byte[3], byte[4], byte[5], byte[6], byte[7]]) - } + // 64-bit floats - Little-endian + #[inline] + pub fn get_le_double(&mut self) -> f64 { + match self.get(8) { + Ok(bytes) => f64::from_le_bytes(bytes.try_into().unwrap()), Err(err) => { - println!("Error get_l_double(): {}", err); - 0.0 + panic!("Error get_l_double(): Not enough bytes, Error: {:?}", err); } } } - pub fn put_l_double(&mut self, value: f64) { - let bytes: [u8; 8] = value.to_le_bytes(); - self.buffer.extend_from_slice(&bytes); + #[inline] + pub fn put_le_double(&mut self, value: f64) { + self.buffer.extend_from_slice(&value.to_le_bytes()); } - pub fn get_long(&mut self) -> i64 { - let bytes = self.get(8); - - match bytes { - Ok(byte) => { - i64::from_be_bytes([byte[0], byte[1], byte[2], byte[3], byte[4], byte[5], byte[6], byte[7]]) - } + // 64-bit integers - Big-endian + #[inline] + pub fn get_be_signed_long(&mut self) -> i64 { + match self.get(8) { + Ok(bytes) => i64::from_be_bytes(bytes.try_into().unwrap()), Err(err) => { - println!("Error get_long(): {}", err); - 0 + panic!("Error get_long(): Not enough bytes, Error: {:?}", err); } } } - pub fn put_long(&mut self, value: i64) { - let bytes: [u8; 8] = value.to_be_bytes(); - self.buffer.extend_from_slice(&bytes); + #[inline] + pub fn put_be_signed_long(&mut self, value: i64) { + self.buffer.extend_from_slice(&value.to_be_bytes()); } - pub fn get_l_long(&mut self) -> i64 { - let bytes = self.get(8); - - match bytes { - Ok(byte) => { - i64::from_le_bytes([byte[0], byte[1], byte[2], byte[3], byte[4], byte[5], byte[6], byte[7]]) - } + // 64-bit integers - Little-endian + #[inline] + pub fn get_le_signed_long(&mut self) -> i64 { + match self.get(8) { + Ok(bytes) => i64::from_le_bytes(bytes.try_into().unwrap()), Err(err) => { - println!("Error get_l_long(): {}", err); - 0 + panic!("Error get_l_long(): Not enough bytes, Error: {:?}", err); } } } - pub fn put_l_long(&mut self, value: i64) { - let bytes: [u8; 8] = value.to_le_bytes(); - self.buffer.extend_from_slice(&bytes); + #[inline] + pub fn put_le_signed_long(&mut self, value: i64) { + self.buffer.extend_from_slice(&value.to_le_bytes()); } + // Variable-length integers pub fn get_unsigned_var_int(&mut self) -> u32 { let mut value = 0u32; for i in 0..5 { @@ -381,32 +331,31 @@ pub mod binary { return value; } } - println!("Error get_unsigned_var_int()"); - 0 + panic!("VarInt did not terminate after 5 bytes!"); } pub fn put_unsigned_var_int(&mut self, mut value: u32) { - for _ in 0..5 { - if (value >> 7) != 0{ - self.buffer.push((value | 0x80) as u8); - }else{ - self.buffer.push((value & 0x7f) as u8); - return; + loop { + if value >= 0x80 { + self.buffer.push((value as u8) | 0x80); + value >>= 7; + } else { + self.buffer.push(value as u8); + break; } - - value = value >> 7; } } + #[inline] pub fn get_var_int(&mut self) -> i32 { - let raw: u32 = self.get_unsigned_var_int(); + let raw = self.get_unsigned_var_int(); ((raw >> 1) as i32) ^ -((raw & 1) as i32) - } + #[inline] pub fn put_var_int(&mut self, value: i32) { - let value: i32 = (value << 1) ^ (value >> 31); - self.put_unsigned_var_int(value as u32); + let encoded = ((value << 1) ^ (value >> 31)) as u32; + self.put_unsigned_var_int(encoded); } pub fn get_unsigned_var_long(&mut self) -> u64 { @@ -418,30 +367,38 @@ pub mod binary { return value; } } - 0 + panic!("VarLong did not terminate after 10 bytes!"); } pub fn put_unsigned_var_long(&mut self, mut value: u64) { - let mut buf = Vec::new(); - while value >= 0x80 { - buf.push((value as u8) | 0x80); - value >>= 7; + loop { + if value >= 0x80 { + self.buffer.push((value as u8) | 0x80); + value >>= 7; + } else { + self.buffer.push(value as u8); + break; + } } - buf.push(value as u8); - self.put(buf); } + #[inline] pub fn get_var_long(&mut self) -> i64 { - let raw = self.get_unsigned_var_long(); - (((raw << 63) >> 63) ^ raw >> 1 ^ (raw & (1 << 63))) as i64 + match self.get_unsigned_var_long() { + Ok(raw) => ((raw >> 1) as i64) ^ (-((raw & 1) as i64)), + Err(err) => { + panic!("Error get_var_long(): Failed to read unsigned var long, Error: {:?}", err); + } + } } + #[inline] pub fn put_var_long(&mut self, value: i64) { - let value: i64 = (value << 1) ^ (value >> 63); - self.put_unsigned_var_long(value as u64); + let encoded = ((value << 1) ^ (value >> 63)) as u64; + self.put_unsigned_var_long(encoded); } - /// Returns whether the offset has reached the end of the buffer. + #[inline] pub fn feof(&self) -> bool { self.offset >= self.buffer.len() as u32 } From 60efdded3d421ca3d2532f6f6f53b3277b0ce40f Mon Sep 17 00:00:00 2001 From: ismail Date: Fri, 7 Nov 2025 11:09:37 +0300 Subject: [PATCH 2/5] error fix #1 --- src/lib.rs | 136 ++++++++++++++--------------------------------------- 1 file changed, 34 insertions(+), 102 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 69a397d..5313cc4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -69,12 +69,8 @@ pub mod binary { #[inline] pub fn get_bool(&mut self) -> bool { - match self.get(1) { - Ok(bytes) => bytes[0] != 0, - Err(err) => { - panic!("Error get_bool(): Not enough bytes, Error: {:?}", err); - } - } + let bytes = self.get(1); + bytes[0] != 0 } #[inline] @@ -84,12 +80,8 @@ pub mod binary { #[inline] pub fn get_byte(&mut self) -> u8 { - match self.get(1) { - Ok(bytes) => bytes[0], - Err(err) => { - panic!("Error get_byte(): Not enough bytes, Error: {:?}", err); - } - } + let bytes = self.get(1); + bytes[0] } #[inline] @@ -100,22 +92,14 @@ pub mod binary { // Big-endian (network byte order) #[inline] pub fn get_be_unsigned_short(&mut self) -> u16 { - match self.get(2) { - Ok(bytes) => u16::from_be_bytes([bytes[0], bytes[1]]), - Err(err) => { - panic!("Error get_short(): Not enough bytes, Error: {:?}", err); - } - } + let bytes = self.get(2); + u16::from_be_bytes([bytes[0], bytes[1]]) } #[inline] pub fn get_be_signed_short(&mut self) -> i16 { - match self.get(2) { - Ok(bytes) => i16::from_be_bytes([bytes[0], bytes[1]]), - Err(err) => { - panic!("Error get_signed_short(): Not enough bytes, Error: {:?}", err); - } - } + let bytes = self.get(2); + i16::from_be_bytes([bytes[0], bytes[1]]) } #[inline] @@ -131,22 +115,14 @@ pub mod binary { // Little-endian #[inline] pub fn get_le_unsigned_short(&mut self) -> u16 { - match self.get(2) { - Ok(bytes) => u16::from_le_bytes([bytes[0], bytes[1]]), - Err(err) => { - panic!("Error get_l_short(): Not enough bytes, Error: {:?}", err); - } - } + let bytes = self.get(2); + u16::from_le_bytes([bytes[0], bytes[1]]) } #[inline] pub fn get_le_signed_short(&mut self) -> i16 { - match self.get(2) { - Ok(bytes) => i16::from_le_bytes([bytes[0], bytes[1]]), - Err(err) => { - panic!("Error get_signed_l_short(): Not enough bytes, Error: {:?}", err); - } - } + let bytes = self.get(2); + i16::from_le_bytes([bytes[0], bytes[1]]) } #[inline] @@ -162,12 +138,8 @@ pub mod binary { // 24-bit integers (Triad) - Big-endian #[inline] pub fn get_be_triad(&mut self) -> i32 { - match self.get(3) { - Ok(bytes) => i32::from_be_bytes([0, bytes[0], bytes[1], bytes[2]]), - Err(err) => { - panic!("Error get_triad(): Not enough bytes, Error: {:?}", err); - } - } + let bytes = self.get(3); + i32::from_be_bytes([0, bytes[0], bytes[1], bytes[2]]) } #[inline] @@ -179,12 +151,8 @@ pub mod binary { // 24-bit integers (Triad) - Little-endian #[inline] pub fn get_le_triad(&mut self) -> i32 { - match self.get(3) { - Ok(bytes) => i32::from_le_bytes([bytes[0], bytes[1], bytes[2], 0]), - Err(err) => { - panic!("Error get_l_triad(): Not enough bytes, Error: {:?}", err); - } - } + let bytes = self.get(3); + i32::from_le_bytes([bytes[0], bytes[1], bytes[2], 0]) } #[inline] @@ -196,12 +164,8 @@ pub mod binary { // 32-bit integers - Big-endian #[inline] pub fn get_be_unsigned_int(&mut self) -> u32 { - match self.get(4) { - Ok(bytes) => u32::from_be_bytes(bytes.try_into().unwrap()), - Err(err) => { - panic!("Error get_int(): Not enough bytes, Error: {:?}", err); - } - } + let bytes = self.get(4); + u32::from_be_bytes(bytes.try_into().unwrap()) } #[inline] @@ -212,12 +176,8 @@ pub mod binary { // 32-bit integers - Little-endian #[inline] pub fn get_le_unsigned_int(&mut self) -> u32 { - match self.get(4) { - Ok(bytes) => u32::from_le_bytes(bytes.try_into().unwrap()), - Err(err) => { - panic!("Error get_l_int(): Not enough bytes, Error: {:?}", err); - } - } + let bytes = self.get(4); + u32::from_le_bytes(bytes.try_into().unwrap()) } #[inline] @@ -228,12 +188,8 @@ pub mod binary { // 32-bit floats - Big-endian #[inline] pub fn get_be_float(&mut self) -> f32 { - match self.get(4) { - Ok(bytes) => f32::from_be_bytes(bytes.try_into().unwrap()), - Err(err) => { - panic!("Error get_float(): Not enough bytes, Error: {:?}", err); - } - } + let bytes = self.get(4); + f32::from_be_bytes(bytes.try_into().unwrap()) } #[inline] @@ -244,12 +200,8 @@ pub mod binary { // 32-bit floats - Little-endian #[inline] pub fn get_le_float(&mut self) -> f32 { - match self.get(4) { - Ok(bytes) => f32::from_le_bytes(bytes.try_into().unwrap()), - Err(err) => { - panic!("Error get_l_float(): Not enough bytes, Error: {:?}", err); - } - } + let bytes = self.get(4); + f32::from_le_bytes(bytes.try_into().unwrap()) } #[inline] @@ -260,12 +212,8 @@ pub mod binary { // 64-bit floats - Big-endian #[inline] pub fn get_be_double(&mut self) -> f64 { - match self.get(8) { - Ok(bytes) => f64::from_be_bytes(bytes.try_into().unwrap()), - Err(err) => { - panic!("Error get_double(): Not enough bytes, Error: {:?}", err); - } - } + let bytes = self.get(8); + f64::from_be_bytes(bytes.try_into().unwrap()) } #[inline] @@ -276,12 +224,8 @@ pub mod binary { // 64-bit floats - Little-endian #[inline] pub fn get_le_double(&mut self) -> f64 { - match self.get(8) { - Ok(bytes) => f64::from_le_bytes(bytes.try_into().unwrap()), - Err(err) => { - panic!("Error get_l_double(): Not enough bytes, Error: {:?}", err); - } - } + let bytes = self.get(8); + f64::from_le_bytes(bytes.try_into().unwrap()) } #[inline] @@ -292,12 +236,8 @@ pub mod binary { // 64-bit integers - Big-endian #[inline] pub fn get_be_signed_long(&mut self) -> i64 { - match self.get(8) { - Ok(bytes) => i64::from_be_bytes(bytes.try_into().unwrap()), - Err(err) => { - panic!("Error get_long(): Not enough bytes, Error: {:?}", err); - } - } + let bytes = self.get(8); + i64::from_be_bytes(bytes.try_into().unwrap()) } #[inline] @@ -308,12 +248,8 @@ pub mod binary { // 64-bit integers - Little-endian #[inline] pub fn get_le_signed_long(&mut self) -> i64 { - match self.get(8) { - Ok(bytes) => i64::from_le_bytes(bytes.try_into().unwrap()), - Err(err) => { - panic!("Error get_l_long(): Not enough bytes, Error: {:?}", err); - } - } + let bytes = self.get(8); + i64::from_le_bytes(bytes.try_into().unwrap()) } #[inline] @@ -384,12 +320,8 @@ pub mod binary { #[inline] pub fn get_var_long(&mut self) -> i64 { - match self.get_unsigned_var_long() { - Ok(raw) => ((raw >> 1) as i64) ^ (-((raw & 1) as i64)), - Err(err) => { - panic!("Error get_var_long(): Failed to read unsigned var long, Error: {:?}", err); - } - } + let raw = self.get_unsigned_var_long(); + ((raw >> 1) as i64) ^ (-((raw & 1) as i64)) } #[inline] From 7f00b3eaf2577bcaad26f50c6cd4a162aa8da1fc Mon Sep 17 00:00:00 2001 From: ismail Date: Fri, 7 Nov 2025 11:11:23 +0300 Subject: [PATCH 3/5] error fix #2 --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 5313cc4..224d810 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -58,7 +58,7 @@ pub mod binary { if self.offset >= self.buffer.len() as u32 { panic!("Error get_remaining(): No bytes left to read"); } else { - self.buffer[self.offset..].to_vec() + self.buffer[(self.offset as usize)..].to_vec() } } From 3b1b13a2466982571a2ea8222761cc6322b6296d Mon Sep 17 00:00:00 2001 From: ismail Date: Sun, 9 Nov 2025 17:22:54 +0300 Subject: [PATCH 4/5] additional functions-1 --- src/lib.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 224d810..ec2d7d5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -256,6 +256,30 @@ pub mod binary { pub fn put_le_signed_long(&mut self, value: i64) { self.buffer.extend_from_slice(&value.to_le_bytes()); } + + // 64-bit unsigned integers - Big-endian + #[inline] + pub fn get_be_unsigned_long(&mut self) -> u64 { + let bytes = self.get(8); + u64::from_be_bytes(bytes.try_into().unwrap()) + } + + #[inline] + pub fn put_be_unsigned_long(&mut self, value: u64) { + self.buffer.extend_from_slice(&value.to_be_bytes()); + } + + // 64-bit unsigned integers - Little-endian + #[inline] + pub fn get_le_unsigned_long(&mut self) -> u64 { + let bytes = self.get(8); + u64::from_le_bytes(bytes.try_into().unwrap()) + } + + #[inline] + pub fn put_le_unsigned_long(&mut self, value: u64) { + self.buffer.extend_from_slice(&value.to_le_bytes()); + } // Variable-length integers pub fn get_unsigned_var_int(&mut self) -> u32 { From b46f6338b714f0c2f00825f0d0ed7baa5aa40152 Mon Sep 17 00:00:00 2001 From: ismail Date: Wed, 12 Nov 2025 17:09:34 +0300 Subject: [PATCH 5/5] function name changes & function descriptions & README+tests --- README.md | 6 +- src/lib.rs | 186 ++++++++++++++++++++++++++++++++++----------------- tests/lib.rs | 2 +- 3 files changed, 128 insertions(+), 66 deletions(-) diff --git a/README.md b/README.md index ba66005..283ca47 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # binary-utils -A binary system to be used for RakNet protocol. +A binary system to be used for Bedrock & RakNet protocol. ## Usage @@ -17,12 +17,12 @@ use binary_utils::binary::Stream; fn main() { let mut stream = Stream::new(vec![1, 2], 0); stream.put_byte(128); - stream.put_l_triad(12345); + stream.put_i24_le(12345); let _ = stream.get_byte(); // first byte -> 1 let _ = stream.get_byte(); // second byte -> 2 let _ = stream.get_byte(); // third byte -> 128 - let triad_num = stream.get_l_triad(); // triad number -> 12345 + let triad_num = stream.get_i24_le(); // triad number -> 12345 println!("{}", triad_num); // 12345 println!("{:?}", stream.get_buffer()); // [1, 2, 128, 57, 48, 0] diff --git a/src/lib.rs b/src/lib.rs index ec2d7d5..6a5551b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,15 +1,21 @@ pub mod binary { + /// A binary stream for reading and writing primitive types + /// in both big-endian and little-endian byte order. + /// + /// Commonly used for Minecraft Bedrock protocol data. pub struct Stream { buffer: Vec, offset: u32, } impl Stream { + /// Creates a new stream from an existing buffer and offset. #[inline] pub fn new(buffer: Vec, offset: u32) -> Self { Self { buffer, offset } } + /// Creates an empty stream with a specified capacity. #[inline] pub fn with_capacity(capacity: usize) -> Self { Self { @@ -18,11 +24,15 @@ pub mod binary { } } + /// Resets the stream offset to the beginning. #[inline] pub fn rewind(&mut self) { self.offset = 0; } + /// Sets the read/write offset. + /// + /// Panics if the offset is greater than the buffer length. #[inline] pub fn set_offset(&mut self, offset: u32) { if offset <= self.buffer.len() as u32 { @@ -32,16 +42,21 @@ pub mod binary { } } + /// Returns the current read/write offset. #[inline] pub fn get_offset(&self) -> u32 { self.offset } + /// Returns the entire buffer as a byte slice. #[inline] pub fn get_buffer(&self) -> &[u8] { &self.buffer } + /// Reads a specific number of bytes and advances the offset. + /// + /// Panics if there are not enough bytes remaining. pub fn get(&mut self, length: u32) -> Vec { let end_index: usize = (self.offset + length) as usize; @@ -54,6 +69,9 @@ pub mod binary { } } + /// Returns the remaining unread bytes. + /// + /// Panics if the stream is already at EOF. pub fn get_remaining(&self) -> Vec { if self.offset >= self.buffer.len() as u32 { panic!("Error get_remaining(): No bytes left to read"); @@ -62,227 +80,263 @@ pub mod binary { } } + /// Writes a raw byte vector to the buffer. #[inline] pub fn put(&mut self, value: Vec) { self.buffer.extend(value); } + /// Reads a single byte and returns `true` if it’s nonzero. #[inline] pub fn get_bool(&mut self) -> bool { let bytes = self.get(1); bytes[0] != 0 } + /// Writes a boolean value (`0x01` for true, `0x00` for false). #[inline] pub fn put_bool(&mut self, value: bool) { self.buffer.push(if value { 0x01 } else { 0x00 }); } + /// Reads a single unsigned byte. #[inline] pub fn get_byte(&mut self) -> u8 { - let bytes = self.get(1); - bytes[0] + self.get(1)[0] } + /// Writes a single unsigned byte. #[inline] pub fn put_byte(&mut self, value: u8) { self.buffer.push(value); } - // Big-endian (network byte order) + // ===== 16-bit integers ===== + + /// Reads an unsigned 16-bit integer (big-endian). #[inline] - pub fn get_be_unsigned_short(&mut self) -> u16 { + pub fn get_u16_be(&mut self) -> u16 { let bytes = self.get(2); u16::from_be_bytes([bytes[0], bytes[1]]) } + /// Reads a signed 16-bit integer (big-endian). #[inline] - pub fn get_be_signed_short(&mut self) -> i16 { + pub fn get_i16_be(&mut self) -> i16 { let bytes = self.get(2); i16::from_be_bytes([bytes[0], bytes[1]]) } + /// Writes an unsigned 16-bit integer (big-endian). #[inline] - pub fn put_be_unsigned_short(&mut self, value: u16) { + pub fn put_u16_be(&mut self, value: u16) { self.buffer.extend_from_slice(&value.to_be_bytes()); } + /// Writes a signed 16-bit integer (big-endian). #[inline] - pub fn put_be_signed_short(&mut self, value: i16) { + pub fn put_i16_be(&mut self, value: i16) { self.buffer.extend_from_slice(&value.to_be_bytes()); } - // Little-endian + /// Reads an unsigned 16-bit integer (little-endian). #[inline] - pub fn get_le_unsigned_short(&mut self) -> u16 { + pub fn get_u16_le(&mut self) -> u16 { let bytes = self.get(2); u16::from_le_bytes([bytes[0], bytes[1]]) } + /// Reads a signed 16-bit integer (little-endian). #[inline] - pub fn get_le_signed_short(&mut self) -> i16 { + pub fn get_i16_le(&mut self) -> i16 { let bytes = self.get(2); i16::from_le_bytes([bytes[0], bytes[1]]) } + /// Writes an unsigned 16-bit integer (little-endian). #[inline] - pub fn put_le_unsigned_short(&mut self, value: u16) { + pub fn put_u16_le(&mut self, value: u16) { self.buffer.extend_from_slice(&value.to_le_bytes()); } + /// Writes a signed 16-bit integer (little-endian). #[inline] - pub fn put_le_signed_short(&mut self, value: i16) { + pub fn put_i16_le(&mut self, value: i16) { self.buffer.extend_from_slice(&value.to_le_bytes()); } - // 24-bit integers (Triad) - Big-endian + // ===== 24-bit (triad) integers ===== + + /// Reads a 24-bit signed integer (big-endian). #[inline] - pub fn get_be_triad(&mut self) -> i32 { + pub fn get_i24_be(&mut self) -> i32 { let bytes = self.get(3); i32::from_be_bytes([0, bytes[0], bytes[1], bytes[2]]) } + /// Writes a 24-bit signed integer (big-endian). #[inline] - pub fn put_be_triad(&mut self, value: i32) { + pub fn put_i24_be(&mut self, value: i32) { let bytes = value.to_be_bytes(); self.buffer.extend_from_slice(&bytes[1..4]); } - // 24-bit integers (Triad) - Little-endian + /// Reads a 24-bit signed integer (little-endian). #[inline] - pub fn get_le_triad(&mut self) -> i32 { + pub fn get_i24_le(&mut self) -> i32 { let bytes = self.get(3); i32::from_le_bytes([bytes[0], bytes[1], bytes[2], 0]) } + /// Writes a 24-bit signed integer (little-endian). #[inline] - pub fn put_le_triad(&mut self, value: i32) { + pub fn put_i24_le(&mut self, value: i32) { let bytes = value.to_le_bytes(); self.buffer.extend_from_slice(&bytes[0..3]); } - // 32-bit integers - Big-endian + // ===== 32-bit integers ===== + + /// Reads an unsigned 32-bit integer (big-endian). #[inline] - pub fn get_be_unsigned_int(&mut self) -> u32 { + pub fn get_u32_be(&mut self) -> u32 { let bytes = self.get(4); u32::from_be_bytes(bytes.try_into().unwrap()) } + /// Writes an unsigned 32-bit integer (big-endian). #[inline] - pub fn put_be_unsigned_int(&mut self, value: u32) { + pub fn put_u32_be(&mut self, value: u32) { self.buffer.extend_from_slice(&value.to_be_bytes()); } - // 32-bit integers - Little-endian + /// Reads an unsigned 32-bit integer (little-endian). #[inline] - pub fn get_le_unsigned_int(&mut self) -> u32 { + pub fn get_u32_le(&mut self) -> u32 { let bytes = self.get(4); u32::from_le_bytes(bytes.try_into().unwrap()) } + /// Writes an unsigned 32-bit integer (little-endian). #[inline] - pub fn put_le_unsigned_int(&mut self, value: u32) { + pub fn put_u32_le(&mut self, value: u32) { self.buffer.extend_from_slice(&value.to_le_bytes()); } - // 32-bit floats - Big-endian + // ===== 32-bit floats ===== + + /// Reads a 32-bit floating-point number (big-endian). #[inline] - pub fn get_be_float(&mut self) -> f32 { + pub fn get_f32_be(&mut self) -> f32 { let bytes = self.get(4); f32::from_be_bytes(bytes.try_into().unwrap()) } + /// Writes a 32-bit floating-point number (big-endian). #[inline] - pub fn put_be_float(&mut self, value: f32) { + pub fn put_f32_be(&mut self, value: f32) { self.buffer.extend_from_slice(&value.to_be_bytes()); } - // 32-bit floats - Little-endian + /// Reads a 32-bit floating-point number (little-endian). #[inline] - pub fn get_le_float(&mut self) -> f32 { + pub fn get_f32_le(&mut self) -> f32 { let bytes = self.get(4); f32::from_le_bytes(bytes.try_into().unwrap()) } + /// Writes a 32-bit floating-point number (little-endian). #[inline] - pub fn put_le_float(&mut self, value: f32) { + pub fn put_f32_le(&mut self, value: f32) { self.buffer.extend_from_slice(&value.to_le_bytes()); } - // 64-bit floats - Big-endian + // ===== 64-bit floats ===== + + /// Reads a 64-bit double-precision float (big-endian). #[inline] - pub fn get_be_double(&mut self) -> f64 { + pub fn get_f64_be(&mut self) -> f64 { let bytes = self.get(8); f64::from_be_bytes(bytes.try_into().unwrap()) } + /// Writes a 64-bit double-precision float (big-endian). #[inline] - pub fn put_be_double(&mut self, value: f64) { + pub fn put_f64_be(&mut self, value: f64) { self.buffer.extend_from_slice(&value.to_be_bytes()); } - // 64-bit floats - Little-endian + /// Reads a 64-bit double-precision float (little-endian). #[inline] - pub fn get_le_double(&mut self) -> f64 { + pub fn get_f64_le(&mut self) -> f64 { let bytes = self.get(8); f64::from_le_bytes(bytes.try_into().unwrap()) } + /// Writes a 64-bit double-precision float (little-endian). #[inline] - pub fn put_le_double(&mut self, value: f64) { + pub fn put_f64_le(&mut self, value: f64) { self.buffer.extend_from_slice(&value.to_le_bytes()); } - // 64-bit integers - Big-endian + // ===== 64-bit integers ===== + + /// Reads a signed 64-bit integer (big-endian). #[inline] - pub fn get_be_signed_long(&mut self) -> i64 { + pub fn get_i64_be(&mut self) -> i64 { let bytes = self.get(8); i64::from_be_bytes(bytes.try_into().unwrap()) } + /// Writes a signed 64-bit integer (big-endian). #[inline] - pub fn put_be_signed_long(&mut self, value: i64) { + pub fn put_i64_be(&mut self, value: i64) { self.buffer.extend_from_slice(&value.to_be_bytes()); } - // 64-bit integers - Little-endian + /// Reads a signed 64-bit integer (little-endian). #[inline] - pub fn get_le_signed_long(&mut self) -> i64 { + pub fn get_i64_le(&mut self) -> i64 { let bytes = self.get(8); i64::from_le_bytes(bytes.try_into().unwrap()) } + /// Writes a signed 64-bit integer (little-endian). #[inline] - pub fn put_le_signed_long(&mut self, value: i64) { + pub fn put_i64_le(&mut self, value: i64) { self.buffer.extend_from_slice(&value.to_le_bytes()); } - - // 64-bit unsigned integers - Big-endian + + /// Reads an unsigned 64-bit integer (big-endian). #[inline] - pub fn get_be_unsigned_long(&mut self) -> u64 { + pub fn get_u64_be(&mut self) -> u64 { let bytes = self.get(8); u64::from_be_bytes(bytes.try_into().unwrap()) } + /// Writes an unsigned 64-bit integer (big-endian). #[inline] - pub fn put_be_unsigned_long(&mut self, value: u64) { + pub fn put_u64_be(&mut self, value: u64) { self.buffer.extend_from_slice(&value.to_be_bytes()); } - // 64-bit unsigned integers - Little-endian + /// Reads an unsigned 64-bit integer (little-endian). #[inline] - pub fn get_le_unsigned_long(&mut self) -> u64 { + pub fn get_u64_le(&mut self) -> u64 { let bytes = self.get(8); u64::from_le_bytes(bytes.try_into().unwrap()) } + /// Writes an unsigned 64-bit integer (little-endian). #[inline] - pub fn put_le_unsigned_long(&mut self, value: u64) { + pub fn put_u64_le(&mut self, value: u64) { self.buffer.extend_from_slice(&value.to_le_bytes()); } - // Variable-length integers - pub fn get_unsigned_var_int(&mut self) -> u32 { + // ===== Variable-length integers ===== + + /// Reads an unsigned variable-length integer (VarInt). + pub fn get_var_u32(&mut self) -> u32 { let mut value = 0u32; for i in 0..5 { let b = self.get_byte(); @@ -294,7 +348,8 @@ pub mod binary { panic!("VarInt did not terminate after 5 bytes!"); } - pub fn put_unsigned_var_int(&mut self, mut value: u32) { + /// Writes an unsigned variable-length integer (VarInt). + pub fn put_var_u32(&mut self, mut value: u32) { loop { if value >= 0x80 { self.buffer.push((value as u8) | 0x80); @@ -306,19 +361,22 @@ pub mod binary { } } + /// Reads a signed variable-length integer (ZigZag encoded). #[inline] - pub fn get_var_int(&mut self) -> i32 { - let raw = self.get_unsigned_var_int(); + pub fn get_var_i32(&mut self) -> i32 { + let raw = self.get_var_u32(); ((raw >> 1) as i32) ^ -((raw & 1) as i32) } + /// Writes a signed variable-length integer (ZigZag encoded). #[inline] - pub fn put_var_int(&mut self, value: i32) { + pub fn put_var_i32(&mut self, value: i32) { let encoded = ((value << 1) ^ (value >> 31)) as u32; - self.put_unsigned_var_int(encoded); + self.put_var_u32(encoded); } - pub fn get_unsigned_var_long(&mut self) -> u64 { + /// Reads an unsigned 64-bit variable-length integer (VarLong). + pub fn get_var_u64(&mut self) -> u64 { let mut value = 0u64; for i in 0..10 { let b = self.get_byte(); @@ -330,7 +388,8 @@ pub mod binary { panic!("VarLong did not terminate after 10 bytes!"); } - pub fn put_unsigned_var_long(&mut self, mut value: u64) { + /// Writes an unsigned 64-bit variable-length integer (VarLong). + pub fn put_var_u64(&mut self, mut value: u64) { loop { if value >= 0x80 { self.buffer.push((value as u8) | 0x80); @@ -342,18 +401,21 @@ pub mod binary { } } + /// Reads a signed 64-bit variable-length integer (ZigZag encoded). #[inline] - pub fn get_var_long(&mut self) -> i64 { - let raw = self.get_unsigned_var_long(); + pub fn get_var_i64(&mut self) -> i64 { + let raw = self.get_var_u64(); ((raw >> 1) as i64) ^ (-((raw & 1) as i64)) } + /// Writes a signed 64-bit variable-length integer (ZigZag encoded). #[inline] - pub fn put_var_long(&mut self, value: i64) { + pub fn put_var_i64(&mut self, value: i64) { let encoded = ((value << 1) ^ (value >> 63)) as u64; - self.put_unsigned_var_long(encoded); + self.put_var_u64(encoded); } + /// Returns `true` if the stream has reached the end of the buffer. #[inline] pub fn feof(&self) -> bool { self.offset >= self.buffer.len() as u32 diff --git a/tests/lib.rs b/tests/lib.rs index 58acc9f..ed36775 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -11,7 +11,7 @@ mod tests { let mut stream = Stream::new(vec![19, 54, 55], 0); - let result = stream.get_var_int(); + let result = stream.get_i24_le(); println!("result: {}", result); }