virtfs 0.0.1
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/.gitignore +18 -0
- data/.rspec +2 -0
- data/.travis.yml +8 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +154 -0
- data/Rakefile +5 -0
- data/lib/virtfs-nativefs-thick.rb +1 -0
- data/lib/virtfs-nativefs-thin.rb +1 -0
- data/lib/virtfs.rb +38 -0
- data/lib/virtfs/activation.rb +97 -0
- data/lib/virtfs/block_io.rb +140 -0
- data/lib/virtfs/byte_range.rb +71 -0
- data/lib/virtfs/context.rb +300 -0
- data/lib/virtfs/context_manager.rb +175 -0
- data/lib/virtfs/context_switch_class_methods.rb +96 -0
- data/lib/virtfs/delegate_module.rb +40 -0
- data/lib/virtfs/dir_instance_delegate.rb +3 -0
- data/lib/virtfs/exception.rb +13 -0
- data/lib/virtfs/file_instance_delegate.rb +3 -0
- data/lib/virtfs/file_modes_and_options.rb +293 -0
- data/lib/virtfs/find_class_methods.rb +106 -0
- data/lib/virtfs/io_buffer.rb +133 -0
- data/lib/virtfs/io_instance_delegate.rb +3 -0
- data/lib/virtfs/kernel.rb +146 -0
- data/lib/virtfs/nativefs/thick.rb +30 -0
- data/lib/virtfs/nativefs/thick/dir_class_methods.rb +38 -0
- data/lib/virtfs/nativefs/thick/file_class_methods.rb +178 -0
- data/lib/virtfs/nativefs/thin.rb +32 -0
- data/lib/virtfs/nativefs/thin/dir.rb +30 -0
- data/lib/virtfs/nativefs/thin/dir_class_methods.rb +41 -0
- data/lib/virtfs/nativefs/thin/file.rb +112 -0
- data/lib/virtfs/nativefs/thin/file_class_methods.rb +181 -0
- data/lib/virtfs/protofs/protofs.rb +7 -0
- data/lib/virtfs/protofs/protofs_base.rb +12 -0
- data/lib/virtfs/protofs/protofs_dir.rb +13 -0
- data/lib/virtfs/protofs/protofs_dir_class.rb +31 -0
- data/lib/virtfs/protofs/protofs_file.rb +27 -0
- data/lib/virtfs/protofs/protofs_file_class.rb +136 -0
- data/lib/virtfs/stat.rb +100 -0
- data/lib/virtfs/thin_dir_delegator.rb +79 -0
- data/lib/virtfs/thin_file_delegator.rb +77 -0
- data/lib/virtfs/thin_io_delegator_methods.rb +301 -0
- data/lib/virtfs/thin_io_delegator_methods_bufferio.rb +337 -0
- data/lib/virtfs/v_dir.rb +238 -0
- data/lib/virtfs/v_file.rb +480 -0
- data/lib/virtfs/v_io.rb +243 -0
- data/lib/virtfs/v_pathname.rb +128 -0
- data/lib/virtfs/version.rb +3 -0
- data/spec/activate_spec.rb +202 -0
- data/spec/chroot_spec.rb +120 -0
- data/spec/context_manager_class_spec.rb +246 -0
- data/spec/context_manager_instance_spec.rb +255 -0
- data/spec/context_spec.rb +335 -0
- data/spec/data/UTF-16LE-data.txt +0 -0
- data/spec/data/UTF-8-data.txt +212 -0
- data/spec/dir_class_spec.rb +506 -0
- data/spec/dir_instance_spec.rb +208 -0
- data/spec/file_class_spec.rb +2106 -0
- data/spec/file_instance_spec.rb +154 -0
- data/spec/file_modes_and_options_spec.rb +1556 -0
- data/spec/find_spec.rb +142 -0
- data/spec/io_bufferio_size_shared_examples.rb +371 -0
- data/spec/io_bufferio_size_spec.rb +861 -0
- data/spec/io_bufferio_spec.rb +801 -0
- data/spec/io_class_spec.rb +145 -0
- data/spec/io_instance_spec.rb +516 -0
- data/spec/kernel_spec.rb +285 -0
- data/spec/mount_spec.rb +186 -0
- data/spec/nativefs_local_root_spec.rb +132 -0
- data/spec/path_spec.rb +39 -0
- data/spec/spec_helper.rb +126 -0
- data/tasks/rspec.rake +3 -0
- data/tasks/yard.rake +7 -0
- data/test/UTF-8-demo.txt +212 -0
- data/test/bench.rb +18 -0
- data/test/bio_internal_test.rb +45 -0
- data/test/delegate_io.rb +31 -0
- data/test/delegate_module.rb +62 -0
- data/test/encode_test.rb +42 -0
- data/test/enoent_test.rb +30 -0
- data/test/namespace_test.rb +42 -0
- data/test/read_block_valid_encoding.rb +44 -0
- data/test/read_test.rb +78 -0
- data/test/stream_readers.rb +46 -0
- data/test/utf-16-demo.txt +0 -0
- data/test/utf8_to_utf16.rb +77 -0
- data/test/wrapper_test.rb +34 -0
- data/virtfs.gemspec +29 -0
- metadata +230 -0
    
        data/test/bench.rb
    ADDED
    
    | @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            big_string = "0123456789" * 1000
         | 
