1pub fn encode_name(name: &[u8]) -> Vec<u8> {
7 let mut encoded_name: Vec<u8> = Vec::new();
8 let mut segments: Vec<[u8; 4]> = Vec::new();
9 let mut i = 0;
10 if name[0] == b'\\' {
11 encoded_name.push(b'\\');
12 i = 1;
13 }
14 loop {
15 if i == name.len() {
16 break;
17 }
18
19 if name[i] == b'^' {
20 assert!(
21 (encoded_name.is_empty() || encoded_name[encoded_name.len() - 1] == b'^')
22 && segments.is_empty()
23 );
24 encoded_name.push(b'^');
25 i += 1;
26 continue;
27 }
28
29 assert!((name[i] == b'_') || (name[i] >= b'A' && name[i] <= b'Z'));
30 let mut seg: [u8; 4] = [b'_'; 4];
31 let mut seg_i = 0;
32 loop {
33 let off = i + seg_i;
34 if off == name.len() || name[off] == b'.' {
35 break;
36 }
37
38 assert!(seg_i < 4);
39 assert!(
40 (name[off] == b'_')
41 || (name[off] >= b'A' && name[off] <= b'Z')
42 || (name[off] >= b'0' && name[off] <= b'9')
43 );
44 seg[seg_i] = name[off];
45 seg_i += 1
46 }
47 assert!(seg_i > 0);
48 segments.push(seg);
49 i += seg_i;
51 if i < name.len() {
52 i += 1;
54 }
55 }
56 if segments.len() > 2 {
57 encoded_name.push(0x2f);
58 encoded_name.push(u8::try_from(segments.len()).unwrap());
59 } else if segments.len() > 1 {
60 encoded_name.push(0x2e);
61 }
62 for seg in segments {
63 encoded_name.extend_from_slice(&seg);
64 }
65 encoded_name
66}
67
68pub fn encode_package_len(len: usize) -> Vec<u8> {
69 assert!(len < (1 << 28) - 1);
70 let mut result: Vec<u8> = Vec::new();
71 if len < 63 {
72 result.push(u8::try_from(len).unwrap() + 1);
73 } else {
74 let len_bytes = if len < 1 << 12 {
78 2
79 } else if len < 1 << 20 {
80 3
81 } else {
82 4
83 };
84
85 let mut encoded_len: [u8; 4] = [0; 4];
86 let mut rem = len + len_bytes;
87 encoded_len[0] =
89 u8::try_from((len_bytes - 1) << 6).unwrap() | u8::try_from(rem & 0xf).unwrap();
90 rem >>= 4;
91 for e in encoded_len.iter_mut().take(len_bytes).skip(1) {
92 *e = u8::try_from(rem & 0xff).unwrap();
93 rem >>= 8;
94 }
95
96 result.extend_from_slice(&encoded_len[..len_bytes]);
97 }
98 result
99}
100
101pub fn encode_integer(value: u64) -> Vec<u8> {
102 let mut byte_stream: Vec<u8> = Vec::new();
103 let end = if value == 0 {
104 return vec![0];
106 } else if value == 1 {
107 return vec![1];
109 } else if value <= 0xff {
110 byte_stream.push(0xa);
111 1
112 } else if value <= 0xffff {
113 byte_stream.push(0xb);
114 2
115 } else if value <= 0xffffffff {
116 byte_stream.push(0xc);
117 4
118 } else {
119 byte_stream.push(0xe);
120 8
121 };
122
123 let bytes = value.to_le_bytes();
124 byte_stream.extend_from_slice(&bytes[..end]);
125 byte_stream
126}
127
128pub fn encode_dword(value: u32) -> Vec<u8> {
129 let mut byte_stream = vec![0xcu8];
130 byte_stream.extend_from_slice(&value.to_le_bytes());
131 while byte_stream.len() < 5 {
132 byte_stream.push(0);
133 }
134 byte_stream
135}
136
137pub fn encode_string(value: &[u8]) -> Vec<u8> {
138 let mut byte_stream: Vec<u8> = Vec::new();
139 byte_stream.push(0xd);
140 byte_stream.extend_from_slice(value);
141 byte_stream.push(0);
142 byte_stream
143}
144
145pub fn char_to_hex(value: u8) -> u8 {
146 match value {
147 b'0'..=b'9' => value - b'0',
148 b'a'..=b'f' => 10 + value - b'a',
149 b'A'..=b'F' => 10 + value - b'A',
150 _ => panic!("Unsupported hex char {}", value),
151 }
152}
153
154pub fn encode_arg(n: u8) -> Vec<u8> {
156 assert!(n < 7, "Arg index must be 0-6");
157 vec![0x68 + n]
158}
159
160pub fn encode_local(n: u8) -> Vec<u8> {
162 assert!(n < 8, "Local index must be 0-7");
163 vec![0x60 + n]
164}
165
166#[cfg(test)]
167mod tests {
168 use super::*;
169 use crate::aml::test_helpers::verify_expected_bytes;
170
171 #[test]
172 fn verify_simple_name() {
173 let bytes = encode_name(b"FOO");
174 verify_expected_bytes(&bytes, b"FOO_");
175 }
176
177 #[test]
178 fn verify_simple_name_with_root() {
179 let bytes = encode_name(b"\\FOO");
180 verify_expected_bytes(&bytes, b"\\FOO_");
181 }
182
183 #[test]
184 fn verify_simple_name_with_prefix() {
185 let bytes = encode_name(b"^FOO");
186 verify_expected_bytes(&bytes, b"^FOO_");
187 }
188
189 #[test]
190 fn verify_dual_name() {
191 let bytes = encode_name(b"FOO.BAR");
192 verify_expected_bytes(&bytes, b"\x2eFOO_BAR_");
193 }
194
195 #[test]
196 fn verify_dual_name_with_root() {
197 let bytes = encode_name(b"\\_SB.FOO");
198 verify_expected_bytes(&bytes, b"\\\x2e_SB_FOO_");
199 }
200
201 #[test]
202 fn verify_multi_name() {
203 let bytes = encode_name(b"FOO.BAR.BAZ.BLAM");
204 verify_expected_bytes(&bytes, b"\x2f\x04FOO_BAR_BAZ_BLAM");
205 }
206}