Class: Omnizip::Formats::Zip::Reader
- Inherits:
-
Object
- Object
- Omnizip::Formats::Zip::Reader
- Includes:
- Constants
- Defined in:
- lib/omnizip/formats/zip/reader.rb
Overview
ZIP archive reader
Constant Summary
Constants included from Constants
Constants::ATTR_ARCHIVE, Constants::ATTR_DIRECTORY, Constants::CENTRAL_DIRECTORY_SIGNATURE, Constants::COMPRESSION_BZIP2, Constants::COMPRESSION_DEFLATE, Constants::COMPRESSION_DEFLATE64, Constants::COMPRESSION_IMPLODED, Constants::COMPRESSION_LZMA, Constants::COMPRESSION_PPMD, Constants::COMPRESSION_REDUCED_1, Constants::COMPRESSION_REDUCED_2, Constants::COMPRESSION_REDUCED_3, Constants::COMPRESSION_REDUCED_4, Constants::COMPRESSION_SHRUNK, Constants::COMPRESSION_STORE, Constants::COMPRESSION_ZSTANDARD, Constants::DATA_DESCRIPTOR_SIGNATURE, Constants::END_OF_CENTRAL_DIRECTORY_SIGNATURE, Constants::FLAG_DATA_DESCRIPTOR, Constants::FLAG_ENCRYPTED, Constants::FLAG_STRONG_ENCRYPTION, Constants::FLAG_UTF8, Constants::LOCAL_FILE_HEADER_SIGNATURE, Constants::MAX_COMMENT_LENGTH, Constants::UNIX_DIR_PERMISSIONS, Constants::UNIX_EXTRA_FIELD_TAG, Constants::UNIX_FILE_PERMISSIONS, Constants::UNIX_SYMLINK_PERMISSIONS, Constants::VERSION_BZIP2, Constants::VERSION_DEFAULT, Constants::VERSION_DEFLATE, Constants::VERSION_LZMA, Constants::VERSION_MADE_BY_UNIX, Constants::VERSION_MADE_BY_WINDOWS, Constants::VERSION_ZIP64, Constants::ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIGNATURE, Constants::ZIP64_END_OF_CENTRAL_DIRECTORY_SIGNATURE, Constants::ZIP64_EXTRA_FIELD_TAG, Constants::ZIP64_LIMIT
Instance Attribute Summary collapse
-
#file_path ⇒ Object
readonly
Returns the value of attribute file_path.
Instance Method Summary collapse
-
#decompress(compressed_data, method, uncompressed_size) ⇒ String
Decompress
compressed_dataaccording tomethod. -
#entries ⇒ Object
All entries, parsing on first use — a Reader is usable immediately; #read remains for explicit eager loading.
-
#extract_all(output_dir, preserve_links: true, dereference_links: false) ⇒ Object
Extract all files to a directory.
-
#extract_entry(entry, output_dir, preserve_links: true, dereference_links: false) ⇒ Object
Extract a specific entry.
-
#extract_symlink(entry, output_dir) ⇒ Object
Extract a symbolic link.
-
#initialize(file_path) ⇒ Reader
constructor
A new instance of Reader.
-
#list_entries(show_links: false) ⇒ Object
List all entries in the archive.
-
#read ⇒ Object
Read and parse the ZIP archive.
-
#read_entry(entry_name) ⇒ String
Read an entry's decompressed content into a String.
-
#read_from_io(io) ⇒ Object
Read from an IO object.
Constructor Details
#initialize(file_path) ⇒ Reader
Returns a new instance of Reader.
14 15 16 17 18 |
# File 'lib/omnizip/formats/zip/reader.rb', line 14 def initialize(file_path) @file_path = file_path @entries = [] @central_directory = [] end |
Instance Attribute Details
#file_path ⇒ Object (readonly)
Returns the value of attribute file_path.
12 13 14 |
# File 'lib/omnizip/formats/zip/reader.rb', line 12 def file_path @file_path end |
Instance Method Details
#decompress(compressed_data, method, uncompressed_size) ⇒ String
Decompress compressed_data according to method. Public API
for callers (e.g., ParallelExtractor) that hold raw compressed
payload outside an entry stream.
132 133 134 |
# File 'lib/omnizip/formats/zip/reader.rb', line 132 def decompress(compressed_data, method, uncompressed_size) decompress_data(compressed_data, method, uncompressed_size) end |
#entries ⇒ Object
All entries, parsing on first use — a Reader is usable immediately; #read remains for explicit eager loading
41 42 43 44 |
# File 'lib/omnizip/formats/zip/reader.rb', line 41 def entries ensure_read @entries end |
#extract_all(output_dir, preserve_links: true, dereference_links: false) ⇒ Object
Extract all files to a directory
47 48 49 50 51 52 53 |
# File 'lib/omnizip/formats/zip/reader.rb', line 47 def extract_all(output_dir, preserve_links: true, dereference_links: false) entries.each do |entry| extract_entry(entry, output_dir, preserve_links: preserve_links, dereference_links: dereference_links) end end |
#extract_entry(entry, output_dir, preserve_links: true, dereference_links: false) ⇒ Object
Extract a specific entry
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/omnizip/formats/zip/reader.rb', line 56 def extract_entry(entry, output_dir, preserve_links: true, dereference_links: false) output_path = File.join(output_dir, entry.filename) if entry.directory? FileUtils.mkdir_p(output_path) elsif preserve_links && !dereference_links && entry.symlink? extract_symlink(entry, output_dir) else FileUtils.mkdir_p(File.dirname(output_path)) decompressed_data = read_entry_data(entry) # Write decompressed data File.binwrite(output_path, decompressed_data) # Set file permissions if Unix if entry..positive? File.chmod(entry. & 0o777, output_path) end end end |
#extract_symlink(entry, output_dir) ⇒ Object
Extract a symbolic link
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/omnizip/formats/zip/reader.rb', line 80 def extract_symlink(entry, output_dir) output_path = File.join(output_dir, entry.filename) unless LinkHandler.symlink_supported? warn "Warning: Symbolic links not supported on #{RUBY_PLATFORM}, extracting as regular file" extract_entry(entry, output_dir, preserve_links: false) return end target = entry.link_target unless target warn "Warning: No link target found for #{entry.filename}, skipping" return end FileUtils.mkdir_p(File.dirname(output_path)) # Remove existing file/link if present FileUtils.rm_f(output_path) if File.exist?(output_path) || File.symlink?(output_path) LinkHandler.create_symlink(target, output_path) end |
#list_entries(show_links: false) ⇒ Object
List all entries in the archive
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/omnizip/formats/zip/reader.rb', line 104 def list_entries(show_links: false) entries.map do |entry| info = { filename: entry.filename, compressed_size: entry.compressed_size, uncompressed_size: entry.uncompressed_size, compression_method: compression_method_name(entry.compression_method), crc32: entry.crc32, directory: entry.directory?, } if show_links && entry.symlink? info[:symlink] = true info[:link_target] = entry.link_target end info end end |
#read ⇒ Object
Read and parse the ZIP archive
21 22 23 24 25 26 |
# File 'lib/omnizip/formats/zip/reader.rb', line 21 def read File.open(file_path, "rb") do |io| read_from_io(io) end self end |
#read_entry(entry_name) ⇒ String
Read an entry's decompressed content into a String. Directory entries return an empty string; symlinks return their target path.
143 144 145 146 147 148 149 150 151 152 |
# File 'lib/omnizip/formats/zip/reader.rb', line 143 def read_entry(entry_name) ensure_read entry = @entries.find { |e| e.filename == entry_name } raise Errno::ENOENT, "Entry not found: #{entry_name}" unless entry return "" if entry.directory? return entry.link_target if entry.symlink? read_entry_data(entry) end |
#read_from_io(io) ⇒ Object
Read from an IO object
29 30 31 32 33 34 35 36 37 |
# File 'lib/omnizip/formats/zip/reader.rb', line 29 def read_from_io(io) # Find and read End of Central Directory eocd = EndOfCentralDirectory.find_in_file(io) # Read Central Directory read_central_directory(io, eocd) self end |