adsp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/AUTHORS +1 -0
 - data/LICENSE +21 -0
 - data/README.md +300 -0
 - data/lib/adsp/error.rb +14 -0
 - data/lib/adsp/file.rb +76 -0
 - data/lib/adsp/option.rb +51 -0
 - data/lib/adsp/stream/abstract.rb +206 -0
 - data/lib/adsp/stream/delegates.rb +39 -0
 - data/lib/adsp/stream/raw/abstract.rb +69 -0
 - data/lib/adsp/stream/raw/compressor.rb +110 -0
 - data/lib/adsp/stream/raw/decompressor.rb +80 -0
 - data/lib/adsp/stream/raw/native_compressor.rb +58 -0
 - data/lib/adsp/stream/raw/native_decompressor.rb +44 -0
 - data/lib/adsp/stream/reader.rb +234 -0
 - data/lib/adsp/stream/reader_helpers.rb +219 -0
 - data/lib/adsp/stream/stat.rb +80 -0
 - data/lib/adsp/stream/writer.rb +206 -0
 - data/lib/adsp/stream/writer_helpers.rb +102 -0
 - data/lib/adsp/string.rb +58 -0
 - data/lib/adsp/validation.rb +46 -0
 - data/lib/adsp/version.rb +7 -0
 - data/lib/adsp.rb +8 -0
 - data/test/common.rb +108 -0
 - data/test/coverage_helper.rb +18 -0
 - data/test/file.test.rb +120 -0
 - data/test/minitest.rb +20 -0
 - data/test/mock/common.rb +57 -0
 - data/test/mock/file.rb +60 -0
 - data/test/mock/stream/raw/compressor.rb +20 -0
 - data/test/mock/stream/raw/decompressor.rb +20 -0
 - data/test/mock/stream/raw/native_compressor.rb +82 -0
 - data/test/mock/stream/raw/native_decompressor.rb +70 -0
 - data/test/mock/stream/reader.rb +18 -0
 - data/test/mock/stream/writer.rb +18 -0
 - data/test/mock/string.rb +44 -0
 - data/test/option.rb +66 -0
 - data/test/stream/abstract.rb +125 -0
 - data/test/stream/minitar.test.rb +50 -0
 - data/test/stream/raw/abstract.rb +45 -0
 - data/test/stream/raw/compressor.test.rb +166 -0
 - data/test/stream/raw/decompressor.test.rb +166 -0
 - data/test/stream/reader.test.rb +643 -0
 - data/test/stream/reader_helpers.test.rb +421 -0
 - data/test/stream/writer.test.rb +610 -0
 - data/test/stream/writer_helpers.test.rb +267 -0
 - data/test/string.test.rb +95 -0
 - data/test/validation.rb +71 -0
 - data/test/version.test.rb +18 -0
 - metadata +274 -0
 
| 
         @@ -0,0 +1,219 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Abstract data stream processor.
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Copyright (c) 2021 AUTHORS, MIT License.
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require "English"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            require_relative "../validation"
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            module ADSP
         
     | 
| 
      
 9 
     | 
    
         
            +
              module Stream
         
     | 
| 
      
 10 
     | 
    
         
            +
                # ADSP::Stream::ReaderHelpers module.
         
     | 
| 
      
 11 
     | 
    
         
            +
                module ReaderHelpers
         
     | 
| 
      
 12 
     | 
    
         
            +
                  # Returns next byte.
         
     | 
| 
      
 13 
     | 
    
         
            +
                  def getbyte
         
     | 
| 
      
 14 
     | 
    
         
            +
                    read 1
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  # Yields each byte.
         
     | 
| 
      
 18 
     | 
    
         
            +
                  def each_byte(&block)
         
     | 
| 
      
 19 
     | 
    
         
            +
                    each_string method(:getbyte), &block
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  # Returns next byte.
         
     | 
| 
      
 23 
     | 
    
         
            +
                  # Raises +::EOFError+ when no data available.
         
     | 
| 
      
 24 
     | 
    
         
            +
                  def readbyte
         
     | 
| 
      
 25 
     | 
    
         
            +
                    readstring method(:getbyte)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                  # Pushes back +byte+.
         
     | 
| 
      
 29 
     | 
    
         
            +
                  def ungetbyte(byte)
         
     | 
| 
      
 30 
     | 
    
         
            +
                    Validation.validate_string byte
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                    @buffer.prepend byte
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 35 
     | 
    
         
            +
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                  # -- char --
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                  # Returns next char.
         
     | 
| 
      
 40 
     | 
    
         
            +
                  def getc
         
     | 
| 
      
 41 
     | 
    
         
            +
                    if @external_encoding.nil?
         
     | 
| 
      
 42 
     | 
    
         
            +
                      byte = getbyte
         
     | 
| 
      
 43 
     | 
    
         
            +
                      return nil if byte.nil?
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                      return transcode_to_internal byte
         
     | 
| 
      
 46 
     | 
    
         
            +
                    end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                    char = ::String.new :encoding => ::Encoding::BINARY
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                    # Read one byte until valid string will appear.
         
     | 
| 
      
 51 
     | 
    
         
            +
                    loop do
         
     | 
| 
      
 52 
     | 
    
         
            +
                      byte = getbyte
         
     | 
| 
      
 53 
     | 
    
         
            +
                      return nil if byte.nil?
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                      char << byte
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                      char.force_encoding @external_encoding
         
     | 