| 2 | 
            +
            big_string.force_encoding("ASCII-8BIT")
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            t0 = Time.now
         | 
| 5 | 
            +
            (0...2_000_000).each do
         | 
| 6 | 
            +
              s = big_string.dup
         | 
| 7 | 
            +
              s[-1] = ""
         | 
| 8 | 
            +
            end
         | 
| 9 | 
            +
            t1 = Time.now
         | 
| 10 | 
            +
            puts "Index: #{t1 - t0} seconds"
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            t0 = Time.now
         | 
| 13 | 
            +
            (0...2_000_000).each do
         | 
| 14 | 
            +
              s = big_string.dup
         | 
| 15 | 
            +
              s.chop!
         | 
| 16 | 
            +
            end
         | 
| 17 | 
            +
            t1 = Time.now
         | 
| 18 | 
            +
            puts "chop!: #{t1 - t0} seconds"
         | 
| @@ -0,0 +1,45 @@ | |
| 1 | 
            +
            require "../lib/virtfs"
         | 
| 2 | 
            +
            require "tempfile"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            begin
         | 
| 5 | 
            +
              @start_marker = "START OF FILE:\n"
         | 
| 6 | 
            +
              @end_marker   = ":END OF FILE"
         | 
| 7 | 
            +
              @data1        = "0123456789"
         | 
| 8 | 
            +
              @data2        = "abcdefghijklmnopqrstuvwxyz\n"
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              @temp_file    = Tempfile.new("VirtFS-IO")
         | 
| 11 | 
            +
              @temp_file.write(@start_marker)
         | 
| 12 | 
            +
              (0..9).each do
         | 
| 13 | 
            +
                @temp_file.write(@data1)
         | 
| 14 | 
            +
                @temp_file.write(@data2)
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
              @temp_file.write(@end_marker)
         | 
| 17 | 
            +
              @temp_file.close
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              @full_path  = @temp_file.path
         | 
| 20 | 
            +
              @rel_path   = File.basename(@full_path)
         | 
| 21 | 
            +
              @parent_dir = File.dirname(@full_path)
         | 
| 22 | 
            +
              @file_size  = VfsRealFile.size(@full_path)
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              @utf_8_filename  = VfsRealFile.join(__dir__, "UTF-8-demo.txt")
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              require "../lib/nativefs"
         | 
| 27 | 
            +
              @root      = File::SEPARATOR
         | 
| 28 | 
            +
              @native_fs = NativeFS.new
         | 
| 29 | 
            +
              VirtFS.mount(@native_fs, @root)
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              @vfile_read_obj = VirtFS::VFile.new(@full_path, "r:UTF-8")
         | 
| 32 | 
            +
              @vfile_read_obj.send(:min_read_buf_sz=, 1)
         | 
| 33 | 
            +
              range = @vfile_read_obj.read_buffer.range
         | 
| 34 | 
            +
             | 
| 35 | 
            +
              puts "pos = #{@vfile_read_obj.pos}, Range(#{range.first}, #{range.end})"
         | 
| 36 | 
            +
             | 
| 37 | 
            +
              char = "X"
         | 
| 38 | 
            +
              @vfile_read_obj.ungetc(char)
         | 
| 39 | 
            +
              puts "pos = #{@vfile_read_obj.pos}, Range(#{range.first}, #{range.end})"
         | 
| 40 | 
            +
              @vfile_read_obj.getc
         | 
| 41 | 
            +
             | 
