1use alloc::vec::Vec;
2use std::mem;
3
4use crate::endianity::Endianity;
5use crate::write::{Error, Result, Writer};
6
7/// A `Vec<u8>` with endianity metadata.
8///
9/// This implements the `Writer` trait, which is used for all writing of DWARF sections.
10#[derive(Debug, Clone)]
11pub struct EndianVec<Endian>
12where
13 Endian: Endianity,
14{
15 vec: Vec<u8>,
16 endian: Endian,
17}
18
19impl<Endian> EndianVec<Endian>
20where
21 Endian: Endianity,
22{
23 /// Construct an empty `EndianVec` with the given endianity.
24 pub fn new(endian: Endian) -> EndianVec<Endian> {
25 EndianVec {
26 vec: Vec::new(),
27 endian,
28 }
29 }
30
31 /// Return a reference to the raw slice.
32 pub fn slice(&self) -> &[u8] {
33 &self.vec
34 }
35
36 /// Convert into a `Vec<u8>`.
37 pub fn into_vec(self) -> Vec<u8> {
38 self.vec
39 }
40
41 /// Take any written data out of the `EndianVec`, leaving an empty `Vec` in its place.
42 pub fn take(&mut self) -> Vec<u8> {
43 let mut vec = Vec::new();
44 mem::swap(&mut self.vec, &mut vec);
45 vec
46 }
47}
48
49impl<Endian> Writer for EndianVec<Endian>
50where
51 Endian: Endianity,
52{
53 type Endian = Endian;
54
55 #[inline]
56 fn endian(&self) -> Self::Endian {
57 self.endian
58 }
59
60 #[inline]
61 fn len(&self) -> usize {
62 self.vec.len()
63 }
64
65 fn write(&mut self, bytes: &[u8]) -> Result<()> {
66 self.vec.extend(bytes);
67 Ok(())
68 }
69
70 fn write_at(&mut self, offset: usize, bytes: &[u8]) -> Result<()> {
71 if offset > self.vec.len() {
72 return Err(Error::OffsetOutOfBounds);
73 }
74 let to = &mut self.vec[offset..];
75 if bytes.len() > to.len() {
76 return Err(Error::LengthOutOfBounds);
77 }
78 let to = &mut to[..bytes.len()];
79 to.copy_from_slice(bytes);
80 Ok(())
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87 use crate::LittleEndian;
88
89 #[test]
90 fn test_endian_vec() {
91 let mut w = EndianVec::new(LittleEndian);
92 assert_eq!(w.endian(), LittleEndian);
93 assert_eq!(w.len(), 0);
94
95 w.write(&[1, 2]).unwrap();
96 assert_eq!(w.slice(), &[1, 2]);
97 assert_eq!(w.len(), 2);
98
99 w.write(&[3, 4, 5]).unwrap();
100 assert_eq!(w.slice(), &[1, 2, 3, 4, 5]);
101 assert_eq!(w.len(), 5);
102
103 w.write_at(0, &[6, 7]).unwrap();
104 assert_eq!(w.slice(), &[6, 7, 3, 4, 5]);
105 assert_eq!(w.len(), 5);
106
107 w.write_at(3, &[8, 9]).unwrap();
108 assert_eq!(w.slice(), &[6, 7, 3, 8, 9]);
109 assert_eq!(w.len(), 5);
110
111 assert_eq!(w.write_at(4, &[6, 7]), Err(Error::LengthOutOfBounds));
112 assert_eq!(w.write_at(5, &[6, 7]), Err(Error::LengthOutOfBounds));
113 assert_eq!(w.write_at(6, &[6, 7]), Err(Error::OffsetOutOfBounds));
114
115 assert_eq!(w.into_vec(), vec![6, 7, 3, 8, 9]);
116 }
117}
118