| 
      
 58 
     | 
    
         
            +
                      return transcode_to_internal char if char.valid_encoding?
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                      char.force_encoding ::Encoding::BINARY
         
     | 
| 
      
 61 
     | 
    
         
            +
                    end
         
     | 
| 
      
 62 
     | 
    
         
            +
                  end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                  # Returns next char.
         
     | 
| 
      
 65 
     | 
    
         
            +
                  # Raises +::EOFError+ when no data available.
         
     | 
| 
      
 66 
     | 
    
         
            +
                  def readchar
         
     | 
| 
      
 67 
     | 
    
         
            +
                    readstring method(:getc)
         
     | 
| 
      
 68 
     | 
    
         
            +
                  end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                  # Yields each char.
         
     | 
| 
      
 71 
     | 
    
         
            +
                  def each_char(&block)
         
     | 
| 
      
 72 
     | 
    
         
            +
                    each_string method(:getc), &block
         
     | 
| 
      
 73 
     | 
    
         
            +
                  end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                  # Pushes back +char+.
         
     | 
| 
      
 76 
     | 
    
         
            +
                  def ungetc(char)
         
     | 
| 
      
 77 
     | 
    
         
            +
                    ungetstring char
         
     | 
| 
      
 78 
     | 
    
         
            +
                  end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                  # -- lines --
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                  # Returns next line by +separator+.
         
     | 
| 
      
 83 
     | 
    
         
            +
                  # Line length is limited by +limit+.
         
     | 
| 
      
 84 
     | 
    
         
            +
                  def gets(separator = $OUTPUT_RECORD_SEPARATOR, limit = nil)
         
     | 
| 
      
 85 
     | 
    
         
            +
                    # Limit can be a first argument.
         
     | 
| 
      
 86 
     | 
    
         
            +
                    if separator.is_a? ::Numeric
         
     | 
| 
      
 87 
     | 
    
         
            +
                      limit     = separator
         
     | 
| 
      
 88 
     | 
    
         
            +
                      separator = $OUTPUT_RECORD_SEPARATOR
         
     | 
| 
      
 89 
     | 
    
         
            +
                    end
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                    line_ending =
         
     | 
| 
      
 92 
     | 
    
         
            +
                      if separator.nil?
         
     | 
| 
      
 93 
     | 
    
         
            +
                        nil
         
     | 
| 
      
 94 
     | 
    
         
            +
                      else
         
     | 
| 
      
 95 
     | 
    
         
            +
                        Validation.validate_string separator
         
     | 
| 
      
 96 
     | 
    
         
            +
                        ::String.new separator, :encoding => target_encoding
         
     | 
| 
      
 97 
     | 
    
         
            +
                      end
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                    Validation.validate_positive_integer limit unless limit.nil?
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                    line = ::String.new :encoding => target_encoding
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
                    loop do
         
     | 
| 
      
 104 
     | 
    
         
            +
                      char = getc
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
                      if char.nil?
         
     | 
| 
      
 107 
     | 
    
         
            +
                        return nil if line.empty?
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
                        break
         
     | 
| 
      
 110 
     | 
    
         
            +
                      end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                      line << char
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                      break if
         
     | 
| 
      
 115 
     | 
    
         
            +
                        (!line_ending.nil? && line.end_with?(line_ending)) ||
         
     | 
| 
      
 116 
     | 
    
         
            +
                        (!limit.nil? && line.length >= limit)
         
     | 
| 
      
 117 
     | 
    
         
            +
                    end
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
                    @lineno += 1
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                    line
         
     | 
| 
      
 122 
     | 
    
         
            +
                  end
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
                  # Returns next line.
         
     | 
| 
      
 125 
     | 
    
         
            +
                  # Raises +::EOFError+ when no data available.
         
     | 
| 
      
 126 
     | 
    
         
            +
                  def readline
         
     | 
| 
      
 127 
     | 
    
         
            +
                    readstring method(:gets)
         
     | 
| 
      
 128 
     | 
    
         
            +
                  end
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
                  # Returns all available lines.
         
     | 
| 
      
 131 
     | 
    
         
            +
                  def readlines
         
     | 
| 
      
 132 
     | 
    
         
            +
                    lines = []
         
     | 
| 
      
 133 
     | 
    
         
            +
                    each_line { |line| lines << line }
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
                    lines
         
     | 
| 
      
 136 
     | 
    
         
            +
                  end
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
                  # Yields each line.
         
     | 
| 
      
 139 
     | 
    
         
            +
                  def each_line(&block)
         
     | 
| 
      
 140 
     | 
    
         
            +
                    each_string method(:gets), &block
         
     | 
| 
      
 141 
     | 
    
         
            +
                  end
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
                  alias each each_line
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
                  # Pushes back +line+.
         
     | 
| 
      
 146 
     | 
    
         
            +
                  def ungetline(line)
         
     | 
| 
      
 147 
     | 
    
         
            +
                    ungetstring line
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
                    @lineno -= 1
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 152 
     | 
    
         
            +
                  end
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                  # -- common --
         
     | 
| 
      
 155 
     | 
    
         
            +
             
     | 
| 
      
 156 
     | 
    
         
            +
                  # Returns next string by +each_proc+.
         
     | 
| 
      
 157 
     | 
    
         
            +
                  # Raises +::EOFError+ when no data available.
         
     | 
