Skip to content

Commit

Permalink
Expose the EntrySet more cleanly through CentralDirectory.
Browse files Browse the repository at this point in the history
There is now no direct access to the set of entries in a central
directory. This makes the interface cleaner because we now, for example,
add/delete things directly to/from the central directory, rather than
to/from the entry set contained within the central directory.
  • Loading branch information
hainesr committed Jan 15, 2022
1 parent 34731b1 commit 5acbfcd
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 28 deletions.
24 changes: 7 additions & 17 deletions lib/zip/central_directory.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
# frozen_string_literal: true

require 'forwardable'

module Zip
class CentralDirectory
extend Forwardable

END_OF_CDS = 0x06054b50
ZIP64_END_OF_CDS = 0x06064b50
ZIP64_EOCD_LOCATOR = 0x07064b50
Expand All @@ -14,12 +18,9 @@ class CentralDirectory

attr_accessor :comment

attr_reader :entry_set

# Returns an Enumerable containing the entries.
def entries
@entry_set.entries
end
def_delegators :@entry_set,
:<<, :delete, :each, :entries, :find_entry, :glob,
:include?, :size

def initialize(entries = EntrySet.new, comment = '') #:nodoc:
super()
Expand Down Expand Up @@ -220,17 +221,6 @@ def start_buf(io)
io.read
end

# For iterating over the entries.
def each(&a_proc)
@entry_set.each(&a_proc)
end

# Returns the number of entries in the central directory (and
# consequently in the zip archive).
def size
@entry_set.size
end

# Reads the End of Central Directory Record (and the Zip64 equivalent if
# needs be) and returns the number of entries in the archive. This is a
# convenience method that avoids reading in all of the entry data to get a
Expand Down
22 changes: 11 additions & 11 deletions lib/zip/file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def initialize(path_or_io, create: false, buffer: false, **options)
raise Error, "File #{@name} not found"
end

@stored_entries = @cdir.entry_set.dup
@stored_entries = @cdir.entries.map(&:dup)
@stored_comment = @cdir.comment
@restore_ownership = options[:restore_ownership]
@restore_permissions = options[:restore_permissions]
Expand Down Expand Up @@ -222,7 +222,7 @@ def get_output_stream(entry, permissions: nil, comment: nil,
end
new_entry.unix_perms = permissions
zip_streamable_entry = StreamableStream.new(new_entry)
@cdir.entry_set << zip_streamable_entry
@cdir << zip_streamable_entry
zip_streamable_entry.get_output_stream(&a_proc)
end

Expand Down Expand Up @@ -250,7 +250,7 @@ def add(entry, src_path, &continue_on_exists_proc)
end
new_entry.gather_fileinfo_from_srcpath(src_path)
new_entry.dirty = true
@cdir.entry_set << new_entry
@cdir << new_entry
end

# Convenience method for adding the contents of a file to the archive
Expand All @@ -264,16 +264,16 @@ def add_stored(entry, src_path, &continue_on_exists_proc)

# Removes the specified entry.
def remove(entry)
@cdir.entry_set.delete(get_entry(entry))
@cdir.delete(get_entry(entry))
end

# Renames the specified entry.
def rename(entry, new_name, &continue_on_exists_proc)
found_entry = get_entry(entry)
check_entry_exists(new_name, continue_on_exists_proc, 'rename')
@cdir.entry_set.delete(found_entry)
@cdir.delete(found_entry)
found_entry.name = new_name
@cdir.entry_set << found_entry
@cdir << found_entry
end

# Replaces the specified entry with the contents of src_path (from
Expand Down Expand Up @@ -331,13 +331,13 @@ def commit_required?
@cdir.each do |e|
return true if e.dirty
end
comment != @stored_comment || @cdir.entry_set != @stored_entries || @create
comment != @stored_comment || entries != @stored_entries || @create
end

# Searches for entry with the specified name. Returns nil if
# no entry is found. See also get_entry
def find_entry(entry_name)
selected_entry = @cdir.entry_set.find_entry(entry_name)
selected_entry = @cdir.find_entry(entry_name)
return if selected_entry.nil?

selected_entry.restore_ownership = @restore_ownership
Expand All @@ -352,7 +352,7 @@ def find_entry(entry_name)
# `::File::FNM_PATHNAME | ::File::FNM_DOTMATCH | ::File::FNM_EXTGLOB`,
# which will be overridden if you set your own flags.
def glob(*args, &block)
@cdir.entry_set.glob(*args, &block)
@cdir.glob(*args, &block)
end

# Searches for an entry just as find_entry, but throws Errno::ENOENT
Expand All @@ -370,7 +370,7 @@ def mkdir(entry_name, permission = 0o755)

entry_name = entry_name.dup.to_s
entry_name << '/' unless entry_name.end_with?('/')
@cdir.entry_set << ::Zip::StreamableDirectory.new(@name, entry_name, nil, permission)
@cdir << ::Zip::StreamableDirectory.new(@name, entry_name, nil, permission)
end

private
Expand All @@ -389,7 +389,7 @@ def directory?(new_entry, src_path)

def check_entry_exists(entry_name, continue_on_exists_proc, proc_name)
continue_on_exists_proc ||= proc { Zip.continue_on_exists_proc }
return unless @cdir.entry_set.include?(entry_name)
return unless @cdir.include?(entry_name)

if continue_on_exists_proc.call
remove get_entry(entry_name)
Expand Down

0 comments on commit 5acbfcd

Please sign in to comment.