jcers/
de.rs

1use std::collections::HashMap;
2use std::hash::Hash;
3
4use super::{JceError, JceHead, JceResult, JceType, JceValue};
5use bytes::{Buf, Bytes};
6
7/// Jce Reader
8pub struct Jce<'a, B>
9where
10    B: Buf + ?Sized,
11{
12    inner: &'a mut B,
13    pub head: JceHead,
14    readed: bool,
15}
16
17/// Deserialize Jce Value
18pub trait JceGet: Sized {
19    fn jce_get<B: Buf + ?Sized>(jce: &mut Jce<B>) -> JceResult<Self>;
20    fn empty() -> JceResult<Self>;
21    fn get_from_buf<B: Buf + ?Sized>(buf: &mut B) -> JceResult<Self> {
22        let mut jce = Jce::new(buf);
23        Self::jce_get(&mut jce)
24    }
25    fn get_by_tag<B: Buf + ?Sized>(jce: &mut Jce<B>, tag: u8) -> JceResult<Self> {
26        jce.get_by_tag(tag)
27    }
28    fn from_buf<B: Buf + ?Sized>(buf: &mut B) -> JceResult<Self> {
29        let mut jce = Jce::new(buf);
30        Self::jce_get(&mut jce)
31    }
32    fn from_boxed_buf<B: Buf + ?Sized>(buf: &mut B) -> JceResult<Self> {
33        buf.advance(1);
34        let mut jce = Jce::new(buf);
35        Self::jce_get(&mut jce)
36    }
37}
38
39impl<'a, B> Jce<'a, B>
40where
41    B: Buf + ?Sized,
42{
43    pub fn new(inner: &'a mut B) -> Self {
44        let mut jce = Jce {
45            inner,
46            head: JceHead::default(),
47            readed: false,
48        };
49        jce.read_head();
50        jce
51    }
52
53    pub fn sub_jce<'b>(&'b mut self) -> Jce<'b, B> {
54        Jce::new(self.inner)
55    }
56
57    pub fn has_remaining(&self) -> bool {
58        self.inner.has_remaining()
59    }
60
61    pub fn read_head(&mut self) -> JceHead {
62        let byte = self.inner.get_u8();
63        let ty = JceType::from(byte & 0xF);
64        let mut tag = (byte & 0xF0) >> 4;
65        if tag == 15 {
66            let next_byte = self.inner.get_u8();
67            tag = next_byte & 0xFF;
68        }
69        let head = JceHead { ty, tag };
70        self.head = head;
71        self.readed = false;
72        head
73    }
74
75    pub fn pass_a_tag(&mut self) -> JceResult<()> {
76        if self.head.ty != JceType::StructEnd {
77            JceValue::jce_get(self).map(|_| ())
78        } else {
79            Ok(())
80        }
81    }
82
83    pub fn go_to_tag(&mut self, tag: u8) -> JceResult<()> {
84        if !self.readed {
85            self.pass_a_tag()?;
86        }
87        while self.read_head().tag != tag {
88            self.pass_a_tag()?;
89            if !self.inner.has_remaining() {
90                return Err(JceError::TagNotFound(tag));
91            }
92        }
93        Ok(())
94    }
95
96    pub fn get_by_tag<T>(&mut self, tag: u8) -> JceResult<T>
97    where
98        T: JceGet,
99    {
100        if self.head.tag != tag {
101            self.go_to_tag(tag)?;
102        }
103        self.readed = true;
104        T::jce_get(self)
105    }
106
107    pub fn end_struct(&mut self) -> JceResult<()> {
108        while self.read_head().ty != JceType::StructEnd {
109            self.pass_a_tag()?;
110        }
111        Ok(())
112    }
113}
114
115impl JceGet for bool {
116    fn jce_get<B: Buf + ?Sized>(jce: &mut Jce<B>) -> JceResult<Self> {
117        match jce.head.ty {
118            JceType::Bool | JceType::U8 => Ok(jce.inner.get_u8() != 0),
119            _ => Err(JceError::ReadTypeError(JceType::Bool, jce.head.ty)),
120        }
121    }
122
123    fn empty() -> JceResult<Self> {
124        panic!() //?
125    }
126}
127
128impl JceGet for u8 {
129    // ty: 0 or 12
130    fn jce_get<B: Buf + ?Sized>(jce: &mut Jce<B>) -> JceResult<Self> {
131        match jce.head.ty {
132            JceType::Empty => Self::empty(),
133            JceType::U8 => Ok(jce.inner.get_u8()),
134            _ => Err(JceError::ReadTypeError(JceType::U8, jce.head.ty)),
135        }
136    }
137
138    fn empty() -> JceResult<Self> {
139        Ok(0)
140    }
141}
142
143impl JceGet for i16 {
144    fn jce_get<B: Buf + ?Sized>(jce: &mut Jce<B>) -> JceResult<Self> {
145        match jce.head.ty {
146            JceType::U8 => u8::jce_get(jce).map(|i| i as i16),
147            JceType::I16 => Ok(jce.inner.get_i16()),
148            JceType::Empty => Self::empty(),
149            _ => Err(JceError::ReadTypeError(JceType::I16, jce.head.ty)),
150        }
151    }
152
153    fn empty() -> JceResult<Self> {
154        Ok(0)
155    }
156}
157
158impl JceGet for i32 {
159    fn jce_get<B: Buf + ?Sized>(jce: &mut Jce<B>) -> JceResult<Self> {
160        match jce.head.ty {
161            JceType::U8 => u8::jce_get(jce).map(|i| i as i32),
162            JceType::I16 => i16::jce_get(jce).map(|i| i as i32),
163            JceType::I32 => Ok(jce.inner.get_i32()),
164            JceType::Empty => Self::empty(),
165            _ => Err(JceError::ReadTypeError(JceType::I32, jce.head.ty)),
166        }
167    }
168
169    fn empty() -> JceResult<Self> {
170        Ok(0)
171    }
172}
173
174impl JceGet for i64 {
175    fn jce_get<B: Buf + ?Sized>(jce: &mut Jce<B>) -> JceResult<Self> {
176        match jce.head.ty {
177            JceType::U8 => u8::jce_get(jce).map(|i| i as i64),
178            JceType::I16 => i16::jce_get(jce).map(|i| i as i64),
179            JceType::I32 => i32::jce_get(jce).map(|i| i as i64),
180            JceType::I64 => Ok(jce.inner.get_i64()),
181            JceType::Empty => Self::empty(),
182            _ => Err(JceError::ReadTypeError(JceType::I64, jce.head.ty)),
183        }
184    }
185
186    fn empty() -> JceResult<Self> {
187        Ok(0)
188    }
189}
190
191impl JceGet for f32 {
192    fn jce_get<B: Buf + ?Sized>(jce: &mut Jce<B>) -> JceResult<Self> {
193        match jce.head.ty {
194            JceType::F32 => Ok(jce.inner.get_f32()),
195            JceType::Empty => Self::empty(),
196            _ => Err(JceError::ReadTypeError(JceType::F32, jce.head.ty)),
197        }
198    }
199
200    fn empty() -> JceResult<Self> {
201        Ok(0.0)
202    }
203}
204
205impl JceGet for f64 {
206    fn jce_get<B: Buf + ?Sized>(jce: &mut Jce<B>) -> JceResult<Self> {
207        match jce.head.ty {
208            JceType::F64 => Ok(jce.inner.get_f64()),
209            JceType::Empty => Self::empty(),
210            _ => Err(JceError::ReadTypeError(JceType::F64, jce.head.ty)),
211        }
212    }
213
214    fn empty() -> JceResult<Self> {
215        Ok(0.0)
216    }
217}
218
219impl JceGet for String {
220    fn jce_get<B: Buf + ?Sized>(jce: &mut Jce<B>) -> JceResult<Self> {
221        let len = match jce.head.ty {
222            JceType::ShortString => jce.inner.get_u8() as usize,
223            JceType::LongString => jce.inner.get_i32() as usize,
224            _ => {
225                return Err(JceError::ReadLenError(jce.head.ty));
226            }
227        };
228        if len == 0 {
229            Self::empty()
230        } else {
231            let data = jce.inner.copy_to_bytes(len);
232            String::from_utf8(data.to_vec()).map_err(|_| JceError::Utf8Error)
233        }
234    }
235
236    fn empty() -> JceResult<Self> {
237        Ok(String::default())
238    }
239}
240
241impl<K, V> JceGet for HashMap<K, V>
242where
243    K: JceGet + Eq + Hash,
244    V: JceGet,
245{
246    fn jce_get<B: Buf + ?Sized>(jce: &mut Jce<B>) -> JceResult<Self> {
247        if jce.head.ty != JceType::Map {
248            return Err(JceError::ReadTypeError(JceType::Map, jce.head.ty));
249        }
250        let mut jce = jce.sub_jce();
251        let len = jce.get_by_tag::<i32>(0)? as usize;
252        let mut map = HashMap::with_capacity(len);
253        for _ in 0..len {
254            let mut jce = jce.sub_jce();
255            let key = jce.get_by_tag(0)?;
256            let value = jce.get_by_tag(1)?;
257            map.insert(key, value);
258        }
259        Ok(map)
260    }
261
262    fn empty() -> JceResult<Self> {
263        Ok(HashMap::new())
264    }
265}
266
267impl<V> JceGet for Vec<V>
268where
269    V: JceGet,
270{
271    fn jce_get<B: Buf + ?Sized>(jce: &mut Jce<B>) -> JceResult<Self> {
272        if jce.head.ty != JceType::List {
273            return Err(JceError::ReadTypeError(JceType::List, jce.head.ty));
274        }
275        let mut jce = jce.sub_jce();
276        let len = jce.get_by_tag::<i32>(0)? as usize;
277        let mut vec = Vec::with_capacity(len);
278        for _ in 0..len {
279            let mut jce = jce.sub_jce();
280            let value = jce.get_by_tag(0)?;
281            vec.push(value);
282        }
283        Ok(vec)
284    }
285
286    fn empty() -> JceResult<Self> {
287        Ok(Vec::new())
288    }
289}
290
291impl JceGet for Bytes {
292    fn jce_get<B: Buf + ?Sized>(jce: &mut Jce<B>) -> JceResult<Self> {
293        jce.inner.get_u8();
294        let mut jce = jce.sub_jce();
295        let len = jce.get_by_tag::<i32>(0)? as usize;
296        Ok(jce.inner.copy_to_bytes(len))
297    }
298
299    fn empty() -> JceResult<Self> {
300        Ok(Bytes::default())
301    }
302}
303
304// impl JceGet for Vec<u8> { conflicting implementations
305//     fn get<B: Buf + ?Sized>(jce: &mut Jce<B>) -> JceResult<Self> {
306//         jce.inner.get_u8();
307//         let len = jce.get_by_tag::<i32>(0)? as usize;
308//         let mut vec = Vec::with_capacity(len);
309//         jce.inner.copy_to_slice(&mut vec)
310//         Ok(vec)
311//     }
312
313//     fn empty() -> JceResult<Self> {
314//         Ok(vec![])
315//     }
316// }