binary_codec/
utils.rs

1use crate::{
2    BitStreamReader, BitStreamWriter, DeserializationError, SerializationError, SerializerConfig,
3};
4
5pub fn get_read_size<'a, T: Clone>(
6    stream: &mut BitStreamReader,
7    size_key: Option<&str>,
8    config: &mut SerializerConfig<T>,
9) -> Result<usize, DeserializationError> {
10    let size = if let Some(size_key) = size_key {
11        if size_key == "__dynamic" {
12            return stream.read_dyn_int().map(|v| v as usize);
13        }
14
15        config.get_length(size_key).unwrap_or(stream.bytes_left())
16    } else {
17        stream.bytes_left()
18    };
19
20    Ok(size)
21}
22
23pub fn write_size<T: Clone>(
24    size: usize,
25    size_key: Option<&str>,
26    stream: &mut BitStreamWriter,
27    config: &mut SerializerConfig<T>,
28) -> Result<(), SerializationError> {
29    if let Some(size_key) = size_key {
30        if size_key == "__dynamic" {
31            stream.write_dyn_int(size as u128);
32            return Ok(());
33        }
34
35        if let Some(expected) = config.get_length(size_key) {
36            if expected != size {
37                return Err(SerializationError::UnexpectedLength(expected, size));
38            }
39        }
40    }
41
42    Ok(())
43}
44
45pub fn read_string<T: Clone>(
46    stream: &mut BitStreamReader,
47    size_key: Option<&str>,
48    config: &mut SerializerConfig<T>,
49) -> Result<String, DeserializationError> {
50    let len = get_read_size(stream, size_key, config)?;
51    let slice = stream.read_bytes(len)?;
52    let string = String::from_utf8(slice.to_vec()).expect("Not valid UTF-8 bytes to create string");
53
54    Ok(string)
55}
56
57pub fn write_string<T: Clone>(
58    value: &str,
59    size_key: Option<&str>,
60    stream: &mut BitStreamWriter,
61    config: &mut SerializerConfig<T>,
62) -> Result<(), SerializationError> {
63    write_size(value.len(), size_key, stream, config)?;
64    stream.write_bytes(&value.as_bytes());
65
66    Ok(())
67}
68
69pub fn read_object<T, U>(
70    stream: &mut BitStreamReader,
71    size_key: Option<&str>,
72    config: &mut SerializerConfig<U>,
73) -> Result<T, DeserializationError>
74where
75    T: crate::BinaryDeserializer<U>,
76    U: Clone,
77{
78    let len = get_read_size(stream, size_key, config)?;
79
80    // If exact size of buffer is available, don't slice
81    if stream.bytes_left() == len {
82        T::read_bytes(stream, Some(config))
83    } else {
84        // Create an isolated slice, because it could be that the object uses a dynamically sized buffer based on bytes left
85        let slice = stream.read_bytes(len)?;
86        let mut isolated_reader = BitStreamReader::new(slice);
87
88        T::read_bytes(&mut isolated_reader, Some(config))
89    }
90}
91
92pub fn write_object<T, U>(
93    value: &T,
94    size_key: Option<&str>,
95    stream: &mut BitStreamWriter,
96    config: &mut SerializerConfig<U>,
97) -> Result<(), SerializationError>
98where
99    T: crate::BinarySerializer<U>,
100    U: Clone,
101{
102    // If length name is provided, we need to ensure the length matches
103    // So we write it to a different buffer
104    if size_key.is_some() {
105        let mut buffer = Vec::new();
106        let mut temp_stream = BitStreamWriter::new(&mut buffer);
107        value.write_bytes(&mut temp_stream, Some(config))?;
108        write_size(buffer.len(), size_key, stream, config)?;
109        stream.write_bytes(&buffer);
110        Ok(())
111    } else {
112        value.write_bytes(stream, Some(config))
113    }
114}