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
|
The maximum supported file size is 8GiB. Also, directories are not supported yet but only flat
|
||||||
collections of files.
|
collections of files.
|
||||||
"""
|
"""
|
||||||
version = "0.1.1"
|
version = "0.1.2"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
keywords = ["tar", "tarball", "archive"]
|
keywords = ["tar", "tarball", "archive"]
|
||||||
categories = ["data-structures", "no-std", "parser-implementations"]
|
categories = ["data-structures", "no-std", "parser-implementations"]
|
||||||
|
@ -26,11 +26,15 @@ fn main() {
|
|||||||
std::env::set_var("RUST_LOG", "trace");
|
std::env::set_var("RUST_LOG", "trace");
|
||||||
env_logger::init();
|
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 = include_bytes!("../tests/gnu_tar_default.tar");
|
||||||
let archive = TarArchive::new(archive);
|
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<_>>();
|
let entries = archive.entries().collect::<Vec<_>>();
|
||||||
println!("{:#?}", entries);
|
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");
|
std::env::set_var("RUST_LOG", "trace");
|
||||||
env_logger::init();
|
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 = include_bytes!("../tests/gnu_tar_default.tar");
|
||||||
let archive = TarArchive::new(archive);
|
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<_>>();
|
let entries = archive.entries().collect::<Vec<_>>();
|
||||||
println!("{:#?}", entries);
|
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)
|
// fetch data of file from next block(s)
|
||||||
let block_count = hdr.payload_block_count();
|
let data_block_count = hdr.payload_block_count();
|
||||||
let i_begin = self.block_index * BLOCKSIZE;
|
// +1: skip hdr block itself and start at data!
|
||||||
let i_end = i_begin + block_count * BLOCKSIZE;
|
// i_begin is the byte begin index of this file in the array of the whole archive
|
||||||
debug_assert!(i_end <= self.archive.data.len(), "index ouf of range!");
|
let i_begin = (self.block_index + 1) * BLOCKSIZE;
|
||||||
// +1: hdr itself + data blocks
|
// i_end is the exclusive byte end index of the data of the current file
|
||||||
self.block_index += block_count + 1;
|
let i_end = i_begin + data_block_count * BLOCKSIZE;
|
||||||
|
|
||||||
let file_block_bytes = &self.archive.data[i_begin..i_end];
|
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()];
|
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(
|
Some(ArchiveEntry::new(
|
||||||
ArrayString::from_str(hdr.name.as_string().as_str()).unwrap(),
|
ArrayString::from_str(hdr.name.as_string().as_str()).unwrap(),
|
||||||
file_bytes,
|
file_bytes,
|
||||||
@ -182,6 +186,7 @@ impl<'a> Iterator for ArchiveIterator<'a> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use core::str;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -230,11 +235,26 @@ mod tests {
|
|||||||
assert_eq!(entries[0].filename().as_str(), "bye_world_513b.txt");
|
assert_eq!(entries[0].filename().as_str(), "bye_world_513b.txt");
|
||||||
assert_eq!(entries[0].size(), 513);
|
assert_eq!(entries[0].size(), 513);
|
||||||
assert_eq!(entries[0].data().len(), 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].filename().as_str(), "hello_world_513b.txt");
|
||||||
assert_eq!(entries[1].size(), 513);
|
assert_eq!(entries[1].size(), 513);
|
||||||
assert_eq!(entries[1].data().len(), 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].filename().as_str(), "hello_world.txt");
|
||||||
assert_eq!(entries[2].size(), 12);
|
assert_eq!(entries[2].size(), 12);
|
||||||
assert_eq!(entries[2].data().len(), 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.
|
//! 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
|
//! [This link](https://www.gnu.org/software/tar/manual/html_section/Formats.html) gives a good overview over possible
|
||||||
//! archive formats and their limitations.
|
//! 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)]
|
#![cfg_attr(not(test), no_std)]
|
||||||
#![deny(rustdoc::all)]
|
#![deny(rustdoc::all)]
|
||||||
|
Loading…
Reference in New Issue
Block a user