jvm_types/
modified_utf8.rs1use alloc::vec::Vec;
4
5pub fn encode(units: &[u16]) -> Vec<u8> {
7 let mut bytes = Vec::with_capacity(units.len());
8 for &value in units {
9 if (0x0001..=0x007f).contains(&value) {
10 bytes.push(value as u8);
11 } else if value <= 0x07ff {
12 bytes.push((0xc0 | (value >> 6)) as u8);
13 bytes.push((0x80 | (value & 0x3f)) as u8);
14 } else {
15 bytes.push((0xe0 | (value >> 12)) as u8);
16 bytes.push((0x80 | ((value >> 6) & 0x3f)) as u8);
17 bytes.push((0x80 | (value & 0x3f)) as u8);
18 }
19 }
20 bytes
21}
22
23pub fn decode(bytes: &[u8]) -> Option<Vec<u16>> {
26 let continuation = |i: usize| match bytes.get(i) {
27 Some(&b) if b & 0xc0 == 0x80 => Some((b & 0x3f) as u16),
28 _ => None,
29 };
30
31 let mut units = Vec::with_capacity(bytes.len());
32 let mut i = 0;
33 while i < bytes.len() {
34 let b = bytes[i] as u16;
35 let (unit, length) = match bytes[i] {
36 0x00..=0x7f => (b, 1),
37 0xc0..=0xdf => (((b & 0x1f) << 6) | continuation(i + 1)?, 2),
38 0xe0..=0xef => (((b & 0x0f) << 12) | (continuation(i + 1)? << 6) | continuation(i + 2)?, 3),
39 _ => return None,
40 };
41 units.push(unit);
42 i += length;
43 }
44 Some(units)
45}