Class: Omnizip::Formats::Zip::Zip64ExtraField

Inherits:
Object
  • Object
show all
Includes:
Constants
Defined in:
lib/omnizip/formats/zip/zip64_extra_field.rb

Overview

ZIP64 Extended Information Extra Field Used in local/central headers when sizes exceed 32-bit limits

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

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tag: ZIP64_EXTRA_FIELD_TAG, uncompressed_size: nil, compressed_size: nil, relative_header_offset: nil, disk_start_number: nil) ⇒ Zip64ExtraField

Returns a new instance of Zip64ExtraField.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/omnizip/formats/zip/zip64_extra_field.rb', line 14

def initialize(
  tag: ZIP64_EXTRA_FIELD_TAG,
  uncompressed_size: nil,
  compressed_size: nil,
  relative_header_offset: nil,
  disk_start_number: nil
)
  @tag = tag
  @uncompressed_size = uncompressed_size
  @compressed_size = compressed_size
  @relative_header_offset = relative_header_offset
  @disk_start_number = disk_start_number
  @size = calculate_size
end

Instance Attribute Details

#compressed_sizeObject

Returns the value of attribute compressed_size.



11
12
13
# File 'lib/omnizip/formats/zip/zip64_extra_field.rb', line 11

def compressed_size
  @compressed_size
end

#disk_start_numberObject

Returns the value of attribute disk_start_number.



11
12
13
# File 'lib/omnizip/formats/zip/zip64_extra_field.rb', line 11

def disk_start_number
  @disk_start_number
end

#relative_header_offsetObject

Returns the value of attribute relative_header_offset.



11
12
13
# File 'lib/omnizip/formats/zip/zip64_extra_field.rb', line 11

def relative_header_offset
  @relative_header_offset
end

#sizeObject

Returns the value of attribute size.



11
12
13
# File 'lib/omnizip/formats/zip/zip64_extra_field.rb', line 11

def size
  @size
end

#tagObject

Returns the value of attribute tag.



11
12
13
# File 'lib/omnizip/formats/zip/zip64_extra_field.rb', line 11

def tag
  @tag
end

#uncompressed_sizeObject

Returns the value of attribute uncompressed_size.



11
12
13
# File 'lib/omnizip/formats/zip/zip64_extra_field.rb', line 11

def uncompressed_size
  @uncompressed_size
end

Class Method Details

.from_binary(data, needs_uncompressed: false, needs_compressed: false, needs_offset: false, needs_disk: false) ⇒ Object

Parse from binary data needs_uncompressed, needs_compressed, needs_offset, needs_disk specify which fields should be present based on the regular header values



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/omnizip/formats/zip/zip64_extra_field.rb', line 47

def self.from_binary(data, needs_uncompressed: false, needs_compressed: false,
                    needs_offset: false, needs_disk: false)
  tag, = data.unpack("vv")

  unless tag == ZIP64_EXTRA_FIELD_TAG
    raise Omnizip::FormatError,
          "Invalid ZIP64 extra field tag"
  end

  offset = 4 # After tag and size
  uncompressed_size = nil
  compressed_size = nil
  relative_header_offset = nil
  disk_start_number = nil

  # Read fields in order based on what's needed
  if needs_uncompressed && offset + 8 <= data.bytesize
    uncompressed_size = data[offset, 8].unpack1("Q")
    offset += 8
  end

  if needs_compressed && offset + 8 <= data.bytesize
    compressed_size = data[offset, 8].unpack1("Q")
    offset += 8
  end

  if needs_offset && offset + 8 <= data.bytesize
    relative_header_offset = data[offset, 8].unpack1("Q")
    offset += 8
  end

  if needs_disk && offset + 4 <= data.bytesize
    disk_start_number = data[offset, 4].unpack1("V")
  end

  new(
    tag: tag,
    uncompressed_size: uncompressed_size,
    compressed_size: compressed_size,
    relative_header_offset: relative_header_offset,
    disk_start_number: disk_start_number,
  )
end

.needed?(uncompressed_size: 0, compressed_size: 0, offset: 0) ⇒ Boolean

Check if this extra field is needed

Returns:

  • (Boolean)


92
93
94
95
96
# File 'lib/omnizip/formats/zip/zip64_extra_field.rb', line 92

def self.needed?(uncompressed_size: 0, compressed_size: 0, offset: 0)
  uncompressed_size >= ZIP64_LIMIT ||
    compressed_size >= ZIP64_LIMIT ||
    offset >= ZIP64_LIMIT
end

Instance Method Details

#to_binaryObject

Serialize to binary format



30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/omnizip/formats/zip/zip64_extra_field.rb', line 30

def to_binary
  @size = calculate_size
  data = [tag, size].pack("vv")

  # Fields are included in the order they're needed
  # based on which values in the regular header are 0xFFFFFFFF
  data << [uncompressed_size].pack("Q") if uncompressed_size
  data << [compressed_size].pack("Q") if compressed_size
  data << [relative_header_offset].pack("Q") if relative_header_offset
  data << [disk_start_number].pack("V") if disk_start_number

  data
end