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
use lib::*;
use super::AbiType;
pub struct Sink {
capacity: usize,
preamble: Vec<u8>,
heap: Vec<u8>,
}
impl Sink {
pub fn new(capacity: usize) -> Self {
Sink {
capacity: 32 * capacity,
preamble: Vec::with_capacity(32 * capacity),
heap: Vec::new(),
}
}
fn top_ptr(&self) -> usize {
self.preamble.capacity() + self.heap.len()
}
pub fn push<T: AbiType>(&mut self, val: T) {
if T::IS_FIXED {
val.encode(self)
} else {
let mut nested_sink = Sink::new(1);
val.encode(&mut nested_sink);
let top_ptr = self.top_ptr() as u32;
nested_sink.drain_to(&mut self.heap);
self.push(top_ptr);
}
}
pub fn drain_to(self, target: &mut Vec<u8>) {
let preamble = self.preamble;
let heap = self.heap;
target.reserve(preamble.len() + heap.len());
target.extend_from_slice(&preamble);
target.extend_from_slice(&heap);
}
pub fn finalize_panicking(self) -> Vec<u8> {
if self.preamble.len() != self.capacity { panic!("Underflow of pushed parameters {}/{}!", self.preamble.len(), self.capacity); }
let mut result = self.preamble;
let heap = self.heap;
result.extend_from_slice(&heap);
result
}
pub fn preamble_mut(&mut self) -> &mut Vec<u8> {
&mut self.preamble
}
pub fn heap_mut(&mut self) -> &mut Vec<u8> {
&mut self.heap
}
}