emote_psb\types/
number.rs1use std::io::{Read, Write};
8
9use crate::{PsbError, PsbErrorKind};
10
11use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
12
13use super::{PSB_TYPE_DOUBLE, PSB_TYPE_FLOAT, PSB_TYPE_INTEGER_N, PSB_TYPE_FLOAT0};
14
15#[cfg(feature = "serde")]
16use serde::{Serialize, Deserialize};
17
18#[derive(Debug, Clone, PartialEq)]
19#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
20#[cfg_attr(feature = "serde", serde(untagged))]
21pub enum PsbNumber {
22
23 Integer(i64),
24 Double(f64),
25 Float(f32)
26
27}
28
29impl PsbNumber {
30
31 pub fn from_bytes(number_type: u8, stream: &mut impl Read) -> Result<(u64, Self), PsbError> {
32 match number_type {
33
34 PSB_TYPE_DOUBLE => {
35 Ok((8, Self::Double(stream.read_f64::<LittleEndian>()?)))
36 },
37
38 PSB_TYPE_FLOAT => {
39 Ok((4, Self::Float(stream.read_f32::<LittleEndian>()?)))
40 },
41
42 PSB_TYPE_FLOAT0 => {
43 Ok((0, Self::Float(0_f32)))
44 },
45
46 _ if number_type >= PSB_TYPE_INTEGER_N && number_type <= PSB_TYPE_INTEGER_N + 8 => {
47 let number_size = number_type - PSB_TYPE_INTEGER_N;
48
49 let (read, val) = Self::read_integer(number_size, stream)?;
50
51 Ok((read, Self::Integer(val)))
52 }
53
54 _ => {
55 Err(PsbError::new(PsbErrorKind::InvalidPSBValue, None))
56 }
57
58 }
59 }
60
61 pub fn read_uint(number_size: u8, stream: &mut impl Read) -> Result<(u64, u64), PsbError> {
63 if number_size == 0 {
64 Ok((1, 0))
65 } else if number_size <= 8 {
66 let mut buf = [0_u8; 8];
67
68 stream.read_exact(&mut buf[..number_size as usize])?;
69
70 Ok((number_size as u64, u64::from_le_bytes(buf)))
71 } else {
72 Err(PsbError::new(PsbErrorKind::InvalidPSBValue, None))
73 }
74 }
75
76 pub fn read_integer(number_size: u8, stream: &mut impl Read) -> Result<(u64, i64), PsbError> {
77 if number_size == 0 {
78 Ok((1, 0))
79 } else if number_size <= 8 {
80 let (read, unsigned) = Self::read_uint(number_size, stream)?;
81
82 let max = 1_u64 << (number_size * 8);
83 let number = if unsigned >= (max >> 1) {
84 -((max - unsigned) as i64)
85 } else {
86 unsigned as i64
87 };
88
89 Ok((read, number))
90 } else {
91 Err(PsbError::new(PsbErrorKind::InvalidPSBValue, None))
92 }
93 }
94
95 pub fn get_n(mut number: i64) -> u8 {
96 if number < 0 {
97 number = -number;
98 }
99
100 if number <= 0x7f {
101 1
102 } else if number <= 0x7fff {
103 2
104 } else if number <= 0x7fffff {
105 3
106 } else if number <= 0x7fffffff {
107 4
108 } else if number <= 0x7fffffffff {
109 5
110 } else if number <= 0x7fffffffffff {
111 6
112 } else if number <= 0x7fffffffffffff {
113 7
114 } else {
115 8
116 }
117 }
118
119 pub fn get_uint_n(number: u64) -> u8 {
120 if number <= 0xff {
121 1
122 } else if number <= 0xffff {
123 2
124 } else if number <= 0xffffff {
125 3
126 } else if number <= 0xffffffff {
127 4
128 } else if number <= 0xffffffffff {
129 5
130 } else if number <= 0xffffffffffff {
131 6
132 } else if number <= 0xffffffffffffff {
133 7
134 } else {
135 8
136 }
137 }
138
139 pub fn write_bytes(&self, stream: &mut impl Write) -> Result<u64, PsbError> {
140 match self {
141 PsbNumber::Integer(val) => {
142 if *val == 0 {
143 return Ok(0);
144 }
145
146 let n = Self::get_n(*val);
147
148 Self::write_integer(n, *val, stream)?;
149 Ok(n as u64)
150 },
151
152 PsbNumber::Double(val) => {
153 stream.write_f64::<LittleEndian>(*val)?;
154 Ok(8)
155 },
156
157 PsbNumber::Float(val) => {
158 if *val == 0f32 {
159 Ok(0)
160 } else {
161 stream.write_f32::<LittleEndian>(*val)?;
162
163 Ok(4)
164 }
165 }
166
167 }
168 }
169
170 pub fn write_uint(n: u8, number: u64, stream: &mut impl Write) -> Result<u8, PsbError> {
171 if n > 0 {
172 stream.write_all(&number.to_le_bytes()[..n as usize])?;
173
174 Ok(n)
175 } else {
176 Ok(0)
177 }
178 }
179
180 pub fn write_integer(n: u8, number: i64, stream: &mut impl Write) -> Result<u8, PsbError> {
181 Self::write_uint(n, number as u64, stream)
182 }
183
184}
185
186impl From<i8> for PsbNumber {
187 fn from(number: i8) -> Self {
188 PsbNumber::Integer(number as i64)
189 }
190}
191
192impl From<i16> for PsbNumber {
193 fn from(number: i16) -> Self {
194 PsbNumber::Integer(number as i64)
195 }
196}
197
198impl From<i32> for PsbNumber {
199 fn from(number: i32) -> Self {
200 PsbNumber::Integer(number as i64)
201 }
202}
203
204impl From<i64> for PsbNumber {
205 fn from(number: i64) -> Self {
206 PsbNumber::Integer(number)
207 }
208}
209
210impl From<f32> for PsbNumber {
211 fn from(number: f32) -> Self {
212 PsbNumber::Float(number)
213 }
214}
215
216impl From<f64> for PsbNumber {
217 fn from(number: f64) -> Self {
218 PsbNumber::Double(number)
219 }
220}