Add Archive
struct to tar
This commit is contained in:
parent
a53cb726f9
commit
405ffd194f
109
tar/src/lib.rs
109
tar/src/lib.rs
@ -1,3 +1,5 @@
|
||||
use std::{fs::File, io::{self, BufReader}};
|
||||
|
||||
mod error;
|
||||
mod header;
|
||||
mod node;
|
||||
@ -10,3 +12,110 @@ pub use {
|
||||
pub struct Archive {
|
||||
pub nodes: Vec<Node>,
|
||||
}
|
||||
|
||||
impl Archive {
|
||||
/// Write out a vector of `TarNodes` to a file or something that implements ``std::io::Write`` and ``std::io::Copy``.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use std::fs::File;
|
||||
/// use tar::tar::TarFile;
|
||||
///
|
||||
/// let data = Archive::new("test/1.txt".to_string()).unwrap();
|
||||
///
|
||||
/// let out = File::create("test/2.tar".to_string()).unwrap();
|
||||
/// data.write(&out).unwrap();
|
||||
/// ```
|
||||
pub fn write<T: io::Write + Copy>(self, mut input: T) -> Result<usize, Error> {
|
||||
let mut written = 0;
|
||||
for f in self.nodes.clone() {
|
||||
written += f.write(input)?;
|
||||
}
|
||||
|
||||
/* Complete the write with 18 blocks of 512 ``0x00`` bytes per the specification */
|
||||
if !self.nodes.is_empty() {
|
||||
input.write_all(&[0; 9216])?;
|
||||
written += 9216;
|
||||
}
|
||||
|
||||
Ok(written)
|
||||
}
|
||||
|
||||
/// Create a new `TarFile` struct and initialize it with a `filename` file. This will read in the file to
|
||||
/// the `TarFile` struct as a `TarNode`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use tar::Archive;
|
||||
///
|
||||
/// let data = Archive::new("test/1.txt".to_string()).unwrap();
|
||||
/// ```
|
||||
pub fn new(filename: String) -> Result<Self, Error> {
|
||||
Ok(Self {
|
||||
nodes: vec![Node::read_file_to_tar(filename)?],
|
||||
})
|
||||
}
|
||||
|
||||
/// Append another file to the `TarFile.file` vector. This adds a file to the internal representation of the tar file.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use tar::Archive;
|
||||
///
|
||||
/// let mut data = Archive::new("test/1.txt".to_string()).unwrap();
|
||||
/// data.append("test/1.txt".to_string()).unwrap();
|
||||
/// ```
|
||||
pub fn append(&mut self, filename: String) -> Result<(), Error> {
|
||||
self.nodes.push(Node::read_file_to_tar(filename)?);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Open and load an external tar file into the internal `TarFile` struct. This parses and loads up all the files
|
||||
/// contained within the external tar file.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use tar::Archive;
|
||||
///
|
||||
/// Archive::open("test/1.tar".to_string()).unwrap();
|
||||
/// ```
|
||||
pub fn open(filename: String) -> Result<Self, Error> {
|
||||
let file = File::open(&filename)?;
|
||||
let mut reader = BufReader::new(file);
|
||||
let mut out = Self {
|
||||
nodes: Vec::<Node>::new(),
|
||||
};
|
||||
|
||||
while let Ok(t) = Node::read(&mut reader) {
|
||||
out.nodes.push(t);
|
||||
}
|
||||
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
/// Remove the first file from the Tar that matches the filename and path.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use minitar::tar::TarFile;
|
||||
///
|
||||
/// let mut data = TarFile::new("test/1.tar".to_string()).unwrap();
|
||||
/// data.remove("test/1.tar".to_string()).unwrap();
|
||||
/// ```
|
||||
pub fn remove(&mut self, filename: String) -> Result<bool, Error> {
|
||||
let mut name = [0u8; 100];
|
||||
name[..filename.len()].copy_from_slice(filename.as_bytes());
|
||||
if let Some(i) = &self.nodes.iter().position(|x| x.header.fname == name) {
|
||||
self.nodes.remove(*i);
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
@ -67,11 +67,7 @@ impl Node {
|
||||
}
|
||||
|
||||
/// Create a Node from in memory data, given the filename and metadata
|
||||
pub fn read_data_to_tar(
|
||||
data: &[u8],
|
||||
filename: &str,
|
||||
meta: &Metadata,
|
||||
) -> Result<Node, Error> {
|
||||
pub fn read_data_to_tar(data: &[u8], filename: &str, meta: &Metadata) -> Result<Node, Error> {
|
||||
let header = Header::new_from_meta(filename, meta)?;
|
||||
if header.link_indicator[0] != FileType::Normal as u8 {
|
||||
return Ok(Node {
|
||||
|
Loading…
Reference in New Issue
Block a user