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.



275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/zip/zip.rb', line 275

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.



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

def comment
  @comment
end

#compressed_sizeObject

Returns the value of attribute compressed_size.



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

def compressed_size
  @compressed_size
end

#compression_methodObject

Returns the value of attribute compression_method.



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

def compression_method
  @compression_method
end

#crcObject

Returns the value of attribute crc.



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

def crc
  @crc
end

#externalFileAttributesObject

Returns the value of attribute externalFileAttributes.



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

def externalFileAttributes
  @externalFileAttributes
end

#extraObject

Returns the value of attribute extra.



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

def extra
  @extra
end

#fstypeObject

Returns the value of attribute fstype.



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

def fstype
  @fstype
end

#localHeaderOffsetObject

Returns the value of attribute localHeaderOffset.



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

def localHeaderOffset
  @localHeaderOffset
end

#nameObject

Returns the value of attribute name.



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

def name
  @name
end

#sizeObject

Returns the value of attribute size.



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

def size
  @size
end

#zipfileObject

Returns the value of attribute zipfile.



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

def zipfile
  @zipfile
end

Class Method Details

.read_c_dir_entry(io) ⇒ Object

:nodoc:all



474
475
476
477
478
479
480
# File 'lib/zip/zip.rb', line 474

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



399
400
401
402
403
404
405
# File 'lib/zip/zip.rb', line 399

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



524
525
526
# File 'lib/zip/zip.rb', line 524

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

#==(other) ⇒ Object



512
513
514
515
516
517
518
519
520
521
522
# File 'lib/zip/zip.rb', line 512

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



333
334
335
336
# File 'lib/zip/zip.rb', line 333

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)


316
317
318
# File 'lib/zip/zip.rb', line 316

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

#file?Boolean

Returns:

  • (Boolean)


321
322
323
# File 'lib/zip/zip.rb', line 321

def file?
  ! directory?
end

#get_input_streamObject



528
529
530
531
532
533
534
535
536
537
538
539
540
# File 'lib/zip/zip.rb', line 528

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



553
554
555
# File 'lib/zip/zip.rb', line 553

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

#local_entry_offsetObject

:nodoc:all



325
326
327
# File 'lib/zip/zip.rb', line 325

def local_entry_offset  #:nodoc:all
  localHeaderOffset + local_header_size
end

#local_header_sizeObject

:nodoc:all



329
330
331
# File 'lib/zip/zip.rb', line 329

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



338
339
340
# File 'lib/zip/zip.rb', line 338

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

#parent_as_stringObject



547
548
549
550
551
# File 'lib/zip/zip.rb', line 547

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



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
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
# File 'lib/zip/zip.rb', line 429

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



360
361
362
363
364
365
366
367
368
369
370
371
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
# File 'lib/zip/zip.rb', line 360

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



297
298
299
300
301
302
303
304
305
# File 'lib/zip/zip.rb', line 297

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



308
309
310
311
312
313
314
# File 'lib/zip/zip.rb', line 308

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

#to_sObject



342
343
344
# File 'lib/zip/zip.rb', line 342

def to_s
  @name
end

#write_c_dir_entry(io) ⇒ Object

:nodoc:all



483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
# File 'lib/zip/zip.rb', line 483

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



407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
# File 'lib/zip/zip.rb', line 407

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



543
544
545
# File 'lib/zip/zip.rb', line 543

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