lib/symmetric_encryption/reader.rb in symmetric-encryption-4.0.0 vs lib/symmetric_encryption/reader.rb in symmetric-encryption-4.0.1

- old
+ new

@@ -57,15 +57,15 @@ # csv = CSV.new(SymmetricEncryption::Reader.open('csv_encrypted')) # csv.each {|row| p row} # ensure # csv.close if csv # end - def self.open(file_name_or_stream, buffer_size: 16384, **args, &block) + def self.open(file_name_or_stream, buffer_size: 16_384, **args, &block) ios = file_name_or_stream.is_a?(String) ? ::File.open(file_name_or_stream, 'rb') : file_name_or_stream begin - file = self.new(ios, buffer_size: buffer_size, **args) + file = new(ios, buffer_size: buffer_size, **args) file = Zlib::GzipReader.new(file) if !file.eof? && file.compressed? block ? block.call(file) : file ensure file.close if block && file && (file.respond_to?(:closed?) && !file.closed?) end @@ -74,11 +74,11 @@ # Read the entire contents of a file or stream into memory. # # Notes: # * Do not use this method for reading large files. def self.read(file_name_or_stream, **args) - open(file_name_or_stream, **args) { |f| f.read } + self.open(file_name_or_stream, **args, &:read) end # Decrypt an entire file. # # Returns [Integer] the number of unencrypted bytes written to the target file. @@ -95,27 +95,25 @@ # For very large files using a larger block size is faster. # Default: 65535 # # Notes: # * The file contents are streamed so that the entire file is _not_ loaded into memory. - def self.decrypt(source:, target:, block_size: 65535, **args) + def self.decrypt(source:, target:, block_size: 65_535, **args) target_ios = target.is_a?(String) ? ::File.open(target, 'wb') : target bytes_written = 0 - open(source, **args) do |input_ios| - while !input_ios.eof? - bytes_written += target_ios.write(input_ios.read(block_size)) - end + self.open(source, **args) do |input_ios| + bytes_written += target_ios.write(input_ios.read(block_size)) until input_ios.eof? end bytes_written ensure - target_ios.close if target_ios && target_ios.respond_to?(:closed?) && !target_ios.closed? + target_ios.close if target_ios&.respond_to?(:closed?) && !target_ios.closed? end # Returns [true|false] whether the file or stream contains any data # excluding the header should it have one def self.empty?(file_name_or_stream) - open(file_name_or_stream) { |file| file.eof? } + open(file_name_or_stream, &:eof?) end # Returns [true|false] whether the file contains the encryption header def self.header_present?(file_name) ::File.open(file_name, 'rb') { |file| new(file).header_present? } @@ -159,13 +157,11 @@ # Returns nil when the header was not present in the stream and no :version # option was supplied # # Note: When no header is present, the version is set to the one supplied # in the options - def version - @version - end + attr_reader :version # Close the IO Stream # # Note: Also closes the passed in io stream or file # @@ -196,36 +192,34 @@ # Reads at most length bytes from the I/O stream, or to the end of file if # length is omitted or is nil. length must be a non-negative integer or nil. # # At end of file, it returns nil if no more data is available, or the last # remaining bytes - def read(length=nil) + def read(length = nil) data = nil if length - return '' if length == 0 + return '' if length.zero? return nil if eof? # Read length bytes - while (@read_buffer.length < length) && !@ios.eof? - read_block - end - if @read_buffer.length == 0 + read_block while (@read_buffer.length < length) && !@ios.eof? + if @read_buffer.empty? data = nil elsif @read_buffer.length > length - data = @read_buffer.slice!(0..length-1) + data = @read_buffer.slice!(0..length - 1) else data = @read_buffer @read_buffer = '' end else # Capture anything already in the buffer data = @read_buffer @read_buffer = '' - if !@ios.eof? + unless @ios.eof? # Read entire file buf = @ios.read || '' - data << @stream_cipher.update(buf) if buf && buf.length > 0 + data << @stream_cipher.update(buf) if buf && !buf.empty? data << @stream_cipher.final end end @pos += data.length data @@ -233,54 +227,50 @@ # Reads a single decrypted line from the file up to and including the optional sep_string. # Raises EOFError on eof # The stream must be opened for reading or an IOError will be raised. def readline(sep_string = "\n") - gets(sep_string) || raise(EOFError.new('End of file reached when trying to read a line')) + gets(sep_string) || raise(EOFError, 'End of file reached when trying to read a line') end # Reads a single decrypted line from the file up to and including the optional sep_string. # A sep_string of nil reads the entire contents of the file # Returns nil on eof # The stream must be opened for reading or an IOError will be raised. - def gets(sep_string, length=nil) + def gets(sep_string, length = nil) return read(length) if sep_string.nil? # Read more data until we get the sep_string while (index = @read_buffer.index(sep_string)).nil? && !@ios.eof? break if length && @read_buffer.length >= length read_block end index ||= -1 data = @read_buffer.slice!(0..index) @pos += data.length - return nil if data.length == 0 && eof? + return nil if data.empty? && eof? data end # ios.each(sep_string="\n") {|line| block } => ios # ios.each_line(sep_string="\n") {|line| block } => ios # Executes the block for every line in ios, where lines are separated by sep_string. # ios must be opened for reading or an IOError will be raised. def each_line(sep_string = "\n") - while !eof? - yield gets(sep_string) - end + yield gets(sep_string) until eof? self end - alias_method :each, :each_line + alias each each_line # Returns whether the end of file has been reached for this stream def eof? - (@read_buffer.size == 0) && @ios.eof? + @read_buffer.empty? && @ios.eof? end # Return the number of bytes read so far from the input stream - def pos - @pos - end + attr_reader :pos # Rewind back to the beginning of the file def rewind @read_buffer = '' @ios.rewind @@ -297,11 +287,11 @@ # # WARNING: IO::SEEK_SET will jump to the beginning of the file and # then re-read upto the point specified # WARNING: IO::SEEK_END will read the entire file and then again # upto the point specified - def seek(amount, whence=IO::SEEK_SET) + def seek(amount, whence = IO::SEEK_SET) offset = 0 case whence when IO::SEEK_SET offset = amount rewind @@ -315,21 +305,21 @@ when IO::SEEK_END rewind # Read and decrypt entire file a block at a time to get its total # unencrypted size size = 0 - while !eof + until eof read_block size += @read_buffer.size @read_buffer = '' end rewind offset = size + amount else raise(ArgumentError, "unknown whence:#{whence} supplied to seek()") end - read(offset) if offset > 0 + read(offset) if offset.positive? 0 end private @@ -362,26 +352,25 @@ @stream_cipher.decrypt @stream_cipher.key = key || cipher.send(:key) @stream_cipher.iv = iv || cipher.iv # First call to #update should return an empty string anyway - if buf && buf.length > 0 + if buf && !buf.empty? @read_buffer = @stream_cipher.update(buf) @read_buffer << @stream_cipher.final if @ios.eof? else @read_buffer = '' end end # Read a block of data and append the decrypted data in the read buffer def read_block buf = @ios.read(@buffer_size) - @read_buffer << @stream_cipher.update(buf) if buf && buf.length > 0 + @read_buffer << @stream_cipher.update(buf) if buf && !buf.empty? @read_buffer << @stream_cipher.final if @ios.eof? end def closed? @closed || @ios.respond_to?(:closed?) && @ios.closed? end - end end