Skip to content

Commit

Permalink
Merge e813bb0 into fe754a4
Browse files Browse the repository at this point in the history
  • Loading branch information
wcampbell0x2a authored Oct 19, 2023
2 parents fe754a4 + e813bb0 commit 7ba92bd
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 47 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ categories = ["filesystem", "parsing"]

[dependencies]
# for lib
deku = { git = "https://github.com/sharksforarms/deku", branch = "impl-reader" }
deku = { git = "https://github.com/sharksforarms/deku", branch = "impl-writer" }
tracing = "0.1.37"
thiserror = "1.0.37"
flate2 = { version = "1.0.24", optional = true }
Expand Down
2 changes: 1 addition & 1 deletion src/bin/unsquashfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ fn main() -> ExitCode {
let mut file = BufReader::new(File::open(args.filesystem.as_ref().unwrap()).unwrap());

let blue_bold: console::Style = console::Style::new().blue().bold();
let red_bold: console::Style = console::Style::new().blue().bold();
let red_bold: console::Style = console::Style::new().red().bold();
let pb = ProgressBar::new_spinner();

if args.auto_offset {
Expand Down
60 changes: 32 additions & 28 deletions src/filesystem/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use std::sync::Arc;
use std::sync::Mutex;
use std::time::{SystemTime, UNIX_EPOCH};

use deku::bitvec::BitVec;
use deku::DekuWrite;
use deku::writer::Writer;
use deku::DekuWriter;
use tracing::{error, info, instrument, trace};

use super::node::{InnerNode, Nodes};
Expand Down Expand Up @@ -573,13 +573,13 @@ impl<'a, 'b> FilesystemWriter<'a, 'b> {
trace!("WRITING DIR: {block_offset:#02x?}");
let mut total_size: usize = 3;
for dir in Entry::into_dir(entries) {
let mut bv = BitVec::new();
dir.write(&mut bv, kind.inner.type_endian)?;
let bytes = bv.as_raw_slice();
dir_writer.write_all(bv.as_raw_slice())?;

let mut bytes = vec![];
let mut writer = Writer::new(&mut bytes);
dir.to_writer(&mut writer, kind.inner.type_endian)?;
total_size += bytes.len();
dir_writer.write_all(&bytes)?;
}
trace!("AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH total size: {total_size:02x?}");
let entry = Entry::path(
filename,
node.header,
Expand Down Expand Up @@ -622,17 +622,24 @@ impl<'a, 'b> FilesystemWriter<'a, 'b> {
// Write compression options, if any
if let Some(options) = &self.fs_compressor.options {
superblock.flags |= Flags::CompressorOptionsArePresent as u16;
let mut buf = BitVec::new();
let mut compression_opt_buf_out = vec![];
let mut writer = Writer::new(&mut compression_opt_buf_out);
match options {
CompressionOptions::Gzip(gzip) => {
gzip.write(&mut buf, self.kind.inner.type_endian)?
gzip.to_writer(&mut writer, self.kind.inner.type_endian)?
}
CompressionOptions::Lz4(lz4) => {
lz4.to_writer(&mut writer, self.kind.inner.type_endian)?
}
CompressionOptions::Lz4(lz4) => lz4.write(&mut buf, self.kind.inner.type_endian)?,
CompressionOptions::Zstd(zstd) => {
zstd.write(&mut buf, self.kind.inner.type_endian)?
zstd.to_writer(&mut writer, self.kind.inner.type_endian)?
}
CompressionOptions::Xz(xz) => {
xz.to_writer(&mut writer, self.kind.inner.type_endian)?
}
CompressionOptions::Lzo(lzo) => {
lzo.to_writer(&mut writer, self.kind.inner.type_endian)?
}
CompressionOptions::Xz(xz) => xz.write(&mut buf, self.kind.inner.type_endian)?,
CompressionOptions::Lzo(lzo) => lzo.write(&mut buf, self.kind.inner.type_endian)?,
CompressionOptions::Lzma => {}
}
let mut metadata = MetadataWriter::new(
Expand All @@ -642,7 +649,7 @@ impl<'a, 'b> FilesystemWriter<'a, 'b> {
inner: self.kind.inner.clone(),
},
);
metadata.write_all(buf.as_raw_slice())?;
metadata.write_all(&compression_opt_buf_out)?;
metadata.finalize(w)?;
}

Expand Down Expand Up @@ -754,17 +761,16 @@ impl<'a, 'b> FilesystemWriter<'a, 'b> {
// Seek back the beginning and write the superblock
info!("Writing Superblock");
w.rewind()?;
let mut bv = BitVec::new();
superblock.write(
&mut bv,
let mut writer = Writer::new(w);
superblock.to_writer(
&mut writer,
(
self.kind.inner.magic,
self.kind.inner.version_major,
self.kind.inner.version_minor,
self.kind.inner.type_endian,
),
)?;
w.write_all(bv.as_raw_slice())?;

info!("Writing Finished");

Expand Down Expand Up @@ -800,7 +806,7 @@ impl<'a, 'b> FilesystemWriter<'a, 'b> {
/// │└────────────────────────────┘│
/// └──────────────────────────────┘
/// ```
fn write_lookup_table<D: DekuWrite<deku::ctx::Endian>, W: Write + Seek>(
fn write_lookup_table<D: DekuWriter<deku::ctx::Endian>, W: Write + Seek>(
&self,
w: &mut W,
table: &Vec<D>,
Expand All @@ -810,20 +816,19 @@ impl<'a, 'b> FilesystemWriter<'a, 'b> {
let mut table_bytes = Vec::with_capacity(table.len() * element_size);
let mut iter = table.iter().peekable();
while let Some(t) = iter.next() {
let mut table_writer = Writer::new(&mut table_bytes);
// convert fragment ptr to bytes
let mut bv = BitVec::new();
t.write(&mut bv, self.kind.inner.type_endian)?;
table_bytes.write_all(bv.as_raw_slice())?;
t.to_writer(&mut table_writer, self.kind.inner.type_endian)?;

// once table_bytes + next is over the maximum size of a metadata block, write
if ((table_bytes.len() + element_size) > METADATA_MAXSIZE) || iter.peek().is_none() {
ptrs.push(w.stream_position()?);
//ptrs.push(start + (writer.bits_written as u64 / 8));

let mut bv = BitVec::new();
// write metadata len
let len = metadata::set_if_uncompressed(table_bytes.len() as u16);
len.write(&mut bv, self.kind.inner.data_endian)?;
w.write_all(bv.as_raw_slice())?;
let mut writer = Writer::new(w);
len.to_writer(&mut writer, self.kind.inner.data_endian)?;
// write metadata bytes
w.write_all(&table_bytes)?;

Expand All @@ -836,9 +841,8 @@ impl<'a, 'b> FilesystemWriter<'a, 'b> {

// write ptr
for ptr in ptrs {
let mut bv = BitVec::new();
ptr.write(&mut bv, self.kind.inner.type_endian)?;
w.write_all(bv.as_raw_slice())?;
let mut writer = Writer::new(w);
ptr.to_writer(&mut writer, self.kind.inner.type_endian)?;
}

Ok((table_position, count))
Expand Down
10 changes: 5 additions & 5 deletions src/inode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
use core::fmt;
use std::io::Write;

use deku::bitvec::{BitVec, Msb0};
use deku::prelude::*;

use crate::data::DataSize;
Expand Down Expand Up @@ -36,9 +35,10 @@ impl Inode {
superblock: &SuperBlock,
kind: &Kind,
) -> Entry<'a> {
let mut bytes = BitVec::<u8, Msb0>::new();
self.write(
&mut bytes,
let mut inode_bytes = vec![];
let mut writer = Writer::new(&mut inode_bytes);
self.to_writer(
&mut writer,
(
0xffff_ffff_ffff_ffff, // bytes_used is unused for ctx. set to max
superblock.block_size,
Expand All @@ -49,7 +49,7 @@ impl Inode {
.unwrap();
let start = m_writer.metadata_start;
let offset = m_writer.uncompressed_bytes.len() as u16;
m_writer.write_all(bytes.as_raw_slice()).unwrap();
m_writer.write_all(&inode_bytes).unwrap();

Entry {
start,
Expand Down
21 changes: 11 additions & 10 deletions src/metadata.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::collections::VecDeque;
use std::io::{self, Cursor, Read, Seek, Write};

use deku::bitvec::BitVec;
use deku::prelude::*;
use tracing::{instrument, trace};

Expand Down Expand Up @@ -41,6 +40,7 @@ impl MetadataWriter {

#[instrument(skip_all)]
fn add_block(&mut self) -> io::Result<()> {
trace!("adding block");
// uncompress data that will create the metablock
let uncompressed_len = self.uncompressed_bytes.len().min(METADATA_MAXSIZE);
if uncompressed_len == 0 {
Expand All @@ -63,9 +63,11 @@ impl MetadataWriter {

// Remove the data consumed, if the uncompressed data is smalled, use it.
let (compressed, metadata) = if compressed.len() > uncompressed_len {
trace!("using uncompressed");
let uncompressed = self.uncompressed_bytes.drain(0..uncompressed_len).collect();
(false, uncompressed)
} else {
trace!("using compressed");
self.uncompressed_bytes.drain(0..uncompressed_len);
(true, compressed)
};
Expand All @@ -75,7 +77,6 @@ impl MetadataWriter {
trace!("new metadata start: {:#02x?}", self.metadata_start);
self.final_bytes.push((compressed, metadata));

trace!("LEN: {:02x?}", self.uncompressed_bytes.len());
Ok(())
}

Expand All @@ -87,15 +88,15 @@ impl MetadataWriter {
}

// write all the metadata blocks
for (compressed, cb) in &self.final_bytes {
trace!("len: {:02x?}", cb.len());
//trace!("total: {:02x?}", out.len());
let mut bv = BitVec::new();
let mut writer = Writer::new(out);
for (compressed, compressed_bytes) in &self.final_bytes {
trace!("len: {:02x?}", compressed_bytes.len());
// if uncompressed, set the highest bit of len
let len = cb.len() as u16 | if *compressed { 0 } else { 1 << (u16::BITS - 1) };
len.write(&mut bv, self.kind.inner.data_endian)?;
out.write_all(bv.as_raw_slice())?;
out.write_all(cb)?;
let len =
compressed_bytes.len() as u16 | if *compressed { 0 } else { 1 << (u16::BITS - 1) };
len.to_writer(&mut writer, self.kind.inner.data_endian)?;
// TODO: this is one byte at a time, which is slow
compressed_bytes.to_writer(&mut writer, ())?;
}

Ok(())
Expand Down

0 comments on commit 7ba92bd

Please sign in to comment.