Skip to main content

nurtex_codec/
buffer.rs

1use std::io::{self, Cursor, Error, ErrorKind, Read, Write};
2
3pub const SEGMENT_BITS: u8 = 0x7F;
4pub const CONTINUE_BIT: u8 = 0x80;
5
6/// Трейт буффера
7pub trait Buffer
8where
9  Self: Sized,
10{
11  fn read_buf(buffer: &mut Cursor<&[u8]>) -> Option<Self>;
12  fn write_buf(&self, buffer: &mut impl Write) -> io::Result<()>;
13}
14
15/// Вспомогательная функция для чтения одного байта из буффера
16pub fn read_byte(buffer: &mut Cursor<&[u8]>) -> Option<u8> {
17  let mut buf = [0u8; 1];
18  buffer.read_exact(&mut buf).ok()?;
19  Some(buf[0])
20}
21
22/// Вспомогательная функция чтения байтов из буффера
23pub fn read_bytes<'a>(buffer: &'a mut Cursor<&[u8]>, length: usize) -> Option<&'a [u8]> {
24  if length > (buffer.get_ref().len() - buffer.position() as usize) {
25    return None;
26  }
27
28  let initial_position = buffer.position() as usize;
29  buffer.set_position(buffer.position() + length as u64);
30  let data = &buffer.get_ref()[initial_position..initial_position + length];
31
32  Some(data)
33}
34
35/// Вспомогательная функция чтения строки из буффера
36pub fn read_str<'a>(buffer: &'a mut Cursor<&[u8]>) -> Option<&'a str> {
37  use crate::VarInt;
38
39  let length = i32::read_varint(buffer)? as u32;
40
41  if length > 32767 * 4 {
42    return None;
43  }
44
45  let buffer = read_bytes(buffer, length as usize)?;
46  let string = std::str::from_utf8(buffer).ok()?;
47
48  if string.len() > length as usize {
49    return None;
50  }
51
52  Some(string)
53}
54
55/// Вспомогательная функция записи строки в буффер
56pub fn write_str(buffer: &mut impl Write, string: &str) -> io::Result<()> {
57  use crate::VarInt;
58
59  let str_len = string.len();
60
61  if str_len > 32767 {
62    return Err(Error::new(ErrorKind::InvalidData, ""));
63  }
64
65  (str_len as i32).write_varint(buffer)?;
66  buffer.write_all(string.as_bytes())?;
67
68  Ok(())
69}