module AWS::S3::DataOptions

Used by S3#S3Object and S3::Client to accept options with data that should be uploaded (streamed). @api private

Protected Instance Methods

compute_write_options(*args, &block) click to toggle source

@return [Hash] Returns a hash of options with a :data option that

responds to #read and #eof?.
# File lib/aws/s3/data_options.rb, line 28
def compute_write_options *args, &block

  options = convert_args_to_options_hash(*args)

  validate_data!(options, &block)

  rename_file_to_data(options)

  convert_data_to_io_obj(options, &block)

  try_to_determine_content_length(options)

  options

end
convert_args_to_options_hash(*args) click to toggle source

Converts an argument list into a single hash of options. Treats non-hash arguments in the first position as a data option.

# File lib/aws/s3/data_options.rb, line 46
def convert_args_to_options_hash *args
  case args.count
  when 0 then {}
  when 1 then args[0].is_a?(Hash) ? args[0] : { :data => args[0] }
  when 2 then args[1].merge(:data => args[0])
  else
    msg = "expected 0, 1 or 2 arguments, got #{args.count}"
    raise ArgumentError, msg
  end
end
convert_data_to_io_obj(options, &block) click to toggle source

Converts the :data option to an IO-like object. This allows us to always perform streaming uploads.

# File lib/aws/s3/data_options.rb, line 67
def convert_data_to_io_obj options, &block

  data = options.delete(:data)

  if block_given?
    options[:data] = IOProxy.new(block)
  elsif data.is_a?(String)
    data = data.dup if data.frozen?
    data.force_encoding("BINARY") if data.respond_to?(:force_encoding)
    options[:data] = StringIO.new(data)
  elsif data.is_a?(Pathname)
    options[:data] = open_file(data.to_s)
  elsif io_like?(data)
    options[:data] = data
  else
    msg = "invalid :data option, expected a String, Pathname or "
    msg << "an object that responds to #read and #eof?"
    raise ArgumentError, msg
  end

end
io_like?(io) click to toggle source

@return [Boolean] Returns ‘true` if the object responds to

`#read` and `#eof?`.
# File lib/aws/s3/data_options.rb, line 132
def io_like? io
  io.respond_to?(:read) and io.respond_to?(:eof?)
end
open_file(path) click to toggle source

@param [String] path Path to a file on disk. @return [File] Given a path string, returns an open File.

# File lib/aws/s3/data_options.rb, line 138
def open_file path
  Core::ManagedFile.open(path)
end
rename_file_to_data(options) click to toggle source

Moves options to options. If this option is a string then it is treated as a file path and is converted to an open file.

# File lib/aws/s3/data_options.rb, line 59
def rename_file_to_data options
  if file = options.delete(:file)
    options[:data] = file.is_a?(String) ? open_file(file) : file
  end
end
try_to_determine_content_length(options) click to toggle source

Attempts to determine the content length of the :data option. This is only done when a content length is not already provided.

# File lib/aws/s3/data_options.rb, line 91
def try_to_determine_content_length options
  unless options[:content_length]

    data = options[:data]

    length = case
      when data.respond_to?(:path) && data.path then File.size(data.path)
      when data.respond_to?(:bytesize) then data.bytesize
      when data.respond_to?(:size)     then data.size
      when data.respond_to?(:length)   then data.length
      else nil
    end

    options[:content_length] = length if length

  end
end
validate_data!(options, &block) click to toggle source
# File lib/aws/s3/data_options.rb, line 109
def validate_data! options, &block

  data = options[:data]
  file = options[:file]

  raise ArgumentError, 'Object data passed multiple ways.' if
    [data, file, block].compact.count > 1

  data = file if file

  return if block_given?
  return if data.kind_of?(String)
  return if data.kind_of?(Pathname)
  return if io_like?(data)

  msg = ":data must be provided as a String, Pathname, File, or "
  msg << "an object that responds to #read and #eof?"
  raise ArgumentError, msg

end