Method: ZipKit::ZipWriter#write_data_descriptor

Defined in:
lib/zip_kit/zip_writer.rb

#write_data_descriptor(io:, compressed_size:, uncompressed_size:, crc32:) ⇒ void

This method returns an undefined value.

Writes the data descriptor following the file data for a file whose local file header was written with general-purpose flag bit 3 set. If the one of the sizes exceeds the Zip64 threshold, the data descriptor will have the sizes written out as 8-byte values instead of 4-byte values.

Parameters:

  • io (#<<)

    the buffer to write the local file header to

  • crc32 (Integer)

    The CRC32 checksum of the file

  • compressed_size (Integer)

    The size of the compressed (or stored) data - how much space it uses in the ZIP

  • uncompressed_size (Integer)

    The size of the file once extracted



260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
# File 'lib/zip_kit/zip_writer.rb', line 260

def write_data_descriptor(io:, compressed_size:, uncompressed_size:, crc32:)
  # Although not originally assigned a signature, the value
  # 0x08074b50 has commonly been adopted as a signature value
  # for the data descriptor record.
  io << [0x08074b50].pack(C_UINT4)

  # crc-32                          4 bytes
  io << [crc32].pack(C_UINT4)

  # If one of the sizes is above 0xFFFFFFF use ZIP64 lengths (8 bytes) instead. A good unarchiver
  # will decide to unpack it as such if it finds the Zip64 extra for the file in the central directory.
  # So also use the opportune moment to switch the entry to Zip64 if needed.
  # We switch if either of the sizes requires ZIP64, so that both values are encoded similarly.
  requires_zip64 = compressed_size > FOUR_BYTE_MAX_UINT || uncompressed_size > FOUR_BYTE_MAX_UINT
  pack_spec = requires_zip64 ? C_UINT8 : C_UINT4

  # compressed size                 4 bytes, or 8 bytes for ZIP64
  io << [compressed_size].pack(pack_spec)
  # uncompressed size               4 bytes, or 8 bytes for ZIP64
  io << [uncompressed_size].pack(pack_spec)
end