1#[cfg(not(feature = "std"))]
10use alloc::vec::Vec;
11use bytes::{BufMut, BytesMut};
12use core::borrow::Borrow;
13
14use crate::traits::Encodable;
15
16#[derive(Debug, Copy, Clone)]
17struct ListInfo {
18 position: usize,
19 current: usize,
20 max: Option<usize>,
21}
22
23impl ListInfo {
24 fn new(position: usize, max: Option<usize>) -> ListInfo {
25 ListInfo { position, current: 0, max }
26 }
27}
28
29pub struct RlpStream {
31 unfinished_lists: Vec<ListInfo>,
32 start_pos: usize,
33 buffer: BytesMut,
34 finished_list: bool,
35}
36
37impl Default for RlpStream {
38 fn default() -> Self {
39 RlpStream::new()
40 }
41}
42
43impl RlpStream {
44 pub fn new() -> Self {
46 Self::new_with_buffer(BytesMut::with_capacity(1024))
47 }
48
49 pub fn new_list(len: usize) -> Self {
51 Self::new_list_with_buffer(BytesMut::with_capacity(1024), len)
52 }
53
54 pub fn new_with_buffer(buffer: BytesMut) -> Self {
56 RlpStream { unfinished_lists: Vec::with_capacity(16), start_pos: buffer.len(), buffer, finished_list: false }
57 }
58
59 pub fn new_list_with_buffer(buffer: BytesMut, len: usize) -> Self {
61 let mut stream = RlpStream::new_with_buffer(buffer);
62 stream.begin_list(len);
63 stream
64 }
65
66 fn total_written(&self) -> usize {
67 self.buffer.len() - self.start_pos
68 }
69
70 pub fn append_empty_data(&mut self) -> &mut Self {
80 self.buffer.put_u8(0x80);
82
83 self.note_appended(1);
85
86 self
88 }
89
90 pub fn append_raw(&mut self, bytes: &[u8], item_count: usize) -> &mut Self {
92 self.buffer.extend_from_slice(bytes);
94
95 self.note_appended(item_count);
97
98 self
100 }
101
102 pub fn append<E>(&mut self, value: &E) -> &mut Self
112 where
113 E: Encodable,
114 {
115 self.finished_list = false;
116 value.rlp_append(self);
117 if !self.finished_list {
118 self.note_appended(1);
119 }
120 self
121 }
122
123 pub fn append_iter<I>(&mut self, value: I) -> &mut Self
133 where
134 I: IntoIterator<Item = u8>,
135 {
136 self.finished_list = false;
137 self.encoder().encode_iter(value);
138 if !self.finished_list {
139 self.note_appended(1);
140 }
141 self
142 }
143
144 pub fn append_list<E, K>(&mut self, values: &[K]) -> &mut Self
146 where
147 E: Encodable,
148 K: Borrow<E>,
149 {
150 self.begin_list(values.len());
151 for value in values {
152 self.append(value.borrow());
153 }
154 self
155 }
156
157 pub fn append_internal<E>(&mut self, value: &E) -> &mut Self
160 where
161 E: Encodable,
162 {
163 value.rlp_append(self);
164 self
165 }
166
167 pub fn begin_list(&mut self, len: usize) -> &mut RlpStream {
178 self.finished_list = false;
179 match len {
180 0 => {
181 self.buffer.put_u8(0xc0u8);
183 self.note_appended(1);
184 self.finished_list = true;
185 },
186 _ => {
187 self.buffer.put_u8(0);
193
194 let position = self.total_written();
195 self.unfinished_lists.push(ListInfo::new(position, Some(len)));
196 },
197 }
198
199 self
201 }
202
203 pub fn begin_unbounded_list(&mut self) -> &mut RlpStream {
205 self.finished_list = false;
206 self.buffer.put_u8(0);
209 let position = self.total_written();
210 self.unfinished_lists.push(ListInfo::new(position, None));
211 self
213 }
214
215 pub fn append_raw_checked(&mut self, bytes: &[u8], item_count: usize, max_size: usize) -> bool {
217 if self.estimate_size(bytes.len()) > max_size {
218 return false
219 }
220 self.append_raw(bytes, item_count);
221 true
222 }
223
224 pub fn estimate_size(&self, add: usize) -> usize {
226 let total_size = self.total_written() + add;
227 let mut base_size = total_size;
228 for list in &self.unfinished_lists[..] {
229 let len = total_size - list.position;
230 if len > 55 {
231 let leading_empty_bytes = (len as u64).leading_zeros() as usize / 8;
232 let size_bytes = 8 - leading_empty_bytes;
233 base_size += size_bytes;
234 }
235 }
236 base_size
237 }
238
239 pub fn len(&self) -> usize {
241 self.estimate_size(0)
242 }
243
244 pub fn is_empty(&self) -> bool {
245 self.len() == 0
246 }
247
248 pub fn clear(&mut self) {
260 self.buffer.truncate(self.start_pos);
262
263 self.unfinished_lists.clear();
265 }
266
267 pub fn is_finished(&self) -> bool {
280 self.unfinished_lists.is_empty()
281 }
282
283 pub fn as_raw(&self) -> &[u8] {
285 &self.buffer
287 }
288
289 pub fn out(self) -> BytesMut {
293 if self.is_finished() {
294 self.buffer
295 } else {
296 panic!()
297 }
298 }
299
300 fn note_appended(&mut self, inserted_items: usize) {
302 if self.unfinished_lists.is_empty() {
303 return
304 }
305
306 let back = self.unfinished_lists.len() - 1;
307 let should_finish = match self.unfinished_lists.get_mut(back) {
308 None => false,
309 Some(ref mut x) => {
310 x.current += inserted_items;
311 match x.max {
312 Some(ref max) if x.current > *max => panic!("You cannot append more items than you expect!"),
313 Some(ref max) => x.current == *max,
314 _ => false,
315 }
316 },
317 };
318 if should_finish {
319 let x = self.unfinished_lists.pop().unwrap();
320 let len = self.total_written() - x.position;
321 self.encoder().insert_list_payload(len, x.position);
322 self.note_appended(1);
323 }
324 self.finished_list = should_finish;
325 }
326
327 pub fn encoder(&mut self) -> BasicEncoder {
328 BasicEncoder::new(self, self.start_pos)
329 }
330
331 pub fn finalize_unbounded_list(&mut self) {
333 let list = self.unfinished_lists.pop().expect("No open list.");
334 if list.max.is_some() {
335 panic!("List type mismatch.");
336 }
337 let len = self.total_written() - list.position;
338 self.encoder().insert_list_payload(len, list.position);
339 self.note_appended(1);
340 self.finished_list = true;
341 }
342}
343
344pub struct BasicEncoder<'a> {
345 buffer: &'a mut BytesMut,
346 start_pos: usize,
347}
348
349impl<'a> BasicEncoder<'a> {
350 fn new(stream: &'a mut RlpStream, start_pos: usize) -> Self {
351 BasicEncoder { buffer: &mut stream.buffer, start_pos }
352 }
353
354 fn total_written(&self) -> usize {
355 self.buffer.len() - self.start_pos
356 }
357
358 fn insert_size(&mut self, size: usize, position: usize) -> u8 {
359 let size = size as u32;
360 let leading_empty_bytes = size.leading_zeros() as usize / 8;
361 let size_bytes = 4 - leading_empty_bytes as u8;
362 let buffer: [u8; 4] = size.to_be_bytes();
363 assert!(position <= self.total_written());
364
365 self.buffer.extend_from_slice(&buffer[leading_empty_bytes..]);
366 self.buffer[self.start_pos + position..].rotate_right(size_bytes as usize);
367 size_bytes as u8
368 }
369
370 fn insert_list_payload(&mut self, len: usize, pos: usize) {
372 match len {
374 0..=55 => {
375 self.buffer[self.start_pos + pos - 1] = 0xc0u8 + len as u8;
376 },
377 _ => {
378 let inserted_bytes = self.insert_size(len, pos);
379 self.buffer[self.start_pos + pos - 1] = 0xf7u8 + inserted_bytes;
380 },
381 };
382 }
383
384 pub fn encode_value(&mut self, value: &[u8]) {
385 self.encode_iter(value.iter().cloned());
386 }
387
388 pub fn encode_iter<I>(&mut self, value: I)
390 where
391 I: IntoIterator<Item = u8>,
392 {
393 let mut value = value.into_iter();
394 let len = match value.size_hint() {
395 (lower, Some(upper)) if lower == upper => lower,
396 _ => {
397 let value = value.collect::<Vec<_>>();
398 return self.encode_iter(value)
399 },
400 };
401 match len {
402 0 => self.buffer.put_u8(0x80u8),
404 len @ 1..=55 => {
405 let first = value.next().expect("iterator length is higher than 1");
406 if len == 1 && first < 0x80 {
407 self.buffer.put_u8(first);
409 } else {
410 self.buffer.put_u8(0x80u8 + len as u8);
412 self.buffer.put_u8(first);
413 self.buffer.extend(value);
414 }
415 },
416 len => {
418 self.buffer.put_u8(0);
419 let position = self.total_written();
420 let inserted_bytes = self.insert_size(len, position);
421 self.buffer[self.start_pos + position - 1] = 0xb7 + inserted_bytes;
422 self.buffer.extend(value);
423 },
424 }
425 }
426}