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
//! the CBOR util and compatible with the haskell usage...

pub mod util {
    //! CBor util and other stuff

    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)
            }
        }
    }
}