]> git.proxmox.com Git - rustc.git/blob - vendor/object/src/write/util.rs
New upstream version 1.57.0+dfsg1
[rustc.git] / vendor / object / src / write / util.rs
1 use std::vec::Vec;
2
3 use crate::pod::{bytes_of, bytes_of_slice, Pod};
4
5 /// Trait for writable buffer.
6 #[allow(clippy::len_without_is_empty)]
7 pub trait WritableBuffer {
8 /// Returns position/offset for data to be written at.
9 fn len(&self) -> usize;
10
11 /// Reserves specified number of bytes in the buffer.
12 fn reserve(&mut self, additional: usize) -> Result<(), ()>;
13
14 /// Writes the specified value at the end of the buffer
15 /// until the buffer has the specified length.
16 fn resize(&mut self, new_len: usize, value: u8);
17
18 /// Writes the specified slice of bytes at the end of the buffer.
19 fn write_bytes(&mut self, val: &[u8]);
20
21 /// Writes the specified `Pod` type at the end of the buffer.
22 fn write_pod<T: Pod>(&mut self, val: &T)
23 where
24 Self: Sized,
25 {
26 self.write_bytes(bytes_of(val))
27 }
28
29 /// Writes the specified `Pod` slice at the end of the buffer.
30 fn write_pod_slice<T: Pod>(&mut self, val: &[T])
31 where
32 Self: Sized,
33 {
34 self.write_bytes(bytes_of_slice(val))
35 }
36 }
37
38 impl<'a> dyn WritableBuffer + 'a {
39 /// Writes the specified `Pod` type at the end of the buffer.
40 pub fn write<T: Pod>(&mut self, val: &T) {
41 self.write_bytes(bytes_of(val))
42 }
43
44 /// Writes the specified `Pod` slice at the end of the buffer.
45 pub fn write_slice<T: Pod>(&mut self, val: &[T]) {
46 self.write_bytes(bytes_of_slice(val))
47 }
48 }
49
50 impl WritableBuffer for Vec<u8> {
51 #[inline]
52 fn len(&self) -> usize {
53 self.len()
54 }
55
56 #[inline]
57 fn reserve(&mut self, additional: usize) -> Result<(), ()> {
58 self.reserve(additional);
59 Ok(())
60 }
61
62 #[inline]
63 fn resize(&mut self, new_len: usize, value: u8) {
64 self.resize(new_len, value);
65 }
66
67 #[inline]
68 fn write_bytes(&mut self, val: &[u8]) {
69 self.extend_from_slice(val)
70 }
71 }
72
73 /// A trait for mutable byte slices.
74 ///
75 /// It provides convenience methods for `Pod` types.
76 pub(crate) trait BytesMut {
77 fn write_at<T: Pod>(self, offset: usize, val: &T) -> Result<(), ()>;
78 }
79
80 impl<'a> BytesMut for &'a mut [u8] {
81 #[inline]
82 fn write_at<T: Pod>(self, offset: usize, val: &T) -> Result<(), ()> {
83 let src = bytes_of(val);
84 let dest = self.get_mut(offset..).ok_or(())?;
85 let dest = dest.get_mut(..src.len()).ok_or(())?;
86 dest.copy_from_slice(src);
87 Ok(())
88 }
89 }
90
91 pub(crate) fn align(offset: usize, size: usize) -> usize {
92 (offset + (size - 1)) & !(size - 1)
93 }
94
95 #[allow(dead_code)]
96 pub(crate) fn align_u64(offset: u64, size: u64) -> u64 {
97 (offset + (size - 1)) & !(size - 1)
98 }
99
100 pub(crate) fn write_align(buffer: &mut dyn WritableBuffer, size: usize) {
101 let new_len = align(buffer.len(), size);
102 buffer.resize(new_len, 0);
103 }
104
105 #[cfg(test)]
106 mod tests {
107 use super::*;
108
109 #[test]
110 fn bytes_mut() {
111 let data = vec![0x01, 0x23, 0x45, 0x67];
112
113 let mut bytes = data.clone();
114 bytes.extend_from_slice(bytes_of(&u16::to_be(0x89ab)));
115 assert_eq!(bytes, [0x01, 0x23, 0x45, 0x67, 0x89, 0xab]);
116
117 let mut bytes = data.clone();
118 assert_eq!(bytes.write_at(0, &u16::to_be(0x89ab)), Ok(()));
119 assert_eq!(bytes, [0x89, 0xab, 0x45, 0x67]);
120
121 let mut bytes = data.clone();
122 assert_eq!(bytes.write_at(2, &u16::to_be(0x89ab)), Ok(()));
123 assert_eq!(bytes, [0x01, 0x23, 0x89, 0xab]);
124
125 assert_eq!(bytes.write_at(3, &u16::to_be(0x89ab)), Err(()));
126 assert_eq!(bytes.write_at(4, &u16::to_be(0x89ab)), Err(()));
127 assert_eq!(vec![].write_at(0, &u32::to_be(0x89ab)), Err(()));
128 }
129 }