Class: Zip::ZipEntry

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

Constant Summary collapse

STORED =
0
DEFLATED =
8
LOCAL_ENTRY_SIGNATURE =
0x04034b50
LOCAL_ENTRY_STATIC_HEADER_LENGTH =
30
CENTRAL_DIRECTORY_ENTRY_SIGNATURE =
0x02014b50
CDIR_ENTRY_STATIC_HEADER_LENGTH =
46

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(zipfile = "", name = "", comment = "", extra = "", compressed_size = 0, crc = 0, compression_method = ZipEntry::DEFLATED, size = 0, time = Time.now) ⇒ ZipEntry

Returns a new instance of ZipEntry.



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/zip/zip.rb', line 218

def initialize(zipfile = "", name = "", comment = "", extra = "", 
               compressed_size = 0, crc = 0, 
 compression_method = ZipEntry::DEFLATED, size = 0,
 time  = Time.now)
  super()
  if name.starts_with("/")
	raise ZipEntryNameError, "Illegal ZipEntry name '#{name}', name must not start with /" 
  end
  @localHeaderOffset = 0
  @internalFileAttributes = 1
  @externalFileAttributes = 0
  @version = 52 # this library's version
  @fstype  = 0  # default is fat
  @zipfile, @comment, @compressed_size, @crc, @extra, @compression_method, 
	@name, @size = zipfile, comment, compressed_size, crc, 
	extra, compression_method, name, size
  @time = time
  unless ZipExtraField === @extra
    @extra = ZipExtraField.new(@extra.to_s)
  end
end

Instance Attribute Details

#commentObject

Returns the value of attribute comment.



215
216
217
# File 'lib/zip/zip.rb', line 215

def comment
  @comment
end

#compressed_sizeObject

Returns the value of attribute compressed_size.



215
216
217
# File 'lib/zip/zip.rb', line 215

def compressed_size
  @compressed_size
end

#compression_methodObject

Returns the value of attribute compression_method.



215
216
217
# File 'lib/zip/zip.rb', line 215

def compression_method
  @compression_method
end

#crcObject

Returns the value of attribute crc.



215
216
217
# File 'lib/zip/zip.rb', line 215

def crc
  @crc
end

#externalFileAttributesObject

Returns the value of attribute externalFileAttributes.



215
216
217
# File 'lib/zip/zip.rb', line 215

def externalFileAttributes
  @externalFileAttributes
end

#extraObject

Returns the value of attribute extra.



215
216
217
# File 'lib/zip/zip.rb', line 215

def extra
  @extra
end

#fstypeObject

Returns the value of attribute fstype.



215
216
217
# File 'lib/zip/zip.rb', line 215

def fstype
  @fstype
end

#localHeaderOffsetObject

Returns the value of attribute localHeaderOffset.



215
216
217
# File 'lib/zip/zip.rb', line 215

def localHeaderOffset
  @localHeaderOffset
end

#nameObject

Returns the value of attribute name.



215
216
217
# File 'lib/zip/zip.rb', line 215

def name
  @name
end

#sizeObject

Returns the value of attribute size.



215
216
217
# File 'lib/zip/zip.rb', line 215

def size
  @size
end

#zipfileObject

Returns the value of attribute zipfile.



215
216
217
# File 'lib/zip/zip.rb', line 215

def zipfile
  @zipfile
end

Class Method Details

.read_c_dir_entry(io) ⇒ Object

:nodoc:all



417
418
419
420
421
422
423
# File 'lib/zip/zip.rb', line 417

def ZipEntry.read_c_dir_entry(io)  #:nodoc:all
  entry = new(io.path)
  entry.read_c_dir_entry(io)
  return entry
rescue ZipError
  return nil
end

.read_local_entry(io) ⇒ Object



342
343
344
345
346
347
348
# File 'lib/zip/zip.rb', line 342

def ZipEntry.read_local_entry(io)
  entry = new(io.path)
  entry.read_local_entry(io)
  return entry
rescue ZipError
  return nil
end

Instance Method Details

#<=>(other) ⇒ Object



467
468
469
# File 'lib/zip/zip.rb', line 467

def <=> (other)
  return to_s <=> other.to_s
end

#==(other) ⇒ Object



455
456
457
458
459
460
461
462
463
464
465
# File 'lib/zip/zip.rb', line 455

