Class: Zip::ZipCentralDirectory

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/zip/zip.rb

Overview

:nodoc:all

Direct Known Subclasses

ZipFile

Constant Summary collapse

END_OF_CENTRAL_DIRECTORY_SIGNATURE =
0x06054b50
MAX_END_OF_CENTRAL_DIRECTORY_STRUCTURE_SIZE =
65536 + 18
STATIC_EOCD_SIZE =
22

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Enumerable

#deep_clone, #deep_dup, #inject, #select_map

Constructor Details

#initialize(entries = ZipEntrySet.new, comment = "") ⇒ ZipCentralDirectory

Returns a new instance of ZipCentralDirectory.



750
751
752
753
754
# File 'lib/zip/zip.rb', line 750

def initialize(entries = ZipEntrySet.new, comment = "")
  super()
  @entrySet = entries.kind_of?(ZipEntrySet) ? entries : ZipEntrySet.new(entries)
  @comment = comment
end

Instance Attribute Details

#commentObject (readonly)

Returns the value of attribute comment.



744
745
746
# File 'lib/zip/zip.rb', line 744

def comment
  @comment
end

Class Method Details

.read_from_stream(io) ⇒ Object



838
839
840
841
842
843
844
# File 'lib/zip/zip.rb', line 838

def ZipCentralDirectory.read_from_stream(io)
  cdir  = new
  cdir.read_from_stream(io)
  return cdir
rescue ZipError
  return nil
end

Instance Method Details

#==(other) ⇒ Object



846
847
848
849
# File 'lib/zip/zip.rb', line 846

def == (other)
  return false unless other.kind_of?(ZipCentralDirectory)
  @entrySet.entries.sort == other.entries.sort && comment == other.comment
end

#each(&proc) ⇒ Object



830
831
832
# File 'lib/zip/zip.rb', line 830

def each(&proc)
  @entrySet.each(&proc)
end

#entriesObject



746
747
748
# File 'lib/zip/zip.rb', line 746

def entries
  @entrySet.entries
end

#get_e_o_c_d(io) ⇒ Object

Raises:



812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
# File 'lib/zip/zip.rb', line 812

def get_e_o_c_d(io)
  begin
	io.seek(-MAX_END_OF_CENTRAL_DIRECTORY_STRUCTURE_SIZE, IO::SEEK_END)
  rescue Errno::EINVAL
	io.seek(0, IO::SEEK_SET)
  rescue Errno::EFBIG # FreeBSD 4.9 returns Errno::EFBIG instead of Errno::EINVAL
	io.seek(0, IO::SEEK_SET)
  end
  buf = io.read
  sigIndex = buf.rindex([END_OF_CENTRAL_DIRECTORY_SIGNATURE].pack('V'))
  raise ZipError, "Zip end of central directory signature not found" unless sigIndex
  buf=buf.slice!((sigIndex+4)...(buf.size))
  def buf.read(count)
	slice!(0, count)
  end
  return buf
end

#read_central_directory_entries(io) ⇒ Object



795
796
797
798
799
800
801
802
803
804
805
# File 'lib/zip/zip.rb', line 795

def read_central_directory_entries(io)
  begin
	io.seek(@cdirOffset, IO::SEEK_SET)
  rescue Errno::EINVAL
	raise ZipError, "Zip consistency problem while reading central directory entry"
  end
  @entrySet = ZipEntrySet.new
  @size.times {
	@entrySet << ZipEntry.read_c_dir_entry(io)
  }
end

#read_e_o_c_d(io) ⇒ Object

Raises:



782
783
784
785
786
787
788
789
790
791
792
793
# File 'lib/zip/zip.rb', line 782

def read_e_o_c_d(io)
  buf = get_e_o_c_d(io)
  @numberOfThisDisk                     = ZipEntry::read_zip_short(buf)
  @numberOfDiskWithStartOfCDir          = ZipEntry::read_zip_short(buf)
  @totalNumberOfEntriesInCDirOnThisDisk = ZipEntry::read_zip_short(buf)
  @size                                 = ZipEntry::read_zip_short(buf)
  @sizeInBytes                          = ZipEntry::read_zip_long(buf)
  @cdirOffset                           = ZipEntry::read_zip_long(buf)
  commentLength                         = ZipEntry::read_zip_short(buf)
  @comment                              = buf.read(commentLength)
  raise ZipError, "Zip consistency problem while reading eocd structure" unless buf.size == 0
end

#read_from_stream(io) ⇒ Object



807
808
809
810
# File 'lib/zip/zip.rb', line 807

def read_from_stream(io)
  read_e_o_c_d(io)
  read_central_directory_entries(io)
end

#sizeObject



834
835
836
# File 'lib/zip/zip.rb', line 834

def size
  @entrySet.size
end

#write_to_stream(io) ⇒ Object



756
757
758
759
760
# File 'lib/zip/zip.rb', line 756

def write_to_stream(io)
  offset = io.tell
  @entrySet.each { |entry| entry.write_c_dir_entry(io) }
  write_e_o_c_d(io, offset)
end