Class: Zip::CentralDirectory

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

Direct Known Subclasses

File

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

Constructor Details

#initialize(entries = EntrySet.new, comment = "") ⇒ CentralDirectory

:nodoc:



16
17
18
19
20
# File 'lib/zip/central_directory.rb', line 16

def initialize(entries = EntrySet.new, comment = "") #:nodoc:
  super()
  @entry_set = entries.kind_of?(EntrySet) ? entries : EntrySet.new(entries)
  @comment  = comment
end

Instance Attribute Details

#commentObject (readonly)

Returns the value of attribute comment.



9
10
11
# File 'lib/zip/central_directory.rb', line 9

def comment
  @comment
end

Class Method Details

.read_from_stream(io) ⇒ Object

:nodoc:



118
119
120
121
122
123
124
# File 'lib/zip/central_directory.rb', line 118

def CentralDirectory.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:



126
127
128
129
# File 'lib/zip/central_directory.rb', line 126

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.



108
109
110
# File 'lib/zip/central_directory.rb', line 108

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

#entriesObject

Returns an Enumerable containing the entries.



12
13
14
# File 'lib/zip/central_directory.rb', line 12

def entries
  @entry_set.entries
end

#get_e_o_c_d(io) ⇒ Object

:nodoc:

Raises:



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/zip/central_directory.rb', line 89

def get_e_o_c_d(io) #:nodoc:
  begin
    io.seek(-MAX_END_OF_CENTRAL_DIRECTORY_STRUCTURE_SIZE, IO::SEEK_END)
  rescue 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.bytesize))

  def buf.read(count)
    slice!(0, count)
  end

  buf
end

#read_central_directory_entries(io) ⇒ Object

:nodoc:



71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/zip/central_directory.rb', line 71

def read_central_directory_entries(io) #:nodoc:
  begin
    io.seek(@cdirOffset, IO::SEEK_SET)
  rescue Errno::EINVAL
    raise ZipError, "Zip consistency problem while reading central directory entry"
  end
  @entry_set = EntrySet.new
  @size.times do
    tmp = Entry.read_c_dir_entry(io)
    @entry_set << tmp
  end
end

#read_e_o_c_d(io) ⇒ Object

:nodoc:

Raises:



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/zip/central_directory.rb', line 54

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

#read_from_stream(io) ⇒ Object

:nodoc:



84
85
86
87
# File 'lib/zip/central_directory.rb', line 84

def read_from_stream(io) #:nodoc:
  read_e_o_c_d(io)
  read_central_directory_entries(io)
end

#sizeObject

Returns the number of entries in the central directory (and consequently in the zip archive).



114
115
116
# File 'lib/zip/central_directory.rb', line 114

def size
  @entry_set.size
end

#write_to_stream(io) ⇒ Object

:nodoc:



22
23
24
25
26
# File 'lib/zip/central_directory.rb', line 22

def write_to_stream(io) #:nodoc:
  offset = io.tell
  @entry_set.each { |entry| entry.write_c_dir_entry(io) }
  write_e_o_c_d(io, offset)
end