lib/symmetric_encryption/writer.rb in symmetric-encryption-4.1.0.beta1 vs lib/symmetric_encryption/writer.rb in symmetric-encryption-4.1.0

- old
+ new

@@ -19,11 +19,11 @@ # avoid having the stream closed automatically. # # compress: [true|false] # Uses Zlib to compress the data before it is encrypted and # written to the file/stream. - # Default: false + # Default: true, unless the file_name extension indicates it is already compressed. # # Note: Compression occurs before encryption # # # Example: Encrypt and write data to a file # SymmetricEncryption::Writer.open('test_file.enc') do |file| @@ -45,15 +45,20 @@ # csv = CSV.new(SymmetricEncryption::Writer.open('csv.enc'), row_sep: "\n") # csv << [1,2,3,4,5] # ensure # csv.close if csv # end - def self.open(file_name_or_stream, compress: false, **args) - ios = file_name_or_stream.is_a?(String) ? ::File.open(file_name_or_stream, 'wb') : file_name_or_stream + def self.open(file_name_or_stream, compress: nil, **args) + if file_name_or_stream.is_a?(String) + file_name_or_stream = ::File.open(file_name_or_stream, 'wb') + compress = !(/\.(zip|gz|gzip|xls.|)\z/i === file_name_or_stream) if compress.nil? + else + compress = true if compress.nil? + end begin - file = new(ios, compress: compress, **args) + file = new(file_name_or_stream, compress: compress, **args) file = Zlib::GzipWriter.new(file) if compress block_given? ? yield(file) : file ensure file.close if block_given? && file && (file.respond_to?(:closed?) && !file.closed?) end @@ -62,11 +67,11 @@ # Write the contents of a string in memory to an encrypted file / stream. # # Notes: # * Do not use this method for writing large files. def self.write(file_name_or_stream, data, **args) - self.open(file_name_or_stream, **args) { |f| f.write(data) } + Writer.open(file_name_or_stream, **args) { |f| f.write(data) } end # Encrypt an entire file. # # Returns [Integer] the number of encrypted bytes written to the target file. @@ -80,26 +85,14 @@ # # compress: [true|false] # Whether to compress the target file prior to encryption. # Default: false # - # block_size: [Integer] - # Number of bytes to read into memory for each read. - # 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.encrypt(source:, target:, block_size: 65_535, **args) - source_ios = source.is_a?(String) ? ::File.open(source, 'rb') : source - bytes_written = 0 - self.open(target, **args) do |output_file| - bytes_written += output_file.write(source_ios.read(block_size)) until source_ios.eof? - end - bytes_written - ensure - source_ios.close if source_ios&.respond_to?(:closed?) && !source_ios.closed? + def self.encrypt(source:, target:, **args) + Writer.open(target, **args) { |output_file| IO.copy_stream(source, output_file) } end # Encrypt data before writing to the supplied stream def initialize(ios, version: nil, cipher_name: nil, header: true, random_key: true, random_iv: true, compress: false) # Compress is only used at this point for setting the flag in the header @@ -147,10 +140,11 @@ # It is recommended to call Symmetric::EncryptedStream.open # rather than creating an instance of Symmetric::Writer directly to # ensure that the encrypted stream is closed before the stream itself is closed. def close(close_child_stream = true) return if closed? + if size.positive? final = @stream_cipher.final @ios.write(final) unless final.empty? end @ios.close if close_child_stream @@ -158,17 +152,29 @@ end # Write to the IO Stream as encrypted data. # # Returns [Integer] the number of bytes written. - def write(data) - return unless data + if defined?(JRuby) + def write(data) + return unless data - bytes = data.to_s - @size += bytes.size - partial = @stream_cipher.update(bytes) - @ios.write(partial) unless partial.empty? - data.length + bytes = data.to_s + @size += bytes.size + partial = @stream_cipher.update(bytes) + @ios.write(partial) unless partial.empty? + data.length + end + else + def write(data) + return unless data + + bytes = data.to_s + @size += bytes.size + partial = @stream_cipher.update(bytes, @cipher_buffer ||= ''.b) + @ios.write(partial) unless partial.empty? + data.length + end end # Write to the IO Stream as encrypted data. # # Returns [SymmetricEncryption::Writer] self