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}