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:
188 189 190 191 192 193 194 |
# File 'lib/zip/central_directory.rb', line 188 def self.read_from_stream(io) #:nodoc: cdir = new cdir.read_from_stream(io) return cdir rescue ZipError return nil end |
Instance Method Details
#==(other) ⇒ Object
:nodoc:
196 197 198 199 |
# File 'lib/zip/central_directory.rb', line 196 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.
178 179 180 |
# File 'lib/zip/central_directory.rb', line 178 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:
163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/zip/central_directory.rb', line 163 def get_64_e_o_c_d(buf) #:nodoc: zip_64_start = buf.rindex([ZIP64_END_OF_CDS].pack('V')) raise ZipError, "Zip64 end of central directory signature not found" unless zip_64_start zip_64_locator = buf.rindex([ZIP64_EOCD_LOCATOR].pack('V')) raise ZipError, "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:
138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/zip/central_directory.rb', line 138 def get_e_o_c_d(buf) #:nodoc: sig_index = buf.rindex([END_OF_CDS].pack('V')) raise ZipError, "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:
84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/zip/central_directory.rb', line 84 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 ZipError, "Zip consistency problem while reading eocd structure" unless buf.size == 0 end |
#read_central_directory_entries(io) ⇒ Object
:nodoc:
116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/zip/central_directory.rb', line 116 def read_central_directory_entries(io) #:nodoc: begin io.seek(@cdir_offset, IO::SEEK_SET) rescue Errno::EINVAL raise ZipError, "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:
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/zip/central_directory.rb', line 99 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 <= 0 buf.slice!(0, buf.size) else buf.read(comment_length) end raise ZipError, "Zip consistency problem while reading eocd structure" unless buf.size == 0 end |
#read_from_stream(io) ⇒ Object
:nodoc:
128 129 130 131 132 133 134 135 136 |
# File 'lib/zip/central_directory.rb', line 128 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).
184 185 186 |
# File 'lib/zip/central_directory.rb', line 184 def size @entry_set.size end |
#start_buf(io) ⇒ Object
154 155 156 157 158 159 160 161 |
# File 'lib/zip/central_directory.rb', line 154 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 |
# 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 has_zip64_entry = @entry_set.any? { |entry| entry.extra['Zip64'] } if has_zip64_entry || cdir_offset > 0xFFFFFFFF || cdir_size > 0xFFFFFFFF || @entry_set.size > 0xFFFF write_64_e_o_c_d(io, cdir_offset, cdir_size) write_64_eocd_locator(io, eocd_offset) end write_e_o_c_d(io, cdir_offset, cdir_size) end |
#zip64_file?(buf) ⇒ Boolean
150 151 152 |
# File 'lib/zip/central_directory.rb', line 150 def zip64_file?(buf) buf.rindex([ZIP64_END_OF_CDS].pack('V')) && buf.rindex([ZIP64_EOCD_LOCATOR].pack('V')) end |