substrate_stellar_xdr/
streams.rs1use core::convert::{AsRef, TryInto};
4use core::iter;
5
6use sp_std::vec::Vec;
7
8fn extend_to_multiple_of_4(value: usize) -> usize {
9 (value + 3) & !3
10}
11
12#[derive(Debug)]
14pub enum DecodeError {
15 SuddenEnd {
21 actual_length: usize,
22 expected_length: usize,
23 },
24
25 TypeEndsTooEarly { remaining_no_of_bytes: isize },
30
31 InvalidBoolean {
35 found_integer: i32,
36 at_position: usize,
37 },
38
39 VarOpaqueExceedsMaxLength {
41 at_position: usize,
42 max_length: i32,
43 actual_length: i32,
44 },
45
46 StringExceedsMaxLength {
48 at_position: usize,
49 max_length: i32,
50 actual_length: i32,
51 },
52
53 VarArrayExceedsMaxLength {
55 at_position: usize,
56 max_length: i32,
57 actual_length: i32,
58 },
59
60 InvalidOptional { at_position: usize, has_code: u32 },
64
65 InvalidEnumDiscriminator { at_position: usize },
69
70 InvalidBase64,
72}
73
74pub struct ReadStream<T: AsRef<[u8]>> {
76 read_index: usize,
77 source: T,
78}
79
80impl<T: AsRef<[u8]>> ReadStream<T> {
81 pub fn new(source: T) -> ReadStream<T> {
83 ReadStream {
84 read_index: 0,
85 source,
86 }
87 }
88
89 fn ensure_size(&self, no_of_bytes_to_read: usize) -> Result<(), DecodeError> {
90 if no_of_bytes_to_read + self.read_index > self.source.as_ref().len() {
91 return Err(self.generate_sudden_end_error(no_of_bytes_to_read));
92 }
93 Ok(())
94 }
95
96 fn generate_sudden_end_error(&self, no_of_bytes_to_read: usize) -> DecodeError {
97 DecodeError::SuddenEnd {
98 actual_length: self.source.as_ref().len(),
99 expected_length: no_of_bytes_to_read + self.read_index,
100 }
101 }
102
103 fn read_next_byte_array<const N: usize>(&mut self) -> Result<&[u8; N], DecodeError> {
104 let array: Result<&[u8; N], _> =
105 (self.source.as_ref()[self.read_index..self.read_index + N]).try_into();
106
107 match array {
108 Ok(array) => {
109 self.read_index += N;
110 Ok(array)
111 }
112 Err(_) => Err(self.generate_sudden_end_error(N)),
113 }
114 }
115
116 pub fn read_next_u32(&mut self) -> Result<u32, DecodeError> {
118 let array: &[u8; 4] = self.read_next_byte_array()?;
119 Ok(u32::from_be_bytes(*array))
120 }
121
122 pub fn read_next_i32(&mut self) -> Result<i32, DecodeError> {
124 let array: &[u8; 4] = self.read_next_byte_array()?;
125 Ok(i32::from_be_bytes(*array))
126 }
127
128 pub fn read_next_u64(&mut self) -> Result<u64, DecodeError> {
130 let array: &[u8; 8] = self.read_next_byte_array()?;
131 Ok(u64::from_be_bytes(*array))
132 }
133
134 pub fn read_next_i64(&mut self) -> Result<i64, DecodeError> {
136 let array: &[u8; 8] = self.read_next_byte_array()?;
137 Ok(i64::from_be_bytes(*array))
138 }
139
140 pub fn read_next_binary_data(&mut self, no_of_bytes: usize) -> Result<Vec<u8>, DecodeError> {
145 self.ensure_size(extend_to_multiple_of_4(no_of_bytes))?;
146 let result = self.source.as_ref()[self.read_index..self.read_index + no_of_bytes].to_vec();
147 self.read_index += extend_to_multiple_of_4(no_of_bytes);
148 Ok(result)
149 }
150
151 pub fn no_of_bytes_left_to_read(&self) -> isize {
153 self.source.as_ref().len() as isize - self.read_index as isize
154 }
155
156 pub fn get_position(&self) -> usize {
158 self.read_index
159 }
160}
161
162pub struct WriteStream {
164 result: Vec<u8>,
165}
166
167impl WriteStream {
168 pub fn new() -> WriteStream {
170 WriteStream {
171 result: Vec::with_capacity(128),
172 }
173 }
174
175 pub fn write_next_u32(&mut self, value: u32) {
177 self.result.extend(value.to_be_bytes().iter());
178 }
179
180 pub fn write_next_i32(&mut self, value: i32) {
182 self.result.extend(value.to_be_bytes().iter());
183 }
184
185 pub fn write_next_u64(&mut self, value: u64) {
187 self.result.extend(value.to_be_bytes().iter());
188 }
189
190 pub fn write_next_i64(&mut self, value: i64) {
192 self.result.extend(value.to_be_bytes().iter());
193 }
194
195 pub fn write_next_binary_data(&mut self, value: &[u8]) {
197 self.result.extend_from_slice(value);
198 let length = value.len();
199 let no_of_padding_bytes = extend_to_multiple_of_4(length) - length;
200 self.result
201 .extend(iter::repeat(0).take(no_of_padding_bytes));
202 }
203
204 pub fn get_result(self) -> Vec<u8> {
206 self.result
207 }
208}