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