| 
      
 158 
     | 
    
         
            +
                  protected def readstring(each_proc)
         
     | 
| 
      
 159 
     | 
    
         
            +
                    string = each_proc.call
         
     | 
| 
      
 160 
     | 
    
         
            +
                    raise ::EOFError if string.nil?
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
                    string
         
     | 
| 
      
 163 
     | 
    
         
            +
                  end
         
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
      
 165 
     | 
    
         
            +
                  # Yields each string by +each_proc+.
         
     | 
| 
      
 166 
     | 
    
         
            +
                  protected def each_string(each_proc, &block)
         
     | 
| 
      
 167 
     | 
    
         
            +
                    return enum_for __method__, each_proc unless block.is_a? ::Proc
         
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
      
 169 
     | 
    
         
            +
                    loop do
         
     | 
| 
      
 170 
     | 
    
         
            +
                      string = each_proc.call
         
     | 
| 
      
 171 
     | 
    
         
            +
                      break if string.nil?
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
                      yield string
         
     | 
| 
      
 174 
     | 
    
         
            +
                    end
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 177 
     | 
    
         
            +
                  end
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
      
 179 
     | 
    
         
            +
                  # Pushes back +string+.
         
     | 
| 
      
 180 
     | 
    
         
            +
                  protected def ungetstring(string)
         
     | 
| 
      
 181 
     | 
    
         
            +
                    Validation.validate_string string
         
     | 
| 
      
 182 
     | 
    
         
            +
             
     | 
| 
      
 183 
     | 
    
         
            +
                    string = ::String.new string, :encoding => @internal_encoding unless @internal_encoding.nil?
         
     | 
| 
      
 184 
     | 
    
         
            +
                    string = transcode_to_external string unless @external_encoding.nil?
         
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
                    string.force_encoding ::Encoding::BINARY
         
     | 
| 
      
 187 
     | 
    
         
            +
                    @buffer.prepend string
         
     | 
| 
      
 188 
     | 
    
         
            +
             
     | 
| 
      
 189 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 190 
     | 
    
         
            +
                  end
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
                  # -- etc --
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
                  # Additional class methods for reader.
         
     | 
| 
      
 195 
     | 
    
         
            +
                  module ClassMethods
         
     | 
| 
      
 196 
     | 
    
         
            +
                    # Opens +file_path+ in binary mode, creates reader and yields it.
         
     | 
| 
      
 197 
     | 
    
         
            +
                    def open(file_path, *args, &block)
         
     | 
| 
      
 198 
     | 
    
         
            +
                      Validation.validate_string file_path
         
     | 
| 
      
 199 
     | 
    
         
            +
                      Validation.validate_proc block
         
     | 
| 
      
 200 
     | 
    
         
            +
             
     | 
| 
      
 201 
     | 
    
         
            +
                      ::File.open file_path, "rb" do |io|
         
     | 
| 
      
 202 
     | 
    
         
            +
                        reader = new io, *args
         
     | 
| 
      
 203 
     | 
    
         
            +
             
     | 
| 
      
 204 
     | 
    
         
            +
                        begin
         
     | 
| 
      
 205 
     | 
    
         
            +
                          yield reader
         
     | 
| 
      
 206 
     | 
    
         
            +
                        ensure
         
     | 
| 
      
 207 
     | 
    
         
            +
                          reader.close
         
     | 
| 
      
 208 
     | 
    
         
            +
                        end
         
     | 
| 
      
 209 
     | 
    
         
            +
                      end
         
     | 
| 
      
 210 
     | 
    
         
            +
                    end
         
     | 
| 
      
 211 
     | 
    
         
            +
                  end
         
     | 
| 
      
 212 
     | 
    
         
            +
             
     | 
| 
      
 213 
     | 
    
         
            +
                  # Extends target +klass+ with additional class methods.
         
     | 
| 
      
 214 
     | 
    
         
            +
                  def self.included(klass)
         
     | 
| 
      
 215 
     | 
    
         
            +
                    klass.extend ClassMethods
         
     | 
| 
      
 216 
     | 
    
         
            +
                  end
         
     | 
| 
      
 217 
     | 
    
         
            +
                end
         
     | 
| 
      
 218 
     | 
    
         
            +
              end
         
     | 
| 
      
 219 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,80 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Abstract data stream processor.
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Copyright (c) 2021 AUTHORS, MIT License.
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require "forwardable"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            module ADSP
         
     | 
| 
      
 7 
     | 
    
         
            +
              module Stream
         
     | 
| 
      
 8 
     | 
    
         
            +
                # ADSP::Stream::Stat class.
         
     | 
| 
      
 9 
     | 
    
         
            +
                class Stat
         
     | 
| 
      
 10 
     | 
    
         
            +
                  # Libraries like minitar tries to access stat to know whether stream is seekable.
         
     | 
| 
      
 11 
     | 
    
         
            +
                  # We need to mark stream as not directory, file, etc, because it is not seekable.
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  extend ::Forwardable
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  # List of methods returning false.
         
     | 
