substrate_stellar_sdk/xdr/
streams.rs1use core::{
4 convert::{AsRef, TryInto},
5 iter,
6};
7
8use sp_std::vec::Vec;
9
10fn extend_to_multiple_of_4(value: usize) -> usize {
11 (value + 3) & !3
12}
13
14#[derive(Debug)]
16pub enum DecodeError {
17 SuddenEnd {
23 actual_length: usize,
24 expected_length: usize,
25 },
26
27 TypeEndsTooEarly {
32 remaining_no_of_bytes: isize,
33 },
34
35 InvalidBoolean {
39 found_integer: i32,
40 at_position: usize,
41 },
42
43 VarOpaqueExceedsMaxLength {
45 at_position: usize,
46 max_length: i32,
47 actual_length: i32,
48 },
49
50 StringExceedsMaxLength {
52 at_position: usize,
53 max_length: i32,
54 actual_length: i32,
55 },
56
57 VarArrayExceedsMaxLength {
59 at_position: usize,
60 max_length: i32,
61 actual_length: i32,
62 },
63
64 InvalidOptional {
68 at_position: usize,
69 has_code: u32,
70 },
71
72 InvalidEnumDiscriminator {
76 at_position: usize,
77 },
78
79 InvalidBase64,
81
82 InvalidXdrArchiveLength {
84 at_position: usize,
85 },
86}
87
88pub struct ReadStream<T: AsRef<[u8]>> {
90 read_index: usize,
91 source: T,
92}
93
94impl<T: AsRef<[u8]>> ReadStream<T> {
95 pub fn new(source: T) -> ReadStream<T> {
97 ReadStream { read_index: 0, source }
98 }
99
100 fn ensure_size(&self, no_of_bytes_to_read: usize) -> Result<(), DecodeError> {
101 if no_of_bytes_to_read + self.read_index > self.source.as_ref().len() {
102 return Err(self.generate_sudden_end_error(no_of_bytes_to_read))
103 }
104 Ok(())
105 }
106
107 fn generate_sudden_end_error(&self, no_of_bytes_to_read: usize) -> DecodeError {
108 DecodeError::SuddenEnd {
109 actual_length: self.source.as_ref().len(),
110 expected_length: no_of_bytes_to_read + self.read_index,
111 }
112 }
113
114 fn read_next_byte_array<const N: usize>(&mut self) -> Result<&[u8; N], DecodeError> {
115 let array: Result<&[u8; N], _> = (self.source.as_ref()[self.read_index..self.read_index + N]).try_into();
116
117 match array {
118 Ok(array) => {
119 self.read_index += N;
120 Ok(array)
121 },
122 Err(_) => Err(self.generate_sudden_end_error(N)),
123 }
124 }
125
126 pub fn read_next_u32(&mut self) -> Result<u32, DecodeError> {
128 let array: &[u8; 4] = self.read_next_byte_array()?;
129 Ok(u32::from_be_bytes(*array))
130 }
131
132 pub fn read_next_i32(&mut self) -> Result<i32, DecodeError> {
134 let array: &[u8; 4] = self.read_next_byte_array()?;
135 Ok(i32::from_be_bytes(*array))
136 }
137
138 pub fn read_next_u64(&mut self) -> Result<u64, DecodeError> {
140 let array: &[u8; 8] = self.read_next_byte_array()?;
141 Ok(u64::from_be_bytes(*array))
142 }
143
144 pub fn read_next_i64(&mut self) -> Result<i64, DecodeError> {
146 let array: &[u8; 8] = self.read_next_byte_array()?;
147 Ok(i64::from_be_bytes(*array))
148 }
149
150 pub fn read_next_binary_data(&mut self, no_of_bytes: usize) -> Result<Vec<u8>, DecodeError> {
155 self.ensure_size(extend_to_multiple_of_4(no_of_bytes))?;
156 let result = self.source.as_ref()[self.read_index..self.read_index + no_of_bytes].to_vec();
157 self.read_index += extend_to_multiple_of_4(no_of_bytes);
158 Ok(result)
159 }
160
161 pub fn no_of_bytes_left_to_read(&self) -> isize {
163 self.source.as_ref().len() as isize - self.read_index as isize
164 }
165
166 pub fn get_position(&self) -> usize {
168 self.read_index
169 }
170}
171
172pub struct WriteStream {
174 result: Vec<u8>,
175}
176
177impl WriteStream {
178 pub fn new() -> WriteStream {
180 WriteStream { result: Vec::with_capacity(128) }
181 }
182
183 pub fn write_next_u32(&mut self, value: u32) {
185 self.result.extend(value.to_be_bytes().iter());
186 }
187
188 pub fn write_next_i32(&mut self, value: i32) {
190 self.result.extend(value.to_be_bytes().iter());
191 }
192
193 pub fn write_next_u64(&mut self, value: u64) {
195 self.result.extend(value.to_be_bytes().iter());
196 }
197
198 pub fn write_next_i64(&mut self, value: i64) {
200 self.result.extend(value.to_be_bytes().iter());
201 }
202
203 pub fn write_next_binary_data(&mut self, value: &[u8]) {
205 self.result.extend_from_slice(value);
206 let length = value.len();
207 let no_of_padding_bytes = extend_to_multiple_of_4(length) - length;
208 self.result.extend(iter::repeat(0).take(no_of_padding_bytes));
209 }
210
211 pub fn get_result(self) -> Vec<u8> {
213 self.result
214 }
215}