godot_binary_serialization/decoder/
int.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
use anyhow::anyhow;
use byteorder::{ByteOrder, LittleEndian};

use crate::types::{primitive::GodotInteger, SerializeFlag, TYPE_PADDING};

use super::Decoder;

impl Decoder {
    /// Decodes bytes into a Godot integer
    pub fn decode_int(bytes: &[u8], flag: &SerializeFlag) -> anyhow::Result<GodotInteger> {
        Self::decode_raw_int(bytes, 4, flag)
    }

    /// Uses a serialization flag and the offset in bytes to decode bytes into a Godot integer
    pub fn decode_raw_int(
        bytes: &[u8],
        offset: usize,
        flag: &SerializeFlag,
    ) -> anyhow::Result<GodotInteger> {
        let mut length = 4;

        if flag == &SerializeFlag::Bit64 {
            length = 8;
        }

        if bytes.len() < TYPE_PADDING as usize + length {
            return Err(anyhow!(
                "Byte slice too short to decode int with flag {flag:?}"
            ));
        }

        if flag == &SerializeFlag::Bit64 {
            return Ok(GodotInteger {
                value: LittleEndian::read_i64(&bytes[offset..offset + length]),
                byte_size: TYPE_PADDING as usize + length,
            });
        }

        Ok(GodotInteger {
            value: LittleEndian::read_i32(&bytes[offset..offset + length]) as i64,
            byte_size: TYPE_PADDING as usize + length,
        })
    }
}

#[cfg(test)]
mod tests {
    use crate::decoder::Decoder;

    #[test]
    fn decode_int32() {
        let bytes: &[u8] = &[2, 0, 0, 0, 1, 0, 0, 0];
        let (_type, flag) = Decoder::get_type_and_flags(bytes).unwrap();
        let int = Decoder::decode_int(bytes, &flag).unwrap();

        assert_eq!(
            int.value, 1,
            "Expected value of {} but got {} instead",
            1, int.value
        );
    }

    #[test]
    fn decode_int64() {
        let bytes: &[u8] = &[2, 0, 1, 0, 31, 166, 227, 165, 155, 196, 32, 0];
        let (_type, flag) = Decoder::get_type_and_flags(bytes).unwrap();
        let int = Decoder::decode_int(bytes, &flag).unwrap();
        let value = 9223372036875807_i64;

        assert_eq!(
            int.value, value,
            "Expected value of {} but got {} instead",
            value, int.value
        );
    }
}