Class: Rant::Archive::Rubyzip::ZipEntry

Inherits:
Object
  • Object
show all
Defined in:
lib/rant/archive/rubyzip.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.



301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
# File 'lib/rant/archive/rubyzip.rb', line 301

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.



298
299
300
# File 'lib/rant/archive/rubyzip.rb', line 298

def comment
  @comment
end

#compressed_sizeObject

Returns the value of attribute compressed_size.



298
299
300
# File 'lib/rant/archive/rubyzip.rb', line 298

def compressed_size
  @compressed_size
end

#compression_methodObject

Returns the value of attribute compression_method.



298
299
300
# File 'lib/rant/archive/rubyzip.rb', line 298

def compression_method
  @compression_method
end

#crcObject

Returns the value of attribute crc.



298
299
300
# File 'lib/rant/archive/rubyzip.rb', line 298

def crc
  @crc
end

#externalFileAttributesObject

Returns the value of attribute externalFileAttributes.



298
299
300
# File 'lib/rant/archive/rubyzip.rb', line 298

def externalFileAttributes
  @externalFileAttributes
end

#extraObject

Returns the value of attribute extra.



298
299
300
# File 'lib/rant/archive/rubyzip.rb', line 298

def extra
  @extra
end

#fstypeObject

Returns the value of attribute fstype.



298
299
300
# File 'lib/rant/archive/rubyzip.rb', line 298

def fstype
  @fstype
end

#localHeaderOffsetObject

Returns the value of attribute localHeaderOffset.



298
299
300
# File 'lib/rant/archive/rubyzip.rb', line 298

def localHeaderOffset
  @localHeaderOffset
end

#nameObject

Returns the value of attribute name.



298
299
300
# File 'lib/rant/archive/rubyzip.rb', line 298

def name
  @name
end

#sizeObject

Returns the value of attribute size.



298
299
300
# File 'lib/rant/archive/rubyzip.rb', line 298

def size
  @size
end

#zipfileObject

Returns the value of attribute zipfile.



298
299
300
# File 'lib/rant/archive/rubyzip.rb', line 298

def zipfile
  @zipfile
end

Class Method Details

.read_c_dir_entry(io) ⇒ Object

:nodoc:all



500
501
502
503
504
505
506
# File 'lib/rant/archive/rubyzip.rb', line 500

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



425
426
427
428
429
430
431
# File 'lib/rant/archive/rubyzip.rb', line 425

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



550
551
552
# File 'lib/rant/archive/rubyzip.rb', line 550

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

#==(other) ⇒ Object



538
539
540
541
542
543
544
545
546
547
548
# File 'lib/rant/archive/rubyzip.rb', line 538

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



359
360
361
362
# File 'lib/rant/archive/rubyzip.rb', line 359

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)


342
343
344
# File 'lib/rant/archive/rubyzip.rb', line 342

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

#file?Boolean

Returns:

  • (Boolean)


347
348
349
# File 'lib/rant/archive/rubyzip.rb', line 347

def file?
  ! directory?
end

#get_input_streamObject



554
555
556
557
558
559
560
561
562
563
564
565
566
# File 'lib/rant/archive/rubyzip.rb', line 554

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



579
580
581
# File 'lib/rant/archive/rubyzip.rb', line 579

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

#local_entry_offsetObject

:nodoc:all



351
352
353
# File 'lib/rant/archive/rubyzip.rb', line 351

def local_entry_offset  #:nodoc:all
  localHeaderOffset + local_header_size
end

#local_header_sizeObject

:nodoc:all



355
356
357
# File 'lib/rant/archive/rubyzip.rb', line 355

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



364
365
366
# File 'lib/rant/archive/rubyzip.rb', line 364

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

#parent_as_stringObject



573
574
575
576
577
# File 'lib/rant/archive/rubyzip.rb', line 573

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



455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
# File 'lib/rant/archive/rubyzip.rb', line 455

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



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
416
417
418
419
420
421
422
423
# File 'lib/rant/archive/rubyzip.rb', line 386

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



323
324
325
326
327
328
329
330
331
# File 'lib/rant/archive/rubyzip.rb', line 323

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



334
335
336
337
338
339
340
# File 'lib/rant/archive/rubyzip.rb', line 334

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

#to_sObject



368
369
370
# File 'lib/rant/archive/rubyzip.rb', line 368

def to_s
  @name
end

#write_c_dir_entry(io) ⇒ Object

:nodoc:all



509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
# File 'lib/rant/archive/rubyzip.rb', line 509

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



433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
# File 'lib/rant/archive/rubyzip.rb', line 433

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



569
570
571
# File 'lib/rant/archive/rubyzip.rb', line 569

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