Skip to main content

binary_codec/
utils.rs

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