1use std::collections::HashMap;
2use std::hash::Hash;
3
4use super::{JceError, JceHead, JceResult, JceType, JceValue};
5use bytes::{Buf, Bytes};
6
7pub struct Jce<'a, B>
9where
10 B: Buf + ?Sized,
11{
12 inner: &'a mut B,
13 pub head: JceHead,
14 readed: bool,
15}
16
17pub 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!() }
126}
127
128impl JceGet for u8 {
129 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