3 use crate::pod
::{bytes_of, bytes_of_slice, Pod}
;
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;
11 /// Reserves specified number of bytes in the buffer.
12 fn reserve(&mut self, additional
: usize) -> Result
<(), ()>;
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);
18 /// Writes the specified slice of bytes at the end of the buffer.
19 fn write_bytes(&mut self, val
: &[u8]);
21 /// Writes the specified `Pod` type at the end of the buffer.
22 fn write_pod
<T
: Pod
>(&mut self, val
: &T
)
26 self.write_bytes(bytes_of(val
))
29 /// Writes the specified `Pod` slice at the end of the buffer.
30 fn write_pod_slice
<T
: Pod
>(&mut self, val
: &[T
])
34 self.write_bytes(bytes_of_slice(val
))
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
))
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
))
50 impl WritableBuffer
for Vec
<u8> {
52 fn len(&self) -> usize {
57 fn reserve(&mut self, additional
: usize) -> Result
<(), ()> {
58 self.reserve(additional
);
63 fn resize(&mut self, new_len
: usize, value
: u8) {
64 self.resize(new_len
, value
);
68 fn write_bytes(&mut self, val
: &[u8]) {
69 self.extend_from_slice(val
)
73 /// A trait for mutable byte slices.
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
<(), ()>;
80 impl<'a
> BytesMut
for &'a
mut [u8] {
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
);
91 pub(crate) fn align(offset
: usize, size
: usize) -> usize {
92 (offset
+ (size
- 1)) & !(size
- 1)
96 pub(crate) fn align_u64(offset
: u64, size
: u64) -> u64 {
97 (offset
+ (size
- 1)) & !(size
- 1)
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);
111 let data
= vec
![0x01, 0x23, 0x45, 0x67];
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]);
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]);
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]);
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(()));