Skip to main content

dynamic/
msgpack.rs

1pub trait MsgPack {
2    fn encode(&self, buf: &mut Vec<u8>);
3}
4
5use indexmap::IndexMap;
6
7use byteorder::{BigEndian, WriteBytesExt};
8use smol_str::SmolStr;
9impl MsgPack for &str {
10    fn encode(&self, buf: &mut Vec<u8>) {
11        let length = self.len();
12        if length < 0x20 {
13            buf.push(0xa0 | length as u8);
14        } else if length < 0x100 {
15            buf.push(0xd9);
16            buf.push(length as u8);
17        } else if length < 0x10000 {
18            buf.push(0xda);
19            buf.write_u16::<BigEndian>(length as u16).unwrap();
20        } else {
21            buf.push(0xdb);
22            buf.write_u32::<BigEndian>(length as u32).unwrap();
23        }
24        buf.extend_from_slice(self.as_bytes());
25    }
26}
27
28impl MsgPack for i64 {
29    fn encode(&self, buf: &mut Vec<u8>) {
30        let value = *self;
31        if value >= 0 && value < 128 {
32            buf.push(value as u8);
33        } else if value < 0 && value > -32 {
34            let raw = (value as i8) as u8;
35            buf.push(raw);
36        } else {
37            if value >= -0x80 && value <= 0x7f {
38                buf.push(0xd0);
39                buf.write_i8(value as i8).unwrap();
40            } else if value >= -0x8000 && value <= 0x7fff {
41                buf.push(0xd1);
42                buf.write_i16::<BigEndian>(value as i16).unwrap();
43            } else if value >= -0x8000_0000 && value <= 0x7fff_ffff {
44                buf.push(0xd2);
45                buf.write_i32::<BigEndian>(value as i32).unwrap();
46            } else {
47                buf.push(0xd3);
48                buf.write_i64::<BigEndian>(value).unwrap();
49            }
50        }
51    }
52}
53
54use super::Dynamic;
55
56fn encode_bytes(raw: &[u8], buf: &mut Vec<u8>) {
57    let length = raw.len();
58    if length < 0x100 {
59        buf.push(0xc4);
60        buf.push(length as u8);
61    } else if length < 0x10000 {
62        buf.push(0xc5);
63        buf.write_u16::<BigEndian>(length as u16).unwrap();
64    } else {
65        buf.push(0xc6);
66        buf.write_u32::<BigEndian>(length as u32).unwrap();
67    }
68    buf.extend_from_slice(&raw);
69}
70
71fn encode_vec(raw: &[u8], len: usize, tag: u8, buf: &mut Vec<u8>) {
72    if len < 0x100 {
73        buf.push(0xc7);
74        buf.push(len as u8);
75        buf.push(tag);
76    } else if len < 0x10000 {
77        buf.push(0xc8);
78        buf.write_u16::<BigEndian>(len as u16).unwrap();
79        buf.push(tag);
80    } else {
81        buf.push(0xc9);
82        buf.write_u32::<BigEndian>(len as u32).unwrap();
83        buf.push(tag);
84    }
85    buf.extend_from_slice(raw);
86}
87
88impl MsgPack for Dynamic {
89    fn encode(&self, buf: &mut Vec<u8>) {
90        match self {
91            Dynamic::Iter { idx: _, keys: _, value: _ } => {}
92            Dynamic::Null => buf.push(0xc0),
93            Dynamic::Bool(b) => buf.push(if *b { 0xc3 } else { 0xc2 }),
94            Dynamic::I8(i) => (*i as i64).encode(buf),
95            Dynamic::I16(i) => (*i as i64).encode(buf),
96            Dynamic::I32(i) => (*i as i64).encode(buf),
97            Dynamic::I64(i) => (*i).encode(buf),
98            Dynamic::U8(i) => (*i as i64).encode(buf),
99            Dynamic::U16(i) => (*i as i64).encode(buf),
100            Dynamic::U32(i) => (*i as i64).encode(buf),
101            Dynamic::U64(i) => (*i as i64).encode(buf),
102            Dynamic::F16(bits) => {
103                // round-trip via f64 for msgpack; native f16 has no msgpack tag
104                let f = crate::f16_to_f64(*bits);
105                Dynamic::F64(f).encode(buf);
106            }
107            Dynamic::F32(f) => {
108                buf.push(0xca);
109                let int_value = f32::to_bits(*f);
110                buf.write_u32::<BigEndian>(int_value).unwrap();
111            }
112            Dynamic::F64(f) => {
113                buf.push(0xcb);
114                let int_value = f64::to_bits(*f);
115                buf.write_u64::<BigEndian>(int_value).unwrap();
116            }
117            Dynamic::String(s) => s.as_str().encode(buf),
118            Dynamic::StringBuf(s) => s.as_str().encode(buf),
119            Dynamic::Bytes(raw) => {
120                encode_bytes(raw.as_slice(), buf);
121            }
122            Dynamic::VecI8(vec) => {
123                let len = self.len();
124                encode_vec(vec.as_slice(), len, 1, buf);
125            }
126            Dynamic::VecU16(vec) => {
127                let len = self.len();
128                encode_vec(vec.as_slice(), len, 2, buf);
129            }
130            Dynamic::VecI16(vec) => {
131                let len = self.len();
132                encode_vec(vec.as_slice(), len, 3, buf);
133            }
134            Dynamic::VecU32(vec) => {
135                let len = self.len();
136                encode_vec(vec.as_slice(), len, 4, buf);
137            }
138            Dynamic::VecI32(vec) => {
139                let len = self.len();
140                encode_vec(vec.as_slice(), len, 5, buf);
141            }
142            Dynamic::VecF32(vec) => {
143                let len = self.len();
144                encode_vec(vec.as_slice(), len, 6, buf);
145            }
146            Dynamic::VecU64(vec) => {
147                let len = self.len();
148                encode_vec(bytemuck::cast_slice(vec.as_slice()), len, 7, buf);
149            }
150            Dynamic::VecI64(vec) => {
151                let len = self.len();
152                encode_vec(bytemuck::cast_slice(vec.as_slice()), len, 8, buf);
153            }
154            Dynamic::VecF64(vec) => {
155                let len = self.len();
156                encode_vec(bytemuck::cast_slice(vec.as_slice()), len, 9, buf);
157            }
158            Dynamic::List(raw) => {
159                let length = raw.read().len();
160                if length < 0x10 {
161                    buf.push(0x90 | length as u8);
162                } else if length < 0x10000 {
163                    buf.push(0xdc);
164                    buf.write_u16::<BigEndian>(length as u16).unwrap();
165                } else {
166                    buf.push(0xdd);
167                    buf.write_u32::<BigEndian>(length as u32).unwrap();
168                }
169                for item in raw.read().iter() {
170                    item.encode(buf);
171                }
172            }
173            Dynamic::Map(raw) => {
174                let length = raw.read().len();
175                if length < 16 {
176                    buf.push(0x80 | length as u8);
177                } else if length < 0x10000 {
178                    buf.push(0xde);
179                    buf.write_u16::<BigEndian>(length as u16).unwrap();
180                } else {
181                    buf.push(0xdf);
182                    buf.write_u32::<BigEndian>(length as u32).unwrap();
183                }
184                for (k, v) in raw.read().iter() {
185                    k.as_str().encode(buf);
186                    v.encode(buf);
187                }
188            }
189            Dynamic::StructView { .. } | Dynamic::StructOwned { .. } => {
190                let keys = self.keys();
191                let length = keys.len();
192                if length < 16 {
193                    buf.push(0x80 | length as u8);
194                } else if length < 0x10000 {
195                    buf.push(0xde);
196                    buf.write_u16::<BigEndian>(length as u16).unwrap();
197                } else {
198                    buf.push(0xdf);
199                    buf.write_u32::<BigEndian>(length as u32).unwrap();
200                }
201                for key in keys {
202                    key.as_str().encode(buf);
203                    self.get_dynamic(key.as_str()).unwrap_or(Dynamic::Null).encode(buf);
204                }
205            }
206            Dynamic::Custom(value) => {
207                buf.push(0x81);
208                "@custom".encode(buf);
209                value.custom_type_name().encode(buf);
210            }
211        }
212    }
213}
214use anyhow::{Result, anyhow};
215
216pub trait MsgUnpack: Sized {
217    fn decode(buf: &[u8]) -> Result<(Self, usize)>;
218    fn decode_array(buf: &[u8], length: usize) -> Result<(Vec<Self>, usize)> {
219        let mut cursor = 0usize;
220        let mut result = Vec::with_capacity(length);
221        for _ in 0..length {
222            let (value, size) = Self::decode(&buf[cursor..])?;
223            result.push(value);
224            cursor += size;
225        }
226        Ok((result, cursor))
227    }
228}
229
230#[inline]
231pub(crate) fn read_8(raw: &[u8]) -> u8 {
232    raw[0]
233}
234
235#[inline]
236pub(crate) fn read_16(raw: &[u8]) -> u16 {
237    raw[1] as u16 | (raw[0] as u16) << 8
238}
239
240#[inline]
241pub(crate) fn read_32(raw: &[u8]) -> u32 {
242    raw[3] as u32 | (raw[2] as u32) << 8 | (raw[1] as u32) << 16 | (raw[0] as u32) << 24
243}
244
245#[inline]
246pub(crate) fn read_64(raw: &[u8]) -> u64 {
247    raw[7] as u64 | (raw[6] as u64) << 8 | (raw[5] as u64) << 16 | (raw[4] as u64) << 24 | (raw[3] as u64) << 32 | (raw[2] as u64) << 40 | (raw[1] as u64) << 48 | (raw[0] as u64) << 56
248}
249
250fn vec_to_map(kvs: Vec<Dynamic>) -> Result<Dynamic> {
251    let mut map: IndexMap<SmolStr, Dynamic> = IndexMap::new();
252    let mut key: Option<Dynamic> = None;
253    for kv in kvs {
254        if let Some(k) = key.take() {
255            map.insert(SmolStr::from(k.to_string()), kv);
256        } else {
257            key = Some(kv);
258        }
259    }
260    Ok(Dynamic::Map(Arc::new(RwLock::new(map))))
261}
262
263const TAG_LEN: [usize; 10] = [0, 1, 2, 2, 4, 4, 4, 8, 8, 8];
264
265/// ext 类型的元素宽度。tag 来自外部字节流,非法 tag 必须报错而非越界 panic。
266fn tag_len(tag: u8) -> Result<usize> {
267    TAG_LEN.get(tag as usize).copied().ok_or_else(|| anyhow!("非法 ext tag: 0x{:02X}", tag))
268}
269
270use bytemuck::pod_collect_to_vec;
271
272fn to_vec(buf: &[u8], tag: u8) -> Result<Dynamic> {
273    match tag {
274        1 => Ok(Dynamic::from(bytemuck::cast_slice::<_, i8>(buf))),
275        2 => {
276            let aligned = pod_collect_to_vec::<_, u16>(buf);
277            Ok(Dynamic::from(aligned.as_slice()))
278        }
279        3 => {
280            let aligned = pod_collect_to_vec::<_, i16>(buf);
281            Ok(Dynamic::from(aligned.as_slice()))
282        }
283        4 => {
284            let aligned = pod_collect_to_vec::<_, u32>(buf);
285            Ok(Dynamic::from(aligned.as_slice()))
286        }
287        5 => {
288            let aligned = pod_collect_to_vec::<_, i32>(buf);
289            Ok(Dynamic::from(aligned.as_slice()))
290        }
291        6 => {
292            let aligned = pod_collect_to_vec::<_, f32>(buf);
293            Ok(Dynamic::from(aligned.as_slice()))
294        }
295        7 => {
296            let aligned = pod_collect_to_vec::<_, u64>(buf);
297            Ok(Dynamic::from(aligned.as_slice()))
298        }
299        8 => {
300            let aligned = pod_collect_to_vec::<_, i64>(buf);
301            Ok(Dynamic::from(aligned.as_slice()))
302        }
303        9 => {
304            let aligned = pod_collect_to_vec::<_, f64>(buf);
305            Ok(Dynamic::from(aligned.as_slice()))
306        }
307        _ => Err(anyhow!("unknow tag {}", tag)),
308    }
309}
310
311use parking_lot::RwLock;
312use std::sync::Arc;
313
314impl MsgUnpack for Dynamic {
315    fn decode(buf: &[u8]) -> Result<(Self, usize)> {
316        assert_err!(buf.len() < 1, anyhow!("no data"));
317        let first_byte = buf[0];
318        assert_ok!(first_byte <= 0x7f, (Dynamic::from(first_byte as i64), 1));
319        assert_ok!(first_byte >= 0xe0, (Dynamic::from(first_byte as i64 - 256), 1));
320        if first_byte >= 0x80 && first_byte <= 0x8f {
321            let len = (first_byte & 0x0f) as usize;
322            let (value, size) = Self::decode_array(&buf[1..], len * 2)?;
323            return vec_to_map(value).map(|r| (r, 1 + size));
324        }
325        if first_byte >= 0x90 && first_byte <= 0x9f {
326            let len = (first_byte & 0x0f) as usize;
327            let (value, size) = Self::decode_array(&buf[1..], len)?;
328            return Ok((Dynamic::List(Arc::new(RwLock::new(value))), 1 + size));
329        }
330
331        if first_byte >= 0xa0 && first_byte <= 0xbf {
332            let len = (first_byte & 0x1f) as usize;
333            assert_err!(buf.len() < 1 + len, anyhow!("no data"));
334            return Ok((Dynamic::from_utf8(&buf[1..1 + len])?, 1 + len));
335        }
336
337        assert_ok!(first_byte == 0xc0, (Dynamic::Null, 1));
338        assert_err!(first_byte == 0xc1, anyhow!("0xc1 never used"));
339        assert_ok!(first_byte == 0xc2, (false.into(), 1));
340        assert_ok!(first_byte == 0xc3, (true.into(), 1));
341
342        if first_byte == 0xc4 {
343            assert_err!(buf.len() < 2, anyhow!("no data"));
344            let len = read_8(&buf[1..]) as usize;
345            assert_err!(buf.len() < 2 + len, anyhow!("no data"));
346            return Ok((Dynamic::from(&buf[2..2 + len]), 2 + len));
347        }
348
349        if first_byte == 0xc5 {
350            assert_err!(buf.len() < 3, anyhow!("no data"));
351            let len = read_16(&buf[1..]) as usize;
352            assert_err!(buf.len() < 3 + len, anyhow!("no data"));
353            return Ok((Dynamic::from(&buf[3..3 + len]), 3 + len));
354        }
355
356        if first_byte == 0xc6 {
357            assert_err!(buf.len() < 5, anyhow!("no data"));
358            let len = read_32(&buf[1..]) as usize;
359            assert_err!(buf.len() < 5 + len, anyhow!("no data"));
360            return Ok((Dynamic::from(&buf[5..5 + len]), 5 + len));
361        }
362
363        if first_byte == 0xc7 {
364            assert_err!(buf.len() < 7, anyhow!("no data"));
365            let len = read_8(&buf[1..]) as usize;
366            let tag = read_8(&buf[2..]);
367            let byte_len = len * tag_len(tag)?;
368            return Ok((to_vec(&buf[3..3 + byte_len], tag)?, 3 + byte_len));
369        }
370
371        if first_byte == 0xc8 {
372            assert_err!(buf.len() < 8, anyhow!("no data"));
373            let len = read_16(&buf[1..]) as usize;
374            let tag = read_8(&buf[3..]);
375            let byte_len = len * tag_len(tag)?;
376            return Ok((to_vec(&buf[4..4 + byte_len], tag)?, 4 + byte_len));
377        }
378
379        if first_byte == 0xc9 {
380            assert_err!(buf.len() < 10, anyhow!("no data"));
381            let len = read_32(&buf[1..]) as usize;
382            let tag = read_8(&buf[5..]);
383            let byte_len = len * tag_len(tag)?;
384            return Ok((to_vec(&buf[6..6 + byte_len], tag)?, 6 + byte_len));
385        }
386
387        if first_byte == 0xca {
388            assert_err!(buf.len() < 5, anyhow!("no data"));
389            let raw_value = read_32(&buf[1..]) as u32;
390            let value = f32::from_bits(raw_value);
391            return Ok((Dynamic::from(value as f64), 5));
392        }
393
394        if first_byte == 0xcb {
395            assert_err!(buf.len() < 9, anyhow!("no data"));
396            let raw_value = read_64(&buf[1..]);
397            let value = f64::from_bits(raw_value);
398            return Ok((Dynamic::from(value), 9));
399        }
400
401        if first_byte == 0xd0 {
402            assert_err!(buf.len() < 2, anyhow!("no data"));
403            let raw_value = read_8(&buf[1..]);
404            let value = raw_value as i8 as i64;
405            return Ok((Dynamic::from(value), 2));
406        }
407
408        if first_byte == 0xcd {
409            assert_err!(buf.len() < 3, anyhow!("no data"));
410            let value = read_16(&buf[1..]);
411            return Ok((Dynamic::from(value as i64), 3));
412        }
413
414        if first_byte == 0xce {
415            assert_err!(buf.len() < 5, anyhow!("no data"));
416            let value = read_32(&buf[1..]);
417            return Ok((Dynamic::from(value as i64), 5));
418        }
419
420        if first_byte == 0xcf {
421            assert_err!(buf.len() < 9, anyhow!("no data"));
422            let value = read_64(&buf[1..]);
423            return Ok((Dynamic::from(value as i64), 9));
424        }
425
426        if first_byte == 0xd3 {
427            assert_err!(buf.len() < 9, anyhow!("no data"));
428            let raw_value = read_64(&buf[1..]);
429            let value = raw_value as i64;
430            return Ok((Dynamic::from(value), 9));
431        }
432
433        if first_byte == 0xd1 {
434            assert_err!(buf.len() < 3, anyhow!("no data"));
435            let raw_value = read_16(&buf[1..]);
436            let value = u16::cast_signed(raw_value) as i64;
437            return Ok((Dynamic::from(value), 3));
438        }
439
440        if first_byte == 0xd2 {
441            assert_err!(buf.len() < 5, anyhow!("no data"));
442            let raw_value = read_32(&buf[1..]);
443            let value = u32::cast_signed(raw_value) as i64;
444            return Ok((Dynamic::from(value), 5));
445        }
446
447        if first_byte == 0xd4 {
448            assert_err!(buf.len() < 3, anyhow!("no data"));
449            let _type_id = u8::cast_signed(buf[1]);
450            //let _value = raw[2..3].to_vec();
451            return Ok((Dynamic::Null, 3));
452        }
453
454        if first_byte == 0xd5 {
455            assert_err!(buf.len() < 4, anyhow!("no data"));
456            let _type_id = u8::cast_signed(buf[1]);
457            return Ok((Dynamic::Null, 4));
458        }
459
460        if first_byte == 0xd6 {
461            assert_err!(buf.len() < 6, anyhow!("no data"));
462            let _type_id = u8::cast_signed(buf[1]);
463            return Ok((Dynamic::Null, 6));
464        }
465
466        if first_byte == 0xd7 {
467            assert_err!(buf.len() < 10, anyhow!("no data"));
468            let _type_id = buf[1] as i8;
469            return Ok((Dynamic::Null, 10));
470        }
471
472        if first_byte == 0xd8 {
473            assert_err!(buf.len() < 18, anyhow!("no data"));
474            let _type_id = buf[1] as i8;
475            return Ok((Dynamic::Null, 18));
476        }
477
478        if first_byte == 0xd9 {
479            assert_err!(buf.len() < 2, anyhow!("no data"));
480            let len = read_8(&buf[1..]) as usize;
481            assert_err!(buf.len() < 2 + len, anyhow!("no data"));
482            return Ok((Dynamic::from_utf8(&buf[2..2 + len])?, 2 + len));
483        }
484
485        if first_byte == 0xda {
486            assert_err!(buf.len() < 3, anyhow!("no data"));
487            let len = read_16(&buf[1..]) as usize;
488            assert_err!(buf.len() < 3 + len, anyhow!("no data"));
489            return Ok((Dynamic::from_utf8(&buf[3..3 + len])?, 3 + len));
490        }
491
492        if first_byte == 0xdb {
493            assert_err!(buf.len() < 5, anyhow!("no data"));
494            let len = read_32(&buf[1..]) as usize;
495            assert_err!(buf.len() < 5 + len, anyhow!("no data"));
496            return Ok((Dynamic::from_utf8(&buf[5..5 + len])?, 5 + len));
497        }
498
499        if first_byte == 0xdc {
500            assert_err!(buf.len() < 3, anyhow!("no data"));
501            let len = read_16(&buf[1..]) as usize;
502            let (value, size) = Self::decode_array(&buf[3..], len)?;
503            return Ok((Dynamic::List(Arc::new(RwLock::new(value))), 3 + size));
504        }
505
506        if first_byte == 0xdd {
507            assert_err!(buf.len() < 5, anyhow!("no data"));
508            let len = read_32(&buf[1..]) as usize;
509            let (value, size) = Self::decode_array(&buf[5..], len)?;
510            return Ok((Dynamic::List(Arc::new(RwLock::new(value))), 5 + size));
511        }
512
513        if first_byte == 0xde {
514            assert_err!(buf.len() < 3, anyhow!("no data"));
515            let len = read_16(&buf[1..]) as usize;
516            let (value, size) = Self::decode_array(&buf[3..], len * 2)?;
517            return vec_to_map(value).map(|r| (r, 3 + size));
518        }
519
520        if first_byte == 0xdf {
521            assert_err!(buf.len() < 5, anyhow!("no data"));
522            let len = read_32(&buf[1..]) as usize;
523            let (value, size) = Self::decode_array(&buf[5..], len * 2)?;
524            return vec_to_map(value).map(|r| (r, 5 + size));
525        }
526        Err(anyhow!("error code {}", first_byte))
527    }
528}