Class: FormatParser::ZIPParser::FileReader
- Inherits:
-
Object
- Object
- FormatParser::ZIPParser::FileReader
- Defined in:
- lib/parsers/zip_parser/file_reader.rb
Overview
A very barebones ZIP file reader
Defined Under Namespace
Classes: ZipEntry
Constant Summary collapse
- Error =
Class.new(StandardError)
- ReadError =
Class.new(Error)
- UnsupportedFeature =
Class.new(Error)
- InvalidStructure =
Class.new(Error)
- LocalHeaderPending =
Class.new(Error) do def 'The compressed data offset is not available (local header has not been read)' end end
- MissingEOCD =
Class.new(Error) do def 'Could not find the EOCD signature in the buffer - maybe a malformed ZIP file' end end
- InvalidCentralDirectory =
Class.new(Error)
Instance Method Summary collapse
-
#read_zip_structure(io:) ⇒ Array<ZipEntry>
Parse an IO handle to a ZIP archive into an array of Entry objects.
Instance Method Details
#read_zip_structure(io:) ⇒ Array<ZipEntry>
Parse an IO handle to a ZIP archive into an array of Entry objects.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/parsers/zip_parser/file_reader.rb', line 151 def read_zip_structure(io:) zip_file_size = io.size eocd_offset = get_eocd_offset(io, zip_file_size) zip64_end_of_cdir_location = get_zip64_eocd_location(io, eocd_offset) num_files, cdir_location, cdir_size = if zip64_end_of_cdir_location num_files_and_central_directory_offset_zip64(io, zip64_end_of_cdir_location) else num_files_and_central_directory_offset(io, eocd_offset) end log { format('Located the central directory start at %d', cdir_location) } seek(io, cdir_location) # In zip_tricks we read the entire central directory _and_ enything behind it. # Strictly speaking, we should be able to read `cdir_size` bytes and not a byte more. # BUT! in format_parser we avoid unbounded reads, as a matter of fact they are forbidden. # So we will again limit ouselves to cdir_size, and we will take cushion of 1 KB. central_directory_str = io.read(cdir_size + 1024) raise InvalidCentralDirectory if central_directory_str.nil? central_directory_io = StringIO.new(central_directory_str) log do format( 'Read %d bytes with central directory + EOCD record and locator', central_directory_str.bytesize) end entries = (0...num_files).map do |entry_n| offset_location = cdir_location + central_directory_io.pos log do format( 'Reading the central directory entry %d starting at offset %d', entry_n, offset_location) end read_cdir_entry(central_directory_io) end entries end |