1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
pub mod util {
use crate::legacy_address::crc32::crc32;
use cbor_event::{self, de::Deserializer, se::Serializer, Len, cbor};
pub fn encode_with_crc32_<T, W>(t: &T, s: &mut Serializer<W>) -> cbor_event::Result<()>
where
T: cbor_event::Serialize,
W: ::std::io::Write + Sized,
{
let bytes = cbor!(t)?;
let crc32 = crc32(&bytes);
s.write_array(Len::Len(2))?
.write_tag(24)?
.write_bytes(&bytes)?
.write_unsigned_integer(crc32 as u64)?;
Ok(())
}
pub fn raw_with_crc32<R: std::io::BufRead>(
raw: &mut Deserializer<R>,
) -> cbor_event::Result<Vec<u8>> {
let len = raw.array()?;
assert!(len == Len::Len(2));
let tag = raw.tag()?;
if tag != 24 {
return Err(cbor_event::Error::CustomError(format!(
"Invalid Tag: {} but expected 24",
tag
)));
}
let bytes = raw.bytes()?;
let crc = raw.unsigned_integer()?;
let found_crc = crc32(&bytes);
if crc != found_crc as u64 {
return Err(cbor_event::Error::CustomError(format!(
"Invalid CRC32: 0x{:x} but expected 0x{:x}",
crc, found_crc
)));
}
Ok(bytes)
}
#[cfg(test)]
#[cfg(feature = "with-bench")]
mod bench {
use super::*;
use cbor_event::{
self,
de::RawCbor,
se::{Serialize, Serializer},
};
#[cfg(feature = "with-bench")]
use test;
const CBOR: &'static [u8] = &[
0x82, 0xd8, 0x18, 0x53, 0x52, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x72, 0x61, 0x6e, 0x64,
0x6f, 0x6d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x1a, 0x71, 0xad, 0x58, 0x36,
];
const BYTES: &'static [u8] = b"some bytes";
#[bench]
fn encode_crc32_with_cbor_event(b: &mut test::Bencher) {
b.iter(|| {
let _ = encode_with_crc32_(&Test(BYTES), Serializer::new_vec()).unwrap();
})
}
#[bench]
fn decode_crc32_with_cbor_event(b: &mut test::Bencher) {
b.iter(|| {
let mut raw = RawCbor::from(CBOR);
let bytes = raw_with_crc32(&mut raw).unwrap();
})
}
struct Test(&'static [u8]);
impl Serialize for Test {
fn serialize<'se, W>(
&self,
serializer: &'se mut Serializer<W>,
) -> cbor_event::Result<&'se mut Serializer<W>>
where
W: ::std::io::Write,
{
serializer.write_bytes(self.0)
}
}
}
}