cardano_serialization_lib/chain_core/
packer.rs

1//! Tooling for packing and unpacking from streams
2//!
3//! This will allow us to expose some standard way of serializing
4//! data.
5
6const INITIAL_BUFFERED_CAPACITY: usize = 2048;
7
8pub struct Codec<I>(I);
9impl<I> Codec<I> {
10    pub fn new(inner: I) -> Self {
11        Codec(inner)
12    }
13
14    pub fn into_inner(self) -> I {
15        self.0
16    }
17}
18
19pub struct Buffered<I: std::io::Write>(I, Codec<Vec<u8>>);
20
21pub struct Hole<T> {
22    _marker: std::marker::PhantomData<T>,
23    start: usize,
24    end: usize,
25}
26
27impl<R: std::io::BufRead> Codec<R> {
28    #[inline]
29    pub fn get_u8(&mut self) -> std::io::Result<u8> {
30        let mut buf = [0u8; 1];
31        self.0.read_exact(&mut buf)?;
32        Ok(buf[0])
33    }
34    #[inline]
35    pub fn get_u16(&mut self) -> std::io::Result<u16> {
36        let mut buf = [0u8; 2];
37        self.0.read_exact(&mut buf)?;
38        Ok(u16::from_be_bytes(buf))
39    }
40    #[inline]
41    pub fn get_u32(&mut self) -> std::io::Result<u32> {
42        let mut buf = [0u8; 4];
43        self.0.read_exact(&mut buf)?;
44        Ok(u32::from_be_bytes(buf))
45    }
46    #[inline]
47    pub fn get_u64(&mut self) -> std::io::Result<u64> {
48        let mut buf = [0u8; 8];
49        self.0.read_exact(&mut buf)?;
50        Ok(u64::from_be_bytes(buf))
51    }
52    #[inline]
53    pub fn get_u128(&mut self) -> std::io::Result<u128> {
54        let mut buf = [0u8; 16];
55        self.0.read_exact(&mut buf)?;
56        Ok(u128::from_be_bytes(buf))
57    }
58    #[inline]
59    pub fn get_bytes(&mut self, n: usize) -> std::io::Result<Vec<u8>> {
60        let mut buf = vec![0u8; n];
61        self.0.read_exact(&mut buf)?;
62        Ok(buf)
63    }
64}
65impl<W: std::io::Write> Codec<W> {
66    #[inline]
67    pub fn buffered(self) -> Buffered<W> {
68        Buffered(self.0, Codec(Vec::with_capacity(INITIAL_BUFFERED_CAPACITY)))
69    }
70
71    #[inline]
72    pub fn put_u8(&mut self, v: u8) -> std::io::Result<()> {
73        self.0.write_all(&[v])
74    }
75    #[inline]
76    pub fn put_u16(&mut self, v: u16) -> std::io::Result<()> {
77        self.0.write_all(&v.to_be_bytes())
78    }
79    #[inline]
80    pub fn put_u32(&mut self, v: u32) -> std::io::Result<()> {
81        self.0.write_all(&v.to_be_bytes())
82    }
83    #[inline]
84    pub fn put_u64(&mut self, v: u64) -> std::io::Result<()> {
85        self.0.write_all(&v.to_be_bytes())
86    }
87    #[inline]
88    pub fn put_u128(&mut self, v: u128) -> std::io::Result<()> {
89        self.0.write_all(&v.to_be_bytes())
90    }
91}
92impl<W: std::io::Write> Buffered<W> {
93    #[inline]
94    pub fn hole<T>(&mut self, len: usize) -> std::io::Result<Hole<T>> {
95        use std::io::Write;
96        let start = (self.1).0.len();
97        let end = start + len;
98        let buf = vec![0; len];
99        self.write_all(&buf)?;
100        Ok(Hole {
101            _marker: std::marker::PhantomData,
102            start: start,
103            end: end,
104        })
105    }
106
107    #[inline]
108    pub fn into_inner(self) -> std::io::Result<Codec<W>> {
109        let mut codec = Codec(self.0);
110        let buffer = (self.1).0;
111        codec.0.write_all(&buffer)?;
112        Ok(codec)
113    }
114
115    #[inline]
116    pub fn fill_hole_u8(&mut self, hole: Hole<u8>, value: u8) {
117        (self.1).0[hole.start..hole.end].copy_from_slice(&[value])
118    }
119    #[inline]
120    pub fn fill_hole_u16(&mut self, hole: Hole<u16>, value: u16) {
121        (self.1).0[hole.start..hole.end].copy_from_slice(&value.to_be_bytes())
122    }
123    #[inline]
124    pub fn fill_hole_u32(&mut self, hole: Hole<u32>, value: u32) {
125        (self.1).0[hole.start..hole.end].copy_from_slice(&value.to_be_bytes())
126    }
127    #[inline]
128    pub fn fill_hole_u64(&mut self, hole: Hole<u64>, value: u64) {
129        (self.1).0[hole.start..hole.end].copy_from_slice(&value.to_be_bytes())
130    }
131    #[inline]
132    pub fn fill_hole_u128(&mut self, hole: Hole<u128>, value: u128) {
133        (self.1).0[hole.start..hole.end].copy_from_slice(&value.to_be_bytes())
134    }
135
136    #[inline]
137    pub fn buffered_len(&self) -> usize {
138        (self.1).0.len()
139    }
140}
141
142impl<R: std::io::Read> std::io::Read for Codec<R> {
143    #[inline]
144    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
145        self.0.read(buf)
146    }
147}
148impl<BR: std::io::BufRead> std::io::BufRead for Codec<BR> {
149    #[inline]
150    fn fill_buf(&mut self) -> std::io::Result<&[u8]> {
151        self.0.fill_buf()
152    }
153    #[inline]
154    fn consume(&mut self, amt: usize) {
155        self.0.consume(amt)
156    }
157}
158impl<W: std::io::Write> std::io::Write for Codec<W> {
159    #[inline]
160    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
161        self.0.write(buf)
162    }
163    #[inline]
164    fn flush(&mut self) -> std::io::Result<()> {
165        self.0.flush()
166    }
167}
168impl<W: std::io::Write> std::io::Write for Buffered<W> {
169    #[inline]
170    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
171        self.1.write(buf)
172    }
173    #[inline]
174    fn flush(&mut self) -> std::io::Result<()> {
175        self.1.flush()
176    }
177}
178impl<I: std::io::Write> std::ops::Deref for Buffered<I> {
179    type Target = Codec<Vec<u8>>;
180    #[inline]
181    fn deref(&self) -> &Self::Target {
182        &self.1
183    }
184}
185impl<I: std::io::Write> std::ops::DerefMut for Buffered<I> {
186    #[inline]
187    fn deref_mut(&mut self) -> &mut Self::Target {
188        &mut self.1
189    }
190}