1use alloc::string::String;
2use core::convert::TryInto;
3use core::fmt;
4use core::marker::PhantomData;
5
6use crate::pod::{from_bytes, slice_from_bytes, Pod};
7use crate::read::ReadRef;
8use crate::SkipDebugList;
9
10#[derive(Default, Clone, Copy, PartialEq, Eq)]
17pub struct Bytes<'data>(pub &'data [u8]);
18
19impl<'data> fmt::Debug for Bytes<'data> {
20 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
21 debug_list_bytes(self.0, fmt)
22 }
23}
24
25impl<'data> Bytes<'data> {
26 #[inline]
28 pub fn len(&self) -> usize {
29 self.0.len()
30 }
31
32 #[inline]
34 pub fn is_empty(&self) -> bool {
35 self.0.is_empty()
36 }
37
38 #[inline]
44 pub fn skip(&mut self, offset: usize) -> Result<(), ()> {
45 match self.0.get(offset..) {
46 Some(tail) => {
47 self.0 = tail;
48 Ok(())
49 }
50 None => {
51 self.0 = &[];
52 Err(())
53 }
54 }
55 }
56
57 #[inline]
63 pub fn read_bytes(&mut self, count: usize) -> Result<Bytes<'data>, ()> {
64 match (self.0.get(..count), self.0.get(count..)) {
65 (Some(head), Some(tail)) => {
66 self.0 = tail;
67 Ok(Bytes(head))
68 }
69 _ => {
70 self.0 = &[];
71 Err(())
72 }
73 }
74 }
75
76 #[inline]
80 pub fn read_bytes_at(mut self, offset: usize, count: usize) -> Result<Bytes<'data>, ()> {
81 self.skip(offset)?;
82 self.read_bytes(count)
83 }
84
85 #[inline]
91 pub fn read<T: Pod>(&mut self) -> Result<&'data T, ()> {
92 match from_bytes(self.0) {
93 Ok((value, tail)) => {
94 self.0 = tail;
95 Ok(value)
96 }
97 Err(()) => {
98 self.0 = &[];
99 Err(())
100 }
101 }
102 }
103
104 #[inline]
108 pub fn read_at<T: Pod>(mut self, offset: usize) -> Result<&'data T, ()> {
109 self.skip(offset)?;
110 self.read()
111 }
112
113 #[inline]
119 pub fn read_slice<T: Pod>(&mut self, count: usize) -> Result<&'data [T], ()> {
120 match slice_from_bytes(self.0, count) {
121 Ok((value, tail)) => {
122 self.0 = tail;
123 Ok(value)
124 }
125 Err(()) => {
126 self.0 = &[];
127 Err(())
128 }
129 }
130 }
131
132 #[inline]
136 pub fn read_slice_at<T: Pod>(mut self, offset: usize, count: usize) -> Result<&'data [T], ()> {
137 self.skip(offset)?;
138 self.read_slice(count)
139 }
140
141 #[inline]
146 pub fn read_string(&mut self) -> Result<&'data [u8], ()> {
147 match memchr::memchr(b'\0', self.0) {
148 Some(null) => {
149 let bytes = self.read_bytes(null)?;
151 self.skip(1)?;
152 Ok(bytes.0)
153 }
154 None => {
155 self.0 = &[];
156 Err(())
157 }
158 }
159 }
160
161 #[inline]
165 pub fn read_string_at(mut self, offset: usize) -> Result<&'data [u8], ()> {
166 self.skip(offset)?;
167 self.read_string()
168 }
169
170 pub fn read_uleb128(&mut self) -> Result<u64, ()> {
172 let mut result = 0;
173 let mut shift = 0;
174
175 loop {
176 let byte = *self.read::<u8>()?;
177 if shift == 63 && byte != 0x00 && byte != 0x01 {
178 return Err(());
179 }
180 result |= u64::from(byte & 0x7f) << shift;
181 shift += 7;
182
183 if byte & 0x80 == 0 {
184 return Ok(result);
185 }
186 }
187 }
188
189 pub fn read_sleb128(&mut self) -> Result<i64, ()> {
191 let mut result = 0;
192 let mut shift = 0;
193
194 loop {
195 let byte = *self.read::<u8>()?;
196 if shift == 63 && byte != 0x00 && byte != 0x7f {
197 return Err(());
198 }
199 result |= i64::from(byte & 0x7f) << shift;
200 shift += 7;
201
202 if byte & 0x80 == 0 {
203 if shift < 64 && (byte & 0x40) != 0 {
204 result |= !0 << shift;
206 }
207 return Ok(result);
208 }
209 }
210 }
211}
212
213fn debug_list_bytes(bytes: &[u8], fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
215 let mut list = fmt.debug_list();
216 list.entries(bytes.iter().take(8).copied().map(DebugByte));
217 if bytes.len() > 8 {
218 list.entry(&DebugLen(bytes.len()));
219 }
220 list.finish()
221}
222
223struct DebugByte(u8);
224
225impl fmt::Debug for DebugByte {
226 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
227 write!(fmt, "0x{:02x}", self.0)
228 }
229}
230
231struct DebugLen(usize);
232
233impl fmt::Debug for DebugLen {
234 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
235 write!(fmt, "...; {}", self.0)
236 }
237}
238
239#[derive(Default, Clone, Copy, PartialEq, Eq)]
245pub(crate) struct ByteString<'data>(pub &'data [u8]);
246
247impl<'data> fmt::Debug for ByteString<'data> {
248 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
249 write!(fmt, "\"{}\"", String::from_utf8_lossy(self.0))
250 }
251}
252
253#[allow(dead_code)]
254#[inline]
255pub(crate) fn align(offset: usize, size: usize) -> usize {
256 (offset + (size - 1)) & !(size - 1)
257}
258
259#[allow(dead_code)]
260pub(crate) fn data_range(
261 data: &[u8],
262 data_address: u64,
263 range_address: u64,
264 size: u64,
265) -> Option<&[u8]> {
266 let offset = range_address.checked_sub(data_address)?;
267 data.get(offset.try_into().ok()?..)?
268 .get(..size.try_into().ok()?)
269}
270
271#[derive(Debug, Clone, Copy)]
275pub struct StringTable<'data, R = &'data [u8]>
276where
277 R: ReadRef<'data>,
278{
279 data: Option<SkipDebugList<R>>,
280 start: u64,
281 end: u64,
282 marker: PhantomData<&'data ()>,
283}
284
285impl<'data, R: ReadRef<'data>> StringTable<'data, R> {
286 pub fn new(data: R, start: u64, end: u64) -> Self {
288 StringTable {
289 data: Some(SkipDebugList(data)),
290 start,
291 end,
292 marker: PhantomData,
293 }
294 }
295
296 pub fn get(&self, offset: u32) -> Result<&'data [u8], ()> {
298 match self.data {
299 Some(data) => {
300 let r_start = self.start.checked_add(offset.into()).ok_or(())?;
301 data.read_bytes_at_until(r_start..self.end, 0)
302 }
303 None => Err(()),
304 }
305 }
306}
307
308impl<'data, R: ReadRef<'data>> Default for StringTable<'data, R> {
309 fn default() -> Self {
310 StringTable {
311 data: None,
312 start: 0,
313 end: 0,
314 marker: PhantomData,
315 }
316 }
317}
318
319#[cfg(test)]
320mod tests {
321 use super::*;
322 use crate::pod::bytes_of;
323
324 #[test]
325 fn bytes() {
326 let x = u32::to_be(0x0123_4567);
327 let data = Bytes(bytes_of(&x));
328
329 let mut bytes = data;
330 assert_eq!(bytes.skip(0), Ok(()));
331 assert_eq!(bytes, data);
332
333 let mut bytes = data;
334 assert_eq!(bytes.skip(4), Ok(()));
335 assert_eq!(bytes, Bytes(&[]));
336
337 let mut bytes = data;
338 assert_eq!(bytes.skip(5), Err(()));
339 assert_eq!(bytes, Bytes(&[]));
340
341 let mut bytes = data;
342 assert_eq!(bytes.read_bytes(0), Ok(Bytes(&[])));
343 assert_eq!(bytes, data);
344
345 let mut bytes = data;
346 assert_eq!(bytes.read_bytes(4), Ok(data));
347 assert_eq!(bytes, Bytes(&[]));
348
349 let mut bytes = data;
350 assert_eq!(bytes.read_bytes(5), Err(()));
351 assert_eq!(bytes, Bytes(&[]));
352
353 assert_eq!(data.read_bytes_at(0, 0), Ok(Bytes(&[])));
354 assert_eq!(data.read_bytes_at(4, 0), Ok(Bytes(&[])));
355 assert_eq!(data.read_bytes_at(0, 4), Ok(data));
356 assert_eq!(data.read_bytes_at(1, 4), Err(()));
357
358 let mut bytes = data;
359 assert_eq!(bytes.read::<u16>(), Ok(&u16::to_be(0x0123)));
360 assert_eq!(bytes, Bytes(&[0x45, 0x67]));
361 assert_eq!(data.read_at::<u16>(2), Ok(&u16::to_be(0x4567)));
362 assert_eq!(data.read_at::<u16>(3), Err(()));
363 assert_eq!(data.read_at::<u16>(4), Err(()));
364
365 let mut bytes = data;
366 assert_eq!(bytes.read::<u32>(), Ok(&x));
367 assert_eq!(bytes, Bytes(&[]));
368
369 let mut bytes = data;
370 assert_eq!(bytes.read::<u64>(), Err(()));
371 assert_eq!(bytes, Bytes(&[]));
372
373 let mut bytes = data;
374 assert_eq!(bytes.read_slice::<u8>(0), Ok(&[][..]));
375 assert_eq!(bytes, data);
376
377 let mut bytes = data;
378 assert_eq!(bytes.read_slice::<u8>(4), Ok(data.0));
379 assert_eq!(bytes, Bytes(&[]));
380
381 let mut bytes = data;
382 assert_eq!(bytes.read_slice::<u8>(5), Err(()));
383 assert_eq!(bytes, Bytes(&[]));
384
385 assert_eq!(data.read_slice_at::<u8>(0, 0), Ok(&[][..]));
386 assert_eq!(data.read_slice_at::<u8>(4, 0), Ok(&[][..]));
387 assert_eq!(data.read_slice_at::<u8>(0, 4), Ok(data.0));
388 assert_eq!(data.read_slice_at::<u8>(1, 4), Err(()));
389
390 let data = Bytes(&[0x01, 0x02, 0x00, 0x04]);
391
392 let mut bytes = data;
393 assert_eq!(bytes.read_string(), Ok(&data.0[..2]));
394 assert_eq!(bytes.0, &data.0[3..]);
395
396 let mut bytes = data;
397 bytes.skip(3).unwrap();
398 assert_eq!(bytes.read_string(), Err(()));
399 assert_eq!(bytes.0, &[]);
400
401 assert_eq!(data.read_string_at(0), Ok(&data.0[..2]));
402 assert_eq!(data.read_string_at(1), Ok(&data.0[1..2]));
403 assert_eq!(data.read_string_at(2), Ok(&[][..]));
404 assert_eq!(data.read_string_at(3), Err(()));
405 }
406
407 #[test]
408 fn bytes_debug() {
409 assert_eq!(format!("{:?}", Bytes(&[])), "[]");
410 assert_eq!(format!("{:?}", Bytes(&[0x01])), "[0x01]");
411 assert_eq!(
412 format!(
413 "{:?}",
414 Bytes(&[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08])
415 ),
416 "[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]"
417 );
418 assert_eq!(
419 format!(
420 "{:?}",
421 Bytes(&[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09])
422 ),
423 "[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, ...; 9]"
424 );
425 }
426}