File: decrypted_io.rb

package info (click to toggle)
ruby-zip 3.2.2-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 11,120 kB
  • sloc: ruby: 9,958; makefile: 23
file content (46 lines) | stat: -rw-r--r-- 1,006 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# frozen_string_literal: true

module Zip
  class DecryptedIo # :nodoc:all
    CHUNK_SIZE = 32_768

    def initialize(io, decrypter, compressed_size)
      @io = io
      @decrypter = decrypter
      @bytes_remaining = compressed_size
      @buffer = +''
    end

    def read(length = nil, outbuf = +'')
      return (length.nil? || length.zero? ? '' : nil) if eof?

      while length.nil? || (@buffer.bytesize < length)
        break if input_finished?

        @buffer << produce_input
      end

      @decrypter.check_integrity!(@io) if input_finished?

      outbuf.replace(@buffer.slice!(0...(length || @buffer.bytesize)))
    end

    private

    def eof?
      @buffer.empty? && input_finished?
    end

    def input_finished?
      !@bytes_remaining.positive?
    end

    def produce_input
      chunk_size = [@bytes_remaining, CHUNK_SIZE].min
      return '' unless chunk_size.positive?

      @bytes_remaining -= chunk_size
      @decrypter.decrypt(@io.read(chunk_size))
    end
  end
end