Add "magic" to file start
This commit is contained in:
parent
f2fff3ce76
commit
ce7fe5f019
@ -68,10 +68,15 @@ by 8, the third byte by 16 and the fourth byte by 24, and the bits combined
|
||||
into a single 32-bit uint. This is dramatically more efficient than storing
|
||||
those numbers as ascii text, as is done by Tar.
|
||||
|
||||
The first 7 bytes of a haggis file make up the "magic" identifier, consisting
|
||||
of the string "\x89haggis". To be clear, that is the integer `0x89` plus
|
||||
"haggis". The first file header immediately follows this string.
|
||||
|
||||
| **bytes** | **meaning** |
|
||||
| ----- | ------- |
|
||||
| 0-8 | The length of the filename (64 bit unsigned int) |
|
||||
| 8 to the length specified above | The bytes making up the filename |
|
||||
| 0-6 | "\x89haggis" - the haggis "magic" identifier |
|
||||
| 7-15 | The **length** of the filename (64 bit unsigned int) |
|
||||
| the next **length** bytes | The bytes making up the filename |
|
||||
| the next 4 bytes | The files Unix permissions mode (32 bit unsigned int) |
|
||||
| the next 4 bytes | The uid of the file's owner (32 bit unsigned int) |
|
||||
| the next 4 bytes | the gid of the file's owner (32 bit unsigned int) |
|
||||
|
@ -10,6 +10,7 @@ pub enum Error {
|
||||
Slice(TryFromSliceError),
|
||||
InvalidChecksum,
|
||||
InvalidAlgorithm,
|
||||
InvalidMagic,
|
||||
MissingData,
|
||||
MutexError,
|
||||
NulError,
|
||||
@ -28,6 +29,7 @@ impl fmt::Display for Error {
|
||||
Self::Io(e) => write!(f, "{e}"),
|
||||
Self::InvalidAlgorithm => write!(f, "invalid algorithm"),
|
||||
Self::InvalidChecksum => write!(f, "invalid checksum"),
|
||||
Self::InvalidMagic => write!(f, "invalid magic"),
|
||||
Self::MissingData => write!(f, "missing data"),
|
||||
Self::MutexError => write!(f, "mutex error"),
|
||||
Self::NulError => write!(f, "nul error"),
|
||||
|
@ -30,6 +30,8 @@ pub use {
|
||||
stream::Stream,
|
||||
};
|
||||
|
||||
pub static MAGIC: [u8; 7] = [0x89, b'h', b'a', b'g', b'g', b'i', b's' ];
|
||||
|
||||
/// Creates a haggis archive from a list of files
|
||||
pub fn create_archive(path: &str, files: Vec<String>, algorithm: Algorithm) -> Result<(), Error> {
|
||||
let fd = fs::OpenOptions::new()
|
||||
@ -48,6 +50,7 @@ pub fn stream_archive<W: Write>(
|
||||
algorithm: Algorithm,
|
||||
) -> Result<(), Error> {
|
||||
let links = Mutex::new(HashMap::new());
|
||||
writer.write_all(&MAGIC)?;
|
||||
for f in &files {
|
||||
let node = Node::from_path(f, algorithm, &links)?;
|
||||
node.write(&mut writer)?;
|
||||
@ -82,11 +85,12 @@ pub fn par_create_archive(
|
||||
/// Streams a Haggis archive from a list of files, processing each file in parallel
|
||||
#[cfg(feature = "parallel")]
|
||||
pub fn par_stream_archive<W: Write + Send>(
|
||||
writer: W,
|
||||
mut writer: W,
|
||||
files: Vec<String>,
|
||||
algorithm: Algorithm,
|
||||
sender: &Sender<Message>,
|
||||
) -> Result<(), Error> {
|
||||
writer.write_all(&MAGIC)?;
|
||||
let links = Mutex::new(HashMap::<u64, String>::new());
|
||||
let writer = Mutex::new(writer);
|
||||
let s = sender.clone();
|
||||
|
@ -1,3 +1,5 @@
|
||||
use crate::MAGIC;
|
||||
|
||||
use {
|
||||
crate::{Error, Node},
|
||||
std::{
|
||||
@ -14,17 +16,11 @@ use {
|
||||
/// An iterator over a series of archive `Node`'s. This struct is generic over any
|
||||
/// type which implements `Read`, such as a file or a network stream.
|
||||
#[derive(Debug)]
|
||||
pub struct Stream<T: Read + Send> {
|
||||
reader: T,
|
||||
pub struct Stream<R: Read + Send> {
|
||||
reader: R,
|
||||
}
|
||||
|
||||
impl<T: Read + Send> From<T> for Stream<T> {
|
||||
fn from(value: T) -> Self {
|
||||
Self { reader: value }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Read + Send> Iterator for Stream<T> {
|
||||
impl<R: Read + Send> Iterator for Stream<R> {
|
||||
type Item = Result<Node, Error>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
@ -50,7 +46,17 @@ pub enum Message {
|
||||
Eof,
|
||||
}
|
||||
|
||||
impl<T: Read + Send> Stream<T> {
|
||||
impl<R: Read + Send> Stream<R> {
|
||||
pub fn new(mut reader: R) -> Result<Self, Error> {
|
||||
let mut buf = [0; 7];
|
||||
reader.read_exact(&mut buf)?;
|
||||
if buf == MAGIC {
|
||||
Ok(Self { reader })
|
||||
} else {
|
||||
Err(Error::InvalidMagic)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extract(&mut self, prefix: Option<&str>) -> Result<(), Error> {
|
||||
for node in self {
|
||||
node?.extract(prefix)?;
|
||||
|
Loading…
Reference in New Issue
Block a user