Crates.io | basic_tar |
lib.rs | basic_tar |
version | 0.1.1 |
source | src |
created_at | 2019-08-05 01:31:15.68193 |
updated_at | 2019-08-05 02:03:38.220645 |
description | Building blocks to read and write classic oldstyle tar archives and streams |
homepage | |
repository | https://github.com/KizzyCode/basic_tar |
max_upload_size | |
id | 154204 |
size | 45,636 |
Welcome to basic_tar
🎉
This crate provides some functionality to read and write basic/classic oldstyle tar archives and
some extensions for io::Read
and io::Write
to make it easier to work with tar streams.
Note: It is not intended as an high-level allround (un-)packer but as a building block of you want
to use the tar format for your own applications – for a high-level solution, take a look at
tar
To read a tar record from an archive stream, you need to read
use std::{ convert::TryFrom, error::Error, io::Read };
use basic_tar::{
ReadExt, U64Ext, Header,
raw::{ self, BLOCK_LEN }
};
/// Reads the next record from `stream`
fn read_next(mut stream: impl Read) -> Result<(Header, Vec<u8>), Box<dyn Error + 'static>> {
// Read the header
let mut header_raw = raw::header::raw();
stream.read_exact(&mut header_raw)?;
// Parse the header and get the payload lengths
let header = Header::parse(header_raw)?;
let payload_len = header.size;
let payload_total_len = payload_len.ceil_to_multiple_of(BLOCK_LEN as u64);
// Read the payload
let mut payload = vec![0; usize::try_from(payload_len)?];
stream.read_exact(&mut payload)?;
// Drain the padding and return the record
let padding_len = usize::try_from(payload_total_len - payload_len)?;
stream.try_drain(padding_len, |_| {})?;
Ok((header, payload))
}
To write a tar record to an archive stream, you need to write
use std::{ convert::TryFrom, error::Error, io::Write };
use basic_tar::{ WriteExt, U64Ext, Header, raw::BLOCK_LEN };
/// Writes `header` and `payload` to `stream`
fn write_next(header: Header, payload: &[u8], mut stream: impl Write)
-> Result<(), Box<dyn Error + 'static>>
{
// Serialize the header and write it and the payload
let header_raw = header.serialize()?;
stream.write_all(&header_raw)?;
stream.write_all(payload)?;
// Write the padding
let payload_len = payload.len() as u64;
let padding_len = payload_len.ceil_to_multiple_of(BLOCK_LEN as u64) - payload_len;
stream.try_fill(usize::try_from(padding_len)?, |_| {})?;
Ok(())
}