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 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::Struct { .. } => {
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
265use bytemuck::pod_collect_to_vec;
266
267fn to_vec(buf: &[u8], tag: u8) -> Result<Dynamic> {
268 match tag {
269 1 => Ok(Dynamic::from(bytemuck::cast_slice::<_, i8>(buf))),
270 2 => {
271 let aligned = pod_collect_to_vec::<_, u16>(buf);
272 Ok(Dynamic::from(aligned.as_slice()))
273 }
274 3 => {
275 let aligned = pod_collect_to_vec::<_, i16>(buf);
276 Ok(Dynamic::from(aligned.as_slice()))
277 }
278 4 => {
279 let aligned = pod_collect_to_vec::<_, u32>(buf);
280 Ok(Dynamic::from(aligned.as_slice()))
281 }
282 5 => {
283 let aligned = pod_collect_to_vec::<_, i32>(buf);
284 Ok(Dynamic::from(aligned.as_slice()))
285 }
286 6 => {
287 let aligned = pod_collect_to_vec::<_, f32>(buf);
288 Ok(Dynamic::from(aligned.as_slice()))
289 }
290 7 => {
291 let aligned = pod_collect_to_vec::<_, u64>(buf);
292 Ok(Dynamic::from(aligned.as_slice()))
293 }
294 8 => {
295 let aligned = pod_collect_to_vec::<_, i64>(buf);
296 Ok(Dynamic::from(aligned.as_slice()))
297 }
298 9 => {
299 let aligned = pod_collect_to_vec::<_, f64>(buf);
300 Ok(Dynamic::from(aligned.as_slice()))
301 }
302 _ => Err(anyhow!("unknow tag {}", tag)),
303 }
304}
305
306use parking_lot::RwLock;
307use std::sync::Arc;
308
309impl MsgUnpack for Dynamic {
310 fn decode(buf: &[u8]) -> Result<(Self, usize)> {
311 assert_err!(buf.len() < 1, anyhow!("no data"));
312 let first_byte = buf[0];
313 assert_ok!(first_byte <= 0x7f, (Dynamic::from(first_byte as i64), 1));
314 assert_ok!(first_byte >= 0xe0, (Dynamic::from(first_byte as i64 - 256), 1));
315 if first_byte >= 0x80 && first_byte <= 0x8f {
316 let len = (first_byte & 0x0f) as usize;
317 let (value, size) = Self::decode_array(&buf[1..], len * 2)?;
318 return vec_to_map(value).map(|r| (r, 1 + size));
319 }
320 if first_byte >= 0x90 && first_byte <= 0x9f {
321 let len = (first_byte & 0x0f) as usize;
322 let (value, size) = Self::decode_array(&buf[1..], len)?;
323 return Ok((Dynamic::List(Arc::new(RwLock::new(value))), 1 + size));
324 }
325
326 if first_byte >= 0xa0 && first_byte <= 0xbf {
327 let len = (first_byte & 0x1f) as usize;
328 assert_err!(buf.len() < 1 + len, anyhow!("no data"));
329 return Ok((Dynamic::from_utf8(&buf[1..1 + len])?, 1 + len));
330 }
331
332 assert_ok!(first_byte == 0xc0, (Dynamic::Null, 1));
333 assert_err!(first_byte == 0xc1, anyhow!("0xc1 never used"));
334 assert_ok!(first_byte == 0xc2, (false.into(), 1));
335 assert_ok!(first_byte == 0xc3, (true.into(), 1));
336
337 if first_byte == 0xc4 {
338 assert_err!(buf.len() < 2, anyhow!("no data"));
339 let len = read_8(&buf[1..]) as usize;
340 assert_err!(buf.len() < 2 + len, anyhow!("no data"));
341 return Ok((Dynamic::from(&buf[2..2 + len]), 2 + len));
342 }
343
344 if first_byte == 0xc5 {
345 assert_err!(buf.len() < 3, anyhow!("no data"));
346 let len = read_16(&buf[1..]) as usize;
347 assert_err!(buf.len() < 2 + len, anyhow!("no data"));
348 return Ok((Dynamic::from(&buf[3..3 + len]), 3 + len));
349 }
350
351 if first_byte == 0xc6 {
352 assert_err!(buf.len() < 5, anyhow!("no data"));
353 let len = read_32(&buf[1..]) as usize;
354 assert_err!(buf.len() < 5 + len, anyhow!("no data"));
355 return Ok((Dynamic::from(&buf[5..5 + len]), 5 + len));
356 }
357
358 if first_byte == 0xc7 {
359 assert_err!(buf.len() < 7, anyhow!("no data"));
360 let len = read_8(&buf[1..]) as usize;
361 let tag = read_8(&buf[2..]);
362 let byte_len = len * TAG_LEN[tag as usize];
363 return Ok((to_vec(&buf[3..3 + byte_len], tag)?, 3 + byte_len));
364 }
365
366 if first_byte == 0xc8 {
367 assert_err!(buf.len() < 8, anyhow!("no data"));
368 let len = read_16(&buf[1..]) as usize;
369 let tag = read_8(&buf[3..]);
370 let byte_len = len * TAG_LEN[tag as usize];
371 return Ok((to_vec(&buf[4..4 + byte_len], tag)?, 4 + byte_len));
372 }
373
374 if first_byte == 0xc9 {
375 assert_err!(buf.len() < 10, anyhow!("no data"));
376 let len = read_32(&buf[1..]) as usize;
377 let tag = read_8(&buf[5..]);
378 let byte_len = len * TAG_LEN[tag as usize];
379 return Ok((to_vec(&buf[6..6 + byte_len], tag)?, 6 + byte_len));
380 }
381
382 if first_byte == 0xca {
383 assert_err!(buf.len() < 5, anyhow!("no data"));
384 let raw_value = read_32(&buf[1..]) as u32;
385 let value = f32::from_bits(raw_value);
386 return Ok((Dynamic::from(value as f64), 5));
387 }
388
389 if first_byte == 0xcb {
390 assert_err!(buf.len() < 9, anyhow!("no data"));
391 let raw_value = read_64(&buf[1..]);
392 let value = f64::from_bits(raw_value);
393 return Ok((Dynamic::from(value), 9));
394 }
395
396 if first_byte == 0xd0 {
397 assert_err!(buf.len() < 2, anyhow!("no data"));
398 let raw_value = read_8(&buf[1..]);
399 let value = raw_value as i8 as i64;
400 return Ok((Dynamic::from(value), 2));
401 }
402
403 if first_byte == 0xcd {
404 assert_err!(buf.len() < 3, anyhow!("no data"));
405 let value = read_16(&buf[1..]);
406 return Ok((Dynamic::from(value as i64), 3));
407 }
408
409 if first_byte == 0xce {
410 assert_err!(buf.len() < 5, anyhow!("no data"));
411 let value = read_32(&buf[1..]);
412 return Ok((Dynamic::from(value as i64), 5));
413 }
414
415 if first_byte == 0xcf {
416 assert_err!(buf.len() < 9, anyhow!("no data"));
417 let value = read_64(&buf[1..]);
418 return Ok((Dynamic::from(value as i64), 9));
419 }
420
421 if first_byte == 0xd3 {
422 assert_err!(buf.len() < 9, anyhow!("no data"));
423 let raw_value = read_64(&buf[1..]);
424 let value = raw_value as i64;
425 return Ok((Dynamic::from(value), 9));
426 }
427
428 if first_byte == 0xd1 {
429 assert_err!(buf.len() < 3, anyhow!("no data"));
430 let raw_value = read_16(&buf[1..]);
431 let value = u16::cast_signed(raw_value) as i64;
432 return Ok((Dynamic::from(value), 3));
433 }
434
435 if first_byte == 0xd2 {
436 assert_err!(buf.len() < 5, anyhow!("no data"));
437 let raw_value = read_32(&buf[1..]);
438 let value = u32::cast_signed(raw_value) as i64;
439 return Ok((Dynamic::from(value), 5));
440 }
441
442 if first_byte == 0xd3 {
443 assert_err!(buf.len() < 9, anyhow!("no data"));
444 let raw_value = read_64(&buf[1..]);
445 let value = u64::cast_signed(raw_value);
446 return Ok((Dynamic::from(value), 9));
447 }
448
449 if first_byte == 0xd4 {
450 assert_err!(buf.len() < 3, anyhow!("no data"));
451 let _type_id = u8::cast_signed(buf[1]);
452 return Ok((Dynamic::Null, 3));
454 }
455
456 if first_byte == 0xd5 {
457 assert_err!(buf.len() < 4, anyhow!("no data"));
458 let _type_id = u8::cast_signed(buf[1]);
459 return Ok((Dynamic::Null, 4));
460 }
461
462 if first_byte == 0xd6 {
463 assert_err!(buf.len() < 6, anyhow!("no data"));
464 let _type_id = u8::cast_signed(buf[1]);
465 return Ok((Dynamic::Null, 6));
466 }
467
468 if first_byte == 0xd7 {
469 assert_err!(buf.len() < 10, anyhow!("no data"));
470 let _type_id = buf[1] as i8;
471 return Ok((Dynamic::Null, 10));
472 }
473
474 if first_byte == 0xd8 {
475 assert_err!(buf.len() < 18, anyhow!("no data"));
476 let _type_id = buf[1] as i8;
477 return Ok((Dynamic::Null, 18));
478 }
479
480 if first_byte == 0xd9 {
481 assert_err!(buf.len() < 2, anyhow!("no data"));
482 let len = read_8(&buf[1..]) as usize;
483 assert_err!(buf.len() < 2 + len, anyhow!("no data"));
484 return Ok((Dynamic::from_utf8(&buf[2..2 + len])?, 2 + len));
485 }
486
487 if first_byte == 0xda {
488 assert_err!(buf.len() < 3, anyhow!("no data"));
489 let len = read_16(&buf[1..]) as usize;
490 assert_err!(buf.len() < 3 + len, anyhow!("no data"));
491 return Ok((Dynamic::from_utf8(&buf[3..3 + len])?, 3 + len));
492 }
493
494 if first_byte == 0xdb {
495 assert_err!(buf.len() < 5, anyhow!("no data"));
496 let len = read_32(&buf[1..]) as usize;
497 assert_err!(buf.len() < 5 + len, anyhow!("no data"));
498 return Ok((Dynamic::from_utf8(&buf[5..5 + len])?, 5 + len));
499 }
500
501 if first_byte == 0xdc {
502 assert_err!(buf.len() < 3, anyhow!("no data"));
503 let len = read_16(&buf[1..]) as usize;
504 let (value, size) = Self::decode_array(&buf[3..], len)?;
505 return Ok((Dynamic::List(Arc::new(RwLock::new(value))), 3 + size));
506 }
507
508 if first_byte == 0xdd {
509 assert_err!(buf.len() < 5, anyhow!("no data"));
510 let len = read_32(&buf[1..]) as usize;
511 let (value, size) = Self::decode_array(&buf[5..], len)?;
512 return Ok((Dynamic::List(Arc::new(RwLock::new(value))), 5 + size));
513 }
514
515 if first_byte == 0xde {
516 assert_err!(buf.len() < 3, anyhow!("no data"));
517 let len = read_16(&buf[1..]) as usize;
518 let (value, size) = Self::decode_array(&buf[3..], len * 2)?;
519 return vec_to_map(value).map(|r| (r, 3 + size));
520 }
521
522 if first_byte == 0xdf {
523 assert_err!(buf.len() < 5, anyhow!("no data"));
524 let len = read_32(&buf[1..]) as usize;
525 let (value, size) = Self::decode_array(&buf[5..], len * 2)?;
526 return vec_to_map(value).map(|r| (r, 5 + size));
527 }
528 Err(anyhow!("error code {}", first_byte))
529 }
530}