Class: Zip::CentralDirectory
- Inherits:
-
Object
- Object
- Zip::CentralDirectory
- Includes:
- Enumerable
- Defined in:
- lib/zip/central_directory.rb
Direct Known Subclasses
Constant Summary collapse
- END_OF_CDS =
0x06054b50
- ZIP64_END_OF_CDS =
0x06064b50
- ZIP64_EOCD_LOCATOR =
0x07064b50
- MAX_END_OF_CDS_SIZE =
65536 + 18
- STATIC_EOCD_SIZE =
22
Instance Attribute Summary collapse
-
#comment ⇒ Object
readonly
Returns the value of attribute comment.
Class Method Summary collapse
-
.read_from_stream(io) ⇒ Object
:nodoc:.
Instance Method Summary collapse
-
#==(other) ⇒ Object
:nodoc:.
-
#each(&proc) ⇒ Object
For iterating over the entries.
-
#entries ⇒ Object
Returns an Enumerable containing the entries.
-
#get_64_e_o_c_d(buf) ⇒ Object
:nodoc:.
-
#get_e_o_c_d(buf) ⇒ Object
:nodoc:.
-
#initialize(entries = EntrySet.new, comment = '') ⇒ CentralDirectory
constructor
:nodoc:.
-
#read_64_e_o_c_d(buf) ⇒ Object
:nodoc:.
-
#read_central_directory_entries(io) ⇒ Object
:nodoc:.
-
#read_e_o_c_d(buf) ⇒ Object
:nodoc:.
-
#read_from_stream(io) ⇒ Object
:nodoc:.
-
#size ⇒ Object
Returns the number of entries in the central directory (and consequently in the zip archive).
- #start_buf(io) ⇒ Object
-
#write_to_stream(io) ⇒ Object
:nodoc:.
- #zip64_file?(buf) ⇒ Boolean
Constructor Details
#initialize(entries = EntrySet.new, comment = '') ⇒ CentralDirectory
:nodoc:
18 19 20 21 22 |
# File 'lib/zip/central_directory.rb', line 18 def initialize(entries = EntrySet.new, comment = '') #:nodoc: super() @entry_set = entries.kind_of?(EntrySet) ? entries : EntrySet.new(entries) @comment = comment end |
Instance Attribute Details
#comment ⇒ Object (readonly)
Returns the value of attribute comment.
11 12 13 |
# File 'lib/zip/central_directory.rb', line 11 def comment @comment end |
Class Method Details
.read_from_stream(io) ⇒ Object
:nodoc:
191 192 193 194 195 196 197 |
# File 'lib/zip/central_directory.rb', line 191 def self.read_from_stream(io) #:nodoc: cdir = new cdir.read_from_stream(io) return cdir rescue Error return nil end |
Instance Method Details
#==(other) ⇒ Object
:nodoc:
199 200 201 202 |
# File 'lib/zip/central_directory.rb', line 199 def ==(other) #:nodoc: return false unless other.kind_of?(CentralDirectory) @entry_set.entries.sort == other.entries.sort && comment == other.comment end |
#each(&proc) ⇒ Object
For iterating over the entries.
181 182 183 |
# File 'lib/zip/central_directory.rb', line 181 def each(&proc) @entry_set.each(&proc) end |
#entries ⇒ Object
Returns an Enumerable containing the entries.
14 15 16 |
# File 'lib/zip/central_directory.rb', line 14 def entries @entry_set.entries end |
#get_64_e_o_c_d(buf) ⇒ Object
:nodoc:
166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/zip/central_directory.rb', line 166 def get_64_e_o_c_d(buf) #:nodoc: zip_64_start = buf.rindex([ZIP64_END_OF_CDS].pack('V')) raise Error, "Zip64 end of central directory signature not found" unless zip_64_start zip_64_locator = buf.rindex([ZIP64_EOCD_LOCATOR].pack('V')) raise Error, "Zip64 end of central directory signature locator not found" unless zip_64_locator buf = buf.slice!((zip_64_start + 4)..zip_64_locator) def buf.read(count) slice!(0, count) end buf end |
#get_e_o_c_d(buf) ⇒ Object
:nodoc:
141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/zip/central_directory.rb', line 141 def get_e_o_c_d(buf) #:nodoc: sig_index = buf.rindex([END_OF_CDS].pack('V')) raise Error, "Zip end of central directory signature not found" unless sig_index buf = buf.slice!((sig_index + 4)..(buf.bytesize)) def buf.read(count) slice!(0, count) end buf end |
#read_64_e_o_c_d(buf) ⇒ Object
:nodoc:
87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/zip/central_directory.rb', line 87 def read_64_e_o_c_d(buf) #:nodoc: buf = get_64_e_o_c_d(buf) @size_of_zip64_e_o_c_d = Entry.read_zip_64_long(buf) @version_made_by = Entry.read_zip_short(buf) @version_needed_for_extract = Entry.read_zip_short(buf) @number_of_this_disk = Entry.read_zip_long(buf) @number_of_disk_with_start_of_cdir = Entry.read_zip_long(buf) @total_number_of_entries_in_cdir_on_this_disk = Entry.read_zip_64_long(buf) @size = Entry.read_zip_64_long(buf) @size_in_bytes = Entry.read_zip_64_long(buf) @cdir_offset = Entry.read_zip_64_long(buf) @zip_64_extensible = buf.slice!(0, buf.bytesize) raise Error, "Zip consistency problem while reading eocd structure" unless buf.size == 0 end |
#read_central_directory_entries(io) ⇒ Object
:nodoc:
119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/zip/central_directory.rb', line 119 def read_central_directory_entries(io) #:nodoc: begin io.seek(@cdir_offset, IO::SEEK_SET) rescue Errno::EINVAL raise Error, "Zip consistency problem while reading central directory entry" end @entry_set = EntrySet.new @size.times do @entry_set << Entry.read_c_dir_entry(io) end end |
#read_e_o_c_d(buf) ⇒ Object
:nodoc:
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/zip/central_directory.rb', line 102 def read_e_o_c_d(buf) #:nodoc: buf = get_e_o_c_d(buf) @number_of_this_disk = Entry.read_zip_short(buf) @number_of_disk_with_start_of_cdir = Entry.read_zip_short(buf) @total_number_of_entries_in_cdir_on_this_disk = Entry.read_zip_short(buf) @size = Entry.read_zip_short(buf) @size_in_bytes = Entry.read_zip_long(buf) @cdir_offset = Entry.read_zip_long(buf) comment_length = Entry.read_zip_short(buf) @comment = if comment_length.to_i <= 0 buf.slice!(0, buf.size) else buf.read(comment_length) end raise Error, "Zip consistency problem while reading eocd structure" unless buf.size == 0 end |
#read_from_stream(io) ⇒ Object
:nodoc:
131 132 133 134 135 136 137 138 139 |
# File 'lib/zip/central_directory.rb', line 131 def read_from_stream(io) #:nodoc: buf = start_buf(io) if self.zip64_file?(buf) read_64_e_o_c_d(buf) else read_e_o_c_d(buf) end read_central_directory_entries(io) end |
#size ⇒ Object
Returns the number of entries in the central directory (and consequently in the zip archive).
187 188 189 |
# File 'lib/zip/central_directory.rb', line 187 def size @entry_set.size end |
#start_buf(io) ⇒ Object
157 158 159 160 161 162 163 164 |
# File 'lib/zip/central_directory.rb', line 157 def start_buf(io) begin io.seek(-MAX_END_OF_CDS_SIZE, IO::SEEK_END) rescue Errno::EINVAL io.seek(0, IO::SEEK_SET) end io.read end |
#write_to_stream(io) ⇒ Object
:nodoc:
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/zip/central_directory.rb', line 24 def write_to_stream(io) #:nodoc: cdir_offset = io.tell @entry_set.each { |entry| entry.write_c_dir_entry(io) } eocd_offset = io.tell cdir_size = eocd_offset - cdir_offset if ::Zip.write_zip64_support need_zip64_eocd = cdir_offset > 0xFFFFFFFF || cdir_size > 0xFFFFFFFF || @entry_set.size > 0xFFFF need_zip64_eocd ||= @entry_set.any? { |entry| entry.extra['Zip64'] } if need_zip64_eocd write_64_e_o_c_d(io, cdir_offset, cdir_size) write_64_eocd_locator(io, eocd_offset) end end write_e_o_c_d(io, cdir_offset, cdir_size) end |
#zip64_file?(buf) ⇒ Boolean
153 154 155 |
# File 'lib/zip/central_directory.rb', line 153 def zip64_file?(buf) buf.rindex([ZIP64_END_OF_CDS].pack('V')) && buf.rindex([ZIP64_EOCD_LOCATOR].pack('V')) end |