Class: Omnizip::Formats::Zip::CentralDirectoryHeader

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

Overview

ZIP Central Directory File Header

Constant Summary

Constants included from Constants

Omnizip::Formats::Zip::Constants::ATTR_ARCHIVE, Omnizip::Formats::Zip::Constants::ATTR_DIRECTORY, Omnizip::Formats::Zip::Constants::CENTRAL_DIRECTORY_SIGNATURE, Omnizip::Formats::Zip::Constants::COMPRESSION_BZIP2, Omnizip::Formats::Zip::Constants::COMPRESSION_DEFLATE, Omnizip::Formats::Zip::Constants::COMPRESSION_DEFLATE64, Omnizip::Formats::Zip::Constants::COMPRESSION_IMPLODED, Omnizip::Formats::Zip::Constants::COMPRESSION_LZMA, Omnizip::Formats::Zip::Constants::COMPRESSION_PPMD, Omnizip::Formats::Zip::Constants::COMPRESSION_REDUCED_1, Omnizip::Formats::Zip::Constants::COMPRESSION_REDUCED_2, Omnizip::Formats::Zip::Constants::COMPRESSION_REDUCED_3, Omnizip::Formats::Zip::Constants::COMPRESSION_REDUCED_4, Omnizip::Formats::Zip::Constants::COMPRESSION_SHRUNK, Omnizip::Formats::Zip::Constants::COMPRESSION_STORE, Omnizip::Formats::Zip::Constants::COMPRESSION_ZSTANDARD, Omnizip::Formats::Zip::Constants::DATA_DESCRIPTOR_SIGNATURE, Omnizip::Formats::Zip::Constants::END_OF_CENTRAL_DIRECTORY_SIGNATURE, Omnizip::Formats::Zip::Constants::FLAG_DATA_DESCRIPTOR, Omnizip::Formats::Zip::Constants::FLAG_ENCRYPTED, Omnizip::Formats::Zip::Constants::FLAG_STRONG_ENCRYPTION, Omnizip::Formats::Zip::Constants::FLAG_UTF8, Omnizip::Formats::Zip::Constants::LOCAL_FILE_HEADER_SIGNATURE, Omnizip::Formats::Zip::Constants::MAX_COMMENT_LENGTH, Omnizip::Formats::Zip::Constants::UNIX_DIR_PERMISSIONS, Omnizip::Formats::Zip::Constants::UNIX_EXTRA_FIELD_TAG, Omnizip::Formats::Zip::Constants::UNIX_FILE_PERMISSIONS, Omnizip::Formats::Zip::Constants::UNIX_SYMLINK_PERMISSIONS, Omnizip::Formats::Zip::Constants::VERSION_BZIP2, Omnizip::Formats::Zip::Constants::VERSION_DEFAULT, Omnizip::Formats::Zip::Constants::VERSION_DEFLATE, Omnizip::Formats::Zip::Constants::VERSION_LZMA, Omnizip::Formats::Zip::Constants::VERSION_MADE_BY_UNIX, Omnizip::Formats::Zip::Constants::VERSION_MADE_BY_WINDOWS, Omnizip::Formats::Zip::Constants::VERSION_ZIP64, Omnizip::Formats::Zip::Constants::ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIGNATURE, Omnizip::Formats::Zip::Constants::ZIP64_END_OF_CENTRAL_DIRECTORY_SIGNATURE, Omnizip::Formats::Zip::Constants::ZIP64_EXTRA_FIELD_TAG, Omnizip::Formats::Zip::Constants::ZIP64_LIMIT

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(signature: CENTRAL_DIRECTORY_SIGNATURE, version_made_by: VERSION_MADE_BY_UNIX, version_needed: VERSION_DEFAULT, flags: 0, compression_method: COMPRESSION_STORE, last_mod_time: 0, last_mod_date: 0, crc32: 0, compressed_size: 0, uncompressed_size: 0, filename_length: 0, extra_field_length: 0, comment_length: 0, disk_number_start: 0, internal_attributes: 0, external_attributes: 0, local_header_offset: 0, filename: "", extra_field: "", comment: "") ⇒ CentralDirectoryHeader

Returns a new instance of CentralDirectoryHeader.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 18

