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