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