Class: Archive::Zip::Entry::File

Inherits:
Object
  • Object
show all
Includes:
Archive::Zip::Entry
Defined in:
lib/archive/zip/entry.rb

Overview

Archive::Zip::Entry::File represents a file entry within a Zip archive.

Constant Summary

Constants included from Archive::Zip::Entry

FLAG_DATA_DESCRIPTOR_FOLLOWS, FLAG_ENCRYPTED

Instance Attribute Summary collapse

Attributes included from Archive::Zip::Entry

#atime, #comment, #compression_codec, #encryption_codec, #expected_data_descriptor, #gid, #mode, #mtime, #password, #raw_data, #uid, #zip_path

Instance Method Summary collapse

Methods included from Archive::Zip::Entry

#add_extra_field, #directory?, #dump_central_file_record, #dump_local_file_record, expand_path, from_file, parse, #symlink?

Constructor Details

#initialize(zip_path, raw_data = nil) ⇒ File

Creates a new file entry where zip_path is the path to the entry in the ZIP archive. The Archive::Zip::Codec::Deflate codec with the default compression level set (NORMAL) is used by default for compression. raw_data, if specified, must be a readable, IO-like object containing possibly compressed/encrypted file data for the entry. It is intended to be used primarily by the Archive::Zip::Entry.parse class method.



1028
1029
1030
1031
1032
1033
# File 'lib/archive/zip/entry.rb', line 1028

def initialize(zip_path, raw_data = nil)
  super(zip_path, raw_data)
  @file_path = nil
  @file_data = nil
  @compression_codec = Zip::Codec::Deflate.new
end

Instance Attribute Details

#file_pathObject

The path to a file whose contents are to be used for uncompressed file data. This will be nil if the file_data attribute is set directly.



1061
1062
1063
# File 'lib/archive/zip/entry.rb', line 1061

def file_path
  @file_path
end

Instance Method Details

#extract(options = {}) ⇒ Object

Extracts this entry.

options is a Hash optionally containing the following:

:file_path

Specifies the path to which this entry will be extracted. Defaults to the zip path of this entry.

:permissions

When set to false (the default), POSIX mode/permission bits will be ignored. Otherwise, they will be restored if possible.

:ownerships

When set to false (the default), user and group ownerships will be ignored. On most systems, only a superuser is able to change ownerships, so setting this option to true as a regular user may have no effect.

:times

When set to false (the default), last accessed and last modified times will be ignored. Otherwise, they will be restored if possible.

Raises Archive::Zip::EntryError if the extracted file data appears corrupt.



1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
# File 'lib/archive/zip/entry.rb', line 1137

def extract(options = {})
  # Ensure that unspecified options have default values.
  file_path           = options.has_key?(:file_path) ?
                        options[:file_path].to_s :
                        @zip_path
  restore_permissions = options.has_key?(:permissions) ?
                        options[:permissions] :
                        false
  restore_ownerships  = options.has_key?(:ownerships) ?
                        options[:ownerships] :
                        false
  restore_times       = options.has_key?(:times) ?
                        options[:times] :
                        false

  # Create the containing directory tree if necessary.
  parent_dir = ::File.dirname(file_path)
  FileUtils.mkdir_p(parent_dir) unless ::File.exist?(parent_dir)

  # Dump the file contents.
  ::File.open(file_path, 'wb') do |f|
    begin
      loop do f.write(file_data.read(8192)) end
    rescue EOFError
      # Ignore
    end
  end

  # Verify that the extracted data is good.
  begin
    unless expected_data_descriptor.nil? then
      expected_data_descriptor.verify(file_data.data_descriptor)
    end
  rescue => e
    raise Zip::EntryError, "`#{zip_path}': #{e.message}"
  end

  # Restore the metadata.
  ::File.chmod(mode, file_path) if restore_permissions
  ::File.chown(uid, gid, file_path) if restore_ownerships
  ::File.utime(atime, mtime, file_path) if restore_times

  # Attempt to rewind the file data back to the beginning, but ignore
  # errors.
  begin
    file_data.seek(0)
  rescue
    # Ignore.
  end

  nil
end

#file?Boolean

Returns true.

Returns:

  • (Boolean)


1041
1042
1043
# File 'lib/archive/zip/entry.rb', line 1041

def file?
  true
end

#file_dataObject

Returns a readable, IO-like object containing uncompressed file data.

NOTE: It is the responsibility of the user of this attribute to ensure that the #close method of the returned IO-like object is called when the object is no longer needed.



1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
# File 'lib/archive/zip/entry.rb', line 1077

def file_data
  return @file_data unless @file_data.nil? || @file_data.closed?

  if raw_data.nil? then
    if @file_path.nil? then
      simulated_raw_data = StringIO.new('', 'rb')
    else
      simulated_raw_data = ::File.new(@file_path, 'rb')
    end
    # Ensure that the IO-like object can return a data descriptor so that
    # it's possible to verify extraction later if desired.
    @file_data = Zip::Codec::Store.new.decompressor(
      IO::LikeHelpers::IOWrapper.new(simulated_raw_data)
    )
  else
    raw_data.seek(0)
    @file_data = compression_codec.decompressor(
      encryption_codec.decryptor(raw_data, password)
    )
  end
  @file_data
end

#file_data=(file_data) ⇒ Object

Sets the file_data attribute of this object to file_data. file_data must be a readable, IO-like object.

NOTE: As a side effect, the file_path and raw_data attributes for this object will be set to nil.



1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
# File 'lib/archive/zip/entry.rb', line 1105

def file_data=(file_data)
  @file_path = nil
  self.raw_data = nil
  @file_data = file_data
  # Ensure that the IO-like object can return CRC32 and data size
  # information so that it's possible to verify extraction later if desired.
  unless @file_data.respond_to?(:data_descriptor) then
    @file_data = Zip::Codec::Store.new.decompressor(@file_data)
  end
  @file_data
end

#ftypeObject

Returns the file type of this entry as the symbol :file.



1036
1037
1038
# File 'lib/archive/zip/entry.rb', line 1036

def ftype
  :file
end

#mode=(mode) ⇒ Object

Overridden in order to ensure that the proper mode bits are set for a file.



1047
1048
1049
# File 'lib/archive/zip/entry.rb', line 1047

def mode=(mode)
  super(0100000 | (mode & 07777))
end

#password=(password) ⇒ Object

Sets the decryption password.



1052
1053
1054
1055
1056
1057
# File 'lib/archive/zip/entry.rb', line 1052

def password=(password)
  unless @raw_data.nil? then
    @file_data = nil
  end
  @password = password
end