def initialize(
  signature: CENTRAL_DIRECTORY_SIGNATURE,
  version_made_by: VERSION_MADE_BY_UNIX,
  version_needed: VERSION_DEFAULT,
  flags: 0,
  compression_method: COMPRESSION_STORE,
  last_mod_time: 0,
  last_mod_date: 0,
  crc32: 0,
  compressed_size: 0,
  uncompressed_size: 0,
  filename_length: 0,
  extra_field_length: 0,
  comment_length: 0,
  disk_number_start: 0,
  internal_attributes: 0,
  external_attributes: 0,
  local_header_offset: 0,
  filename: "",
  extra_field: "",
  comment: ""
)
  @signature = signature
  @version_made_by = version_made_by
  @version_needed = version_needed
  @flags = flags
  @compression_method = compression_method
  @last_mod_time = last_mod_time
  @last_mod_date = last_mod_date
  @crc32 = crc32
  @compressed_size = compressed_size
  @uncompressed_size = uncompressed_size
  @filename_length = filename_length
  @extra_field_length = extra_field_length
  @comment_length = comment_length
  @disk_number_start = disk_number_start
  @internal_attributes = internal_attributes
  @external_attributes = external_attributes
  @local_header_offset = local_header_offset
  @filename = filename
  @extra_field = extra_field
  @comment = comment
end

Instance Attribute Details

#cached_original_dataObject

Returns the value of attribute cached_original_data.



10
11
12
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 10

def cached_original_data
  @cached_original_data
end

#commentObject

Returns the value of attribute comment.



10
11
12
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 10

def comment
  @comment
end

#comment_lengthObject

Returns the value of attribute comment_length.



10
11
12
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 10

def comment_length
  @comment_length
end

#compressed_sizeObject

Returns the value of attribute compressed_size.



10
11
12
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 10

def compressed_size
  @compressed_size
end

#compression_methodObject

Returns the value of attribute compression_method.



10
11
12
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 10

def compression_method
  @compression_method
end

#crc32Object

Returns the value of attribute crc32.



10
11
12
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 10

def crc32
  @crc32
end

#disk_number_startObject

Returns the value of attribute disk_number_start.



10
11
12
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 10

def disk_number_start
  @disk_number_start
end

#external_attributesObject

Returns the value of attribute external_attributes.



10
11
12
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 10

def external_attributes
  @external_attributes
end

#extra_fieldObject

Returns the value of attribute extra_field.



10
11
12
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 10

def extra_field
  @extra_field
end

#extra_field_lengthObject

Returns the value of attribute extra_field_length.



10
11
12
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 10

def extra_field_length
  @extra_field_length
end

#filenameObject

Returns the value of attribute filename.



10
11
12
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 10

def filename
  @filename
end

#filename_lengthObject

Returns the value of attribute filename_length.



10
11
12
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 10

def filename_length
  @filename_length
end

#flagsObject

Returns the value of attribute flags.



10
11
12
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 10

def flags
  @flags
end

#internal_attributesObject

Returns the value of attribute internal_attributes.



10
11
12
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 10

def internal_attributes
  @internal_attributes
end

#last_mod_dateObject

Returns the value of attribute last_mod_date.



10
11
12
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 10

def last_mod_date
  @last_mod_date
end

#last_mod_timeObject

Returns the value of attribute last_mod_time.



10
11
12
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 10

def last_mod_time
  @last_mod_time
end

#local_header_offsetObject

Returns the value of attribute local_header_offset.



10
11
12
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 10

def local_header_offset
  @local_header_offset
end

#signatureObject

Returns the value of attribute signature.



10
11
12
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 10

def signature
  @signature
end

#uncompressed_sizeObject

Returns the value of attribute uncompressed_size.



10
11
12
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 10

def uncompressed_size
  @uncompressed_size
end

#version_made_byObject

Returns the value of attribute version_made_by.



10
11
12
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 10

def version_made_by
  @version_made_by
end

#version_neededObject

Returns the value of attribute version_needed.



10
11
12
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 10

def version_needed
  @version_needed
end

Class Method Details

.from_binary(data) ⇒ Object

Parse from binary data



