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