rs_zip2asn2data2concat/
lib.rs

1use std::io;
2
3use io::Read;
4use io::Seek;
5
6use io::BufWriter;
7use io::Write;
8
9use std::fs::File;
10
11use der::asn1::OctetString;
12
13pub use der;
14pub use zip;
15
16use zip::ZipArchive;
17use zip::read::ZipFile;
18
19use der::Decode;
20
21#[derive(Debug, PartialEq, Eq, Clone, Copy, der::Enumerated)]
22#[repr(u8)]
23pub enum CompressionMethod {
24    Unspecified = 0,
25    Store = 100,
26    Deflate = 108,
27}
28
29impl Default for CompressionMethod {
30    fn default() -> Self {
31        Self::Unspecified
32    }
33}
34
35#[derive(Default, der::Sequence)]
36pub struct ZipMeta {
37    pub filename: String,
38    pub comment: String,
39    pub modified_unixtime: u32,
40    pub compression: CompressionMethod,
41    pub is_dir: bool,
42}
43
44#[derive(der::Sequence)]
45pub struct ZipItem {
46    pub meta: ZipMeta,
47    pub data: OctetString,
48}
49
50impl ZipItem {
51    pub fn slice2items(s: &[u8]) -> Result<Vec<Self>, io::Error> {
52        <Vec<Self> as Decode>::from_der(s).map_err(io::Error::other)
53    }
54
55    pub fn rdr2items<R>(rdr: &mut R, buf: &mut Vec<u8>) -> Result<Vec<Self>, io::Error>
56    where
57        R: Read,
58    {
59        buf.clear();
60        io::copy(rdr, buf)?;
61        Self::slice2items(buf)
62    }
63}
64
65impl ZipItem {
66    pub fn items2data2concat2writer<W>(items: &[Self], wtr: &mut W) -> Result<(), io::Error>
67    where
68        W: Write,
69    {
70        for item in items {
71            let dat: &[u8] = item.data.as_bytes();
72            wtr.write_all(dat)?;
73        }
74        Ok(())
75    }
76}
77
78pub fn zip2files2items2writer<R, W>(
79    mut z: ZipArchive<R>,
80    mut wtr: W,
81    buf: &mut Vec<u8>,
82) -> Result<(), io::Error>
83where
84    R: Read + Seek,
85    W: Write,
86{
87    let sz: usize = z.len();
88    for i in 0..sz {
89        let mut zfile: ZipFile<_> = z.by_index(i).map_err(io::Error::other)?;
90        let items: Vec<ZipItem> = ZipItem::rdr2items(&mut zfile, buf)?;
91        ZipItem::items2data2concat2writer(&items, &mut wtr)?;
92    }
93    wtr.flush()?;
94    Ok(())
95}
96
97pub fn zipfile2items2stdout(zfile: File) -> Result<(), io::Error> {
98    let za: ZipArchive<_> = ZipArchive::new(zfile).map_err(io::Error::other)?;
99    let mut buf: Vec<u8> = vec![];
100
101    let o = io::stdout();
102    let mut ol = o.lock();
103
104    let bw = BufWriter::new(&mut ol);
105    zip2files2items2writer(za, bw, &mut buf)?;
106
107    ol.flush()
108}