| 
      
 16 
     | 
    
         
            +
                  METHODS_RETURNING_FALSE = %i[
         
     | 
| 
      
 17 
     | 
    
         
            +
                    blockdev?
         
     | 
| 
      
 18 
     | 
    
         
            +
                    chardev?
         
     | 
| 
      
 19 
     | 
    
         
            +
                    directory?
         
     | 
| 
      
 20 
     | 
    
         
            +
                    executable?
         
     | 
| 
      
 21 
     | 
    
         
            +
                    executable_real?
         
     | 
| 
      
 22 
     | 
    
         
            +
                    file?
         
     | 
| 
      
 23 
     | 
    
         
            +
                    grpowned?
         
     | 
| 
      
 24 
     | 
    
         
            +
                    owned?
         
     | 
| 
      
 25 
     | 
    
         
            +
                    pipe?
         
     | 
| 
      
 26 
     | 
    
         
            +
                    setgid?
         
     | 
| 
      
 27 
     | 
    
         
            +
                    setuid?
         
     | 
| 
      
 28 
     | 
    
         
            +
                    socket?
         
     | 
| 
      
 29 
     | 
    
         
            +
                    sticky?
         
     | 
| 
      
 30 
     | 
    
         
            +
                    symlink?
         
     | 
| 
      
 31 
     | 
    
         
            +
                    zero?
         
     | 
| 
      
 32 
     | 
    
         
            +
                  ]
         
     | 
| 
      
 33 
     | 
    
         
            +
                  .freeze
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  # List of methods to be forwarded for native stream status info.
         
     | 
| 
      
 36 
     | 
    
         
            +
                  DELEGATES = %i[
         
     | 
| 
      
 37 
     | 
    
         
            +
                    <=>
         
     | 
| 
      
 38 
     | 
    
         
            +
                    atime
         
     | 
| 
      
 39 
     | 
    
         
            +
                    birthtime
         
     | 
| 
      
 40 
     | 
    
         
            +
                    blksize
         
     | 
| 
      
 41 
     | 
    
         
            +
                    blocks
         
     | 
| 
      
 42 
     | 
    
         
            +
                    ctime
         
     | 
| 
      
 43 
     | 
    
         
            +
                    dev
         
     | 
| 
      
 44 
     | 
    
         
            +
                    dev_major
         
     | 
| 
      
 45 
     | 
    
         
            +
                    dev_minor
         
     | 
| 
      
 46 
     | 
    
         
            +
                    ftype
         
     | 
| 
      
 47 
     | 
    
         
            +
                    gid
         
     | 
| 
      
 48 
     | 
    
         
            +
                    ino
         
     | 
| 
      
 49 
     | 
    
         
            +
                    inspect
         
     | 
| 
      
 50 
     | 
    
         
            +
                    mode
         
     | 
| 
      
 51 
     | 
    
         
            +
                    mtime
         
     | 
| 
      
 52 
     | 
    
         
            +
                    nlink
         
     | 
| 
      
 53 
     | 
    
         
            +
                    rdev
         
     | 
| 
      
 54 
     | 
    
         
            +
                    rdev_major
         
     | 
| 
      
 55 
     | 
    
         
            +
                    rdev_minor
         
     | 
| 
      
 56 
     | 
    
         
            +
                    readable?
         
     | 
| 
      
 57 
     | 
    
         
            +
                    readable_real?
         
     | 
| 
      
 58 
     | 
    
         
            +
                    size
         
     | 
| 
      
 59 
     | 
    
         
            +
                    size?
         
     | 
| 
      
 60 
     | 
    
         
            +
                    uid
         
     | 
| 
      
 61 
     | 
    
         
            +
                    world_readable?
         
     | 
| 
      
 62 
     | 
    
         
            +
                    world_writable?
         
     | 
| 
      
 63 
     | 
    
         
            +
                    writable?
         
     | 
| 
      
 64 
     | 
    
         
            +
                    writable_real?
         
     | 
| 
      
 65 
     | 
    
         
            +
                  ]
         
     | 
| 
      
 66 
     | 
    
         
            +
                  .freeze
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                  # Initializes status info based on native stream +stat+.
         
     | 
| 
      
 69 
     | 
    
         
            +
                  def initialize(stat)
         
     | 
| 
      
 70 
     | 
    
         
            +
                    @stat = stat
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                  METHODS_RETURNING_FALSE.each do |method_name|
         
     | 
| 
      
 74 
     | 
    
         
            +
                    define_method(method_name) { false }
         
     | 
| 
      
 75 
     | 
    
         
            +
                  end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                  def_delegators :@stat, *DELEGATES
         
     | 
| 
      
 78 
     | 
    
         
            +
                end
         
     | 
| 
      
 79 
     | 
    
         
            +
              end
         
     | 
| 
      
 80 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,206 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Abstract data stream processor.
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Copyright (c) 2021 AUTHORS, MIT License.
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative "abstract"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require_relative "raw/compressor"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require_relative "writer_helpers"
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            module ADSP
         
     | 
| 
      
 9 
     | 
    
         
            +
              module Stream
         
     | 
| 
      
 10 
     | 
    
         
            +
                # ADSP::Stream::Writer class.
         
     | 
| 
      
 11 
     | 
    
         
            +
                class Writer < Abstract
         
     | 
| 
      
 12 
     | 
    
         
            +
                  include WriterHelpers
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  # Current raw stream class.
         
     | 
| 
      
 15 
     | 
    
         
            +
                  RawCompressor = Raw::Compressor
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  # Initializes stream using +destination_io+ native stream and +options+.
         
     | 
