1use crate::DeserializationError;
2use crate::Deserialize;
3use crate::Deserializer;
4use crate::ReaderContext;
5use crate::SerializationError;
6use crate::Serialize;
7use std::convert::TryInto;
8
9pub type uint16 = u16;
10pub type uint32 = u32;
11pub type int16 = i16;
12pub type FWORD = i16;
13pub type UFWORD = u16;
14pub type Tag = [u8; 4];
15
16pub use fixed::types::U16F16;
17
18pub fn tag(s: &str) -> Tag {
19 (*s).as_bytes().try_into().unwrap()
20}
21
22impl Serialize for Tag {
23 fn to_bytes(&self, data: &mut Vec<u8>) -> Result<(), SerializationError> {
24 self[0].to_bytes(data)?;
25 self[1].to_bytes(data)?;
26 self[2].to_bytes(data)?;
27 self[3].to_bytes(data)?;
28 Ok(())
29 }
30}
31
32impl Deserialize for Tag {
33 fn from_bytes(c: &mut ReaderContext) -> Result<Self, DeserializationError> {
34 Ok(c.consume(4)?.try_into().unwrap())
35 }
36}
37
38#[derive(Shrinkwrap, Debug, PartialEq, Copy, Clone)]
39pub struct Fixed(pub f32);
40
41pub type Tuple = Vec<f32>;
42
43fn ot_round(value: f32) -> i32 {
44 (value + 0.5).floor() as i32
45}
46
47impl Serialize for Fixed {
48 fn to_bytes(&self, data: &mut Vec<u8>) -> Result<(), SerializationError> {
49 let packed: i32 = ot_round(self.0 * 65536.0);
50 packed.to_bytes(data)
51 }
52}
53impl Deserialize for Fixed {
54 fn from_bytes(c: &mut ReaderContext) -> Result<Self, DeserializationError> {
55 let packed: i32 = c.de()?;
56 Ok(Fixed(packed as f32 / 65536.0))
57 }
58}
59
60impl From<f32> for Fixed {
61 fn from(num: f32) -> Self {
62 Self(num)
63 }
64}
65impl From<Fixed> for f32 {
66 fn from(num: Fixed) -> Self {
67 num.0
68 }
69}
70
71#[derive(Shrinkwrap, Debug, Copy, Clone)]
72pub struct F2DOT14(pub f32);
73
74impl F2DOT14 {
75 pub fn as_packed(&self) -> Result<i16, std::num::TryFromIntError> {
76 ot_round(self.0 * 16384.0).try_into()
77 }
78 pub fn from_packed(packed: i16) -> Self {
79 F2DOT14(packed as f32 / 16384.0)
80 }
81}
82impl PartialEq for F2DOT14 {
83 fn eq(&self, other: &Self) -> bool {
84 self.as_packed() == other.as_packed()
85 }
86}
87impl Eq for F2DOT14 {}
88
89impl std::hash::Hash for F2DOT14 {
90 fn hash<H>(&self, state: &mut H)
91 where
92 H: std::hash::Hasher,
93 {
94 self.as_packed().unwrap().hash(state)
95 }
96}
97
98impl Serialize for F2DOT14 {
99 fn to_bytes(&self, data: &mut Vec<u8>) -> Result<(), SerializationError> {
100 let packed: i16 = self
101 .as_packed()
102 .map_err(|_| SerializationError("Value didn't fit into a F2DOT14".to_string()))?;
103 packed.to_bytes(data)
104 }
105}
106impl Deserialize for F2DOT14 {
107 fn from_bytes(c: &mut ReaderContext) -> Result<Self, DeserializationError> {
108 let packed: i16 = c.de()?;
109 Ok(F2DOT14::from_packed(packed))
110 }
111}
112
113impl From<f32> for F2DOT14 {
114 fn from(num: f32) -> Self {
115 Self(num)
116 }
117}
118impl From<F2DOT14> for f32 {
119 fn from(num: F2DOT14) -> Self {
120 num.0
121 }
122}
123
124#[derive(Shrinkwrap, Debug, PartialEq)]
125pub struct Version16Dot16(pub U16F16);
126
127impl Serialize for Version16Dot16 {
128 fn to_bytes(&self, data: &mut Vec<u8>) -> Result<(), SerializationError> {
129 let major = self.0.floor().to_num::<u8>();
130 let minor = (self.0.frac().to_num::<f32>() * 160.0) as u8;
131 0_u8.to_bytes(data)?;
132 major.to_bytes(data)?;
133 minor.to_bytes(data)?;
134 0_u8.to_bytes(data)
135 }
136}
137impl Deserialize for Version16Dot16 {
138 fn from_bytes(c: &mut ReaderContext) -> Result<Self, DeserializationError> {
139 let packed: i32 = c.de()?;
140 let orig = packed.to_be_bytes();
141 let major = orig[1] as f32;
142 let minor = orig[2] as f32 / 160.0;
143 Ok(Self(U16F16::from_num(major + minor)))
144 }
145}
146
147impl From<U16F16> for Version16Dot16 {
148 fn from(num: U16F16) -> Self {
149 Self(num)
150 }
151}
152impl From<Version16Dot16> for U16F16 {
153 fn from(num: Version16Dot16) -> Self {
154 num.0
155 }
156}
157#[derive(Shrinkwrap, Debug, PartialEq)]
158pub struct LONGDATETIME(pub chrono::NaiveDateTime);
159
160use chrono::Duration;
161use chrono::NaiveDate;
162
163impl Serialize for LONGDATETIME {
164 fn to_bytes(&self, data: &mut Vec<u8>) -> Result<(), SerializationError> {
165 let now = self.timestamp();
166 let epoch = NaiveDate::from_ymd(1904, 1, 1).and_hms(0, 0, 0).timestamp();
167 (now - epoch).to_bytes(data)
168 }
169}
170impl Deserialize for LONGDATETIME {
171 fn from_bytes(c: &mut ReaderContext) -> Result<Self, DeserializationError> {
172 let diff: i64 = c.de()?;
173 let epoch = NaiveDate::from_ymd(1904, 1, 1).and_hms(0, 0, 0);
174 let res = epoch + Duration::seconds(diff);
175 Ok(LONGDATETIME(res))
176 }
177}
178
179impl From<chrono::NaiveDateTime> for LONGDATETIME {
180 fn from(num: chrono::NaiveDateTime) -> Self {
181 Self(num)
182 }
183}
184impl From<LONGDATETIME> for chrono::NaiveDateTime {
185 fn from(num: LONGDATETIME) -> Self {
186 num.0
187 }
188}
189
190#[derive(Debug, Clone)]
191pub struct Offset16<T> {
192 off: Option<u16>,
193 link: T,
194}
195
196impl<T> Offset16<T> {
197 pub fn to(thing: T) -> Self {
198 Offset16 {
199 off: None,
200 link: thing,
201 }
202 }
203}
204
205impl<T: PartialEq> PartialEq for Offset16<T> {
206 fn eq(&self, rhs: &Offset16<T>) -> bool {
207 self.link == rhs.link
208 }
209}
210impl<T> Serialize for Offset16<T> {
211 fn to_bytes(&self, data: &mut Vec<u8>) -> Result<(), SerializationError> {
212 match self.off {
213 Some(x) => x.to_bytes(data),
214 None => Err(SerializationError("Offset not set".to_string())),
215 }
216 }
217}
218
219impl<T: Deserialize> Deserialize for Offset16<T> {
220 fn from_bytes(c: &mut ReaderContext) -> Result<Self, DeserializationError> {
221 let off: uint16 = c.de()?;
222 let oldptr = c.ptr;
223 c.ptr = c.top_of_table() + off as usize;
224 let obj: T = c.de()?;
225 c.ptr = oldptr;
226 Ok(Offset16 {
227 off: Some(off),
228 link: obj,
229 })
230 }
231}
232
233use std::ops::Deref;
234
235impl<T> Deref for Offset16<T> {
236 type Target = T;
237 fn deref(&self) -> &Self::Target {
238 &self.link
239 }
240}
241
242#[cfg(test)]
243mod tests {
244 use super::*;
245 use crate as otspec;
246 use otspec_macros::Deserialize;
247
248 #[derive(Deserialize)]
249 struct One {
250 thing: uint16,
251 off: Offset16<Two>,
252 other: uint16,
253 }
254
255 #[derive(Deserialize, Debug, PartialEq)]
256 struct Two {
257 test1: uint16,
258 deep: Offset16<Three>,
259 test2: uint16,
260 }
261
262 #[derive(Deserialize, Debug, PartialEq)]
263 struct Three {
264 blah: uint16,
265 }
266
267 #[test]
268 fn test_de_off16() {
269 let bytes = vec![
270 0x00, 0x01, 0x00, 0x08, 0x00, 0x02, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x06, 0x00, 0x0b, 0x00, 0xaa,
278 ];
279 let mut rc = ReaderContext::new(bytes);
280 let one: One = rc.de().unwrap();
281 assert_eq!(one.other, 0x02);
282 assert_eq!(one.thing, 0x01);
283 assert_eq!(one.off.test1, 0x0a);
284
285 }
296}