| 42 | 
            +
            rescue => err
         | 
| 43 | 
            +
              puts err.to_s
         | 
| 44 | 
            +
              puts err.backtrace.join("\n")
         | 
| 45 | 
            +
            end
         | 
    
        data/test/delegate_io.rb
    ADDED
    
    | @@ -0,0 +1,31 @@ | |
| 1 | 
            +
            require "delegate"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            begin
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              class MyFile < DelegateClass(::File)
         | 
| 6 | 
            +
                SUPER_CLASSES = [File, IO]
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                def initialize(*args)
         | 
| 9 | 
            +
                  fobj = ::File.new(*args)
         | 
| 10 | 
            +
                  super(fobj)
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def is_a?(klass)
         | 
| 14 | 
            +
                  super(klass) || SUPER_CLASSES.include?(klass)
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
                alias_method :kind_of?, :is_a?
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              f = MyFile.new(__FILE__, "r")
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              puts "f.is_a?(File)   = #{f.is_a?(File)}"
         | 
| 22 | 
            +
              puts "f.is_a?(IO)     = #{f.is_a?(IO)}"
         | 
| 23 | 
            +
              puts "f.is_a?(MyFile) = #{f.is_a?(MyFile)}"
         | 
| 24 | 
            +
              puts "f.is_a?(String) = #{f.is_a?(String)}"
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              f.close
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            rescue => err
         | 
| 29 | 
            +
              puts err.to_s
         | 
| 30 | 
            +
              puts err.backtrace.join("\n")
         | 
| 31 | 
            +
            end
         | 
| @@ -0,0 +1,62 @@ | |
| 1 | 
            +
            require "delegate"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            begin
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              def DelegateModule(superclass)
         | 
| 6 | 
            +
                klass = Module.new
         | 
| 7 | 
            +
                methods = superclass.instance_methods
         | 
| 8 | 
            +
                methods -= ::Delegator.public_api
         | 
| 9 | 
            +
                methods -= [:to_s,:inspect,:=~,:!~,:===]
         | 
| 10 | 
            +
                klass.module_eval do
         | 
| 11 | 
            +
                  def __getobj__  # :nodoc:
         | 
| 12 | 
            +
                    unless defined?(@delegate_dc_obj)
         | 
| 13 | 
            +
                      return yield if block_given?
         | 
| 14 | 
            +
                      __raise__ ::ArgumentError, "not delegated"
         | 
| 15 | 
            +
                    end
         | 
| 16 | 
            +
                    @delegate_dc_obj
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                  def __setobj__(obj)  # :nodoc:
         | 
| 19 | 
            +
                    __raise__ ::ArgumentError, "cannot delegate to self" if self.equal?(obj)
         | 
| 20 | 
            +
                    @delegate_dc_obj = obj
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
                  methods.each do |method|
         | 
| 23 | 
            +
                    define_method(method, Delegator.delegating_block(method))
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
                klass.define_singleton_method :public_instance_methods do |all=true|
         | 
| 27 | 
            +
                  super(all) - superclass.protected_instance_methods
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
                klass.define_singleton_method :protected_instance_methods do |all=true|
         | 
| 30 | 
            +
                  super(all) | superclass.protected_instance_methods
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
                return klass
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
              FileDelegate = DelegateModule(File)
         | 
| 36 | 
            +
             | 
| 37 | 
            +
              class MyIO
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              class MyFile < MyIO
         | 
| 41 | 
            +
                include FileDelegate
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                def initialize(dobj)
         | 
| 44 | 
            +
                  __setobj__(dobj)
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              fobj = File.new(__FILE__, "r")
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              mf = MyFile.new(fobj)
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              puts "mf.is_a?(MyFile) = #{mf.is_a?(MyFile)}"
         | 
| 53 | 
            +
              puts "mf.is_a?(MyIO)   = #{mf.is_a?(MyIO)}"
         | 
| 54 | 
            +
             | 
| 55 | 
            +
              puts
         | 
| 56 | 
            +
              mf.each { |l| puts l }
         | 
| 57 | 
            +
              mf.close
         | 
| 58 | 
            +
             | 
| 59 | 
            +
            rescue => err
         | 
| 60 | 
            +
              puts err.to_s
         | 
| 61 | 
            +
              puts err.backtrace.join("\n")
         | 
| 62 | 
            +
            end
         | 
    
        data/test/encode_test.rb
    ADDED
    
    | @@ -0,0 +1,42 @@ | |