| 
      
 18 
     | 
    
         
            +
                  # Option: +:external_encoding+ encoding name for destination data.
         
     | 
| 
      
 19 
     | 
    
         
            +
                  # Option: +:internal_encoding+ encoding name for source data.
         
     | 
| 
      
 20 
     | 
    
         
            +
                  # Option: +:transcode_options+ transcode options for data.
         
     | 
| 
      
 21 
     | 
    
         
            +
                  def initialize(destination_io, options = {}, *args)
         
     | 
| 
      
 22 
     | 
    
         
            +
                    @options = options
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                    super destination_io, *args
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  # Creates raw stream.
         
     | 
| 
      
 28 
     | 
    
         
            +
                  protected def create_raw_stream
         
     | 
| 
      
 29 
     | 
    
         
            +
                    self.class::RawCompressor.new @options
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  # -- synchronous --
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  # Writes +objects+ to stream.
         
     | 
| 
      
 35 
     | 
    
         
            +
                  def write(*objects)
         
     | 
| 
      
 36 
     | 
    
         
            +
                    validate_write
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                    write_remaining_buffer
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                    bytes_written = 0
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                    objects.each do |object|
         
     | 
| 
      
 43 
     | 
    
         
            +
                      source         = transcode object.to_s
         
     | 
| 
      
 44 
     | 
    
         
            +
                      bytes_written += raw_wrapper :write, source
         
     | 
| 
      
 45 
     | 
    
         
            +
                    end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                    @pos += bytes_written
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                    bytes_written
         
     | 
| 
      
 50 
     | 
    
         
            +
                  end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                  # Flushes stream.
         
     | 
| 
      
 53 
     | 
    
         
            +
                  def flush
         
     | 
| 
      
 54 
     | 
    
         
            +
                    validate_write
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                    finish :flush
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                    @io.flush if @io.respond_to? :flush
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                    self
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                  # Resets stream.
         
     | 
| 
      
 64 
     | 
    
         
            +
                  def rewind
         
     | 
| 
      
 65 
     | 
    
         
            +
                    validate_write
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                    finish :close
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                    super
         
     | 
| 
      
 70 
     | 
    
         
            +
                  end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                  # Closes stream.
         
     | 
| 
      
 73 
     | 
    
         
            +
                  def close
         
     | 
| 
      
 74 
     | 
    
         
            +
                    validate_write
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                    finish :close
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                    super
         
     | 
| 
      
 79 
     | 
    
         
            +
                  end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                  # Finishes stream using +method_name+.
         
     | 
| 
      
 82 
     | 
    
         
            +
                  protected def finish(method_name)
         
     | 
| 
      
 83 
     | 
    
         
            +
                    write_remaining_buffer
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                    raw_wrapper method_name
         
     | 
| 
      
 86 
     | 
    
         
            +
                  end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                  # Writes remaining buffer and resets it.
         
     | 
| 
      
 89 
     | 
    
         
            +
                  protected def write_remaining_buffer
         
     | 
| 
      
 90 
     | 
    
         
            +
                    return nil if @buffer.bytesize.zero?
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                    @io.write @buffer
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                    reset_buffer
         
     | 
| 
      
 95 
     | 
    
         
            +
                  end
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                  # Wraps +method_name+ for raw stream.
         
     | 
| 
      
 98 
     | 
    
         
            +
                  protected def raw_wrapper(method_name, *args)
         
     | 
| 
      
 99 
     | 
    
         
            +
                    @raw_stream.send(method_name, *args) { |portion| @io.write portion }
         
     | 
| 
      
 100 
     | 
    
         
            +
                  end
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                  # Validates native stream responsibility to +write+ method.
         
     | 
| 
      
 103 
     | 
    
         
            +
                  protected def validate_write
         
     | 
| 
      
 104 
     | 
    
         
            +
                    raise ValidateError, "io should be responsible to write" unless @io.respond_to? :write
         
     | 
| 
      
 105 
     | 
    
         
            +
                  end
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                  # -- asynchronous --
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
                  # Writes +object+ nonblock.
         
     | 
| 
      
 110 
     | 
    
         
            +
                  # +options+ will be passed to native stream.
         
     | 
| 
      
 111 
     | 
    
         
            +
                  # Native stream +write_nonblock+ can raise +IO::WaitWritable+ error.
         
     | 
| 
      
 112 
     | 
    
         
            +
                  # After resolving this error user may provide same content again.
         
     | 
| 
      
 113 
     | 
    
         
            +
                  # It is not possible to revert accepted content after error.
         
     | 
| 
      
 114 
     | 
    
         
            +
                  # So we have to accept content after processing native stream +write_nonblock+.
         
     | 
| 
      
 115 
     | 
    
         
            +
                  # It means that first write nonblock won't call native stream +write_nonblock+.
         
     | 
| 
      
 116 
     | 
    
         
            +
                  def write_nonblock(object, *options)
         
     | 
| 
      
 117 
     | 
    
         
            +
                    validate_write_nonblock
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
                    return 0 unless write_remaining_buffer_nonblock(*options)
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                    source         = transcode object.to_s
         
     | 
| 
      
 122 
     | 
    
         
            +
                    bytes_written  = raw_nonblock_wrapper :write, source
         
     | 
| 
      
 123 
     | 
    
         
            +
                    @pos          += bytes_written
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
                    bytes_written
         
     | 
