lib/s3io/wrapper.rb in s3io-0.0.2 vs lib/s3io/wrapper.rb in s3io-1.0.0
- old
+ new
@@ -1,88 +1,44 @@
module S3io
- # This class wraps an AWS S3 object in order to provide IO-like API.
- # S3 objects wrapped this way can be used in methods that would otherwise expect an instance of File, StringIO etc.
- class Wrapper
- # Default buffer size for line parser in bytes
- LINE_BUFFER_SIZE = 5 * 1024 * 1024 # MiB
+ def self.open(s3object, mode_string = 'r', options = {}, &block)
+ wrapper_class = case mode_string
+ when 'r'
+ ReadWrapper
+ when 'w'
+ WriteWrapper
+ else
+ fail "S3IO only supports 'r' or 'w' as access modes"
+ end
- include Enumerable
+ wrapper = wrapper_class.new(s3object, options)
- # Current byte position in S3 object
- attr_accessor :pos
+ if block_given?
+ result = yield wrapper if block_given?
+ wrapper.close
- # Options that were passed during initialization
- attr_reader :options
+ return result
+ else
+ return wrapper
+ end
+ end
+ # This class wraps an AWS S3 object in order to provide IO-like API.
+ # S3 objects wrapped this way can be used in methods that would otherwise expect an instance of File, StringIO etc.
+ class Wrapper
+
# Wraps an AWS::S3::S3Object into IO-like object.
#
# @param [AWS::S3::S3Object] s3object an object to wrap
- # @param [Hash] options options hash
- # @option options [Integer] :line_buffer_size size of the buffer that is used for reading contents of S3 object when iterating over its lines
- def initialize(s3object, options = {})
+ def initialize(s3object)
@s3object = s3object
- @options = {
- :line_buffer_size => (options[:line_buffer_size] || LINE_BUFFER_SIZE)
- }
-
@pos = 0
end
- # Reads data from S3 object.
- #
- # @param [Integer] bytes number of bytes to read
- def read(bytes = nil)
- content_length = @s3object.content_length
-
- return '' if (@pos >= content_length) || (bytes == 0)
-
- bytes ||= content_length
-
- upper_bound = @pos + bytes - 1
- upper_bound = (content_length - 1) if upper_bound >= content_length
-
- data = @s3object.read :range => @pos..upper_bound
- @pos = upper_bound + 1
-
- return data
- end
-
- # Rewinds position to the very beginning of S3 object.
- def rewind
+ def close
+ @s3object = nil
@pos = 0
- end
- # Iterates over S3 object lines.
- #
- # @param [String] separator line separator string
- def each(separator = $/)
- return enum_for(:each, separator) unless block_given?
-
- line = ''
- newline_pos = nil
-
- # Either trying to parse the remainder or reading some more data
- while newline_pos || !(buffer = read(@options[:line_buffer_size])).empty?
- prev_newline_pos = newline_pos || 0
- newline_pos = buffer.index(separator, prev_newline_pos)
-
- if newline_pos
- line << buffer[prev_newline_pos..newline_pos]
- newline_pos += 1
- yield line
- line = ''
- else
- line << buffer[prev_newline_pos..-1]
- end
- end
-
- # Flush the remainder if body doesn't end with separator
- yield line unless line.empty?
-
- return self
+ return nil
end
- alias lines each
- alias each_line each
-
end
end