Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allocate fewer binaries #22

Merged
merged 1 commit into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
186 changes: 91 additions & 95 deletions lib/zstream/protocol.ex
Original file line number Diff line number Diff line change
Expand Up @@ -18,49 +18,43 @@ defmodule Zstream.Protocol do
)

[
# local file header signature
<<0x04034B50::little-size(32)>>,
# version needed to extract
<<zip64?(options, 20, 45)::little-size(16)>>,
general_purpose_bit_flag(options),
# compression method
<<compression_method(options)::little-size(16)>>,
# last mod file time
<<dos_time(Keyword.fetch!(options, :mtime))::little-size(16)>>,
# last mod file date
<<dos_date(Keyword.fetch!(options, :mtime))::little-size(16)>>,
# crc-32
<<0::little-size(32)>>,
# compressed size
<<0::little-size(32)>>,
# uncompressed size
<<0::little-size(32)>>,
# file name length
<<byte_size(name)::little-size(16)>>,
# extra field length
<<IO.iodata_length(extra_field)::little-size(16)>>,
<<
# local file header signature
0x04034B50::little-size(32),
# version needed to extract
zip64?(options, 20, 45)::little-size(16),
general_purpose_bit_flag(options)::little-size(16),
# compression method
compression_method(options)::little-size(16),
# last mod file time
dos_time(Keyword.fetch!(options, :mtime))::little-size(16),
# last mod file date
dos_date(Keyword.fetch!(options, :mtime))::little-size(16),
# crc-32
0::little-size(32),
# compressed size
0::little-size(32),
# uncompressed size
0::little-size(32),
# file name length
byte_size(name)::little-size(16),
# extra field length
IO.iodata_length(extra_field)::little-size(16)
>>,
name,
extra_field
]
end

def data_descriptor(crc32, compressed_size, uncompressed_size, options) do
if Keyword.fetch!(options, :zip64) do
[
# signature
<<0x08074B50::little-size(32)>>,
<<crc32::little-size(32)>>,
<<compressed_size::little-size(64)>>,
<<uncompressed_size::little-size(64)>>
]
# signature
<<0x08074B50::little-size(32), crc32::little-size(32), compressed_size::little-size(64),
uncompressed_size::little-size(64)>>
else
[
# signature
<<0x08074B50::little-size(32)>>,
<<crc32::little-size(32)>>,
<<compressed_size::little-size(32)>>,
<<uncompressed_size::little-size(32)>>
]
# signature
<<0x08074B50::little-size(32), crc32::little-size(32), compressed_size::little-size(32),
uncompressed_size::little-size(32)>>
end
end

Expand All @@ -75,37 +69,39 @@ defmodule Zstream.Protocol do
)