| 
      
 126 
     | 
    
         
            +
                  end
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
                  # Flushes stream nonblock.
         
     | 
| 
      
 129 
     | 
    
         
            +
                  # +options+ will be passed to native stream.
         
     | 
| 
      
 130 
     | 
    
         
            +
                  def flush_nonblock(*options)
         
     | 
| 
      
 131 
     | 
    
         
            +
                    validate_write_nonblock
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
                    return false unless finish_nonblock :flush, *options
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
                    @io.flush if @io.respond_to? :flush
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
                    true
         
     | 
| 
      
 138 
     | 
    
         
            +
                  end
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
                  # Resets stream nonblock.
         
     | 
| 
      
 141 
     | 
    
         
            +
                  # +options+ will be passed to native stream.
         
     | 
| 
      
 142 
     | 
    
         
            +
                  def rewind_nonblock(*options)
         
     | 
| 
      
 143 
     | 
    
         
            +
                    validate_write_nonblock
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
                    return false unless finish_nonblock :close, *options
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
                    method(:rewind).super_method.call
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
                    true
         
     | 
| 
      
 150 
     | 
    
         
            +
                  end
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
                  # Closes stream nonblock.
         
     | 
| 
      
 153 
     | 
    
         
            +
                  # +options+ will be passed to native stream.
         
     | 
| 
      
 154 
     | 
    
         
            +
                  def close_nonblock(*options)
         
     | 
| 
      
 155 
     | 
    
         
            +
                    validate_write_nonblock
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
                    return false unless finish_nonblock :close, *options
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
                    method(:close).super_method.call
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
                    true
         
     | 
| 
      
 162 
     | 
    
         
            +
                  end
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
                  # Finishes stream using +method_name+ nonblock.
         
     | 
| 
      
 165 
     | 
    
         
            +
                  # +options+ will be passed to native stream.
         
     | 
| 
      
 166 
     | 
    
         
            +
                  protected def finish_nonblock(method_name, *options)
         
     | 
| 
      
 167 
     | 
    
         
            +
                    return false unless write_remaining_buffer_nonblock(*options)
         
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
      
 169 
     | 
    
         
            +
                    raw_nonblock_wrapper method_name
         
     | 
| 
      
 170 
     | 
    
         
            +
             
     | 
| 
      
 171 
     | 
    
         
            +
                    write_remaining_buffer_nonblock(*options)
         
     | 
| 
      
 172 
     | 
    
         
            +
                  end
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
      
 174 
     | 
    
         
            +
                  # Writes remaining buffer nonblock.
         
     | 
| 
      
 175 
     | 
    
         
            +
                  # +options+ will be passed to native stream.
         
     | 
| 
      
 176 
     | 
    
         
            +
                  protected def write_remaining_buffer_nonblock(*options)
         
     | 
| 
      
 177 
     | 
    
         
            +
                    return true if @buffer.bytesize.zero?
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
      
 179 
     | 
    
         
            +
                    bytes_written = @io.write_nonblock @buffer, *options
         
     | 
| 
      
 180 
     | 
    
         
            +
                    return false if bytes_written.zero?
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
                    @buffer = @buffer.byteslice bytes_written, @buffer.bytesize - bytes_written
         
     | 
| 
      
 183 
     | 
    
         
            +
             
     | 
| 
      
 184 
     | 
    
         
            +
                    @buffer.bytesize.zero?
         
     | 
| 
      
 185 
     | 
    
         
            +
                  end
         
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
                  # Wraps nonblock +method_name+ for raw stream.
         
     | 
| 
      
 188 
     | 
    
         
            +
                  protected def raw_nonblock_wrapper(method_name, *args)
         
     | 
| 
      
 189 
     | 
    
         
            +
                    @raw_stream.send(method_name, *args) { |portion| @buffer << portion }
         
     | 
| 
      
 190 
     | 
    
         
            +
                  end
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
                  # Validates native stream responsibility to +write_nonblock+ method.
         
     | 
| 
      
 193 
     | 
    
         
            +
                  protected def validate_write_nonblock
         
     | 
| 
      
 194 
     | 
    
         
            +
                    raise ValidateError, "io should be responsible to write nonblock" unless @io.respond_to? :write_nonblock
         
     | 
| 
      
 195 
     | 
    
         
            +
                  end
         
     | 
| 
      
 196 
     | 
    
         
            +
             
     | 
| 
      
 197 
     | 
    
         
            +
                  # -- common --
         
     | 
| 
      
 198 
     | 
    
         
            +
             
     | 
| 
      
 199 
     | 
    
         
            +
                  # Transcodes +data+ to external encoding.
         
     | 
| 
      
 200 
     | 
    
         
            +
                  protected def transcode(data)
         
     | 
| 
      
 201 
     | 
    
         
            +
                    data = data.encode @external_encoding, **@transcode_options unless @external_encoding.nil?
         
     | 
| 
      
 202 
     | 
    
         
            +
                    data
         
     | 
| 
      
 203 
     | 
    
         
            +
                  end
         
     | 
| 
      
 204 
     | 
    
         
            +
                end
         
     | 
| 
      
 205 
     | 
    
         
            +
              end
         
     | 
| 
      
 206 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,102 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Abstract data stream processor.
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Copyright (c) 2021 AUTHORS, MIT License.
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require "English"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            require_relative "../validation"
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            module ADSP
         
     | 
