1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
use std::fmt::Debug;
use byteorder::{LittleEndian, WriteBytesExt};
use failure::{Error, ResultExt};
pub use self::{
package::PackageBuf,
resources::ResourcesBuf,
string_table::{Encoding, StringTableBuf},
table_type::{ComplexEntry, ConfigurationBuf, Entry, EntryHeader, SimpleEntry, TableTypeBuf},
table_type_spec::TableTypeSpecBuf,
xml::{AttributeBuf, XmlNamespaceEndBuf, XmlNamespaceStartBuf, XmlTagEndBuf, XmlTagStartBuf},
};
mod package;
mod resources;
mod string_table;
mod table_type;
mod table_type_spec;
mod xml;
pub trait OwnedBuf: Debug {
fn get_token(&self) -> u16;
fn get_body_data(&self) -> Result<Vec<u8>, Error>;
fn get_header(&self) -> Result<Vec<u8>, Error> {
Ok(Vec::new())
}
fn to_vec(&self) -> Result<Vec<u8>, Error> {
let mut out = Vec::new();
let body = self.get_body_data().context("could not read chunk body")?;
self.write_header(&mut out, &body)
.context("could not write header")?;
out.extend(body.iter());
Ok(out)
}
fn write_header(&self, buffer: &mut Vec<u8>, body: &[u8]) -> Result<(), Error> {
let header = self.get_header()?;
let header_size = header.len() as u16 + 8;
buffer.write_u16::<LittleEndian>(self.get_token())?;
buffer.write_u16::<LittleEndian>(header_size)?;
buffer.write_u32::<LittleEndian>(body.len() as u32 + u32::from(header_size))?;
buffer.extend(&header);
Ok(())
}
}