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.



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

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.



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

def comment
  @comment
end

#compressed_sizeObject

Returns the value of attribute compressed_size.



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

def compressed_size
  @compressed_size
end

#compression_methodObject

Returns the value of attribute compression_method.



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

def compression_method
  @compression_method
end

#crcObject

Returns the value of attribute crc.



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

def crc
  @crc
end

#externalFileAttributesObject

Returns the value of attribute externalFileAttributes.



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

def externalFileAttributes
  @externalFileAttributes
end

#extraObject

Returns the value of attribute extra.



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

def extra
  @extra
end

#fstypeObject

Returns the value of attribute fstype.



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

def fstype
  @fstype
end

#localHeaderOffsetObject

Returns the value of attribute localHeaderOffset.



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

def localHeaderOffset
  @localHeaderOffset
end

#nameObject

Returns the value of attribute name.



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

def name
  @name
end

#sizeObject

Returns the value of attribute size.



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

def size
  @size
end

#zipfileObject

Returns the value of attribute zipfile.



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

def zipfile
  @zipfile
end

Class Method Details

.read_c_dir_entry(io) ⇒ Object

:nodoc:all



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

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



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

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



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

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

#==(other) ⇒ Object



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

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



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

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)


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

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

#file?Boolean

Returns:

  • (Boolean)


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

def file?
  ! directory?
end

#get_input_streamObject



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

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



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

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

#local_entry_offsetObject

:nodoc:all



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

def local_entry_offset  #:nodoc:all
  localHeaderOffset + local_header_size
end

#local_header_sizeObject

:nodoc:all



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

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



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

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

#parent_as_stringObject



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

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



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

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



359
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
# File 'lib/zip/zip.rb', line 359

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



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

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



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

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

#to_sObject



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

def to_s
  @name
end

#write_c_dir_entry(io) ⇒ Object

:nodoc:all



482
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
# File 'lib/zip/zip.rb', line 482

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



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

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



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

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