| 1 | 
            +
            begin
         | 
| 2 | 
            +
              #
         | 
| 3 | 
            +
              # Find the offset within the file of the first multi-byte character.
         | 
| 4 | 
            +
              #
         | 
| 5 | 
            +
              binary_string = ""
         | 
| 6 | 
            +
              File.open("UTF-16-demo.txt", "rb") do |io|
         | 
| 7 | 
            +
                binary_string = io.read
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
              puts "\tbinary_string.encoding.name   = #{binary_string.encoding.name} (valid: #{binary_string.valid_encoding?})"
         | 
| 10 | 
            +
              puts "\tbinary_string.length          = #{binary_string.length}"
         | 
| 11 | 
            +
              puts "\tbinary_string.bytesize        = #{binary_string.bytesize}"
         | 
| 12 | 
            +
              puts
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              utf8_string = ""
         | 
| 15 | 
            +
              ec = Encoding::Converter.new("UTF-16le", "UTF-8")
         | 
| 16 | 
            +
              rv = ec.primitive_convert(binary_string, utf8_string)
         | 
| 17 | 
            +
              puts "primitive_convert --> #{rv}"
         | 
| 18 | 
            +
              puts "\tutf8_string.encoding.name   = #{utf8_string.encoding.name} (valid: #{utf8_string.valid_encoding?})"
         | 
| 19 | 
            +
              puts "\tutf8_string.length          = #{utf8_string.length}"
         | 
| 20 | 
            +
              puts "\tutf8_string.bytesize        = #{utf8_string.bytesize}"
         | 
| 21 | 
            +
              puts
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              nchunk = 0
         | 
| 24 | 
            +
              utf8_string = ""
         | 
| 25 | 
            +
              ec = Encoding::Converter.new("UTF-16le", "UTF-8")
         | 
| 26 | 
            +
              File.open("UTF-16-demo.txt", "rb") do |io|
         | 
| 27 | 
            +
                while (binary_string = io.read(99))
         | 
| 28 | 
            +
                  rv = ec.primitive_convert(binary_string, utf8_string, nil, nil, :partial_input => true)
         | 
| 29 | 
            +
                  puts "Chunk: #{nchunk}, rv = #{rv}"
         | 
| 30 | 
            +
                  nchunk += 1
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              puts "nchunk = #{nchunk}"
         | 
| 35 | 
            +
              puts "\tutf8_string.encoding.name   = #{utf8_string.encoding.name} (valid: #{utf8_string.valid_encoding?})"
         | 
| 36 | 
            +
              puts "\tutf8_string.length          = #{utf8_string.length}"
         | 
| 37 | 
            +
              puts "\tutf8_string.bytesize        = #{utf8_string.bytesize}"
         | 
| 38 | 
            +
              puts
         | 
| 39 | 
            +
            rescue => err
         | 
| 40 | 
            +
              puts err.to_s
         | 
| 41 | 
            +
              puts err.backtrace.join("\n")
         | 
| 42 | 
            +
            end
         | 
    
        data/test/enoent_test.rb
    ADDED
    
    | @@ -0,0 +1,30 @@ | |
| 1 | 
            +
            require "yaml"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            begin
         | 
| 4 | 
            +
              begin
         | 
| 5 | 
            +
                Dir.new("/not/a/dir")
         | 
| 6 | 
            +
              rescue => err
         | 
| 7 | 
            +
                puts " err => #{err.class.name}"
         | 
| 8 | 
            +
                puts " err => #{err.inspect}"
         | 
| 9 | 
            +
                puts " err.errno = #{err.errno}"
         | 
| 10 | 
            +
                puts " err.class::Errno = #{err.class::Errno}"
         | 
| 11 | 
            +
                err = YAML.load(YAML.dump(err))
         | 
| 12 | 
            +
                nerr = SystemCallError.new("dir", err.class::Errno)
         | 
| 13 | 
            +
                # nerr.message = err.message
         | 
| 14 | 
            +
                raise nerr
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
            rescue Errno::ENOENT => oerr
         | 
| 17 | 
            +
              puts "**** Got Errno::ENOENT"
         | 
| 18 | 
            +
              puts "oerr => #{oerr.class.name}"
         | 
| 19 | 
            +
              puts "oerr => #{oerr.inspect}"
         | 
