diff --git a/README.md b/README.md index 2356f81..c8e050b 100644 --- a/README.md +++ b/README.md @@ -19,11 +19,24 @@ GNU Extensions such as sparse files, incremental archives, and long filename ext [This link](https://www.gnu.org/software/tar/manual/html_section/Formats.html) gives a good overview over possible archive formats and their limitations. +## Example +```rust +fn main() { + // log: not mandatory + std::env::set_var("RUST_LOG", "trace"); + env_logger::init(); + // also works in no_std environment + let archive = include_bytes!("../tests/gnu_tar_default.tar"); + let archive = TarArchive::new(archive); + let entries = archive.entries().collect::>(); + println!("{:#?}", entries); +} +``` ## Compression -If your tar file is compressed, e.g. bei `gzip`, you need to uncompress the bytes first (e.g. by a *deflate* algorithm), -before +If your tar file is compressed, e.g. bei `.tar.gz`/`gzip`, you need to uncompress the bytes first +(e.g. by a *gzip* library). Afterwards, this crate can read and write the Tar archive format from the bytes. ## MSRV The MSRV is 1.51.0 stable. diff --git a/src/archive.rs b/src/archive.rs index 9366705..4e13412 100644 --- a/src/archive.rs +++ b/src/archive.rs @@ -30,7 +30,7 @@ use core::fmt::{Debug, Formatter}; use core::ptr; use core::str::FromStr; -/// Describes an entry in a archive. +/// Describes an entry in an archive. /// Currently only supports files but no directories. pub struct ArchiveEntry<'a> { filename: ArrayString<100>, @@ -40,7 +40,7 @@ pub struct ArchiveEntry<'a> { #[allow(unused)] impl<'a> ArchiveEntry<'a> { - pub fn new(filename: ArrayString<100>, data: &'a [u8]) -> Self { + pub const fn new(filename: ArrayString<100>, data: &'a [u8]) -> Self { ArchiveEntry { filename, data, @@ -49,17 +49,17 @@ impl<'a> ArchiveEntry<'a> { } /// Filename of the entry. Max 99 characters. - pub fn filename(&self) -> ArrayString<100> { + pub const fn filename(&self) -> ArrayString<100> { self.filename } /// Data of the file. - pub fn data(&self) -> &'a [u8] { + pub const fn data(&self) -> &'a [u8] { self.data } /// Filesize in bytes. - pub fn size(&self) -> usize { + pub const fn size(&self) -> usize { self.size } } @@ -95,7 +95,7 @@ impl<'a> TarArchive<'a> { /// Iterates over all entries of the TAR Archive. /// Returns items of type [`ArchiveEntry`]. - pub fn entries(&self) -> ArchiveIterator { + pub const fn entries(&self) -> ArchiveIterator { ArchiveIterator::new(self) } } @@ -109,7 +109,7 @@ pub struct ArchiveIterator<'a> { } impl<'a> ArchiveIterator<'a> { - pub fn new(archive: &'a TarArchive<'a>) -> Self { + pub const fn new(archive: &'a TarArchive<'a>) -> Self { Self { archive, block_index: 0, @@ -117,7 +117,7 @@ impl<'a> ArchiveIterator<'a> { } /// Returns a pointer to the next Header. - fn next_hdr(&self, block_index: usize) -> *const PosixHeader { + const fn next_hdr(&self, block_index: usize) -> *const PosixHeader { let hdr_ptr = &self.archive.data[block_index * BLOCKSIZE]; let hdr_ptr = hdr_ptr as *const u8; hdr_ptr as *const PosixHeader @@ -157,6 +157,10 @@ impl<'a> Iterator for ArchiveIterator<'a> { return None; } + if hdr.name.is_empty() { + log::warn!("Found empty file name",); + } + // fetch data of file from next block(s) let block_count = hdr.payload_block_count(); let i_begin = self.block_index * BLOCKSIZE; diff --git a/src/header.rs b/src/header.rs index a37b9ba..ffb333d 100644 --- a/src/header.rs +++ b/src/header.rs @@ -83,7 +83,7 @@ pub struct StaticCString([u8; N]); #[allow(unused)] impl StaticCString { /// Constructor. - fn new(bytes: [u8; N]) -> Self { + const fn new(bytes: [u8; N]) -> Self { Self(bytes) } @@ -93,6 +93,11 @@ impl StaticCString { self.as_string().len() } + /// Returns if the string without NULL-byte is empty. + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + /// Returns a string without null bytes. pub fn as_string(&self) -> ArrayString { let mut string = ArrayString::new(); @@ -114,7 +119,7 @@ impl Debug for StaticCString { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { let mut debug = f.debug_tuple("Name"); let str = self.as_string(); - if str.len() == 0 { + if str.is_empty() { debug.field(&""); } else { debug.field(&str); diff --git a/src/lib.rs b/src/lib.rs index 8739814..cd35e9e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,6 +40,11 @@ SOFTWARE. //! archive formats and their limitations. #![cfg_attr(not(test), no_std)] +#![deny(rustdoc::all)] +#![allow(rustdoc::missing_doc_code_examples)] +#![deny(clippy::all)] +#![deny(clippy::missing_const_for_fn)] +#![deny(missing_debug_implementations)] #[cfg_attr(test, macro_use)] #[cfg(test)]