[
# central file header signature
<<0x02014B50::little-size(32)>>,
# version made by
<<52::little-size(16)>>,
# version needed to extract
<<zip64?(options, 20, 45)::little-size(16)>>,
general_purpose_bit_flag(entry.options),
# compression method
<<compression_method(entry.options)::little-size(16)>>,
# last mod file time
<<dos_time(Keyword.fetch!(entry.options, :mtime))::little-size(16)>>,
# last mod file date
<<dos_date(Keyword.fetch!(entry.options, :mtime))::little-size(16)>>,
# crc-32
<<entry.crc::little-size(32)>>,
# compressed size
<<zip64?(options, entry.c_size, 0xFFFFFFFF)::little-size(32)>>,
# uncompressed size
<<zip64?(options, entry.size, 0xFFFFFFFF)::little-size(32)>>,
# file name length
<<byte_size(entry.name)::little-size(16)>>,
# extra field length
<<IO.iodata_length(extra_field)::little-size(16)>>,
# file comment length
<<0::little-size(16)>>,
# disk number start
<<zip64?(options, 0, 0xFFFF)::little-size(16)>>,
# internal file attributes
<<0::little-size(16)>>,
<<external_file_attributes()::little-size(32)>>,
<<zip64?(options, entry.local_file_header_offset, 0xFFFFFFFF)::little-size(32)>>,
<<
# central file header signature
0x02014B50::little-size(32),
# version made by
52::little-size(16),
# version needed to extract
zip64?(options, 20, 45)::little-size(16),
general_purpose_bit_flag(entry.options)::little-size(16),
# compression method
compression_method(entry.options)::little-size(16),
# last mod file time
dos_time(Keyword.fetch!(entry.options, :mtime))::little-size(16),
# last mod file date
dos_date(Keyword.fetch!(entry.options, :mtime))::little-size(16),
# crc-32
entry.crc::little-size(32),
# compressed size
zip64?(options, entry.c_size, 0xFFFFFFFF)::little-size(32),
# uncompressed size
zip64?(options, entry.size, 0xFFFFFFFF)::little-size(32),
# file name length
byte_size(entry.name)::little-size(16),
# extra field length
IO.iodata_length(extra_field)::little-size(16),
# file comment length
0::little-size(16),
# disk number start
zip64?(options, 0, 0xFFFF)::little-size(16),
# internal file attributes
0::little-size(16),
external_file_attributes()::little-size(32),
zip64?(options, entry.local_file_header_offset, 0xFFFFFFFF)::little-size(32)
>>,
# file name
entry.name,
extra_field
Expand All @@ -114,70 +110,70 @@ defmodule Zstream.Protocol do

def zip64_end_of_central_directory_record(offset, size, entries_count, options) do
if Keyword.fetch!(options, :zip64) do
[
<<
# signature
<<0x06064B50::little-size(32)>>,
0x06064B50::little-size(32),
# size of zip64 end of central directory record
<<44::little-size(64)>>,
44::little-size(64),
# version made by
<<52::little-size(16)>>,
52::little-size(16),
# version needed to extract
<<45::little-size(16)>>,
45::little-size(16),
# number of this disk
<<0::little-size(32)>>,
0::little-size(32),
# number of the disk with the start of the central directory
<<0::little-size(32)>>,
0::little-size(32),
# total number of entries in the central directory on this disk
<<entries_count::little-size(64)>>,
entries_count::little-size(64),
# total number of entries in the central directory
<<entries_count::little-size(64)>>,
entries_count::little-size(64),
# size of the central directory
<<size::little-size(64)>>,
size::little-size(64),
# offset of start of central directory with respect to the starting disk number
<<offset::little-size(64)>>
]
offset::little-size(64)
>>
else
<<>>
end
end

def zip64_end_of_central_directory_locator(offset, options) do
if Keyword.fetch!(options, :zip64) do
[
<<
# signature
<<0x07064B50::little-size(32)>>,
0x07064B50::little-size(32),
# number of the disk with the start of the zip64 end of central directory
<<0::little-size(32)>>,
0::little-size(32),
# relative offset of the zip64 end of central directory record
<<offset::little-size(64)>>,
offset::little-size(64),
# total number of disks
<<1::little-size(32)>>
]
1::little-size(32)
>>
else
<<>>
end
end

def end_of_central_directory(offset, size, entries_count, options) do
[
<<
# end of central dir signature
<<0x06054B50::little-size(32)>>,
0x06054B50::little-size(32),
# number of this disk
<<zip64?(options, 0, 0xFFFF)::little-size(16)>>,
zip64?(options, 0, 0xFFFF)::little-size(16),
# number of the disk with the start of the central directory
<<zip64?(options, 0, 0xFFFF)::little-size(16)>>,
zip64?(options, 0, 0xFFFF)::little-size(16),
# total number of entries in the central directory on this disk
<<zip64?(options, entries_count, 0xFFFF)::little-size(16)>>,
zip64?(options, entries_count, 0xFFFF)::little-size(16),
# total number of entries in the central directory
<<zip64?(options, entries_count, 0xFFFF)::little-size(16)>>,
zip64?(options, entries_count, 0xFFFF)::little-size(16),
# size of the central directory
<<zip64?(options, size, 0xFFFFFFFF)::little-size(32)>>,
zip64?(options, size, 0xFFFFFFFF)::little-size(32),
# offset of start of central directory with respect to the starting disk number
<<zip64?(options, offset, 0xFFFFFFFF)::little-size(32)>>,
zip64?(options, offset, 0xFFFFFFFF)::little-size(32),
# .ZIP file comment length
<<byte_size(@comment)::little-size(16)>>,
byte_size(@comment)::little-size(16),
@comment
]
>>
end

defp general_purpose_bit_flag(options) do
Expand All @@ -186,7 +182,7 @@ defmodule Zstream.Protocol do
# encryption bit set based on coder
# bit 3 use data descriptor
# bit 11 UTF-8 encoding of filename & comment fields
<<encryption_coder.general_purpose_flag() ||| 0x0008 ||| 0x0800::little-size(16)>>
encryption_coder.general_purpose_flag() ||| 0x0008 ||| 0x0800
ananthakumaran marked this conversation as resolved.
Show resolved Hide resolved
end

defp external_file_attributes do
Expand Down
10 changes: 2 additions & 8 deletions lib/zstream/zip/extra.ex
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,7 @@ defmodule Zstream.Zip.Extra do
# Local Header for the original file size will be zero.

def zip64_extended_info(size, c_size, offset) do
[
<<0x0001::little-size(16)>>,
<<28::little-size(16)>>,
<<size::little-size(64)>>,
<<c_size::little-size(64)>>,
<<offset::little-size(64)>>,
<<0::little-size(32)>>
]
<<0x0001::little-size(16), 28::little-size(16), size::little-size(64),
c_size::little-size(64), offset::little-size(64), 0::little-size(32)>>
end
end
Loading