1 use alloc::vec::Vec;
2 use std::mem;
3 
4 use crate::endianity::Endianity;
5 use 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)]
11 pub struct EndianVec<Endian>
12 where
13     Endian: Endianity,
14 {
15     vec: Vec<u8>,
16     endian: Endian,
17 }
18 
19 impl<Endian> EndianVec<Endian>
20 where
21     Endian: Endianity,
22 {
23     /// Construct an empty `EndianVec` with the given endianity.
new(endian: Endian) -> EndianVec<Endian>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.
slice(&self) -> &[u8]32     pub fn slice(&self) -> &[u8] {
33         &self.vec
34     }
35 
36     /// Convert into a `Vec<u8>`.
into_vec(self) -> 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.
take(&mut self) -> Vec<u8>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 
49 impl<Endian> Writer for EndianVec<Endian>
50 where
51     Endian: Endianity,
52 {
53     type Endian = Endian;
54 
55     #[inline]
endian(&self) -> Self::Endian56     fn endian(&self) -> Self::Endian {
57         self.endian
58     }
59 
60     #[inline]
len(&self) -> usize61     fn len(&self) -> usize {
62         self.vec.len()
63     }
64 
write(&mut self, bytes: &[u8]) -> Result<()>65     fn write(&mut self, bytes: &[u8]) -> Result<()> {
66         self.vec.extend(bytes);
67         Ok(())
68     }
69 
write_at(&mut self, offset: usize, bytes: &[u8]) -> Result<()>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)]
85 mod tests {
86     use super::*;
87     use crate::LittleEndian;
88 
89     #[test]
test_endian_vec()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