def == (other)
  return false unless other.class == ZipEntry
  # Compares contents of local entry and exposed fields
  (@compression_method == other.compression_method &&
   @crc               == other.crc		     &&
   @compressed_size    == other.compressed_size    &&
   @size              == other.size	             &&
   @name              == other.name	             &&
   @extra             == other.extra             &&
   self.time.dos_equals(other.time))
end

#cdir_header_sizeObject

:nodoc:all



276
277
278
279
# File 'lib/zip/zip.rb', line 276

def cdir_header_size  #:nodoc:all
  CDIR_ENTRY_STATIC_HEADER_LENGTH  + (@name ?  @name.size : 0) + 
	(@extra ? @extra.c_dir_size : 0) + (@comment ? @comment.size : 0)
end

#directory?Boolean Also known as: is_directory

Returns:

  • (Boolean)


259
260
261
# File 'lib/zip/zip.rb', line 259

def directory?
  return (%r{\/$} =~ @name) != nil
end

#file?Boolean

Returns:

  • (Boolean)


264
265
266
# File 'lib/zip/zip.rb', line 264

def file?
  ! directory?
end

#get_input_streamObject



471
472
473
474
475
476
477
478
479
480
481
482
483
# File 'lib/zip/zip.rb', line 471

def get_input_stream
  zis = ZipInputStream.new(@zipfile, localHeaderOffset)
  zis.get_next_entry
  if block_given?
	begin
	  return yield(zis)
	ensure
	  zis.close
	end
  else
	return zis
  end
end

#get_raw_input_stream(&aProc) ⇒ Object



496
497
498
# File 'lib/zip/zip.rb', line 496

def get_raw_input_stream(&aProc)
  File.open(@zipfile, "rb", &aProc)
end

#local_entry_offsetObject

:nodoc:all



268
269
270
# File 'lib/zip/zip.rb', line 268

def local_entry_offset  #:nodoc:all
  localHeaderOffset + local_header_size
end

#local_header_sizeObject

:nodoc:all



272
273
274
# File 'lib/zip/zip.rb', line 272

def local_header_size  #:nodoc:all
  LOCAL_ENTRY_STATIC_HEADER_LENGTH + (@name ?  @name.size : 0) + (@extra ? @extra.local_size : 0)
end

#next_header_offsetObject

:nodoc:all



281
282
283
# File 'lib/zip/zip.rb', line 281

def next_header_offset  #:nodoc:all
  local_entry_offset + self.compressed_size
end

#parent_as_stringObject



490
491
492
493
494
# File 'lib/zip/zip.rb', line 490

def parent_as_string
  entry_name = name.chomp("/")
  slash_index = entry_name.rindex("/")
  slash_index ? entry_name.slice(0, slash_index+1) : nil
end

#read_c_dir_entry(io) ⇒ Object

:nodoc:all



372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
# File 'lib/zip/zip.rb', line 372

def read_c_dir_entry(io)  #:nodoc:all
  staticSizedFieldsBuf = io.read(CDIR_ENTRY_STATIC_HEADER_LENGTH)
  unless (staticSizedFieldsBuf.size == CDIR_ENTRY_STATIC_HEADER_LENGTH)
	raise ZipError, "Premature end of file. Not enough data for zip cdir entry header"
  end
  
  cdirSignature          ,
	@version               , # version of encoding software
    @fstype                , # filesystem type
	@versionNeededToExtract,
	@gpFlags               ,
	@compression_method     ,
	lastModTime            ,
	lastModDate            ,
	@crc                   ,
	@compressed_size        ,
	@size                  ,
	nameLength             ,
	extraLength            ,
	commentLength          ,
	diskNumberStart        ,
	@internalFileAttributes,
	@externalFileAttributes,
	@localHeaderOffset     ,
	@name                  ,
	@extra                 ,
	@comment               = staticSizedFieldsBuf.unpack('VCCvvvvvVVVvvvvvVV')

  unless (cdirSignature == CENTRAL_DIRECTORY_ENTRY_SIGNATURE)
	raise ZipError, "Zip local header magic not found at location '#{localHeaderOffset}'"
  end
  set_time(lastModDate, lastModTime)
  
  @name                  = io.read(nameLength)
  if ZipExtraField === @extra
    @extra.merge(io.read(extraLength))
  else
    @extra = ZipExtraField.new(io.read(extraLength))
  end
  @comment               = io.read(commentLength)
  unless (@comment && @comment.length == commentLength)
	raise ZipError, "Truncated cdir zip entry header"
  end
end

#read_local_entry(io) ⇒ Object

:nodoc:all



