]> git.proxmox.com Git - rustc.git/blame - vendor/object/src/pod.rs
New upstream version 1.50.0+dfsg1
[rustc.git] / vendor / object / src / pod.rs
CommitLineData
f035d41b
XL
1//! Tools for converting file format structures to and from bytes.
2//!
3//! This module should be replaced once rust provides safe transmutes.
4
5// This module provides functions for both read and write features.
6#![cfg_attr(not(all(feature = "read_core", feature = "write_core")), allow(dead_code))]
7
8use alloc::vec::Vec;
9use core::{fmt, mem, result, slice};
10
11type Result<T> = result::Result<T, ()>;
12
13/// A trait for types that can safely be converted from and to byte slices.
14///
15/// A type that is `Pod` must:
16/// - be `#[repr(C)]` or `#[repr(transparent)]`
17/// - have no invalid byte values
18/// - have no padding
19pub unsafe trait Pod: Copy + 'static {}
20
21/// Cast a byte slice to a `Pod` type.
22///
23/// Returns the type and the tail of the slice.
24#[inline]
25pub fn from_bytes<T: Pod>(data: &[u8]) -> Result<(&T, &[u8])> {
26 let ptr = data.as_ptr();
27 if (ptr as usize) % mem::align_of::<T>() != 0 {
28 return Err(());
29 }
30 let size = mem::size_of::<T>();
31 let tail = data.get(size..).ok_or(())?;
32 // Safety:
33 // The alignment and size are checked by this function.
34 // The Pod trait ensures the type is valid to cast from bytes.
35 let val = unsafe { &*ptr.cast() };
36 Ok((val, tail))
37}
38
39/// Cast a byte slice to a slice of a `Pod` type.
40///
41/// Returns the type slice and the tail of the byte slice.
42#[inline]
43pub fn slice_from_bytes<T: Pod>(data: &[u8], count: usize) -> Result<(&[T], &[u8])> {
44 let ptr = data.as_ptr();
45 if (ptr as usize) % mem::align_of::<T>() != 0 {
46 return Err(());
47 }
48 let size = count.checked_mul(mem::size_of::<T>()).ok_or(())?;
49 let tail = data.get(size..).ok_or(())?;
50 // Safety:
51 // The alignment and size are checked by this function.
52 // The Pod trait ensures the type is valid to cast from bytes.
53 let slice = unsafe { slice::from_raw_parts(ptr.cast(), count) };
54 Ok((slice, tail))
55}
56
57/// Cast a `Pod` type to a byte slice.
58#[inline]
59pub fn bytes_of<T: Pod>(val: &T) -> &[u8] {
60 let size = mem::size_of::<T>();
61 // Safety:
62 // Any alignment is allowed.
63 // The size is determined in this function.
64 // The Pod trait ensures the type is valid to cast to bytes.
65 unsafe { slice::from_raw_parts(slice::from_ref(val).as_ptr().cast(), size) }
66}
67
68/// A newtype for byte slices.
69///
70/// It has these important features:
71/// - no methods that can panic, such as `Index`
72/// - convenience methods for `Pod` types
73/// - a useful `Debug` implementation
74#[derive(Default, Clone, Copy, PartialEq, Eq)]
75pub struct Bytes<'data>(pub &'data [u8]);
76
77impl<'data> fmt::Debug for Bytes<'data> {
78 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
79 debug_list_bytes(self.0, fmt)
80 }
81}
82
83impl<'data> Bytes<'data> {
84 /// Return the length of the byte slice.
85 #[inline]
86 pub fn len(&self) -> usize {
87 self.0.len()
88 }
89
90 /// Return true if the byte slice is empty.
91 #[inline]
92 pub fn is_empty(&self) -> bool {
93 self.0.is_empty()
94 }
95
96 /// Skip over the given number of bytes at the start of the byte slice.
97 ///
98 /// Modifies the byte slice to start after the bytes.
99 ///
100 /// Returns an error if there are too few bytes.
101 #[inline]
102 pub fn skip(&mut self, offset: usize) -> Result<()> {
103 match self.0.get(offset..) {
104 Some(tail) => {
105 self.0 = tail;
106 Ok(())
107 }
108 None => {
109 self.0 = &[];
110 Err(())
111 }
112 }
113 }
114
115 /// Return a reference to the given number of bytes at the start of the byte slice.
116 ///
117 /// Modifies the byte slice to start after the bytes.
118 ///
119 /// Returns an error if there are too few bytes.
120 #[inline]
121 pub fn read_bytes(&mut self, count: usize) -> Result<Bytes<'data>> {
122 match (self.0.get(..count), self.0.get(count..)) {
123 (Some(head), Some(tail)) => {
124 self.0 = tail;
125 Ok(Bytes(head))
126 }
127 _ => {
128 self.0 = &[];
129 Err(())
130 }
131 }
132 }
133
134 /// Return a reference to the given number of bytes at the given offset of the byte slice.
135 ///
136 /// Returns an error if the offset is invalid or there are too few bytes.
137 #[inline]
138 pub fn read_bytes_at(mut self, offset: usize, count: usize) -> Result<Bytes<'data>> {
139 self.skip(offset)?;
140 self.read_bytes(count)
141 }
142
143 /// Return a reference to a `Pod` struct at the start of the byte slice.
144 ///
145 /// Modifies the byte slice to start after the bytes.
146 ///
147 /// Returns an error if there are too few bytes or the slice is incorrectly aligned.
148 #[inline]
149 pub fn read<T: Pod>(&mut self) -> Result<&'data T> {
150 match from_bytes(self.0) {
151 Ok((value, tail)) => {
152 self.0 = tail;
153 Ok(value)
154 }
155 Err(()) => {
156 self.0 = &[];
157 Err(())
158 }
159 }
160 }
161
162 /// Return a reference to a `Pod` struct at the given offset of the byte slice.
163 ///
164 /// Returns an error if there are too few bytes or the offset is incorrectly aligned.
165 #[inline]
166 pub fn read_at<T: Pod>(mut self, offset: usize) -> Result<&'data T> {
167 self.skip(offset)?;
168 self.read()
169 }
170
171 /// Return a reference to a slice of `Pod` structs at the start of the byte slice.
172 ///
173 /// Modifies the byte slice to start after the bytes.
174 ///
175 /// Returns an error if there are too few bytes or the offset is incorrectly aligned.
176 #[inline]
177 pub fn read_slice<T: Pod>(&mut self, count: usize) -> Result<&'data [T]> {
178 match slice_from_bytes(self.0, count) {
179 Ok((value, tail)) => {
180 self.0 = tail;
181 Ok(value)
182 }
183 Err(()) => {
184 self.0 = &[];
185 Err(())
186 }
187 }
188 }
189
190 /// Return a reference to a slice of `Pod` structs at the given offset of the byte slice.
191 ///
192 /// Returns an error if there are too few bytes or the offset is incorrectly aligned.
193 #[inline]
194 pub fn read_slice_at<T: Pod>(mut self, offset: usize, count: usize) -> Result<&'data [T]> {
195 self.skip(offset)?;
196 self.read_slice(count)
197 }
198
199 /// Read a null terminated string.
200 ///
201 /// Does not assume any encoding.
202 /// Reads past the null byte, but doesn't return it.
203 #[inline]
204 pub fn read_string(&mut self) -> Result<&'data [u8]> {
205 match self.0.iter().position(|&x| x == 0) {
206 Some(null) => {
207 // These will never fail.
208 let bytes = self.read_bytes(null)?;
209 self.skip(1)?;
210 Ok(bytes.0)
211 }
212 None => {
213 self.0 = &[];
214 Err(())
215 }
216 }
217 }
218
219 /// Read a null terminated string at an offset.
220 ///
221 /// Does not assume any encoding. Does not return the null byte.
222 #[inline]
223 pub fn read_string_at(mut self, offset: usize) -> Result<&'data [u8]> {
224 self.skip(offset)?;
225 self.read_string()
226 }
227}
228
fc512014
XL
229/// Trait for writable buffer.
230pub trait WritableBuffer {
231 /// Returns position/offset for data to be written at.
232 fn len(&self) -> usize;
233 /// Returns true if buffer contains no data.
234 fn is_empty(&self) -> bool;
235 /// Reserves specified number of bytes in the buffer.
236 fn reserve(&mut self, additional: usize) -> Result<()>;
237 /// Resizes buffer to the specified length, fills new items
238 /// with the specified value.
239 fn resize(&mut self, new_len: usize, value: u8);
240 /// Extends buffer with the specified slice of bytes.
241 fn extend(&mut self, val: &[u8]);
242}
243
f035d41b
XL
244/// A newtype for byte vectors.
245///
246/// It provides convenience methods for `Pod` types.
247// TODO: should this be an extension trait for `Vec<u8>` instead?
248#[derive(Default, Clone, PartialEq, Eq)]
249pub(crate) struct BytesMut(pub Vec<u8>);
250
251impl fmt::Debug for BytesMut {
252 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
253 debug_list_bytes(&self.0, fmt)
254 }
255}
256
257impl BytesMut {
258 #[inline]
259 pub fn new() -> Self {
260 BytesMut(Vec::new())
261 }
262
263 #[inline]
fc512014
XL
264 pub fn write<T: Pod>(&mut self, val: &T) {
265 self.0.extend_from_slice(bytes_of(val))
f035d41b
XL
266 }
267
268 #[inline]
fc512014
XL
269 pub fn write_at<T: Pod>(&mut self, offset: usize, val: &T) -> Result<()> {
270 let src = bytes_of(val);
271 let dest = self.0.get_mut(offset..).ok_or(())?;
272 let dest = dest.get_mut(..src.len()).ok_or(())?;
273 dest.copy_from_slice(src);
274 Ok(())
f035d41b
XL
275 }
276
277 #[inline]
fc512014
XL
278 pub fn as_slice(&self) -> &[u8] {
279 self.0.as_slice()
f035d41b 280 }
fc512014 281}
f035d41b 282
fc512014 283impl WritableBuffer for BytesMut {
f035d41b 284 #[inline]
fc512014
XL
285 fn len(&self) -> usize {
286 self.0.len()
f035d41b
XL
287 }
288
289 #[inline]
fc512014
XL
290 fn is_empty(&self) -> bool {
291 self.0.is_empty()
292 }
293
294 #[inline]
295 fn reserve(&mut self, additional: usize) -> Result<()> {
296 self.0.reserve(additional);
f035d41b
XL
297 Ok(())
298 }
299
300 #[inline]
fc512014
XL
301 fn resize(&mut self, new_len: usize, value: u8) {
302 self.0.resize(new_len, value);
f035d41b
XL
303 }
304
305 #[inline]
fc512014 306 fn extend(&mut self, val: &[u8]) {
f035d41b
XL
307 self.0.extend_from_slice(val)
308 }
309}
310
311// Only for Debug impl of `Bytes/BytesMut`.
312fn debug_list_bytes(bytes: &[u8], fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
313 let mut list = fmt.debug_list();
314 list.entries(bytes.iter().take(8).copied().map(DebugByte));
315 if bytes.len() > 8 {
316 list.entry(&DebugLen(bytes.len()));
317 }
318 list.finish()
319}
320
321struct DebugByte(u8);
322
323impl fmt::Debug for DebugByte {
324 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
325 write!(fmt, "0x{:02x}", self.0)
326 }
327}
328
329struct DebugLen(usize);
330
331impl fmt::Debug for DebugLen {
332 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
333 write!(fmt, "...; {}", self.0)
334 }
335}
336
337macro_rules! unsafe_impl_pod {
338 ($($struct_name:ident),+ $(,)?) => {
339 $(
340 unsafe impl Pod for $struct_name { }
341 )+
342 }
343}
344
345unsafe_impl_pod!(u8, u16, u32, u64);
346
347#[cfg(test)]
348mod tests {
349 use super::*;
350
351 #[test]
352 fn single() {
353 let x = u32::to_be(0x0123_4567);
354 let bytes = bytes_of(&x);
355 assert_eq!(bytes, [0x01, 0x23, 0x45, 0x67]);
356
357 let x16 = [u16::to_be(0x0123), u16::to_be(0x4567)];
358
359 let (y, tail) = from_bytes::<u32>(bytes).unwrap();
360 assert_eq!(*y, x);
361 assert_eq!(tail, &[]);
362
363 let (y, tail) = from_bytes::<u16>(bytes).unwrap();
364 assert_eq!(*y, x16[0]);
365 assert_eq!(tail, &bytes[2..]);
366
367 let (y, tail) = from_bytes::<u16>(&bytes[2..]).unwrap();
368 assert_eq!(*y, x16[1]);
369 assert_eq!(tail, &[]);
370
371 assert_eq!(from_bytes::<u16>(&bytes[1..]), Err(()));
372 assert_eq!(from_bytes::<u16>(&bytes[3..]), Err(()));
373 assert_eq!(from_bytes::<u16>(&bytes[4..]), Err(()));
374 }
375
376 #[test]
377 fn slice() {
378 let x = u64::to_be(0x0123_4567_89ab_cdef);
379 let bytes = bytes_of(&x);
380 assert_eq!(bytes, [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]);
381
382 let x16 = [
383 u16::to_be(0x0123),
384 u16::to_be(0x4567),
385 u16::to_be(0x89ab),
386 u16::to_be(0xcdef),
387 ];
388
389 let (y, tail) = slice_from_bytes::<u16>(&bytes, 4).unwrap();
390 assert_eq!(y, x16);
391 assert_eq!(tail, &[]);
392
393 let (y, tail) = slice_from_bytes::<u16>(&bytes[2..], 2).unwrap();
394 assert_eq!(y, &x16[1..3]);
395 assert_eq!(tail, &bytes[6..]);
396
397 assert_eq!(slice_from_bytes::<u16>(&bytes, 5), Err(()));
398 assert_eq!(slice_from_bytes::<u16>(&bytes[2..], 4), Err(()));
399 assert_eq!(slice_from_bytes::<u16>(&bytes[1..], 2), Err(()));
400 }
401
402 #[test]
403 fn bytes() {
404 let x = u32::to_be(0x0123_4567);
405 let data = Bytes(bytes_of(&x));
406
407 let mut bytes = data;
408 assert_eq!(bytes.skip(0), Ok(()));
409 assert_eq!(bytes, data);
410
411 let mut bytes = data;
412 assert_eq!(bytes.skip(4), Ok(()));
413 assert_eq!(bytes, Bytes(&[]));
414
415 let mut bytes = data;
416 assert_eq!(bytes.skip(5), Err(()));
417 assert_eq!(bytes, Bytes(&[]));
418
419 let mut bytes = data;
420 assert_eq!(bytes.read_bytes(0), Ok(Bytes(&[])));
421 assert_eq!(bytes, data);
422
423 let mut bytes = data;
424 assert_eq!(bytes.read_bytes(4), Ok(data));
425 assert_eq!(bytes, Bytes(&[]));
426
427 let mut bytes = data;
428 assert_eq!(bytes.read_bytes(5), Err(()));
429 assert_eq!(bytes, Bytes(&[]));
430
431 assert_eq!(data.read_bytes_at(0, 0), Ok(Bytes(&[])));
432 assert_eq!(data.read_bytes_at(4, 0), Ok(Bytes(&[])));
433 assert_eq!(data.read_bytes_at(0, 4), Ok(data));
434 assert_eq!(data.read_bytes_at(1, 4), Err(()));
435
436 let mut bytes = data;
437 assert_eq!(bytes.read::<u16>(), Ok(&u16::to_be(0x0123)));
438 assert_eq!(bytes, Bytes(&[0x45, 0x67]));
439 assert_eq!(data.read_at::<u16>(2), Ok(&u16::to_be(0x4567)));
440 assert_eq!(data.read_at::<u16>(3), Err(()));
441 assert_eq!(data.read_at::<u16>(4), Err(()));
442
443 let mut bytes = data;
444 assert_eq!(bytes.read::<u32>(), Ok(&x));
445 assert_eq!(bytes, Bytes(&[]));
446
447 let mut bytes = data;
448 assert_eq!(bytes.read::<u64>(), Err(()));
449 assert_eq!(bytes, Bytes(&[]));
450
451 let mut bytes = data;
452 assert_eq!(bytes.read_slice::<u8>(0), Ok(&[][..]));
453 assert_eq!(bytes, data);
454
455 let mut bytes = data;
456 assert_eq!(bytes.read_slice::<u8>(4), Ok(data.0));
457 assert_eq!(bytes, Bytes(&[]));
458
459 let mut bytes = data;
460 assert_eq!(bytes.read_slice::<u8>(5), Err(()));
461 assert_eq!(bytes, Bytes(&[]));
462
463 assert_eq!(data.read_slice_at::<u8>(0, 0), Ok(&[][..]));
464 assert_eq!(data.read_slice_at::<u8>(4, 0), Ok(&[][..]));
465 assert_eq!(data.read_slice_at::<u8>(0, 4), Ok(data.0));
466 assert_eq!(data.read_slice_at::<u8>(1, 4), Err(()));
467
468 let data = Bytes(&[0x01, 0x02, 0x00, 0x04]);
469
470 let mut bytes = data;
471 assert_eq!(bytes.read_string(), Ok(&data.0[..2]));
472 assert_eq!(bytes.0, &data.0[3..]);
473
474 let mut bytes = data;
475 bytes.skip(3).unwrap();
476 assert_eq!(bytes.read_string(), Err(()));
477 assert_eq!(bytes.0, &[]);
478
479 assert_eq!(data.read_string_at(0), Ok(&data.0[..2]));
480 assert_eq!(data.read_string_at(1), Ok(&data.0[1..2]));
481 assert_eq!(data.read_string_at(2), Ok(&[][..]));
482 assert_eq!(data.read_string_at(3), Err(()));
483 }
484
485 #[test]
486 fn bytes_mut() {
487 let data = BytesMut(vec![0x01, 0x23, 0x45, 0x67]);
488
489 let mut bytes = data.clone();
490 bytes.write(&u16::to_be(0x89ab));
491 assert_eq!(bytes.0, [0x01, 0x23, 0x45, 0x67, 0x89, 0xab]);
492
493 let mut bytes = data.clone();
494 assert_eq!(bytes.write_at(0, &u16::to_be(0x89ab)), Ok(()));
495 assert_eq!(bytes.0, [0x89, 0xab, 0x45, 0x67]);
496
497 let mut bytes = data.clone();
498 assert_eq!(bytes.write_at(2, &u16::to_be(0x89ab)), Ok(()));
499 assert_eq!(bytes.0, [0x01, 0x23, 0x89, 0xab]);
500
501 assert_eq!(bytes.write_at(3, &u16::to_be(0x89ab)), Err(()));
502 assert_eq!(bytes.write_at(4, &u16::to_be(0x89ab)), Err(()));
503 assert_eq!(
504 BytesMut::default().write_at(0, &u32::to_be(0x89ab)),
505 Err(())
506 );
507 }
508
509 #[test]
510 fn bytes_debug() {
511 assert_eq!(format!("{:?}", Bytes(&[])), "[]");
512 assert_eq!(format!("{:?}", Bytes(&[0x01])), "[0x01]");
513 assert_eq!(
514 format!(
515 "{:?}",
516 Bytes(&[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08])
517 ),
518 "[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]"
519 );
520 assert_eq!(
521 format!(
522 "{:?}",
523 Bytes(&[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09])
524 ),
525 "[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, ...; 9]"
526 );
527
528 assert_eq!(format!("{:?}", BytesMut(vec![])), "[]");
529 assert_eq!(
530 format!(
531 "{:?}",
532 BytesMut(vec![0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09])
533 ),
534 "[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, ...; 9]"
535 );
536 }
537}