substrate_data/wire/frame/
packer.rs1use super::sizes::{LENGTH_RESERVED, ONE_BYTE_MAX, VARINT_MAX_BYTES};
4use super::{floats, lanes};
5use crate::binary::interner::Interner;
6use crate::binary::writer::START_BYTES;
7use crate::binary::{Writer, varint, zigzag};
8use crate::schema::Schema;
9
10pub fn to_frame<T: Schema>(v: &T) -> Vec<u8> {
12 let mut p = Packer::new();
13 v.pack(&mut p);
14 p.finish()
15}
16
17#[derive(Debug)]
19pub struct Packer {
20 out: Vec<u8>,
21 table: Vec<u8>,
22 strings: Interner,
23}
24
25impl Default for Packer {
26 fn default() -> Self {
27 Self::new()
28 }
29}
30
31impl Packer {
32 #[must_use]
34 pub fn new() -> Self {
35 Packer {
36 out: Vec::with_capacity(START_BYTES),
37 table: Vec::new(),
38 strings: Interner::new(),
39 }
40 }
41
42 pub fn put_u(&mut self, n: u64) {
44 varint(&mut self.out, n);
45 }
46
47 pub fn put_i(&mut self, n: i64) {
49 varint(&mut self.out, zigzag(n));
50 }
51
52 pub fn put_bool(&mut self, b: bool) {
54 self.out.push(u8::from(b));
55 }
56
57 pub fn put_f64(&mut self, f: f64) {
59 self.out.extend_from_slice(&f.to_le_bytes());
60 }
61
62 pub fn put_f32(&mut self, f: f32) {
64 self.out.extend_from_slice(&f.to_le_bytes());
65 }
66
67 pub fn put_f64s(&mut self, items: &[f64]) {
70 self.put_u(items.len() as u64);
71 let narrow = floats::fits_f32(items);
72 self.put_bool(narrow);
73 if narrow {
74 floats::put_narrow(&mut self.out, items);
75 } else {
76 floats::put_wide(&mut self.out, items);
77 }
78 }
79
80 pub fn put_uints(&mut self, len: usize, items: impl Iterator<Item = u64> + Clone) {
83 self.put_u(len as u64);
84 let max = items.clone().fold(0, u64::max);
85 let bits = (u64::BITS - max.leading_zeros()).max(1);
86 self.out.push(u8::try_from(bits).unwrap_or(u8::MAX));
87 lanes::pack(&mut self.out, len, bits, items);
88 }
89
90 pub fn put_f32s(&mut self, items: &[f32]) {
92 self.put_u(items.len() as u64);
93 floats::put_f32s(&mut self.out, items);
94 }
95
96 pub fn put_str(&mut self, s: &str) {
98 let i = if let Some(i) = self.strings.find(&self.table, s) {
99 i
100 } else {
101 varint(&mut self.table, s.len() as u64);
102 let at = self.table.len();
103 self.table.extend_from_slice(s.as_bytes());
104 self.strings.add(&self.table, s, at)
105 };
106 self.put_u(i as u64);
107 }
108
109 pub fn put_bytes(&mut self, b: &[u8]) {
111 self.put_u(b.len() as u64);
112 self.out.extend_from_slice(b);
113 }
114
115 pub fn put_tagged<T: Schema>(&mut self, v: &T) {
118 let mut w = Writer::body();
119 v.encode(&mut w);
120 self.put_bytes(&w.finish());
121 }
122
123 pub fn begin(&mut self) -> usize {
125 let at = self.out.len();
126 self.out.extend_from_slice(&[0; LENGTH_RESERVED]);
127 at
128 }
129
130 pub fn begin_list(&mut self, len: usize) -> usize {
134 self.put_u(len as u64);
135 self.begin()
136 }
137
138 pub fn end(&mut self, at: usize) {
140 let len = self.out.len() - at - LENGTH_RESERVED;
141 if let Ok(byte) = u8::try_from(len)
142 && len <= ONE_BYTE_MAX
143 {
144 self.out[at] = byte;
145 return;
146 }
147 let end = self.out.len();
150 varint(&mut self.out, len as u64);
151 let mut length = [0; VARINT_MAX_BYTES];
152 let used = self.out.len() - end;
153 length[..used].copy_from_slice(&self.out[end..]);
154 self.out.truncate(end);
155 self.out.splice(at..=at, length[..used].iter().copied());
156 }
157
158 #[must_use]
160 pub fn finish(mut self) -> Vec<u8> {
161 self.seal();
162 self.out
163 }
164
165 fn seal(&mut self) {
167 let table_len = self.table.len();
168 self.out.extend_from_slice(&self.table);
169 let at = self.out.len();
171 varint(&mut self.out, table_len as u64);
172 self.out[at..].reverse();
173 }
174
175 pub fn with_frame<T: Schema, R>(&mut self, v: &T, f: impl FnOnce(&[u8]) -> R) -> R {
178 self.clear();
179 v.pack(self);
180 self.seal();
181 let out = f(&self.out);
182 self.clear();
183 out
184 }
185
186 fn clear(&mut self) {
188 self.out.clear();
189 self.table.clear();
190 self.strings.clear();
191 }
192}