]>
Commit | Line | Data |
---|---|---|
fe692bf9 FG |
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. | |
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 | ||
49 | impl<Endian> Writer for EndianVec<Endian> | |
50 | where | |
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)] | |
85 | mod 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 | } |