| 20 | 
            +
              puts "oerr.errno = #{oerr.errno}"
         | 
| 21 | 
            +
              puts "oerr.class::Errno = #{oerr.class::Errno}"
         | 
| 22 | 
            +
            rescue SystemCallError => oerr
         | 
| 23 | 
            +
              puts "**** Got SystemCallError"
         | 
| 24 | 
            +
            rescue => oerr
         | 
| 25 | 
            +
              puts "**** Not Errno::ENOENT"
         | 
| 26 | 
            +
              puts "oerr => #{oerr.class.name}"
         | 
| 27 | 
            +
              puts "oerr => #{oerr.inspect}"
         | 
| 28 | 
            +
              puts "oerr.errno = #{oerr.errno}"
         | 
| 29 | 
            +
              puts "oerr.class::Errno = #{oerr.class::Errno}"
         | 
| 30 | 
            +
            end
         | 
| @@ -0,0 +1,42 @@ | |
| 1 | 
            +
            class MyFile
         | 
| 2 | 
            +
              def self.name
         | 
| 3 | 
            +
                "MyFile"
         | 
| 4 | 
            +
              end
         | 
| 5 | 
            +
            end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            class Vfs
         | 
| 8 | 
            +
              def self.nest(ext)
         | 
| 9 | 
            +
                ext.const_set(:File, MyFile)
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
            end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            begin
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              Module.new do
         | 
| 16 | 
            +
                class << self
         | 
| 17 | 
            +
                  puts self.class.name
         | 
| 18 | 
            +
                  puts constants.inspect
         | 
| 19 | 
            +
                  puts File.name
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  Vfs.nest(self)
         | 
| 22 | 
            +
                  puts constants.inspect
         | 
| 23 | 
            +
                  puts File.name
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              puts
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              Module.new do
         | 
| 30 | 
            +
                class << self
         | 
| 31 | 
            +
                  puts self.class.name
         | 
| 32 | 
            +
                  puts constants.inspect
         | 
| 33 | 
            +
                  puts File.name
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
              puts File.name
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            rescue => err
         | 
| 40 | 
            +
              puts err.to_s
         | 
| 41 | 
            +
              puts err.backtrace.join("\n")
         | 
| 42 | 
            +
            end
         | 
| @@ -0,0 +1,44 @@ | |
| 1 | 
            +
            require "tempfile"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            begin
         | 
| 4 | 
            +
              input_file_name   = "UTF-8-demo.txt"
         | 
| 5 | 
            +
              external_encoding = Encoding.find("UTF-8")
         | 
| 6 | 
            +
              binary_encoding   = Encoding.find("ASCII-8BIT")
         | 
| 7 | 
            +
              buffer_size       = 95
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              temp_file  = Tempfile.new("rbve")
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              File.open(input_file_name, "rb") do |io|
         | 
| 12 | 
            +
                block = 0
         | 
| 13 | 
            +
                while (binary_string = io.read(buffer_size))
         | 
| 14 | 
            +
                  binary_string.force_encoding(external_encoding)
         | 
| 15 | 
            +
                  puts "Block: #{block}, valid: #{binary_string.valid_encoding?}"
         | 
| 16 | 
            +
                  push_back = 0
         | 
| 17 | 
            +
                  (0...8).each do
         | 
| 18 | 
            +
                    break if binary_string.valid_encoding?
         | 
| 19 | 
            +
                    binary_string.force_encoding(binary_encoding)
         | 
| 20 | 
            +
                    binary_string[-1] = ""
         | 
| 21 | 
            +
                    binary_string.force_encoding(external_encoding)
         | 
| 22 | 
            +
                    push_back += 1
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
                  raise "Invalid byte sequence" unless binary_string.valid_encoding?
         | 
| 25 | 
            +
                  puts "Block: #{block}, valid: #{binary_string.valid_encoding?}, push_back: #{push_back}"
         | 
| 26 | 
            +
                  temp_file.write(binary_string)
         | 
| 27 | 
            +
                  io.seek(-push_back, IO::SEEK_CUR) unless push_back == 0
         | 
| 28 | 
            +
                  block += 1
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              temp_file.close
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              input  = File.read(input_file_name)
         | 
| 35 | 
            +
              output = File.read(temp_file.path)
         | 
| 36 | 
            +
             | 
| 37 | 
            +
              puts
         | 
| 38 | 
            +
              puts "Input size:  #{input.bytesize}"
         | 
