Skip to content

Commit

Permalink
add to_and_from_le! macro
Browse files Browse the repository at this point in the history
  • Loading branch information
cosmicexplorer committed May 24, 2024
1 parent 83cdbad commit 03c92a1
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 203 deletions.
156 changes: 47 additions & 109 deletions src/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,24 @@ macro_rules! to_le {
};
}

/* TODO: derive macro to generate these fields? */
/// Implement `from_le()` and `to_le()`, providing the field specification to both macros
/// and methods.
macro_rules! to_and_from_le {
($($args:tt),+ $(,)?) => {
#[inline(always)]
fn from_le(mut self) -> Self {
from_le![self, [$($args),+]];
self
}
#[inline(always)]
fn to_le(mut self) -> Self {
to_le![self, [$($args),+]];
self
}
};
}

#[derive(Copy, Clone, Debug)]
#[repr(packed)]
pub struct Zip32CDEBlock {
Expand All @@ -166,41 +184,16 @@ impl Block for Zip32CDEBlock {

const ERROR: ZipError = ZipError::InvalidArchive("Invalid digital signature header");

#[inline(always)]
fn from_le(mut self) -> Self {
from_le![
self,
[
(magic, Magic),
(disk_number, u16),
(disk_with_central_directory, u16),
(number_of_files_on_this_disk, u16),
(number_of_files, u16),
(central_directory_size, u32),
(central_directory_offset, u32),
(zip_file_comment_length, u16)
]
];
self
}

#[inline(always)]
fn to_le(mut self) -> Self {
to_le![
self,
[
(magic, Magic),
(disk_number, u16),
(disk_with_central_directory, u16),
(number_of_files_on_this_disk, u16),
(number_of_files, u16),
(central_directory_size, u32),
(central_directory_offset, u32),
(zip_file_comment_length, u16)
]
];
self
}
to_and_from_le![
(magic, Magic),
(disk_number, u16),
(disk_with_central_directory, u16),
(number_of_files_on_this_disk, u16),
(number_of_files, u16),
(central_directory_size, u32),
(central_directory_offset, u32),
(zip_file_comment_length, u16)
];
}

#[derive(Debug)]
Expand Down Expand Up @@ -368,33 +361,12 @@ impl Block for Zip64CDELocatorBlock {
const ERROR: ZipError =
ZipError::InvalidArchive("Invalid zip64 locator digital signature header");

#[inline(always)]
fn from_le(mut self) -> Self {
from_le![
self,
[
(magic, Magic),
(disk_with_central_directory, u32),
(end_of_central_directory_offset, u64),
(number_of_disks, u32),
]
];
self
}

#[inline(always)]
fn to_le(mut self) -> Self {
to_le![
self,
[
(magic, Magic),
(disk_with_central_directory, u32),
(end_of_central_directory_offset, u64),
(number_of_disks, u32),
]
];
self
}
to_and_from_le![
(magic, Magic),
(disk_with_central_directory, u32),
(end_of_central_directory_offset, u64),
(number_of_disks, u32),
];
}

pub struct Zip64CentralDirectoryEndLocator {
Expand Down Expand Up @@ -463,45 +435,18 @@ impl Block for Zip64CDEBlock {

const ERROR: ZipError = ZipError::InvalidArchive("Invalid digital signature header");

#[inline(always)]
fn from_le(mut self) -> Self {
from_le![
self,
[
(magic, Magic),
(record_size, u64),
(version_made_by, u16),
(version_needed_to_extract, u16),
(disk_number, u32),
(disk_with_central_directory, u32),
(number_of_files_on_this_disk, u64),
(number_of_files, u64),
(central_directory_size, u64),
(central_directory_offset, u64),
]
];
self
}

#[inline(always)]
fn to_le(mut self) -> Self {
to_le![
self,
[
(magic, Magic),
(record_size, u64),
(version_made_by, u16),
(version_needed_to_extract, u16),
(disk_number, u32),
(disk_with_central_directory, u32),
(number_of_files_on_this_disk, u64),
(number_of_files, u64),
(central_directory_size, u64),
(central_directory_offset, u64),
]
];
self
}
to_and_from_le![
(magic, Magic),
(record_size, u64),
(version_made_by, u16),
(version_needed_to_extract, u16),
(disk_number, u32),
(disk_with_central_directory, u32),
(number_of_files_on_this_disk, u64),
(number_of_files, u64),
(central_directory_size, u64),
(central_directory_offset, u64),
];
}

pub struct Zip64CentralDirectoryEnd {
Expand Down Expand Up @@ -730,14 +675,7 @@ mod test {

const ERROR: ZipError = ZipError::InvalidArchive("unreachable");

fn from_le(mut self) -> Self {
from_le![self, [(magic, Magic), (file_name_length, u16)]];
self
}
fn to_le(mut self) -> Self {
to_le![self, [(magic, Magic), (file_name_length, u16)]];
self
}
to_and_from_le![(magic, Magic), (file_name_length, u16)];
}

/// Demonstrate that a block object can be safely written to memory and deserialized back out.
Expand Down
126 changes: 32 additions & 94 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -820,59 +820,25 @@ impl Block for ZipEntryBlock {

const ERROR: ZipError = ZipError::InvalidArchive("Invalid Central Directory header");

#[inline(always)]
fn from_le(mut self) -> Self {
from_le![
self,
[
(magic, spec::Magic),
(version_made_by, u16),
(version_to_extract, u16),
(flags, u16),
(compression_method, u16),
(last_mod_time, u16),
(last_mod_date, u16),
(crc32, u32),
(compressed_size, u32),
(uncompressed_size, u32),
(file_name_length, u16),
(extra_field_length, u16),
(file_comment_length, u16),
(disk_number, u16),
(internal_file_attributes, u16),
(external_file_attributes, u32),
(offset, u32),
]
];
self
}

#[inline(always)]
fn to_le(mut self) -> Self {
to_le![
self,
[
(magic, spec::Magic),
(version_made_by, u16),
(version_to_extract, u16),
(flags, u16),
(compression_method, u16),
(last_mod_time, u16),
(last_mod_date, u16),
(crc32, u32),
(compressed_size, u32),
(uncompressed_size, u32),
(file_name_length, u16),
(extra_field_length, u16),
(file_comment_length, u16),
(disk_number, u16),
(internal_file_attributes, u16),
(external_file_attributes, u32),
(offset, u32),
]
];
self
}
to_and_from_le![
(magic, spec::Magic),
(version_made_by, u16),
(version_to_extract, u16),
(flags, u16),
(compression_method, u16),
(last_mod_time, u16),
(last_mod_date, u16),
(crc32, u32),
(compressed_size, u32),
(uncompressed_size, u32),
(file_name_length, u16),
(extra_field_length, u16),
(file_comment_length, u16),
(disk_number, u16),
(internal_file_attributes, u16),
(external_file_attributes, u32),
(offset, u32),
];
}

#[derive(Copy, Clone, Debug)]
Expand Down Expand Up @@ -901,47 +867,19 @@ impl Block for ZipLocalEntryBlock {

const ERROR: ZipError = ZipError::InvalidArchive("Invalid local file header");

#[inline(always)]
fn from_le(mut self) -> Self {
from_le![
self,
[
(magic, spec::Magic),
(version_made_by, u16),
(flags, u16),
(compression_method, u16),
(last_mod_time, u16),
(last_mod_date, u16),
(crc32, u32),
(compressed_size, u32),
(uncompressed_size, u32),
(file_name_length, u16),
(extra_field_length, u16),
]
];
self
}

#[inline(always)]
fn to_le(mut self) -> Self {
to_le![
self,
[
(magic, spec::Magic),
(version_made_by, u16),
(flags, u16),
(compression_method, u16),
(last_mod_time, u16),
(last_mod_date, u16),
(crc32, u32),
(compressed_size, u32),
(uncompressed_size, u32),
(file_name_length, u16),
(extra_field_length, u16),
]
];
self
}
to_and_from_le![
(magic, spec::Magic),
(version_made_by, u16),
(flags, u16),
(compression_method, u16),
(last_mod_time, u16),
(last_mod_date, u16),
(crc32, u32),
(compressed_size, u32),
(uncompressed_size, u32),
(file_name_length, u16),
(extra_field_length, u16),
];
}

/// The encryption specification used to encrypt a file with AES.
Expand Down

0 comments on commit 03c92a1

Please sign in to comment.