otspec/
types.rs

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, // thing
271            0x00, 0x08, // off
272            0x00, 0x02, // other
273            0xff, 0xff, // filler
274            0x00, 0x0a, // test1
275            0x00, 0x06, // deep
276            0x00, 0x0b, // test2
277            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        // XXX Need to work out automatic top-of-table stuff
286
287        // assert_eq!(
288        //     one.off.link,
289        //     Two {
290        //         test1: 0x0a,
291        //         deep: Offset16::to(Three { blah: 0xaa }),
292        //         test2: 0x0b
293        //     }
294        // );
295    }
296}