| 39 | 
            +
              puts "Output size: #{output.bytesize}"
         | 
| 40 | 
            +
              puts "Data check pass: #{input == output}"
         | 
| 41 | 
            +
            rescue => err
         | 
| 42 | 
            +
              puts err.to_s
         | 
| 43 | 
            +
              puts err.backtrace.join("\n")
         | 
| 44 | 
            +
            end
         | 
    
        data/test/read_test.rb
    ADDED
    
    | @@ -0,0 +1,78 @@ | |
| 1 | 
            +
            begin
         | 
| 2 | 
            +
              #
         | 
| 3 | 
            +
              # Find the offset within the file of the first multi-byte character.
         | 
| 4 | 
            +
              #
         | 
| 5 | 
            +
              first_mb_char_pos = 0
         | 
| 6 | 
            +
              File.open("UTF-8-demo.txt", "r:utf-8:utf-8") do |io|
         | 
| 7 | 
            +
                io.each_char do |c|
         | 
| 8 | 
            +
                  if c.length != c.bytesize
         | 
| 9 | 
            +
                    puts "first_mb_char_pos = #{first_mb_char_pos}, char = '#{c}' #{c.bytes.to_a.inspect}"
         | 
| 10 | 
            +
                    puts
         | 
| 11 | 
            +
                    break
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                  first_mb_char_pos += 1
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              puts "Read whole file as binary:"
         | 
| 18 | 
            +
              binary_string = ""
         | 
| 19 | 
            +
              File.open("UTF-8-demo.txt", "rb") do |io|
         | 
| 20 | 
            +
                binary_string = io.read
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
              puts "\tbinary_string.encoding.name   = #{binary_string.encoding.name} (valid: #{binary_string.valid_encoding?})"
         | 
| 23 | 
            +
              puts "\tbinary_string.length          = #{binary_string.length}"
         | 
| 24 | 
            +
              puts "\tbinary_string.bytesize        = #{binary_string.bytesize}"
         | 
| 25 | 
            +
              puts
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              puts "Read whole file as utf-8:"
         | 
| 28 | 
            +
              utf8_string = ""
         | 
| 29 | 
            +
              File.open("UTF-8-demo.txt", "r:utf-8:utf-8") do |io|
         | 
| 30 | 
            +
                utf8_string = io.read
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
              puts "\tutf8_string.encoding.name   = #{utf8_string.encoding.name} (valid: #{utf8_string.valid_encoding?})"
         | 
| 33 | 
            +
              puts "\tutf8_string.length          = #{utf8_string.length}"
         | 
| 34 | 
            +
              puts "\tutf8_string.bytesize        = #{utf8_string.bytesize}"
         | 
| 35 | 
            +
              puts
         | 
| 36 | 
            +
             | 
| 37 | 
            +
              puts "Partial read (100 bytes) as utf-8:"
         | 
| 38 | 
            +
              File.open("UTF-8-demo.txt", "r:utf-8:utf-8") do |io|
         | 
| 39 | 
            +
                utf8_string = io.read(100)
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
              puts "\tutf8_string.encoding.name   = #{utf8_string.encoding.name} (valid: #{utf8_string.valid_encoding?})"
         | 
| 42 | 
            +
              puts "\tutf8_string.length          = #{utf8_string.length}"
         | 
| 43 | 
            +
              puts "\tutf8_string.bytesize        = #{utf8_string.bytesize}"
         | 
| 44 | 
            +
              puts
         | 
| 45 | 
            +
             | 
| 46 | 
            +
              puts "Offset read (on char boundary) as utf-8:"
         | 
| 47 | 
            +
              File.open("UTF-8-demo.txt", "r:utf-8:utf-8") do |io|
         | 
| 48 | 
            +
                io.seek(first_mb_char_pos, IO::SEEK_SET)
         | 
| 49 | 
            +
                utf8_string = io.read
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
              puts "\tutf8_string.encoding.name   = #{utf8_string.encoding.name} (valid: #{utf8_string.valid_encoding?})"
         | 
| 52 | 
            +
              puts "\tutf8_string.length          = #{utf8_string.length}"
         | 
| 53 | 
            +
              puts "\tutf8_string.bytesize        = #{utf8_string.bytesize}"
         | 
| 54 | 
            +
              puts
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              puts "Offset read (not on char boundary) as utf-8:"
         | 
