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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use {
crate::{package_info::PackageInfo, PkgResult},
cpio_archive::ChainedCpioReader,
std::io::{Cursor, Read},
};
const GZIP_HEADER: [u8; 3] = [0x1f, 0x8b, 0x08];
fn decode_archive(data: Vec<u8>) -> PkgResult<Box<dyn Read>> {
if data.len() > 3 && data[0..3] == GZIP_HEADER {
Ok(Box::new(flate2::read::GzDecoder::new(Cursor::new(data))) as Box<dyn Read>)
} else {
Ok(Box::new(Cursor::new(data)) as Box<dyn Read>)
}
}
pub type CpioReader = Box<ChainedCpioReader<Box<dyn Read>>>;
fn cpio_reader(data: &[u8]) -> PkgResult<CpioReader> {
let decoder = decode_archive(data.to_vec())?;
Ok(cpio_archive::reader(decoder)?)
}
pub struct ComponentPackageReader {
bom: Option<Vec<u8>>,
package_info: Option<PackageInfo>,
payload: Option<Vec<u8>>,
scripts: Option<Vec<u8>>,
}
impl ComponentPackageReader {
pub fn from_file_data(
bom: Option<Vec<u8>>,
package_info: Option<Vec<u8>>,
payload: Option<Vec<u8>>,
scripts: Option<Vec<u8>>,
) -> PkgResult<Self> {
let package_info = if let Some(data) = package_info {
Some(PackageInfo::from_reader(Cursor::new(data))?)
} else {
None
};
Ok(Self {
bom,
package_info,
payload,
scripts,
})
}
pub fn bom(&self) -> Option<&[u8]> {
self.bom.as_ref().map(|x| x.as_ref())
}
pub fn package_info(&self) -> Option<&PackageInfo> {
self.package_info.as_ref()
}
pub fn payload_reader(&self) -> PkgResult<Option<CpioReader>> {
if let Some(payload) = &self.payload {
Ok(Some(cpio_reader(payload)?))
} else {
Ok(None)
}
}
pub fn scripts_reader(&self) -> PkgResult<Option<CpioReader>> {
if let Some(data) = &self.scripts {
Ok(Some(cpio_reader(data)?))
} else {
Ok(None)
}
}
}