Skip to main content

sark_json/
encode.rs

1use o3::buffer::Owned;
2
3pub struct Encode;
4
5impl Encode {
6    pub fn u64_len(mut value: u64) -> usize {
7        if value == 0 {
8            return 1;
9        }
10        let mut digits = 0usize;
11        while value != 0 {
12            digits += 1;
13            value /= 10;
14        }
15        digits
16    }
17
18    pub fn str_len(value: &[u8]) -> usize {
19        2 + Self::esc_len(value)
20    }
21
22    pub fn extend_str(value: &[u8], out: &mut Owned) {
23        out.extend_from_slice(b"\"");
24        let mut start = 0usize;
25        let mut idx = 0usize;
26        while idx < value.len() {
27            let esc = Self::esc_token(value[idx]);
28            if let Some(token) = esc {
29                if start != idx {
30                    out.extend_from_slice(&value[start..idx]);
31                }
32                out.extend_from_slice(token.as_bytes());
33                idx += 1;
34                start = idx;
35                continue;
36            }
37            idx += 1;
38        }
39        if start != value.len() {
40            out.extend_from_slice(&value[start..]);
41        }
42        out.extend_from_slice(b"\"");
43    }
44
45    pub fn extend_u64(out: &mut Owned, value: u64) {
46        if value == 0 {
47            out.extend_from_slice(b"0");
48            return;
49        }
50        let mut digits = [0u8; 20];
51        let mut idx = digits.len();
52        let mut value = value;
53        while value != 0 {
54            idx -= 1;
55            digits[idx] = b'0' + (value % 10) as u8;
56            value /= 10;
57        }
58        out.extend_from_slice(&digits[idx..]);
59    }
60
61    fn esc_len(value: &[u8]) -> usize {
62        let mut len = 0usize;
63        let mut idx = 0usize;
64        while idx < value.len() {
65            len += Self::esc_size(value[idx]);
66            idx += 1;
67        }
68        len
69    }
70
71    fn esc_size(byte: u8) -> usize {
72        match byte {
73            b'"' | b'\\' | 0x08 | b'\n' | 0x0c | b'\r' | b'\t' => 2,
74            0x00..=0x1f => 6,
75            _ => 1,
76        }
77    }
78
79    fn esc_token(byte: u8) -> Option<&'static str> {
80        match byte {
81            b'"' => Some("\\\""),
82            b'\\' => Some("\\\\"),
83            b'\n' => Some("\\n"),
84            b'\r' => Some("\\r"),
85            b'\t' => Some("\\t"),
86            0x00 => Some("\\u0000"),
87            0x01 => Some("\\u0001"),
88            0x02 => Some("\\u0002"),
89            0x03 => Some("\\u0003"),
90            0x04 => Some("\\u0004"),
91            0x05 => Some("\\u0005"),
92            0x06 => Some("\\u0006"),
93            0x07 => Some("\\u0007"),
94            0x08 => Some("\\b"),
95            0x0b => Some("\\u000b"),
96            0x0c => Some("\\f"),
97            0x0e => Some("\\u000e"),
98            0x0f => Some("\\u000f"),
99            0x10 => Some("\\u0010"),
100            0x11 => Some("\\u0011"),
101            0x12 => Some("\\u0012"),
102            0x13 => Some("\\u0013"),
103            0x14 => Some("\\u0014"),
104            0x15 => Some("\\u0015"),
105            0x16 => Some("\\u0016"),
106            0x17 => Some("\\u0017"),
107            0x18 => Some("\\u0018"),
108            0x19 => Some("\\u0019"),
109            0x1a => Some("\\u001a"),
110            0x1b => Some("\\u001b"),
111            0x1c => Some("\\u001c"),
112            0x1d => Some("\\u001d"),
113            0x1e => Some("\\u001e"),
114            0x1f => Some("\\u001f"),
115            _ => None,
116        }
117    }
118}