Skip to main content

rs_tar2sqlite/
tar.rs

1use std::borrow::Cow;
2use std::io;
3use std::path::Path;
4
5use io::Read;
6
7use tar::Archive;
8use tar::Entry;
9use tar::Header;
10
11use crate::core::TarEntry;
12
13pub fn header2size(hdr: &Header) -> Result<u64, io::Error> {
14    hdr.size()
15}
16
17pub fn header2mode(hdr: &Header) -> Result<u32, io::Error> {
18    hdr.mode()
19}
20
21pub fn header2mtime(hdr: &Header) -> Result<u64, io::Error> {
22    hdr.mtime()
23}
24
25pub fn ent2path<'a, R>(ent: &'a Entry<R>) -> Result<Cow<'a, Path>, io::Error>
26where
27    R: Read,
28{
29    ent.path()
30}
31
32pub fn ent2hdr<'a, R>(ent: &'a Entry<R>) -> &'a Header
33where
34    R: Read,
35{
36    ent.header()
37}
38
39pub fn ent2data<R>(ent: &mut Entry<R>, buf: &mut Vec<u8>, limit: u64) -> Result<usize, io::Error>
40where
41    R: Read,
42{
43    buf.clear();
44    let mut taken = ent.take(limit);
45    taken.read_to_end(buf)
46}
47
48pub fn copy<R>(src: &mut Entry<R>, dst: &mut TarEntry, limit: u64) -> Result<usize, io::Error>
49where
50    R: Read,
51{
52    let hdr: &Header = ent2hdr(src);
53
54    let mode: u32 = header2mode(hdr)?;
55    let unixtime: u64 = header2mtime(hdr)?;
56
57    let pat: &Path = &ent2path(src)?;
58    let ostr: Option<&str> = pat.to_str();
59    let upat: &str = ostr.ok_or(io::Error::other("invalid path"))?;
60    dst.name.clear();
61    dst.name.push_str(upat);
62
63    let usz: usize = ent2data(src, &mut dst.data, limit)?;
64
65    dst.mode = mode;
66    dst.modified_unixtime = unixtime;
67    dst.size = usz as u64;
68
69    Ok(usz)
70}
71
72pub fn reader2tar2entries2wtr<R, W>(rdr: R, wtr: &mut W, limit: u64) -> Result<(), io::Error>
73where
74    R: Read,
75    W: FnMut(&TarEntry) -> Result<(), io::Error>,
76{
77    let mut ta = Archive::new(rdr);
78    let entries = ta.entries()?;
79    let mut buf = TarEntry::default();
80    for rent in entries {
81        let mut ent = rent?;
82        copy(&mut ent, &mut buf, limit)?;
83        wtr(&buf)?;
84    }
85    Ok(())
86}