| 
      
 9 
     | 
    
         
            +
              module Stream
         
     | 
| 
      
 10 
     | 
    
         
            +
                # ADSP::Stream::WriterHelpers module.
         
     | 
| 
      
 11 
     | 
    
         
            +
                module WriterHelpers
         
     | 
| 
      
 12 
     | 
    
         
            +
                  # Writes +object+ to stream.
         
     | 
| 
      
 13 
     | 
    
         
            +
                  def <<(object)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    write object
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  # Writes +objects+ to stream.
         
     | 
| 
      
 18 
     | 
    
         
            +
                  # Uses +field_separator+ for each object.
         
     | 
| 
      
 19 
     | 
    
         
            +
                  # Uses +record_separator+ for group of objects.
         
     | 
| 
      
 20 
     | 
    
         
            +
                  def print(*objects, field_separator: $OUTPUT_FIELD_SEPARATOR, record_separator: $OUTPUT_RECORD_SEPARATOR)
         
     | 
| 
      
 21 
     | 
    
         
            +
                    objects.each do |object|
         
     | 
| 
      
 22 
     | 
    
         
            +
                      write object
         
     | 
| 
      
 23 
     | 
    
         
            +
                      write field_separator unless field_separator.nil?
         
     | 
| 
      
 24 
     | 
    
         
            +
                    end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                    write record_separator unless record_separator.nil?
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 29 
     | 
    
         
            +
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  # Formats each argument and writes to stream.
         
     | 
| 
      
 32 
     | 
    
         
            +
                  def printf(*args)
         
     | 
| 
      
 33 
     | 
    
         
            +
                    write sprintf(*args)
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  # Writes first char of +object+ to stream.
         
     | 
| 
      
 39 
     | 
    
         
            +
                  # Numeric object uses +encoding+ for providing first char.
         
     | 
| 
      
 40 
     | 
    
         
            +
                  def putc(object, encoding: ::Encoding::BINARY)
         
     | 
| 
      
 41 
     | 
    
         
            +
                    case object
         
     | 
| 
      
 42 
     | 
    
         
            +
                    when ::Numeric
         
     | 
| 
      
 43 
     | 
    
         
            +
                      write object.chr(encoding)
         
     | 
| 
      
 44 
     | 
    
         
            +
                    when ::String
         
     | 
| 
      
 45 
     | 
    
         
            +
                      write object[0]
         
     | 
| 
      
 46 
     | 
    
         
            +
                    else
         
     | 
| 
      
 47 
     | 
    
         
            +
                      raise ValidateError, "invalid object: \"#{object}\" for putc"
         
     | 
| 
      
 48 
     | 
    
         
            +
                    end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                    object
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  # Writes +objects+ to stream.
         
     | 
| 
      
 54 
     | 
    
         
            +
                  def puts(*objects)
         
     | 
| 
      
 55 
     | 
    
         
            +
                    objects.each do |object|
         
     | 
| 
      
 56 
     | 
    
         
            +
                      if object.is_a? ::Array
         
     | 
| 
      
 57 
     | 
    
         
            +
                        puts(*object)
         
     | 
| 
      
 58 
     | 
    
         
            +
                        next
         
     | 
| 
      
 59 
     | 
    
         
            +
                      end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                      source  = object.to_s
         
     | 
| 
      
 62 
     | 
    
         
            +
                      newline = "\n".encode source.encoding
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                      # Do not add newline if source ends with newline.
         
     | 
| 
      
 65 
     | 
    
         
            +
                      if source.end_with? newline
         
     | 
| 
      
 66 
     | 
    
         
            +
                        write source
         
     | 
| 
      
 67 
     | 
    
         
            +
                      else
         
     | 
| 
      
 68 
     | 
    
         
            +
                        write source + newline
         
     | 
| 
      
 69 
     | 
    
         
            +
                      end
         
     | 
| 
      
 70 
     | 
    
         
            +
                    end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 73 
     | 
    
         
            +
                  end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                  # -- etc --
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                  # Additional class methods for writer.
         
     | 
| 
      
 78 
     | 
    
         
            +
                  module ClassMethods
         
     | 
| 
      
 79 
     | 
    
         
            +
                    # Opens +file_path+ in binary mode, creates writer and yields it.
         
     | 
| 
      
 80 
     | 
    
         
            +
                    def open(file_path, *args, &block)
         
     | 
| 
      
 81 
     | 
    
         
            +
                      Validation.validate_string file_path
         
     | 
| 
      
 82 
     | 
    
         
            +
                      Validation.validate_proc block
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                      ::File.open file_path, "wb" do |io|
         
     | 
| 
      
 85 
     | 
    
         
            +
                        writer = new io, *args
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                        begin
         
     | 
| 
      
 88 
     | 
    
         
            +
                          yield writer
         
     | 
| 
      
 89 
     | 
    
         
            +
                        ensure
         
     | 
| 
      
 90 
     | 
    
         
            +
                          writer.close
         
     | 
| 
      
 91 
     | 
    
         
            +
                        end
         
     | 
| 
      
 92 
     | 
    
         
            +
                      end
         
     | 
| 
      
 93 
     | 
    
         
            +
                    end
         
     | 
| 
      
 94 
     | 
    
         
            +
                  end
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                  # Extends target +klass+ with additional class methods.
         
     | 