140
141
142
143
144
145
146
147
148
149
150
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
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 140

def self.from_binary(data)
  signature, version_made_by, version_needed, flags,
  compression_method, last_mod_time, last_mod_date,
  crc32, compressed_size, uncompressed_size,
  filename_length, extra_field_length, comment_length,
  disk_number_start, internal_attributes,
  external_attributes, local_header_offset = data.unpack("VvvvvvvVVVvvvvvVV")

  unless signature == CENTRAL_DIRECTORY_SIGNATURE
    raise Omnizip::FormatError,
          "Invalid central directory signature"
  end

  offset = 46
  filename = data[offset, filename_length].force_encoding("UTF-8")
  offset += filename_length

  extra_field = data[offset, extra_field_length]
  offset += extra_field_length

  comment = data[offset, comment_length].force_encoding("UTF-8")

  new(
    signature: signature,
    version_made_by: version_made_by,
    version_needed: version_needed,
    flags: flags,
    compression_method: compression_method,
    last_mod_time: last_mod_time,
    last_mod_date: last_mod_date,
    crc32: crc32,
    compressed_size: compressed_size,
    uncompressed_size: uncompressed_size,
    filename_length: filename_length,
    extra_field_length: extra_field_length,
    comment_length: comment_length,
    disk_number_start: disk_number_start,
    internal_attributes: internal_attributes,
    external_attributes: external_attributes,
    local_header_offset: local_header_offset,
    filename: filename,
    extra_field: extra_field,
    comment: comment,
  )
end

Instance Method Details

#directory?Boolean

Check if this is a directory entry

Returns:

  • (Boolean)


63
64
65
66
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 63

def directory?
  filename.end_with?("/") ||
    external_attributes.anybits?(ATTR_DIRECTORY)
end

#encrypted?Boolean

Check if entry is encrypted

Returns:

  • (Boolean)


77
78
79
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 77

def encrypted?
  flags.anybits?(FLAG_ENCRYPTED)
end

#header_sizeObject

Size of the header in bytes



187
188
189
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 187

def header_size
  46 + filename_length + extra_field_length + comment_length
end

Get link target from Unix extra field



102
103
104
105
106
107
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 102

def link_target
  return nil unless symlink?

  unix_field = UnixExtraField.find_in_extra_field(extra_field)
  unix_field&.link_target
end

#symlink?Boolean

Check if this is a symbolic link

Returns:

  • (Boolean)


97
98
99
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 97

def symlink?
  (unix_permissions & 0o170000) == 0o120000
end

#to_binaryObject

Serialize to binary format



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 110

def to_binary
  @filename_length = filename.bytesize
  @extra_field_length = extra_field.bytesize
  @comment_length = comment.bytesize

  [
    signature,
    version_made_by,
    version_needed,
    flags,
    compression_method,
    last_mod_time,
    last_mod_date,
    crc32,
    compressed_size,
    uncompressed_size,
    filename_length,
    extra_field_length,
    comment_length,
    disk_number_start,
    internal_attributes,
    external_attributes,
    local_header_offset,
  ].pack("VvvvvvvVVVvvvvvVV") +
    filename.b +
    extra_field.b +
    comment.b
end

#unix_permissionsObject

Get Unix permissions from external attributes



87
88
89
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 87

def unix_permissions
  (external_attributes >> 16) & 0xFFFF
end

#unix_permissions=(perms) ⇒ Object

Set Unix permissions in external attributes



92
93
94
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 92

def unix_permissions=(perms)
  @external_attributes = (perms << 16) | (external_attributes & 0xFFFF)
end

#utf8?Boolean

Check if UTF-8 encoding is used

Returns:

  • (Boolean)


82
83
84
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 82

def utf8?
  flags.anybits?(FLAG_UTF8)
end

#zip64?Boolean

Check if ZIP64 format is needed

Returns:

  • (Boolean)


69
70
71
72
73
74
# File 'lib/omnizip/formats/zip/central_directory_header.rb', line 69

def zip64?
  compressed_size == ZIP64_LIMIT ||
    uncompressed_size == ZIP64_LIMIT ||
    local_header_offset == ZIP64_LIMIT ||
    disk_number_start == 0xFFFF
end