multiversx_sc/hex_call_data/
cd_de.rs1use super::SEPARATOR;
2use crate::{
3 codec::{DecodeError, DecodeErrorHandler, TopDecodeMultiInput},
4 err_msg,
5 formatter::hex_util::hex_digits_to_byte,
6};
7use alloc::{boxed::Box, vec::Vec};
8
9pub struct HexCallDataDeserializer<'a> {
23 source: &'a [u8],
24 index: usize,
25 func_name_output: &'a [u8],
26}
27
28impl<'a> HexCallDataDeserializer<'a> {
29 pub fn new(source: &'a [u8]) -> Self {
30 let mut de = HexCallDataDeserializer {
31 source,
32 index: 0,
33 func_name_output: &[],
34 };
35
36 if let Some(func_name) = de.next_argument_hex() {
38 de.func_name_output = func_name
39 }
40
41 de
42 }
43
44 #[inline]
47 pub fn get_func_name(&self) -> &'a [u8] {
48 self.func_name_output
49 }
50
51 fn next_argument_hex(&mut self) -> Option<&'a [u8]> {
52 let initial_index = self.index;
53 loop {
54 if !self.has_next() {
55 return None;
56 }
57
58 if self.index == self.source.len() {
59 let slice = &self.source[initial_index..self.index];
60 self.index += 1; return Some(slice);
62 }
63
64 let c = self.source[self.index];
65 if c == SEPARATOR {
66 let slice = &self.source[initial_index..self.index];
67 self.index += 1;
68 return Some(slice);
69 }
70
71 self.index += 1;
72 }
73 }
74
75 #[inline]
76 pub fn has_next(&self) -> bool {
77 self.index <= self.source.len()
78 }
79
80 pub fn next_argument(&mut self) -> Result<Option<Vec<u8>>, &'static str> {
82 match self.next_argument_hex() {
83 None => Ok(None),
84 Some(arg_hex) => {
85 if arg_hex.len() % 2 != 0 {
86 return Err(err_msg::DESERIALIZATION_ODD_DIGITS);
87 }
88 let res_len = arg_hex.len() / 2;
89 let mut res_vec = Vec::with_capacity(res_len);
90 for i in 0..res_len {
91 match hex_digits_to_byte(arg_hex[2 * i], arg_hex[2 * i + 1]) {
92 None => {
93 return Err(err_msg::DESERIALIZATION_INVALID_BYTE);
94 }
95 Some(byte) => {
96 res_vec.push(byte);
97 }
98 }
99 }
100 Ok(Some(res_vec))
101 }
102 }
103 }
104}
105
106impl TopDecodeMultiInput for HexCallDataDeserializer<'_> {
107 type ValueInput = Box<[u8]>;
108
109 fn has_next(&self) -> bool {
110 self.has_next()
111 }
112
113 fn next_value_input<H>(&mut self, h: H) -> Result<Self::ValueInput, H::HandledErr>
114 where
115 H: DecodeErrorHandler,
116 {
117 match self.next_argument() {
118 Ok(Some(arg_bytes)) => Ok(arg_bytes.into_boxed_slice()),
119 Ok(None) => Err(h.handle_error(DecodeError::MULTI_TOO_FEW_ARGS)),
120 Err(sc_err) => Err(h.handle_error(DecodeError::from(sc_err))),
121 }
122 }
123}
124
125#[cfg(test)]
126mod tests {
127 use super::*;
128
129 #[test]
130 fn test_next_raw_bytes_1() {
131 let input: &[u8] = b"func@1111@2222";
132 let mut de = HexCallDataDeserializer::new(input);
133 assert_eq!(de.get_func_name(), &b"func"[..]);
134 assert_eq!(de.next_argument_hex(), Some(&b"1111"[..]));
135 assert_eq!(de.next_argument(), Ok(Some([0x22, 0x22].to_vec())));
136 assert_eq!(de.next_argument(), Ok(None));
137 assert_eq!(de.next_argument(), Ok(None));
138 }
139
140 #[test]
141 fn test_next_raw_bytes_empty() {
142 let mut de = HexCallDataDeserializer::new(&[]);
143 assert_eq!(de.get_func_name(), &[][..]);
144 assert_eq!(de.next_argument(), Ok(None));
145 }
146
147 #[test]
148 fn test_next_raw_bytes_only_func() {
149 let input: &[u8] = b"func";
150 let mut de = HexCallDataDeserializer::new(input);
151
152 assert_eq!(de.get_func_name(), &b"func"[..]);
153 assert_eq!(de.next_argument(), Ok(None));
154 assert_eq!(de.next_argument(), Ok(None));
155 }
156
157 #[test]
158 fn test_next_raw_bytes_some_empty() {
159 let input: &[u8] = b"func@@2222";
160 let mut de = HexCallDataDeserializer::new(input);
161 assert_eq!(de.next_argument(), Ok(Some(Vec::new())));
162 assert_eq!(de.next_argument(), Ok(Some([0x22, 0x22].to_vec())));
163 assert_eq!(de.next_argument(), Ok(None));
164 assert_eq!(de.next_argument(), Ok(None));
165
166 assert_eq!(de.get_func_name(), &b"func"[..]);
167 }
168
169 #[test]
170 fn test_next_raw_bytes_ends_empty() {
171 let input: &[u8] = b"func@";
172 let mut de = HexCallDataDeserializer::new(input);
173 assert_eq!(de.get_func_name(), &b"func"[..]);
174 assert_eq!(de.next_argument(), Ok(Some(Vec::new())));
175 assert_eq!(de.next_argument(), Ok(None));
176 assert_eq!(de.next_argument(), Ok(None));
177 }
178
179 #[test]
180 fn test_next_raw_bytes_many_empty() {
181 let input: &[u8] = b"func@@2222@@";
182 let mut de = HexCallDataDeserializer::new(input);
183 assert_eq!(de.get_func_name(), &b"func"[..]);
184 assert_eq!(de.next_argument(), Ok(Some(Vec::new())));
185 assert_eq!(de.next_argument(), Ok(Some([0x22, 0x22].to_vec())));
186 assert_eq!(de.next_argument(), Ok(Some(Vec::new())));
187 assert_eq!(de.next_argument(), Ok(Some(Vec::new())));
188 assert_eq!(de.next_argument(), Ok(None));
189 assert_eq!(de.next_argument(), Ok(None));
190 }
191
192 #[test]
193 fn test_next_raw_bytes_all_empty() {
194 let input: &[u8] = b"@@@";
195 let mut de = HexCallDataDeserializer::new(input);
196 assert_eq!(de.get_func_name(), &[][..]);
197 assert_eq!(de.next_argument(), Ok(Some(Vec::new())));
198 assert_eq!(de.next_argument(), Ok(Some(Vec::new())));
199 assert_eq!(de.next_argument(), Ok(Some(Vec::new())));
200 assert_eq!(de.next_argument(), Ok(None));
201 assert_eq!(de.next_argument(), Ok(None));
202 }
203
204 #[test]
205 fn test_next_raw_bytes_all_empty_but_last() {
206 let input: &[u8] = b"@@@1234";
207 let mut de = HexCallDataDeserializer::new(input);
208 assert_eq!(de.get_func_name(), &[][..]);
209 assert_eq!(de.next_argument(), Ok(Some(Vec::new())));
210 assert_eq!(de.next_argument(), Ok(Some(Vec::new())));
211 assert_eq!(de.next_argument(), Ok(Some([0x12, 0x34].to_vec())));
212 assert_eq!(de.next_argument(), Ok(None));
213 assert_eq!(de.next_argument(), Ok(None));
214 }
215
216 #[test]
217 fn test_next_argument_large() {
218 let input: &[u8] = b"func@0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
219 let mut de = HexCallDataDeserializer::new(input);
220 let expected: [u8; 32] = [
221 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab,
222 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67,
223 0x89, 0xab, 0xcd, 0xef,
224 ];
225 assert_eq!(de.get_func_name(), &b"func"[..]);
226 assert!(de.next_argument() == Ok(Some(expected.to_vec())));
227 assert_eq!(de.next_argument(), Ok(None));
228 assert_eq!(de.next_argument(), Ok(None));
229 }
230
231 #[test]
232 fn test_next_vec_odd() {
233 let input: &[u8] = b"func@123";
234 let mut de = HexCallDataDeserializer::new(input);
235 assert_eq!(de.get_func_name(), &b"func"[..]);
236 assert_eq!(de.next_argument(), Err(err_msg::DESERIALIZATION_ODD_DIGITS));
237 assert_eq!(de.next_argument(), Ok(None));
238 assert_eq!(de.next_argument(), Ok(None));
239 }
240}