| 57 | 
            +
              File.open("UTF-8-demo.txt", "r:utf-8:utf-8") do |io|
         | 
| 58 | 
            +
                io.seek(first_mb_char_pos+1, IO::SEEK_SET)
         | 
| 59 | 
            +
                utf8_string = io.read
         | 
| 60 | 
            +
              end
         | 
| 61 | 
            +
              puts "\tutf8_string.encoding.name   = #{utf8_string.encoding.name} (valid: #{utf8_string.valid_encoding?})"
         | 
| 62 | 
            +
              puts "\tutf8_string.length          = #{utf8_string.length}"
         | 
| 63 | 
            +
              puts "\tutf8_string.bytesize        = #{utf8_string.bytesize}"
         | 
| 64 | 
            +
              puts
         | 
| 65 | 
            +
             | 
| 66 | 
            +
              # File.open("UTF-8-demo.txt", "r:utf-8:utf-8") do |io|
         | 
| 67 | 
            +
              #   while utf8_string = io.gets
         | 
| 68 | 
            +
              #     puts utf8_string
         | 
| 69 | 
            +
              #     puts "\tutf8_string.encoding.name   = #{utf8_string.encoding.name} (valid: #{utf8_string.valid_encoding?})"
         | 
| 70 | 
            +
              #     puts "\tutf8_string.length          = #{utf8_string.length}"
         | 
| 71 | 
            +
              #     puts "\tutf8_string.bytesize        = #{utf8_string.bytesize}"
         | 
| 72 | 
            +
              #     puts
         | 
| 73 | 
            +
              #   end
         | 
| 74 | 
            +
              # end
         | 
| 75 | 
            +
            rescue => err
         | 
| 76 | 
            +
              puts err.to_s
         | 
| 77 | 
            +
              puts err.backtrace.join("\n")
         | 
| 78 | 
            +
            end
         | 
| @@ -0,0 +1,46 @@ | |
| 1 | 
            +
            begin
         | 
| 2 | 
            +
              first_mb_char_pos = 0
         | 
| 3 | 
            +
              File.open("UTF-8-demo.txt", "r:utf-8:utf-8") do |io|
         | 
| 4 | 
            +
                io.each_char do |c|
         | 
| 5 | 
            +
                  if c.length != c.bytesize
         | 
| 6 | 
            +
                    puts "first_mb_char_pos = #{first_mb_char_pos}, char = '#{c}' #{c.bytes.to_a.inspect}"
         | 
| 7 | 
            +
                    puts
         | 
| 8 | 
            +
                    break
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
                  first_mb_char_pos += 1
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              File.open("UTF-8-demo.txt", "r:utf-8:utf-8") do |io|
         | 
| 15 | 
            +
                puts "File opened"
         | 
| 16 | 
            +
                puts "\tio.pos = #{io.pos}"
         | 
| 17 | 
            +
                puts
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                puts "Reading 10 bytes."
         | 
| 20 | 
            +
                barray = io.each_byte.first(10)
         | 
| 21 | 
            +
                puts "\tio.pos = #{io.pos}"
         | 
| 22 | 
            +
                puts
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                puts "Reading 10 bytes."
         | 
| 25 | 
            +
                barray = io.each_char.first(10)
         | 
| 26 | 
            +
                puts "\tio.pos = #{io.pos}"
         | 
| 27 | 
            +
                puts
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                puts "Reading 10 lines."
         | 
| 30 | 
            +
                ln = 0
         | 
| 31 | 
            +
                io.each_line do |line|
         | 
| 32 | 
            +
                  break if ln >= 10
         | 
| 33 | 
            +
                  puts "Line: #{ln}"
         | 
| 34 | 
            +
                  puts "\tline.length            = #{line.length}"
         | 
| 35 | 
            +
                  puts "\tline.bytesize          = #{line.bytesize}"
         | 
| 36 | 
            +
                  puts "\tline.codepoints.length = #{line.codepoints.length}"
         | 
| 37 | 
            +
                  puts "\tio.pos                 = #{io.pos}"
         | 
| 38 | 
            +
                  puts "\tio.lineno              = #{io.lineno}"
         | 
| 39 | 
            +
                  puts
         | 
| 40 | 
            +
                  ln += 1
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
            rescue => err
         | 
| 44 | 
            +
              puts err.to_s
         | 
| 45 | 
            +
              puts err.backtrace.join("\n")
         | 
| 46 | 
            +
            end
         |