303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
# File 'lib/zip/zip.rb', line 303

def read_local_entry(io)  #:nodoc:all
  @localHeaderOffset = io.tell
  staticSizedFieldsBuf = io.read(LOCAL_ENTRY_STATIC_HEADER_LENGTH)
  unless (staticSizedFieldsBuf.size==LOCAL_ENTRY_STATIC_HEADER_LENGTH)
	raise ZipError, "Premature end of file. Not enough data for zip entry local header"
  end
  
  localHeader       ,
    @version          ,
	@fstype           ,
	@gpFlags          ,
	@compression_method,
	lastModTime       ,
	lastModDate       ,
	@crc              ,
	@compressed_size   ,
	@size             ,
	nameLength        ,
	extraLength       = staticSizedFieldsBuf.unpack('VCCvvvvVVVvv') 

  unless (localHeader == LOCAL_ENTRY_SIGNATURE)
	raise ZipError, "Zip local header magic not found at location '#{localHeaderOffset}'"
  end
  set_time(lastModDate, lastModTime)
  
  @name              = io.read(nameLength)
  extra              = io.read(extraLength)

  if (extra && extra.length != extraLength)
	raise ZipError, "Truncated local zip entry header"
  else
    if ZipExtraField === @extra
      @extra.merge(extra)
    else
      @extra = ZipExtraField.new(extra)
    end
  end
end

#timeObject Also known as: mtime



240
241
242
243
244
245
246
247
248
# File 'lib/zip/zip.rb', line 240

def time
  if @extra["UniversalTime"]
    @extra["UniversalTime"].mtime
  else
    # Atandard time field in central directory has local time
    # under archive creator. Then, we can't get timezone.
    @time
  end
end

#time=(aTime) ⇒ Object



251
252
253
254
255
256
257
# File 'lib/zip/zip.rb', line 251

def time=(aTime)
  unless @extra.member?("UniversalTime")
    @extra.create("UniversalTime")
  end
  @extra["UniversalTime"].mtime = aTime
  @time = aTime
end

#to_sObject



285
286
287
# File 'lib/zip/zip.rb', line 285

def to_s
  @name
end

#write_c_dir_entry(io) ⇒ Object

:nodoc:all



426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
# File 'lib/zip/zip.rb', line 426

def write_c_dir_entry(io)  #:nodoc:all
  io << 
	[CENTRAL_DIRECTORY_ENTRY_SIGNATURE,
    @version                          , # version of encoding software
	@fstype                           , # filesystem type
	0                                 , # @versionNeededToExtract           ,
	0                                 , # @gpFlags                          ,
	@compression_method                ,
    @time.to_binary_dos_time             , # @lastModTime                      ,
	@time.to_binary_dos_date             , # @lastModDate                      ,
	@crc                              ,
	@compressed_size                   ,
	@size                             ,
	@name  ?  @name.length  : 0       ,
	@extra ? @extra.c_dir_length : 0  ,
	@comment ? comment.length : 0     ,
	0                                 , # disk number start
	@internalFileAttributes           , # file type (binary=0, text=1)
	@externalFileAttributes           , # native filesystem attributes
	@localHeaderOffset                ,
	@name                             ,
	@extra                            ,
	@comment                          ].pack('VCCvvvvvVVVvvvvvVV')

  io << @name
  io << (@extra ? @extra.to_c_dir_bin : "")
  io << @comment
end

#write_local_entry(io) ⇒ Object

:nodoc:all



350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
# File 'lib/zip/zip.rb', line 350

def write_local_entry(io)   #:nodoc:all
  @localHeaderOffset = io.tell
  
  io << 
	[LOCAL_ENTRY_SIGNATURE    ,
	0                  ,
	0                         , # @gpFlags                  ,
	@compression_method        ,
	@time.to_binary_dos_time     , # @lastModTime              ,
	@time.to_binary_dos_date     , # @lastModDate              ,
	@crc                      ,
	@compressed_size           ,
	@size                     ,
	@name ? @name.length   : 0,
	@extra? @extra.local_length : 0 ].pack('VvvvvvVVVvv')
  io << @name
  io << (@extra ? @extra.to_local_bin : "")
end

#write_to_zip_output_stream(aZipOutputStream) ⇒ Object

:nodoc:all



486
487
488
# File 'lib/zip/zip.rb', line 486

def write_to_zip_output_stream(aZipOutputStream)  #:nodoc:all
  aZipOutputStream.copy_raw_entry(self)
end