| 
      
 97 
     | 
    
         
            +
                  def self.included(klass)
         
     | 
| 
      
 98 
     | 
    
         
            +
                    klass.extend ClassMethods
         
     | 
| 
      
 99 
     | 
    
         
            +
                  end
         
     | 
| 
      
 100 
     | 
    
         
            +
                end
         
     | 
| 
      
 101 
     | 
    
         
            +
              end
         
     | 
| 
      
 102 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/adsp/string.rb
    ADDED
    
    | 
         @@ -0,0 +1,58 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Abstract data stream processor.
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Copyright (c) 2021 AUTHORS, MIT License.
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative "error"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require_relative "option"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require_relative "validation"
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            module ADSP
         
     | 
| 
      
 9 
     | 
    
         
            +
              # ADSP::String class.
         
     | 
| 
      
 10 
     | 
    
         
            +
              class String
         
     | 
| 
      
 11 
     | 
    
         
            +
                # Current option class.
         
     | 
| 
      
 12 
     | 
    
         
            +
                Option = ADSP::Option
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                # Current buffer length names.
         
     | 
| 
      
 15 
     | 
    
         
            +
                # It is a part of decompressor options.
         
     | 
| 
      
 16 
     | 
    
         
            +
                BUFFER_LENGTH_NAMES = %i[destination_buffer_length].freeze
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                # Compresses +source+ string using +options+.
         
     | 
| 
      
 19 
     | 
    
         
            +
                # Option: +:destination_buffer_length+ destination buffer length.
         
     | 
| 
      
 20 
     | 
    
         
            +
                # Returns compressed string.
         
     | 
| 
      
 21 
     | 
    
         
            +
                def self.compress(source, options = {})
         
     | 
| 
      
 22 
     | 
    
         
            +
                  Validation.validate_string source
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  options = self::Option.get_compressor_options options, BUFFER_LENGTH_NAMES
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  native_compress_string source, options
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                # :nocov:
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                # Internal method for compressing +source+ string using +options+.
         
     | 
| 
      
 32 
     | 
    
         
            +
                def self.native_compress_string(source, options)
         
     | 
| 
      
 33 
     | 
    
         
            +
                  raise NotImplementedError
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                # :nocov:
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                # Decompresses +source+ string using +options+.
         
     | 
| 
      
 39 
     | 
    
         
            +
                # Option: +:destination_buffer_length+ destination buffer length.
         
     | 
| 
      
 40 
     | 
    
         
            +
                # Returns decompressed string.
         
     | 
| 
      
 41 
     | 
    
         
            +
                def self.decompress(source, options = {})
         
     | 
| 
      
 42 
     | 
    
         
            +
                  Validation.validate_string source
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  options = self::Option.get_decompressor_options options, BUFFER_LENGTH_NAMES
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                  native_decompress_string source, options
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                # :nocov:
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                # Internal method for decompressing +source+ string using +options+.
         
     | 
| 
      
 52 
     | 
    
         
            +
                def self.native_decompress_string(source, options)
         
     | 
| 
      
 53 
     | 
    
         
            +
                  raise NotImplementedError
         
     | 
| 
      
 54 
     | 
    
         
            +
                end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                # :nocov:
         
     | 
| 
      
 57 
     | 
    
         
            +
              end
         
     | 
| 
      
 58 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,46 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Abstract data stream processor.
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Copyright (c) 2021 AUTHORS, MIT License.
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative "error"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            module ADSP
         
     | 
| 
      
 7 
     | 
    
         
            +
              # ADSP::Validation class.
         
     | 
| 
      
 8 
     | 
    
         
            +
              class Validation
         
     | 
| 
      
 9 
     | 
    
         
            +
                # Raises error when +value+ is not array.
         
     | 
| 
      
 10 
     | 
    
         
            +
                def self.validate_array(value)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  raise ValidateError, "invalid array" unless value.is_a? ::Array
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                # Raises error when +value+ is not hash.
         
     | 
| 
      
 15 
     | 
    
         
            +
                def self.validate_hash(value)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  raise ValidateError, "invalid hash" unless value.is_a? ::Hash
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                # Raises error when +value+ is not negative integer.
         
     | 
| 
      
 20 
     | 
    
         
            +
                def self.validate_not_negative_integer(value)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  raise ValidateError, "invalid not negative integer" unless value.is_a?(::Integer) && value >= 0
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                # Raises error when +value+ is not positive integer.
         
     | 
| 
      
 25 
     | 
    
         
            +
                def self.validate_positive_integer(value)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  raise ValidateError, "invalid positive integer" unless value.is_a?(::Integer) && value.positive?
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                # Raises error when +value+ is not proc.
         
     | 
| 
      
 30 
     | 
    
         
            +
                def self.validate_proc(value)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  unless value.is_a?(::Proc) || value.is_a?(::Method) || value.is_a?(::UnboundMethod)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    raise ValidateError, "invalid proc"
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                # Raises error when +value+ is not string.
         
     | 
| 
      
 37 
     | 
    
         
            +
                def self.validate_string(value)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  raise ValidateError, "invalid string" unless value.is_a? ::String
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                # Raises error when +value+ is not symbol.
         
     | 
| 
      
 42 
     | 
    
         
            +
                def self.validate_symbol(value)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  raise ValidateError, "invalid symbol" unless value.is_a? ::Symbol
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
            end
         
     |