Skip to main content

binary_codec/
utils.rs

1use std::net::{Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6};
2
3use crate::{
4    BinaryDeserializer, BinarySerializer, BitStreamReader, BitStreamWriter, DeserializationError,
5    SerializationError, SerializerConfig,
6};
7
8pub fn get_read_size<'a, T: Clone, E: From<DeserializationError>>(
9    stream: &mut BitStreamReader,
10    size_key: Option<&str>,
11    config: &mut SerializerConfig<T>,
12) -> Result<usize, E> {
13    let size = if let Some(size_key) = size_key {
14        if size_key == "__dynamic" {
15            return stream
16                .read_dyn_int()
17                .map(|v| v as usize)
18                .map_err(Into::into);
19        }
20
21        config.get_length(size_key).unwrap_or(stream.bytes_left())
22    } else {
23        stream.bytes_left()
24    };
25
26    Ok(size)
27}
28
29pub fn write_size<T: Clone, E: From<SerializationError>>(
30    size: usize,
31    size_key: Option<&str>,
32    stream: &mut BitStreamWriter,
33    config: &mut SerializerConfig<T>,
34) -> Result<(), E> {
35    if let Some(size_key) = size_key {
36        if size_key == "__dynamic" {
37            stream.write_dyn_int(size as u128);
38            return Ok(());
39        }
40
41        if let Some(expected) = config.get_length(size_key) {
42            if expected != size {
43                return Err(
44                    SerializationError::UnexpectedLength(expected as u64, size as u64).into(),
45                );
46            }
47        }
48    }
49
50    Ok(())
51}
52
53pub fn read_string<T: Clone, E: From<DeserializationError>>(
54    stream: &mut BitStreamReader,
55    size_key: Option<&str>,
56    config: &mut SerializerConfig<T>,
57) -> Result<String, E> {
58    let len = get_read_size(stream, size_key, config)?;
59    let slice = stream.read_bytes(len).map_err(Into::into)?;
60    let string = String::from_utf8(slice.to_vec()).expect("Not valid UTF-8 bytes to create string");
61
62    Ok(string)
63}
64
65pub fn write_string<T: Clone, E: From<SerializationError>>(
66    value: &str,
67    size_key: Option<&str>,
68    stream: &mut BitStreamWriter,
69    config: &mut SerializerConfig<T>,
70) -> Result<(), E> {
71    write_size(value.len(), size_key, stream, config)?;
72    stream.write_bytes(&value.as_bytes());
73
74    Ok(())
75}
76
77pub fn read_object<T, U, E>(
78    stream: &mut BitStreamReader,
79    size_key: Option<&str>,
80    config: &mut SerializerConfig<U>,
81) -> Result<T, E>
82where
83    T: BinaryDeserializer<U, E>,
84    U: Clone,
85    E: From<DeserializationError>,
86{
87    let len = get_read_size::<U, E>(stream, size_key, config)?;
88
89    // If exact size of buffer is available, don't slice
90    if stream.bytes_left() == len {
91        T::read_bytes(stream, Some(config))
92    } else {
93        // Create an isolated slice, because it could be that the object uses a dynamically sized buffer based on bytes left
94        let slice = stream.read_bytes(len).map_err(Into::into)?;
95        let mut isolated_reader = BitStreamReader::new(slice);
96
97        T::read_bytes(&mut isolated_reader, Some(config))
98    }
99}
100
101pub fn write_object<T, U, E>(
102    value: &T,
103    size_key: Option<&str>,
104    stream: &mut BitStreamWriter,
105    config: &mut SerializerConfig<U>,
106) -> Result<(), E>
107where
108    T: BinarySerializer<U, E>,
109    U: Clone,
110    E: From<SerializationError>,
111{
112    // If length name is provided, we need to ensure the length matches
113    // So we write it to a different buffer
114    if size_key.is_some() {
115        let mut buffer = Vec::new();
116        let mut temp_stream = BitStreamWriter::new(&mut buffer);
117        value.write_bytes(&mut temp_stream, Some(config))?;
118        write_size::<U, E>(buffer.len(), size_key, stream, config)?;
119        stream.write_bytes(&buffer);
120        Ok(())
121    } else {
122        value.write_bytes(stream, Some(config))
123    }
124}
125
126pub fn read_socketaddr_v4(
127    stream: &mut BitStreamReader,
128) -> Result<std::net::SocketAddrV4, DeserializationError> {
129    let octets: [u8; 4] = stream.read_bytes(4)?.try_into().unwrap();
130    let port = stream.read_fixed_int()?;
131    let ip = Ipv4Addr::from_octets(octets);
132    Ok(SocketAddrV4::new(ip, port))
133}
134
135pub fn write_socketaddr_v4(value: &std::net::SocketAddrV4, stream: &mut BitStreamWriter) {
136    stream.write_bytes(&value.ip().octets());
137    stream.write_fixed_int(value.port());
138}
139
140pub fn read_socketaddr_v6(
141    stream: &mut BitStreamReader,
142) -> Result<std::net::SocketAddrV6, DeserializationError> {
143    let octets: [u8; 16] = stream.read_bytes(16)?.try_into().unwrap();
144    let port = stream.read_fixed_int()?;
145    let ip = Ipv6Addr::from_octets(octets);
146    Ok(SocketAddrV6::new(ip, port, 0, 0))
147}
148
149pub fn write_socketaddr_v6(value: &std::net::SocketAddrV6, stream: &mut BitStreamWriter) {
150    stream.write_bytes(&value.ip().octets());
151    stream.write_fixed_int(value.port());
152}