1#[cfg(feature = "serde")]
2mod serde;
3
4use crate::marker::Marker;
5
6use byteorder::{BigEndian, ByteOrder};
7use num_traits::cast::FromPrimitive;
8use zerocopy::ByteSlice;
9
10#[derive(Debug)]
12pub enum Error {
13 EndOfBuffer(Marker),
15 OutOfBounds,
21 InvalidType,
23 CustomError,
24 #[cfg(all(not(feature = "std"), feature = "custom-error-messages"))]
25 CustomErrorWithMessage(heapless::String<64>),
26 #[cfg(all(feature = "std", feature = "custom-error-messages"))]
27 CustomErrorWithMessage(String),
28 NotAscii,
29 InvalidBoolean,
30 InvalidBinType,
31 InvalidStringType,
32 InvalidArrayType,
33 InvalidMapType,
34 InvalidNewTypeLength,
35 InvalidUtf8(core::str::Utf8Error),
36}
37
38#[cfg(feature = "serde")]
39pub fn from_slice<'a, T: ::serde::de::Deserialize<'a>>(buf: &'a [u8]) -> Result<T, Error> {
41 let mut de = serde::Deserializer::new(buf);
42 let value = ::serde::de::Deserialize::deserialize(&mut de)?;
43
44 Ok(value)
45}
46
47pub trait DeserializeFromSlice {
48 fn from_slice(&mut self, buf: &[u8]) -> Result<usize, Error>;
49}
50
51impl DeserializeFromSlice for Option<u8> {
52 fn from_slice(&mut self, buf: &[u8]) -> Result<usize, Error> {
53 let (v, n) = read_u8(buf)?;
54 *self = Some(v);
55 Ok(n)
56 }
57}
58impl DeserializeFromSlice for Option<u16> {
59 fn from_slice(&mut self, buf: &[u8]) -> Result<usize, Error> {
60 let (v, n) = read_u16(buf)?;
61 *self = Some(v);
62 Ok(n)
63 }
64}
65impl DeserializeFromSlice for Option<u32> {
66 fn from_slice(&mut self, buf: &[u8]) -> Result<usize, Error> {
67 let (v, n) = read_u32(buf)?;
68 *self = Some(v);
69 Ok(n)
70 }
71}
72impl DeserializeFromSlice for Option<u64> {
73 fn from_slice(&mut self, buf: &[u8]) -> Result<usize, Error> {
74 let (v, n) = read_u64(buf)?;
75 *self = Some(v);
76 Ok(n)
77 }
78}
79impl DeserializeFromSlice for Option<i8> {
80 fn from_slice(&mut self, buf: &[u8]) -> Result<usize, Error> {
81 let (v, n) = read_i8(buf)?;
82 *self = Some(v);
83 Ok(n)
84 }
85}
86impl DeserializeFromSlice for Option<i16> {
87 fn from_slice(&mut self, buf: &[u8]) -> Result<usize, Error> {
88 let (v, n) = read_i16(buf)?;
89 *self = Some(v);
90 Ok(n)
91 }
92}
93impl DeserializeFromSlice for Option<i32> {
94 fn from_slice(&mut self, buf: &[u8]) -> Result<usize, Error> {
95 let (v, n) = read_i32(buf)?;
96 *self = Some(v);
97 Ok(n)
98 }
99}
100impl DeserializeFromSlice for Option<i64> {
101 fn from_slice(&mut self, buf: &[u8]) -> Result<usize, Error> {
102 let (v, n) = read_i64(buf)?;
103 *self = Some(v);
104 Ok(n)
105 }
106}
107
108pub fn read_raw_u8(buf: &[u8]) -> Result<(u8, &[u8]), Error> {
109 buf.split_first().map(|(&x, rest)| (x, rest)).ok_or(Error::EndOfBuffer(Marker::U8))
110}
111pub fn read_raw_u16<B: ByteSlice>(buf: B) -> Result<(u16, B), Error> {
112 if buf.len() < 2 {
114 return Err(Error::EndOfBuffer(Marker::U16));
115 }
116 let (v, rest) = buf.split_at(2);
117 Ok((BigEndian::read_u16(&*v), rest))
118}
119pub fn read_raw_u32(buf: &[u8]) -> Result<(u32, &[u8]), Error> {
120 if buf.len() < 4 {
121 return Err(Error::EndOfBuffer(Marker::U32));
122 }
123 let (v, rest) = buf.split_at(4);
124 Ok((BigEndian::read_u32(v), rest))
125}
126#[cfg(feature = "u64")]
127pub fn read_raw_u64(buf: &[u8]) -> Result<(u64, &[u8]), Error> {
128 if buf.len() < 8 {
129 return Err(Error::EndOfBuffer(Marker::U64));
130 }
131 let (v, rest) = buf.split_at(8);
132 Ok((BigEndian::read_u64(v), rest))
133}
134#[allow(dead_code)]
135fn read_raw_ux(buf: &[u8], num_bytes: u8) -> Result<(usize, &[u8]), Error> {
136 Ok(match num_bytes {
137 1 => {
138 let (x, rest) = read_raw_u8(buf)?;
139 (x as usize, rest)
140 }
141 2 => {
142 let (x, rest) = read_raw_u16(buf)?;
143 (x as usize, rest)
144 }
145 4 => {
146 let (x, rest) = read_raw_u32(buf)?;
147 (x as usize, rest)
148 }
149 _ => unreachable!(),
150 })
151}
152
153pub fn read_int<B: ByteSlice, T: FromPrimitive>(buf: B) -> Result<(T, usize), Error> {
154 match read_u64(buf) {
155 Ok((v, len)) => T::from_u64(v).map_or(Err(Error::OutOfBounds), |v| Ok((v, len))),
156 Err(kind) => Err(kind),
157 }
158}
159#[cfg(feature = "i64")]
160pub fn read_sint<B: ByteSlice, T: FromPrimitive>(buf: B) -> Result<(T, usize), Error> {
161 match read_i64(buf) {
162 Ok((v, len)) => T::from_i64(v).map_or(Err(Error::OutOfBounds), |v| Ok((v, len))),
163 Err(kind) => Err(kind),
164 }
165}
166#[cfg(not(feature = "i64"))]
167pub fn read_sint<B: ByteSlice, T: FromPrimitive>(buf: B) -> Result<(T, usize), Error> {
168 match read_i32(buf) {
169 Ok((v, len)) => {
170 if let Some(v) = T::from_i32(v) {
171 Ok((v, len))
172 } else {
173 Err(Error::OutOfBounds)
174 }
175 }
176 Err(kind) => Err(kind),
177 }
178}
179
180#[inline(always)]
181pub fn read_u8<B: ByteSlice>(buf: B) -> Result<(u8, usize), Error> {
182 read_int(buf)
183}
184#[inline(always)]
185pub fn read_u16<B: ByteSlice>(buf: B) -> Result<(u16, usize), Error> {
186 read_int(buf)
187}
188#[inline(always)]
189pub fn read_u32<B: ByteSlice>(buf: B) -> Result<(u32, usize), Error> {
190 read_int(buf)
191}
192
193#[inline(always)]
194pub fn read_i8<B: ByteSlice>(buf: B) -> Result<(i8, usize), Error> {
195 read_sint(buf)
196}
197#[inline(always)]
198pub fn read_i16<B: ByteSlice>(buf: B) -> Result<(i16, usize), Error> {
199 read_sint(buf)
200}
201#[inline(always)]
202pub fn read_i32<B: ByteSlice>(buf: B) -> Result<(i32, usize), Error> {
203 read_sint(buf)
204}
205
206pub fn read_bool<B: ByteSlice>(buf: B) -> Result<(bool, usize), Error> {
207 if buf.len() == 0 {
208 return Err(Error::EndOfBuffer(Marker::True));
209 }
210
211 match Marker::from(buf[0]) {
212 Marker::True => Ok((true, 1)),
213 Marker::False => Ok((false, 1)),
214 _ => Err(Error::InvalidBoolean),
215 }
216}
217
218pub fn read_u64<B: ByteSlice>(buf: B) -> Result<(u64, usize), Error> {
219 if buf.len() == 0 {
220 return Err(Error::EndOfBuffer(Marker::U64));
221 }
222
223 let marker = Marker::from(buf[0]);
224 match marker {
225 Marker::U64 => {
227 if buf.len() >= 9 {
228 Ok((BigEndian::read_u64(&buf[1..9]), 9))
229 } else {
230 Err(Error::EndOfBuffer(Marker::U64))
231 }
232 }
233 _ => match read_i64(buf) {
234 Ok((i, l)) => u64::from_i64(i).map_or(Err(Error::OutOfBounds), |u| Ok((u, l))),
235 Err(kind) => Err(kind),
236 },
237 }
238}
239
240pub fn read_i64<B: ByteSlice>(buf: B) -> Result<(i64, usize), Error> {
241 if buf.len() == 0 {
242 return Err(Error::EndOfBuffer(Marker::I64));
243 }
244
245 let marker = Marker::from(buf[0]);
246 match marker {
247 Marker::FixPos(val) => Ok((i64::from(val), 1)),
248 Marker::FixNeg(val) => Ok((i64::from(val), 1)),
249
250 Marker::U8 => {
251 if buf.len() >= 2 {
252 Ok((i64::from(buf[1]), 2))
253 } else {
254 Err(Error::EndOfBuffer(Marker::I64))
255 }
256 }
257 Marker::U16 => {
258 if buf.len() >= 3 {
259 Ok((i64::from(BigEndian::read_u16(&buf[1..3])), 3))
260 } else {
261 Err(Error::EndOfBuffer(Marker::I64))
262 }
263 }
264 Marker::U32 => {
265 if buf.len() >= 5 {
266 Ok((i64::from(BigEndian::read_u32(&buf[1..5])), 5))
267 } else {
268 Err(Error::EndOfBuffer(Marker::I64))
269 }
270 }
271 Marker::U64 => {
272 if buf.len() >= 9 {
273 let u = BigEndian::read_u64(&buf[1..9]);
274 i64::from_u64(u).map_or(Err(Error::OutOfBounds), |i| Ok((i, 9)))
275 } else {
276 Err(Error::EndOfBuffer(Marker::I64))
277 }
278 }
279 #[allow(clippy::cast_possible_wrap)]
280 Marker::I8 => {
281 if buf.len() >= 2 {
282 Ok((i64::from(buf[1] as i8), 2))
283 } else {
284 Err(Error::EndOfBuffer(Marker::I64))
285 }
286 }
287 Marker::I16 => {
288 if buf.len() >= 3 {
289 Ok((i64::from(BigEndian::read_i16(&buf[1..3])), 3))
290 } else {
291 Err(Error::EndOfBuffer(Marker::I64))
292 }
293 }
294 Marker::I32 => {
295 if buf.len() >= 5 {
296 Ok((i64::from(BigEndian::read_i32(&buf[1..5])), 5))
297 } else {
298 Err(Error::EndOfBuffer(Marker::I64))
299 }
300 }
301 Marker::I64 => {
302 if buf.len() >= 9 {
303 Ok((BigEndian::read_i64(&buf[1..9]), 9))
304 } else {
305 Err(Error::EndOfBuffer(Marker::I64))
306 }
307 }
308 _ => Err(Error::EndOfBuffer(Marker::I64)),
309 }
310}
311
312pub fn read_f32<B: ByteSlice>(buf: B) -> Result<(f32, usize), Error> {
313 if buf.len() == 0 {
314 return Err(Error::EndOfBuffer(Marker::F32));
315 }
316
317 let marker = Marker::from(buf[0]);
318 match marker {
319 Marker::F32 => {
320 if buf.len() >= 5 {
321 Ok((BigEndian::read_f32(&buf[1..5]), 5))
322 } else {
323 Err(Error::EndOfBuffer(Marker::F32))
324 }
325 }
326 _ => Err(Error::EndOfBuffer(Marker::F32)),
327 }
328}
329pub fn read_f64<B: ByteSlice>(buf: B) -> Result<(f64, usize), Error> {
330 if buf.len() == 0 {
331 return Err(Error::EndOfBuffer(Marker::F64));
332 }
333
334 let marker = Marker::from(buf[0]);
335
336 match marker {
337 Marker::F32 => {
338 if buf.len() >= 5 {
339 let v = BigEndian::read_f32(&buf[1..5]);
340 Ok((f64::from(v), 5))
341 } else {
342 Err(Error::EndOfBuffer(Marker::F32))
343 }
344 }
345 Marker::F64 => {
346 if buf.len() >= 9 {
347 Ok((BigEndian::read_f64(&buf[1..9]), 9))
348 } else {
349 Err(Error::EndOfBuffer(Marker::F64))
350 }
351 }
352 Marker::FixPos(v) => Ok((f64::from(v), 1)),
353 _ => Err(Error::EndOfBuffer(Marker::F64)),
354 }
355}
356
357pub fn read_bin<B: ByteSlice>(buf: B) -> Result<(B, usize), Error> {
358 if buf.len() == 0 {
359 return Err(Error::EndOfBuffer(Marker::Bin16));
360 }
361
362 let marker = Marker::from(buf[0]);
363 match marker {
364 Marker::FixStr(len) => {
365 let header_len = 1;
366 let len = len as usize;
367 if buf.len() >= header_len + len {
368 let (_head, rest) = buf.split_at(header_len);
369 let (bin, _rest) = rest.split_at(len);
370 Ok((bin, header_len + len))
371 } else {
372 Err(Error::EndOfBuffer(Marker::FixStr(len as u8)))
373 }
374 }
375 Marker::Bin8 | Marker::Str8 => {
376 let header_len = 2;
377 if let Some(&len) = buf.get(1) {
378 let len = len as usize;
379 if buf.len() >= header_len + len {
380 let (_head, rest) = buf.split_at(header_len);
381 let (bin, _rest) = rest.split_at(len);
382 Ok((bin, header_len + len))
383 } else {
384 Err(Error::EndOfBuffer(Marker::Bin8))
385 }
386 } else {
387 Err(Error::EndOfBuffer(Marker::Bin8))
388 }
389 }
390 Marker::Bin16 | Marker::Str16 => {
391 let header_len = 3;
392 if buf.len() < header_len {
393 return Err(Error::EndOfBuffer(Marker::Bin16));
394 }
395 let (_, buf) = buf.split_at(1);
396 let (len, buf) = read_raw_u16(buf)?; let len = len as usize;
398 if buf.len() >= len {
399 let (bin, _rest) = buf.split_at(len);
400 Ok((bin, header_len + len))
401 } else {
402 Err(Error::EndOfBuffer(Marker::Bin16))
403 }
404 }
405 #[cfg(feature = "bin32")]
406 Marker::Bin32 | Marker::Str32 => {
407 let header_len = 5;
408 if buf.len() < header_len {
409 return Err(Error::EndOfBuffer(Marker::Bin32));
410 }
411 let len = BigEndian::read_u32(&buf[1..header_len]) as usize;
412 if buf.len() >= header_len + len {
413 let (_head, rest) = buf.split_at(header_len);
414 let (bin, _rest) = rest.split_at(len);
415 Ok((bin, header_len + len))
416 } else {
417 Err(Error::EndOfBuffer(Marker::Bin32))
418 }
419 }
420 _ => Err(Error::InvalidBinType),
421 }
422}
423
424pub fn read_str(buf: &[u8]) -> Result<(&str, usize), Error> {
425 if buf.is_empty() {
426 return Err(Error::EndOfBuffer(Marker::Str32));
427 }
428
429 let marker = Marker::from(buf[0]);
430 let (header_len, len) = match marker {
431 Marker::FixStr(len) => {
432 let header_len = 1;
433 let len = len as usize;
434 if buf.len() >= header_len + len {
435 (header_len, len)
436 } else {
437 return Err(Error::EndOfBuffer(Marker::FixStr(len as u8)));
438 }
439 }
440 Marker::Str8 => {
441 let header_len = 2;
442 if let Some(&len) = buf.get(1) {
443 let len = len as usize;
444 if buf.len() >= header_len + len {
445 (header_len, len)
446 } else {
447 return Err(Error::EndOfBuffer(Marker::Str8));
448 }
449 } else {
450 return Err(Error::EndOfBuffer(Marker::Str8));
451 }
452 }
453 Marker::Str16 => {
454 let header_len = 3;
455 if buf.len() < header_len {
456 return Err(Error::EndOfBuffer(Marker::Str16));
457 }
458 let len = BigEndian::read_u16(&buf[1..header_len]) as usize;
459 if buf.len() >= header_len + len {
460 (header_len, len)
461 } else {
462 return Err(Error::EndOfBuffer(Marker::Str16));
463 }
464 }
465 #[cfg(feature = "str32")]
466 Marker::Str32 => {
467 let header_len = 5;
468 if buf.len() < header_len {
469 return Err(Error::EndOfBuffer(Marker::Str32));
470 }
471 let len = BigEndian::read_u32(&buf[1..header_len]) as usize;
472 if buf.len() >= header_len + len {
473 (header_len, len)
474 } else {
475 return Err(Error::EndOfBuffer(Marker::Str32));
476 }
477 }
478 _ => {
479 return Err(Error::InvalidStringType);
480 }
481 };
482 let buf = &buf[header_len..header_len + len];
483 let s = core::str::from_utf8(buf).map_err(Error::InvalidUtf8)?;
484
485 Ok((s, header_len + len))
486}
487
488pub fn read_array_len<B: ByteSlice>(buf: B) -> Result<(usize, usize), Error> {
489 if buf.len() == 0 {
490 return Err(Error::EndOfBuffer(Marker::Array32));
491 }
492
493 let marker = Marker::from(buf[0]);
495 let (header_len, len) = match marker {
496 Marker::FixArray(len) => {
497 let header_len = 1;
498 let len = len as usize;
499 if buf.len() >= header_len + len {
500 (header_len, len)
501 } else {
502 return Err(Error::EndOfBuffer(Marker::FixArray(len as u8)));
503 }
504 }
505 #[cfg(feature = "array16")]
506 Marker::Array16 => {
507 let header_len = 3;
508 if buf.len() < header_len {
509 return Err(Error::EndOfBuffer(Marker::Array16));
510 }
511 let len = BigEndian::read_u16(&buf[1..header_len]) as usize;
512 if buf.len() >= header_len + len {
513 (header_len, len)
514 } else {
515 return Err(Error::EndOfBuffer(Marker::Array16));
516 }
517 }
518 #[cfg(feature = "array32")]
519 Marker::Array32 => {
520 let header_len = 5;
521 if buf.len() < header_len {
522 return Err(Error::EndOfBuffer(Marker::Array32));
523 }
524 let len = BigEndian::read_u32(&buf[1..header_len]) as usize;
525 if buf.len() >= header_len + len {
526 (header_len, len)
527 } else {
528 return Err(Error::EndOfBuffer(Marker::Array32));
529 }
530 }
531 _ => return Err(Error::InvalidArrayType),
532 };
533 Ok((len, header_len))
534}
535
536pub fn read_map_len<B: ByteSlice>(buf: B) -> Result<(usize, usize), Error> {
537 if buf.len() == 0 {
538 return Err(Error::EndOfBuffer(Marker::Map32));
539 }
540
541 let marker = Marker::from(buf[0]);
542 let (len, header_len) = match marker {
543 Marker::FixMap(len) => {
544 let header_len = 1;
545 let len = len as usize;
546 (len, header_len)
547 }
548 #[cfg(feature = "map16")]
549 Marker::Map16 => {
550 let header_len = 3;
551 if buf.len() < header_len {
552 return Err(Error::EndOfBuffer(Marker::Map16));
553 }
554 let len = BigEndian::read_u16(&buf[1..header_len]) as usize;
555 (len, header_len)
556 }
557 #[cfg(feature = "map32")]
558 Marker::Map32 => {
559 let header_len = 5;
560 if buf.len() < header_len {
561 return Err(Error::EndOfBuffer(Marker::Map32));
562 }
563 let len = BigEndian::read_u32(&buf[1..header_len]) as usize;
564 (len, header_len)
565 }
566
567 _ => return Err(Error::InvalidMapType),
568 };
569 if buf.len() >= header_len + len {
570 Ok((len, header_len))
571 } else {
572 Err(Error::EndOfBuffer(Marker::Map32))
573 }
574}
575
576pub fn skip_any<B: ByteSlice>(buf: B) -> Result<((), usize), Error> {
577 if buf.is_empty() {
578 return Ok(((), 0));
579 }
580 let marker = Marker::from_u8(buf[0]);
581 let n = match marker {
582 Marker::FixPos(_) => 1,
583 Marker::U8 => 2,
584 Marker::U16 => 3,
585 Marker::U32 => 5,
586 Marker::U64 => 9,
587 Marker::FixNeg(_) => 1,
588 Marker::I8 => 2,
589 Marker::I16 => 3,
590 Marker::I32 => 5,
591 Marker::I64 => 9,
592
593 Marker::F32 => 5,
594 Marker::F64 => 9,
595
596 Marker::Null | Marker::True | Marker::False | Marker::Reserved => 1,
597
598 Marker::FixStr(n) => n as usize + 1,
599 Marker::Str8 | Marker::Bin8 => {
600 if buf.len() < 2 {
601 return Err(Error::EndOfBuffer(Marker::Str8));
602 }
603 2 + buf[1] as usize
604 }
605 Marker::Str16 | Marker::Bin16 => {
606 if buf.len() < 3 {
607 return Err(Error::EndOfBuffer(Marker::Str16));
608 }
609 3 + BigEndian::read_u16(&buf[1..3]) as usize
610 }
611 Marker::Str32 | Marker::Bin32 => {
612 if buf.len() < 5 {
613 return Err(Error::EndOfBuffer(Marker::Str32));
614 }
615 5 + BigEndian::read_u32(&buf[1..5]) as usize
616 }
617
618 Marker::FixArray(_) | Marker::Array16 | Marker::Array32 => {
619 let (len, n) = read_array_len(&buf[..])?;
620 let mut n = n;
621 for _ in 0..len {
622 n += skip_any(&buf[n..])?.1;
624 }
625 n
626 }
627 Marker::FixMap(_) | Marker::Map16 | Marker::Map32 => {
628 let (len, n) = read_map_len(&buf[..])?;
629 let mut n = n;
630 for _ in 0..len * 2 {
631 n += skip_any(&buf[n..])?.1;
633 }
634 n
635 }
636 Marker::FixExt1 => 3,
637 Marker::FixExt2 => 4,
638 Marker::FixExt4 => 6,
639 Marker::FixExt8 => 10,
640 Marker::FixExt16 => 18,
641 Marker::Ext8 => {
642 if buf.len() < 2 {
643 return Err(Error::EndOfBuffer(Marker::Ext8));
644 }
645 3 + buf[1] as usize
646 }
647 Marker::Ext16 => {
648 if buf.len() < 3 {
649 return Err(Error::EndOfBuffer(Marker::Ext16));
650 }
651 4 + BigEndian::read_u16(&buf[1..3]) as usize
652 }
653 Marker::Ext32 => {
654 if buf.len() < 5 {
655 return Err(Error::EndOfBuffer(Marker::Ext32));
656 }
657 6 + BigEndian::read_u32(&buf[1..5]) as usize
658 }
659 };
660 if buf.len() < n {
661 return Err(Error::EndOfBuffer(Marker::Ext32));
662 }
663 Ok(((), n))
664}