nodedb_types/json_msgpack/
reader.rs1pub(crate) struct Cursor<'a> {
9 pub(crate) data: &'a [u8],
10 pub(crate) pos: usize,
11 pub(crate) depth: usize,
12}
13
14impl<'a> Cursor<'a> {
15 pub(crate) fn new(data: &'a [u8]) -> Self {
16 Self {
17 data,
18 pos: 0,
19 depth: 0,
20 }
21 }
22
23 #[inline]
24 pub(crate) fn peek(&self) -> zerompk::Result<u8> {
25 self.data
26 .get(self.pos)
27 .copied()
28 .ok_or(zerompk::Error::BufferTooSmall)
29 }
30
31 #[inline]
32 pub(crate) fn take(&mut self) -> zerompk::Result<u8> {
33 let b = self.peek()?;
34 self.pos += 1;
35 Ok(b)
36 }
37
38 #[inline]
39 pub(crate) fn take_n(&mut self, n: usize) -> zerompk::Result<&'a [u8]> {
40 if self.pos + n > self.data.len() {
41 return Err(zerompk::Error::BufferTooSmall);
42 }
43 let slice = &self.data[self.pos..self.pos + n];
44 self.pos += n;
45 Ok(slice)
46 }
47
48 pub(crate) fn read_u16_be(&mut self) -> zerompk::Result<u16> {
49 let b = self.take_n(2)?;
50 Ok(u16::from_be_bytes([b[0], b[1]]))
51 }
52
53 pub(crate) fn read_u32_be(&mut self) -> zerompk::Result<u32> {
54 let b = self.take_n(4)?;
55 Ok(u32::from_be_bytes([b[0], b[1], b[2], b[3]]))
56 }
57}
58
59pub fn json_from_msgpack(bytes: &[u8]) -> zerompk::Result<serde_json::Value> {
61 let mut cursor = Cursor::new(bytes);
62 read_json_value(&mut cursor)
63}
64
65pub fn value_from_msgpack(bytes: &[u8]) -> zerompk::Result<crate::Value> {
67 let mut cursor = Cursor::new(bytes);
68 read_native_value(&mut cursor)
69}
70
71fn read_json_value(c: &mut Cursor<'_>) -> zerompk::Result<serde_json::Value> {
74 if c.depth > 500 {
75 return Err(zerompk::Error::DepthLimitExceeded { max: 500 });
76 }
77
78 let marker = c.take()?;
79 match marker {
80 0xC0 => Ok(serde_json::Value::Null),
81 0xC2 => Ok(serde_json::Value::Bool(false)),
82 0xC3 => Ok(serde_json::Value::Bool(true)),
83
84 0x00..=0x7F => Ok(serde_json::Value::Number((marker as i64).into())),
85 0xE0..=0xFF => Ok(serde_json::Value::Number((marker as i8 as i64).into())),
86
87 0xCC => Ok(serde_json::Value::Number(c.take()?.into())),
88 0xCD => Ok(serde_json::Value::Number(c.read_u16_be()?.into())),
89 0xCE => Ok(serde_json::Value::Number(c.read_u32_be()?.into())),
90 0xCF => {
91 let b = c.take_n(8)?;
92 let v = u64::from_be_bytes([b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]]);
93 Ok(serde_json::Value::Number(v.into()))
94 }
95
96 0xD0 => Ok(serde_json::Value::Number((c.take()? as i8 as i64).into())),
97 0xD1 => {
98 let b = c.take_n(2)?;
99 Ok(serde_json::Value::Number(
100 (i16::from_be_bytes([b[0], b[1]]) as i64).into(),
101 ))
102 }
103 0xD2 => {
104 let b = c.take_n(4)?;
105 Ok(serde_json::Value::Number(
106 (i32::from_be_bytes([b[0], b[1], b[2], b[3]]) as i64).into(),
107 ))
108 }
109 0xD3 => {
110 let b = c.take_n(8)?;
111 Ok(serde_json::Value::Number(
112 i64::from_be_bytes([b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]]).into(),
113 ))
114 }
115
116 0xCA => {
117 let b = c.take_n(4)?;
118 Ok(serde_json::json!(
119 f32::from_be_bytes([b[0], b[1], b[2], b[3]]) as f64
120 ))
121 }
122 0xCB => {
123 let b = c.take_n(8)?;
124 Ok(serde_json::json!(f64::from_be_bytes([
125 b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]
126 ])))
127 }
128
129 m @ 0xA0..=0xBF => read_json_str(c, (m & 0x1F) as usize),
130 0xD9 => {
131 let l = c.take()? as usize;
132 read_json_str(c, l)
133 }
134 0xDA => {
135 let l = c.read_u16_be()? as usize;
136 read_json_str(c, l)
137 }
138 0xDB => {
139 let l = c.read_u32_be()? as usize;
140 read_json_str(c, l)
141 }
142
143 0xC4 => {
144 let l = c.take()? as usize;
145 Ok(serde_json::Value::String(base64_encode(c.take_n(l)?)))
146 }
147 0xC5 => {
148 let l = c.read_u16_be()? as usize;
149 Ok(serde_json::Value::String(base64_encode(c.take_n(l)?)))
150 }
151 0xC6 => {
152 let l = c.read_u32_be()? as usize;
153 Ok(serde_json::Value::String(base64_encode(c.take_n(l)?)))
154 }
155
156 m @ 0x90..=0x9F => read_json_array(c, (m & 0x0F) as usize),
157 0xDC => {
158 let l = c.read_u16_be()? as usize;
159 read_json_array(c, l)
160 }
161 0xDD => {
162 let l = c.read_u32_be()? as usize;
163 read_json_array(c, l)
164 }
165
166 m @ 0x80..=0x8F => read_json_map(c, (m & 0x0F) as usize),
167 0xDE => {
168 let l = c.read_u16_be()? as usize;
169 read_json_map(c, l)
170 }
171 0xDF => {
172 let l = c.read_u32_be()? as usize;
173 read_json_map(c, l)
174 }
175
176 0xD4 => {
178 c.take_n(2)?;
179 Ok(serde_json::Value::Null)
180 }
181 0xD5 => {
182 c.take_n(3)?;
183 Ok(serde_json::Value::Null)
184 }
185 0xD6 => {
186 c.take_n(5)?;
187 Ok(serde_json::Value::Null)
188 }
189 0xD7 => {
190 c.take_n(9)?;
191 Ok(serde_json::Value::Null)
192 }
193 0xD8 => {
194 c.take_n(17)?;
195 Ok(serde_json::Value::Null)
196 }
197 0xC7 => {
198 let l = c.take()? as usize;
199 c.take_n(1 + l)?;
200 Ok(serde_json::Value::Null)
201 }
202 0xC8 => {
203 let l = c.read_u16_be()? as usize;
204 c.take_n(1 + l)?;
205 Ok(serde_json::Value::Null)
206 }
207 0xC9 => {
208 let l = c.read_u32_be()? as usize;
209 c.take_n(1 + l)?;
210 Ok(serde_json::Value::Null)
211 }
212
213 _ => Err(zerompk::Error::InvalidMarker(marker)),
214 }
215}
216
217fn read_json_str(c: &mut Cursor<'_>, len: usize) -> zerompk::Result<serde_json::Value> {
218 let bytes = c.take_n(len)?;
219 let s = String::from_utf8(bytes.to_vec()).map_err(|_| zerompk::Error::InvalidMarker(0))?;
220 Ok(serde_json::Value::String(s))
221}
222
223fn read_json_array(c: &mut Cursor<'_>, len: usize) -> zerompk::Result<serde_json::Value> {
224 c.depth += 1;
225 let mut arr = Vec::with_capacity(len.min(4096));
226 for _ in 0..len {
227 arr.push(read_json_value(c)?);
228 }
229 c.depth -= 1;
230 Ok(serde_json::Value::Array(arr))
231}
232
233fn read_json_map(c: &mut Cursor<'_>, len: usize) -> zerompk::Result<serde_json::Value> {
234 c.depth += 1;
235 let mut map = serde_json::Map::with_capacity(len.min(4096));
236 for _ in 0..len {
237 let key_marker = c.peek()?;
238 let key = if (0xA0..=0xBF).contains(&key_marker)
239 || key_marker == 0xD9
240 || key_marker == 0xDA
241 || key_marker == 0xDB
242 {
243 match read_json_value(c)? {
244 serde_json::Value::String(s) => s,
245 other => other.to_string(),
246 }
247 } else {
248 read_json_value(c)?.to_string()
249 };
250 let val = read_json_value(c)?;
251 map.insert(key, val);
252 }
253 c.depth -= 1;
254 Ok(serde_json::Value::Object(map))
255}
256
257fn read_native_value(c: &mut Cursor<'_>) -> zerompk::Result<crate::Value> {
260 if c.depth > 500 {
261 return Err(zerompk::Error::DepthLimitExceeded { max: 500 });
262 }
263
264 let marker = c.take()?;
265 match marker {
266 0xC0 => Ok(crate::Value::Null),
267 0xC2 => Ok(crate::Value::Bool(false)),
268 0xC3 => Ok(crate::Value::Bool(true)),
269
270 0x00..=0x7F => Ok(crate::Value::Integer(marker as i64)),
271 0xE0..=0xFF => Ok(crate::Value::Integer(marker as i8 as i64)),
272
273 0xCC => Ok(crate::Value::Integer(c.take()? as i64)),
274 0xCD => Ok(crate::Value::Integer(c.read_u16_be()? as i64)),
275 0xCE => Ok(crate::Value::Integer(c.read_u32_be()? as i64)),
276 0xCF => {
277 let b = c.take_n(8)?;
278 Ok(crate::Value::Integer(u64::from_be_bytes([
279 b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7],
280 ]) as i64))
281 }
282
283 0xD0 => Ok(crate::Value::Integer(c.take()? as i8 as i64)),
284 0xD1 => {
285 let b = c.take_n(2)?;
286 Ok(crate::Value::Integer(
287 i16::from_be_bytes([b[0], b[1]]) as i64
288 ))
289 }
290 0xD2 => {
291 let b = c.take_n(4)?;
292 Ok(crate::Value::Integer(
293 i32::from_be_bytes([b[0], b[1], b[2], b[3]]) as i64,
294 ))
295 }
296 0xD3 => {
297 let b = c.take_n(8)?;
298 Ok(crate::Value::Integer(i64::from_be_bytes([
299 b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7],
300 ])))
301 }
302
303 0xCA => {
304 let b = c.take_n(4)?;
305 Ok(crate::Value::Float(
306 f32::from_be_bytes([b[0], b[1], b[2], b[3]]) as f64,
307 ))
308 }
309 0xCB => {
310 let b = c.take_n(8)?;
311 Ok(crate::Value::Float(f64::from_be_bytes([
312 b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7],
313 ])))
314 }
315
316 m @ 0xA0..=0xBF => read_native_str(c, (m & 0x1F) as usize),
317 0xD9 => {
318 let l = c.take()? as usize;
319 read_native_str(c, l)
320 }
321 0xDA => {
322 let l = c.read_u16_be()? as usize;
323 read_native_str(c, l)
324 }
325 0xDB => {
326 let l = c.read_u32_be()? as usize;
327 read_native_str(c, l)
328 }
329
330 0xC4 => {
331 let l = c.take()? as usize;
332 Ok(crate::Value::Bytes(c.take_n(l)?.to_vec()))
333 }
334 0xC5 => {
335 let l = c.read_u16_be()? as usize;
336 Ok(crate::Value::Bytes(c.take_n(l)?.to_vec()))
337 }
338 0xC6 => {
339 let l = c.read_u32_be()? as usize;
340 Ok(crate::Value::Bytes(c.take_n(l)?.to_vec()))
341 }
342
343 m @ 0x90..=0x9F => read_native_array(c, (m & 0x0F) as usize),
344 0xDC => {
345 let l = c.read_u16_be()? as usize;
346 read_native_array(c, l)
347 }
348 0xDD => {
349 let l = c.read_u32_be()? as usize;
350 read_native_array(c, l)
351 }
352
353 m @ 0x80..=0x8F => read_native_map(c, (m & 0x0F) as usize),
354 0xDE => {
355 let l = c.read_u16_be()? as usize;
356 read_native_map(c, l)
357 }
358 0xDF => {
359 let l = c.read_u32_be()? as usize;
360 read_native_map(c, l)
361 }
362
363 0xD4 => {
365 c.take_n(2)?;
366 Ok(crate::Value::Null)
367 }
368 0xD5 => {
369 c.take_n(3)?;
370 Ok(crate::Value::Null)
371 }
372 0xD6 => {
373 c.take_n(5)?;
374 Ok(crate::Value::Null)
375 }
376 0xD7 => {
377 c.take_n(9)?;
378 Ok(crate::Value::Null)
379 }
380 0xD8 => {
381 c.take_n(17)?;
382 Ok(crate::Value::Null)
383 }
384 0xC7 => {
385 let l = c.take()? as usize;
386 c.take_n(1 + l)?;
387 Ok(crate::Value::Null)
388 }
389 0xC8 => {
390 let l = c.read_u16_be()? as usize;
391 c.take_n(1 + l)?;
392 Ok(crate::Value::Null)
393 }
394 0xC9 => {
395 let l = c.read_u32_be()? as usize;
396 c.take_n(1 + l)?;
397 Ok(crate::Value::Null)
398 }
399
400 _ => Err(zerompk::Error::InvalidMarker(marker)),
401 }
402}
403
404fn read_native_str(c: &mut Cursor<'_>, len: usize) -> zerompk::Result<crate::Value> {
405 let bytes = c.take_n(len)?;
406 let s = String::from_utf8(bytes.to_vec()).map_err(|_| zerompk::Error::InvalidMarker(0))?;
407 Ok(crate::Value::String(s))
408}
409
410fn read_native_array(c: &mut Cursor<'_>, len: usize) -> zerompk::Result<crate::Value> {
411 c.depth += 1;
412 let mut arr = Vec::with_capacity(len.min(4096));
413 for _ in 0..len {
414 arr.push(read_native_value(c)?);
415 }
416 c.depth -= 1;
417 Ok(crate::Value::Array(arr))
418}
419
420fn read_native_map(c: &mut Cursor<'_>, len: usize) -> zerompk::Result<crate::Value> {
421 c.depth += 1;
422 let mut map = std::collections::HashMap::with_capacity(len.min(4096));
423 for _ in 0..len {
424 let key_marker = c.peek()?;
425 let key = if (0xA0..=0xBF).contains(&key_marker)
426 || key_marker == 0xD9
427 || key_marker == 0xDA
428 || key_marker == 0xDB
429 {
430 match read_native_value(c)? {
431 crate::Value::String(s) => s,
432 other => format!("{other:?}"),
433 }
434 } else {
435 let v = read_native_value(c)?;
436 format!("{v:?}")
437 };
438 let val = read_native_value(c)?;
439 map.insert(key, val);
440 }
441 c.depth -= 1;
442 Ok(crate::Value::Object(map))
443}
444
445pub(crate) fn base64_encode(data: &[u8]) -> String {
448 use std::fmt::Write;
449 const CHARS: &[u8; 64] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
450 let mut out = String::with_capacity(data.len().div_ceil(3) * 4);
451 for chunk in data.chunks(3) {
452 let b0 = chunk[0] as u32;
453 let b1 = chunk.get(1).copied().unwrap_or(0) as u32;
454 let b2 = chunk.get(2).copied().unwrap_or(0) as u32;
455 let triple = (b0 << 16) | (b1 << 8) | b2;
456 let _ = write!(out, "{}", CHARS[((triple >> 18) & 0x3F) as usize] as char);
457 let _ = write!(out, "{}", CHARS[((triple >> 12) & 0x3F) as usize] as char);
458 if chunk.len() > 1 {
459 let _ = write!(out, "{}", CHARS[((triple >> 6) & 0x3F) as usize] as char);
460 }
461 if chunk.len() > 2 {
462 let _ = write!(out, "{}", CHARS[(triple & 0x3F) as usize] as char);
463 }
464 }
465 out
466}