Bugfix (v0.1.2)
This commit is contained in:
parent
48bfc67213
commit
47bdfd1f85
@ -7,7 +7,7 @@ as GNU Longname. The maximum supported file name length is 100 characters includ
|
||||
The maximum supported file size is 8GiB. Also, directories are not supported yet but only flat
|
||||
collections of files.
|
||||
"""
|
||||
version = "0.1.1"
|
||||
version = "0.1.2"
|
||||
edition = "2018"
|
||||
keywords = ["tar", "tarball", "archive"]
|
||||
categories = ["data-structures", "no-std", "parser-implementations"]
|
||||
|
@ -26,11 +26,15 @@ fn main() {
|
||||
std::env::set_var("RUST_LOG", "trace");
|
||||
env_logger::init();
|
||||
|
||||
// also works in no_std environment
|
||||
// also works in no_std environment (except the println!, of course)
|
||||
let archive = include_bytes!("../tests/gnu_tar_default.tar");
|
||||
let archive = TarArchive::new(archive);
|
||||
// Vec needs an allocator of course, but the library itself doesn't need one
|
||||
let entries = archive.entries().collect::<Vec<_>>();
|
||||
println!("{:#?}", entries);
|
||||
println!("content of last file:");
|
||||
let last_file_content = unsafe { core::str::from_utf8_unchecked(entries[2].data()) };
|
||||
println!("{:#?}", last_file_content);
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -28,9 +28,13 @@ fn main() {
|
||||
std::env::set_var("RUST_LOG", "trace");
|
||||
env_logger::init();
|
||||
|
||||
// also works in no_std environment
|
||||
// also works in no_std environment (except the println!, of course)
|
||||
let archive = include_bytes!("../tests/gnu_tar_default.tar");
|
||||
let archive = TarArchive::new(archive);
|
||||
// Vec needs an allocator of course, but the library itself doesn't need one
|
||||
let entries = archive.entries().collect::<Vec<_>>();
|
||||
println!("{:#?}", entries);
|
||||
println!("content of last file:");
|
||||
let last_file_content = unsafe { core::str::from_utf8_unchecked(entries[2].data()) };
|
||||
println!("{:#?}", last_file_content);
|
||||
}
|
||||
|
@ -162,16 +162,20 @@ impl<'a> Iterator for ArchiveIterator<'a> {
|
||||
}
|
||||
|
||||
// fetch data of file from next block(s)
|
||||
let block_count = hdr.payload_block_count();
|
||||
let i_begin = self.block_index * BLOCKSIZE;
|
||||
let i_end = i_begin + block_count * BLOCKSIZE;
|
||||
debug_assert!(i_end <= self.archive.data.len(), "index ouf of range!");
|
||||
// +1: hdr itself + data blocks
|
||||
self.block_index += block_count + 1;
|
||||
|
||||
let data_block_count = hdr.payload_block_count();
|
||||
// +1: skip hdr block itself and start at data!
|
||||
// i_begin is the byte begin index of this file in the array of the whole archive
|
||||
let i_begin = (self.block_index + 1) * BLOCKSIZE;
|
||||
// i_end is the exclusive byte end index of the data of the current file
|
||||
let i_end = i_begin + data_block_count * BLOCKSIZE;
|
||||
let file_block_bytes = &self.archive.data[i_begin..i_end];
|
||||
// because each block is 512 bytes long, the file is not necessarily a multiple of 512 bytes
|
||||
let file_bytes = &file_block_bytes[0..hdr.size.val()];
|
||||
|
||||
// in next iteration: start at next Archive entry header
|
||||
// +1 for current hdr block itself + all data blocks
|
||||
self.block_index += data_block_count + 1;
|
||||
|
||||
Some(ArchiveEntry::new(
|
||||
ArrayString::from_str(hdr.name.as_string().as_str()).unwrap(),
|
||||
file_bytes,
|
||||
@ -182,6 +186,7 @@ impl<'a> Iterator for ArchiveIterator<'a> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use core::str;
|
||||
use std::vec::Vec;
|
||||
|
||||
#[test]
|
||||
@ -230,11 +235,26 @@ mod tests {
|
||||
assert_eq!(entries[0].filename().as_str(), "bye_world_513b.txt");
|
||||
assert_eq!(entries[0].size(), 513);
|
||||
assert_eq!(entries[0].data().len(), 513);
|
||||
assert_eq!(
|
||||
unsafe { str::from_utf8_unchecked(entries[0].data) },
|
||||
include_str!("../tests/bye_world_513b.txt")
|
||||
);
|
||||
|
||||
assert_eq!(entries[1].filename().as_str(), "hello_world_513b.txt");
|
||||
assert_eq!(entries[1].size(), 513);
|
||||
assert_eq!(entries[1].data().len(), 513);
|
||||
assert_eq!(
|
||||
unsafe { str::from_utf8_unchecked(entries[1].data) },
|
||||
include_str!("../tests/hello_world_513b.txt")
|
||||
);
|
||||
|
||||
assert_eq!(entries[2].filename().as_str(), "hello_world.txt");
|
||||
assert_eq!(entries[2].size(), 12);
|
||||
assert_eq!(entries[2].data().len(), 12);
|
||||
assert_eq!(
|
||||
unsafe { str::from_utf8_unchecked(entries[2].data) },
|
||||
"Hello World\n",
|
||||
"file content must match"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
21
src/lib.rs
21
src/lib.rs
@ -38,6 +38,27 @@ SOFTWARE.
|
||||
//! GNU Extensions such as sparse files, incremental archives, and long filename extension are not supported yet.
|
||||
//! [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
|
||||
//! use tar_no_std::TarArchive;
|
||||
//!
|
||||
//! fn main() {
|
||||
//! // log: not mandatory
|
||||
//! std::env::set_var("RUST_LOG", "trace");
|
||||
//! env_logger::init();
|
||||
//!
|
||||
//! // also works in no_std environment (except the println!, of course)
|
||||
//! let archive = include_bytes!("../tests/gnu_tar_default.tar");
|
||||
//! let archive = TarArchive::new(archive);
|
||||
//! // Vec needs an allocator of course, but the library itself doesn't need one
|
||||
//! let entries = archive.entries().collect::<Vec<_>>();
|
||||
//! println!("{:#?}", entries);
|
||||
//! println!("content of last file:");
|
||||
//! let last_file_content = unsafe { core::str::from_utf8_unchecked(entries[2].data()) };
|
||||
//! println!("{:#?}", last_file_content);
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
#![cfg_attr(not(test), no_std)]
|
||||
#![deny(rustdoc::all)]
|
||||
|
Loading…
Reference in New Issue
Block a user