extlzham 0.0.1.PROTOTYPE → 0.0.1.PROTOTYPE2
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 +4 -4
- data/README.md +56 -3
- data/Rakefile +8 -4
- data/ext/constants.c +50 -0
- data/ext/decoder.c +315 -0
- data/ext/depend +5 -0
- data/ext/encoder.c +338 -0
- data/ext/error.c +80 -0
- data/ext/extconf.rb +5 -3
- data/ext/extlzham.c +14 -721
- data/ext/extlzham.h +57 -0
- data/lib/extlzham/version.rb +1 -1
- data/lib/extlzham.rb +7 -1
- metadata +14 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 38a6dfeed7afbd9178b072cbc682d5d239b396e5
         | 
| 4 | 
            +
              data.tar.gz: a70c0b958bd0b1652830755f20ed86a2df3bc695
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: b2d6760152aac48b4e78646c02ea99fe1f5618a34bda0339de1c00ff955485650adfb389dfc729a02c03bf7d6b59e836f552923ae6810577b8a3acd5d5cebd26
         | 
| 7 | 
            +
              data.tar.gz: 2a4324dd8844f739448e18f0f5654494a7e95d786cc6ee437c98142dd3e03a7179cabe1f402f9562dd260007efc826593c6d52f05540158bd953cb6c4c55d5d9
         | 
    
        data/README.md
    CHANGED
    
    | @@ -2,19 +2,72 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            # extlzham - ruby binding for LZHAM
         | 
| 4 4 |  | 
| 5 | 
            -
            This is ruby  | 
| 5 | 
            +
            This is ruby bindings for compression library
         | 
| 6 6 | 
             
            [LZHAM (https://github.com/richgel999/lzham\_codec)](https://github.com/richgel999/lzham_codec).
         | 
| 7 7 |  | 
| 8 8 | 
             
            *   PACKAGE NAME: extlzham
         | 
| 9 9 | 
             
            *   AUTHOR: dearblue <dearblue@users.sourceforge.jp>
         | 
| 10 | 
            -
            *   VERSION: 0.0.1. | 
| 10 | 
            +
            *   VERSION: 0.0.1.PROTOTYPE2
         | 
| 11 11 | 
             
            *   LICENSING: 2-clause BSD License
         | 
| 12 12 | 
             
            *   REPORT ISSUE TO: <http://sourceforge.jp/projects/rutsubo/ticket/>
         | 
| 13 13 | 
             
            *   DEPENDENCY RUBY: ruby-2.0+
         | 
| 14 14 | 
             
            *   DEPENDENCY RUBY GEMS: (none)
         | 
| 15 15 | 
             
            *   DEPENDENCY LIBRARY: (none)
         | 
| 16 16 | 
             
            *   BUNDLED EXTERNAL LIBRARIES:
         | 
| 17 | 
            -
                *   LZHAM | 
| 17 | 
            +
                *   LZHAM <https://github.com/richgel999/lzham_codec>
         | 
| 18 | 
            +
             | 
| 19 | 
            +
             | 
| 20 | 
            +
            ## HOW TO USE
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            ### Simply process
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            ``` ruby:ruby
         | 
| 25 | 
            +
            # First, load library
         | 
| 26 | 
            +
            require "extlzham"
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            # Prepair data
         | 
| 29 | 
            +
            source = "sample data..." * 50
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            # Directly compression
         | 
| 32 | 
            +
            encdata = LZHAM.encode(source)
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            # Directly decompression
         | 
| 35 | 
            +
            decdata = LZHAM.decode(encdata)
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            # Comparison source and decoded data
         | 
| 38 | 
            +
            p source == decdata
         | 
| 39 | 
            +
            ```
         | 
| 40 | 
            +
             | 
| 41 | 
            +
            ### Streaming process
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            ``` ruby:ruby
         | 
| 44 | 
            +
            # First, load library
         | 
| 45 | 
            +
            require "extlzham"
         | 
| 46 | 
            +
             | 
| 47 | 
            +
            # Prepair data
         | 
| 48 | 
            +
            source = "sample data..." * 50
         | 
| 49 | 
            +
            sourceio = StringIO.new(source)
         | 
| 50 | 
            +
             | 
| 51 | 
            +
            # streaming compression
         | 
| 52 | 
            +
            LZHAM.encode(dest = StringIO.new("")) do |encoder|
         | 
| 53 | 
            +
              while buf = sourceio.read(50) # Please increase the value if you want to actually use.
         | 
| 54 | 
            +
                encoder << buf
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
              # block leave to encoder.close
         | 
| 57 | 
            +
            end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
            # streaming decompression
         | 
| 60 | 
            +
            dest.rewind
         | 
| 61 | 
            +
            decdata = ""
         | 
| 62 | 
            +
            LZHAM.decode(StringIO.new(decdata)) do |decoder|
         | 
| 63 | 
            +
              while buf = dest.read(50)
         | 
| 64 | 
            +
                decoder << buf
         | 
| 65 | 
            +
              end
         | 
| 66 | 
            +
            end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
            # Comparison source and decoded data
         | 
| 69 | 
            +
            p source == decdata
         | 
| 70 | 
            +
            ```
         | 
| 18 71 |  | 
| 19 72 | 
             
            ----
         | 
| 20 73 |  | 
    
        data/Rakefile
    CHANGED
    
    | @@ -10,10 +10,11 @@ BIN = FileList["bin/*"] | |
| 10 10 | 
             
            LIB = FileList["lib/**/*.rb"]
         | 
| 11 11 | 
             
            SPEC = FileList["spec/**/*"]
         | 
| 12 12 | 
             
            EXAMPLE = FileList["examples/**/*"]
         | 
| 13 | 
            -
             | 
| 13 | 
            +
            GEMSTUB_SRC = "gemstub.rb"
         | 
| 14 | 
            +
            RAKEFILE = [File.basename(__FILE__), GEMSTUB_SRC]
         | 
| 14 15 | 
             
            EXTRA = []
         | 
| 15 16 |  | 
| 16 | 
            -
            load  | 
| 17 | 
            +
            load GEMSTUB_SRC
         | 
| 17 18 |  | 
| 18 19 | 
             
            EXTCONF = FileList["ext/extconf.rb"]
         | 
| 19 20 | 
             
            EXTCONF.reject! { |n| !File.file?(n) }
         | 
| @@ -59,7 +60,7 @@ unless EXTCONF.empty? | |
| 59 60 | 
             
                PLATFORM = platforms1[0]
         | 
| 60 61 |  | 
| 61 62 | 
             
                RUBY_VERSIONS = RUBYSET.map do |ruby|
         | 
| 62 | 
            -
                  ver = `#{ruby} --disable gem -rrbconfig -e "puts RbConfig::CONFIG['ruby_version']"`. | 
| 63 | 
            +
                  ver = `#{ruby} --disable gem -rrbconfig -e "puts RbConfig::CONFIG['ruby_version']"`.slice(/\d+\.\d+/)
         | 
| 63 64 | 
             
                  raise "failed ruby checking - ``#{ruby}''" unless $?.success?
         | 
| 64 65 | 
             
                  [ver, ruby]
         | 
| 65 66 | 
             
                end
         | 
| @@ -85,10 +86,13 @@ unless EXTCONF.empty? | |
| 85 86 | 
             
                  sh "gem build #{GEMSPEC_NATIVE}"
         | 
| 86 87 | 
             
                end
         | 
| 87 88 |  | 
| 88 | 
            -
                file GEMSPEC_NATIVE =>  | 
| 89 | 
            +
                file GEMSPEC_NATIVE => RAKEFILE do
         | 
| 89 90 | 
             
                  File.write(GEMSPEC_NATIVE, GEMSTUB_NATIVE.to_ruby, mode: "wb")
         | 
| 90 91 | 
             
                end
         | 
| 91 92 |  | 
| 93 | 
            +
                desc "build c-extension libraries"
         | 
| 94 | 
            +
                task "sofiles" => SOFILES
         | 
| 95 | 
            +
             | 
| 92 96 | 
             
                SOFILES_SET.each do |(soname, ruby)|
         | 
| 93 97 | 
             
                  sodir = File.dirname(soname)
         | 
| 94 98 | 
             
                  makefile = File.join(sodir, "Makefile")
         | 
    
        data/ext/constants.c
    ADDED
    
    | @@ -0,0 +1,50 @@ | |
| 1 | 
            +
            #include "extlzham.h"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            VALUE mConsts;
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            void
         | 
| 6 | 
            +
            init_constants(void)
         | 
| 7 | 
            +
            {
         | 
| 8 | 
            +
                mConsts = rb_define_module_under(mLZHAM, "Constants");
         | 
| 9 | 
            +
                rb_include_module(mLZHAM, mConsts);
         | 
| 10 | 
            +
                rb_define_const(mConsts, "NO_FLUSH", INT2FIX(LZHAM_NO_FLUSH));
         | 
| 11 | 
            +
                rb_define_const(mConsts, "SYNC_FLUSH", INT2FIX(LZHAM_SYNC_FLUSH));
         | 
| 12 | 
            +
                rb_define_const(mConsts, "FULL_FLUSH", INT2FIX(LZHAM_FULL_FLUSH));
         | 
| 13 | 
            +
                rb_define_const(mConsts, "FINISH", INT2FIX(LZHAM_FINISH));
         | 
| 14 | 
            +
                rb_define_const(mConsts, "TABLE_FLUSH", INT2FIX(LZHAM_TABLE_FLUSH));
         | 
| 15 | 
            +
                rb_define_const(mConsts, "MIN_DICT_SIZE_LOG2", INT2FIX(LZHAM_MIN_DICT_SIZE_LOG2));
         | 
| 16 | 
            +
                rb_define_const(mConsts, "MAX_DICT_SIZE_LOG2_X86", INT2FIX(LZHAM_MAX_DICT_SIZE_LOG2_X86));
         | 
| 17 | 
            +
                rb_define_const(mConsts, "MAX_DICT_SIZE_LOG2_X64", INT2FIX(LZHAM_MAX_DICT_SIZE_LOG2_X64));
         | 
| 18 | 
            +
                rb_define_const(mConsts, "MAX_HELPER_THREADS", INT2FIX(LZHAM_MAX_HELPER_THREADS));
         | 
| 19 | 
            +
                rb_define_const(mConsts, "COMP_FLAG_EXTREME_PARSING", INT2FIX(LZHAM_COMP_FLAG_EXTREME_PARSING));
         | 
| 20 | 
            +
                rb_define_const(mConsts, "COMP_FLAG_DETERMINISTIC_PARSING", INT2FIX(LZHAM_COMP_FLAG_DETERMINISTIC_PARSING));
         | 
| 21 | 
            +
                rb_define_const(mConsts, "COMP_FLAG_TRADEOFF_DECOMPRESSION_RATE_FOR_COMP_RATIO", INT2FIX(LZHAM_COMP_FLAG_TRADEOFF_DECOMPRESSION_RATE_FOR_COMP_RATIO));
         | 
| 22 | 
            +
                rb_define_const(mConsts, "COMP_FLAG_WRITE_ZLIB_STREAM", INT2FIX(LZHAM_COMP_FLAG_WRITE_ZLIB_STREAM));
         | 
| 23 | 
            +
                rb_define_const(mConsts, "INSANELY_SLOW_TABLE_UPDATE_RATE", INT2FIX(LZHAM_INSANELY_SLOW_TABLE_UPDATE_RATE));
         | 
| 24 | 
            +
                rb_define_const(mConsts, "SLOWEST_TABLE_UPDATE_RATE", INT2FIX(LZHAM_SLOWEST_TABLE_UPDATE_RATE));
         | 
| 25 | 
            +
                rb_define_const(mConsts, "DEFAULT_TABLE_UPDATE_RATE", INT2FIX(LZHAM_DEFAULT_TABLE_UPDATE_RATE));
         | 
| 26 | 
            +
                rb_define_const(mConsts, "FASTEST_TABLE_UPDATE_RATE", INT2FIX(LZHAM_FASTEST_TABLE_UPDATE_RATE));
         | 
| 27 | 
            +
                rb_define_const(mConsts, "DECOMP_FLAG_OUTPUT_UNBUFFERED", INT2FIX(LZHAM_DECOMP_FLAG_OUTPUT_UNBUFFERED));
         | 
| 28 | 
            +
                rb_define_const(mConsts, "DECOMP_FLAG_COMPUTE_ADLER32", INT2FIX(LZHAM_DECOMP_FLAG_COMPUTE_ADLER32));
         | 
| 29 | 
            +
                rb_define_const(mConsts, "DECOMP_FLAG_READ_ZLIB_STREAM", INT2FIX(LZHAM_DECOMP_FLAG_READ_ZLIB_STREAM));
         | 
| 30 | 
            +
                rb_define_const(mConsts, "LZHAM_NO_FLUSH", INT2FIX(LZHAM_NO_FLUSH));
         | 
| 31 | 
            +
                rb_define_const(mConsts, "LZHAM_SYNC_FLUSH", INT2FIX(LZHAM_SYNC_FLUSH));
         | 
| 32 | 
            +
                rb_define_const(mConsts, "LZHAM_FULL_FLUSH", INT2FIX(LZHAM_FULL_FLUSH));
         | 
| 33 | 
            +
                rb_define_const(mConsts, "LZHAM_FINISH", INT2FIX(LZHAM_FINISH));
         | 
| 34 | 
            +
                rb_define_const(mConsts, "LZHAM_TABLE_FLUSH", INT2FIX(LZHAM_TABLE_FLUSH));
         | 
| 35 | 
            +
                rb_define_const(mConsts, "LZHAM_MIN_DICT_SIZE_LOG2", INT2FIX(LZHAM_MIN_DICT_SIZE_LOG2));
         | 
| 36 | 
            +
                rb_define_const(mConsts, "LZHAM_MAX_DICT_SIZE_LOG2_X86", INT2FIX(LZHAM_MAX_DICT_SIZE_LOG2_X86));
         | 
| 37 | 
            +
                rb_define_const(mConsts, "LZHAM_MAX_DICT_SIZE_LOG2_X64", INT2FIX(LZHAM_MAX_DICT_SIZE_LOG2_X64));
         | 
| 38 | 
            +
                rb_define_const(mConsts, "LZHAM_MAX_HELPER_THREADS", INT2FIX(LZHAM_MAX_HELPER_THREADS));
         | 
| 39 | 
            +
                rb_define_const(mConsts, "LZHAM_COMP_FLAG_EXTREME_PARSING", INT2FIX(LZHAM_COMP_FLAG_EXTREME_PARSING));
         | 
| 40 | 
            +
                rb_define_const(mConsts, "LZHAM_COMP_FLAG_DETERMINISTIC_PARSING", INT2FIX(LZHAM_COMP_FLAG_DETERMINISTIC_PARSING));
         | 
| 41 | 
            +
                rb_define_const(mConsts, "LZHAM_COMP_FLAG_TRADEOFF_DECOMPRESSION_RATE_FOR_COMP_RATIO", INT2FIX(LZHAM_COMP_FLAG_TRADEOFF_DECOMPRESSION_RATE_FOR_COMP_RATIO));
         | 
| 42 | 
            +
                rb_define_const(mConsts, "LZHAM_COMP_FLAG_WRITE_ZLIB_STREAM", INT2FIX(LZHAM_COMP_FLAG_WRITE_ZLIB_STREAM));
         | 
| 43 | 
            +
                rb_define_const(mConsts, "LZHAM_INSANELY_SLOW_TABLE_UPDATE_RATE", INT2FIX(LZHAM_INSANELY_SLOW_TABLE_UPDATE_RATE));
         | 
| 44 | 
            +
                rb_define_const(mConsts, "LZHAM_SLOWEST_TABLE_UPDATE_RATE", INT2FIX(LZHAM_SLOWEST_TABLE_UPDATE_RATE));
         | 
| 45 | 
            +
                rb_define_const(mConsts, "LZHAM_DEFAULT_TABLE_UPDATE_RATE", INT2FIX(LZHAM_DEFAULT_TABLE_UPDATE_RATE));
         | 
| 46 | 
            +
                rb_define_const(mConsts, "LZHAM_FASTEST_TABLE_UPDATE_RATE", INT2FIX(LZHAM_FASTEST_TABLE_UPDATE_RATE));
         | 
| 47 | 
            +
                rb_define_const(mConsts, "LZHAM_DECOMP_FLAG_OUTPUT_UNBUFFERED", INT2FIX(LZHAM_DECOMP_FLAG_OUTPUT_UNBUFFERED));
         | 
| 48 | 
            +
                rb_define_const(mConsts, "LZHAM_DECOMP_FLAG_COMPUTE_ADLER32", INT2FIX(LZHAM_DECOMP_FLAG_COMPUTE_ADLER32));
         | 
| 49 | 
            +
                rb_define_const(mConsts, "LZHAM_DECOMP_FLAG_READ_ZLIB_STREAM", INT2FIX(LZHAM_DECOMP_FLAG_READ_ZLIB_STREAM));
         | 
| 50 | 
            +
            }
         | 
    
        data/ext/decoder.c
    ADDED
    
    | @@ -0,0 +1,315 @@ | |
| 1 | 
            +
            #include "extlzham.h"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            VALUE cDecoder;
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            /*
         | 
| 6 | 
            +
             * decoder
         | 
| 7 | 
            +
             */
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            static inline lzham_decompress_params
         | 
| 10 | 
            +
            aux_conv_decode_params(VALUE opts)
         | 
| 11 | 
            +
            {
         | 
| 12 | 
            +
                lzham_decompress_params p;
         | 
| 13 | 
            +
                memset(&p, 0, sizeof(p));
         | 
| 14 | 
            +
                p.m_struct_size = sizeof(p);
         | 
| 15 | 
            +
                if (NIL_P(opts)) {
         | 
| 16 | 
            +
                    p.m_dict_size_log2 = LZHAM_MIN_DICT_SIZE_LOG2;
         | 
| 17 | 
            +
                    p.m_table_update_rate = 0;
         | 
| 18 | 
            +
                    p.m_decompress_flags = 0; // (see lzham_decompress_flags enum)
         | 
| 19 | 
            +
                    p.m_num_seed_bytes = 0;
         | 
| 20 | 
            +
                    p.m_pSeed_bytes = NULL;
         | 
| 21 | 
            +
                    p.m_table_max_update_interval = 0;
         | 
| 22 | 
            +
                    p.m_table_update_interval_slow_rate = 0;
         | 
| 23 | 
            +
                } else {
         | 
| 24 | 
            +
                    p.m_dict_size_log2 = aux_hash_lookup_to_u32(opts, IDdictsize, LZHAM_MIN_DICT_SIZE_LOG2);
         | 
| 25 | 
            +
                    p.m_table_update_rate = aux_hash_lookup_to_u32(opts, IDtable_update_rate, 0);
         | 
| 26 | 
            +
                    p.m_decompress_flags = aux_hash_lookup_to_u32(opts, IDflags, 0);
         | 
| 27 | 
            +
                    p.m_num_seed_bytes = 0;
         | 
| 28 | 
            +
                    p.m_pSeed_bytes = NULL;
         | 
| 29 | 
            +
                    p.m_table_max_update_interval = aux_hash_lookup_to_u32(opts, IDtable_max_update_interval, 0);
         | 
| 30 | 
            +
                    p.m_table_update_interval_slow_rate = aux_hash_lookup_to_u32(opts, IDtable_update_interval_slow_rate, 0);
         | 
| 31 | 
            +
                }
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                return p;
         | 
| 34 | 
            +
            }
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            /*
         | 
| 37 | 
            +
             * call-seq:
         | 
| 38 | 
            +
             *  decode(string, max_decoded_size, opts = {}) -> decoded string
         | 
| 39 | 
            +
             */
         | 
| 40 | 
            +
            static VALUE
         | 
| 41 | 
            +
            ext_s_decode(int argc, VALUE argv[], VALUE mod)
         | 
| 42 | 
            +
            {
         | 
| 43 | 
            +
                VALUE src, size, opts;
         | 
| 44 | 
            +
                rb_scan_args(argc, argv, "2:", &src, &size, &opts);
         | 
| 45 | 
            +
                rb_check_type(src, RUBY_T_STRING);
         | 
| 46 | 
            +
                rb_str_locktmp(src);
         | 
| 47 | 
            +
                size_t srcsize = RSTRING_LEN(src);
         | 
| 48 | 
            +
                size_t destsize = NUM2SIZET(size);
         | 
| 49 | 
            +
                VALUE dest = rb_str_buf_new(destsize);
         | 
| 50 | 
            +
                lzham_decompress_params p = aux_conv_decode_params(opts);
         | 
| 51 | 
            +
                lzham_decompress_status_t s;
         | 
| 52 | 
            +
                s = lzham_decompress_memory(&p,
         | 
| 53 | 
            +
                        (lzham_uint8 *)RSTRING_PTR(dest), &destsize,
         | 
| 54 | 
            +
                        (lzham_uint8 *)RSTRING_PTR(src), srcsize, NULL);
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                rb_str_unlocktmp(src);
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                if (s != LZHAM_DECOMP_STATUS_SUCCESS) {
         | 
| 59 | 
            +
                    rb_str_resize(dest, 0);
         | 
| 60 | 
            +
                    aux_decode_error(s);
         | 
| 61 | 
            +
                }
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                rb_str_resize(dest, destsize);
         | 
| 64 | 
            +
                rb_str_set_len(dest, destsize);
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                return dest;
         | 
| 67 | 
            +
            }
         | 
| 68 | 
            +
             | 
| 69 | 
            +
            struct decoder
         | 
| 70 | 
            +
            {
         | 
| 71 | 
            +
                lzham_decompress_state_ptr decoder;
         | 
| 72 | 
            +
                VALUE outport;
         | 
| 73 | 
            +
                VALUE outbuf;
         | 
| 74 | 
            +
            };
         | 
| 75 | 
            +
             | 
| 76 | 
            +
            static void
         | 
| 77 | 
            +
            ext_dec_mark(struct decoder *p)
         | 
| 78 | 
            +
            {
         | 
| 79 | 
            +
                if (p) {
         | 
| 80 | 
            +
                    rb_gc_mark(p->outport);
         | 
| 81 | 
            +
                    rb_gc_mark(p->outbuf);
         | 
| 82 | 
            +
                }
         | 
| 83 | 
            +
            }
         | 
| 84 | 
            +
             | 
| 85 | 
            +
            static void
         | 
| 86 | 
            +
            ext_dec_free(struct decoder *p)
         | 
| 87 | 
            +
            {
         | 
| 88 | 
            +
                if (p) {
         | 
| 89 | 
            +
                    if (p->decoder) {
         | 
| 90 | 
            +
                        lzham_decompress_deinit(p->decoder);
         | 
| 91 | 
            +
                    }
         | 
| 92 | 
            +
                }
         | 
| 93 | 
            +
            }
         | 
| 94 | 
            +
             | 
| 95 | 
            +
            static VALUE
         | 
| 96 | 
            +
            ext_dec_alloc(VALUE klass)
         | 
| 97 | 
            +
            {
         | 
| 98 | 
            +
                struct decoder *p;
         | 
| 99 | 
            +
                VALUE obj = Data_Make_Struct(klass, struct decoder, ext_dec_mark, ext_dec_free, p);
         | 
| 100 | 
            +
                return obj;
         | 
| 101 | 
            +
            }
         | 
| 102 | 
            +
             | 
| 103 | 
            +
            static inline struct decoder *
         | 
| 104 | 
            +
            aux_decoder_refp(VALUE obj)
         | 
| 105 | 
            +
            {
         | 
| 106 | 
            +
                struct decoder *p;
         | 
| 107 | 
            +
                Data_Get_Struct(obj, struct decoder, p);
         | 
| 108 | 
            +
                return p;
         | 
| 109 | 
            +
            }
         | 
| 110 | 
            +
             | 
| 111 | 
            +
            static inline struct decoder *
         | 
| 112 | 
            +
            aux_decoder_ref(VALUE obj)
         | 
| 113 | 
            +
            {
         | 
| 114 | 
            +
                struct decoder *p = aux_decoder_refp(obj);
         | 
| 115 | 
            +
                if (!p || !p->decoder) {
         | 
| 116 | 
            +
                    rb_raise(eError,
         | 
| 117 | 
            +
                             "not initialized - #<%s:%p>",
         | 
| 118 | 
            +
                             rb_obj_classname(obj), (void *)obj);
         | 
| 119 | 
            +
                }
         | 
| 120 | 
            +
                return p;
         | 
| 121 | 
            +
            }
         | 
| 122 | 
            +
             | 
| 123 | 
            +
            /*
         | 
| 124 | 
            +
             * call-seq:
         | 
| 125 | 
            +
             *  initialize(outport = nil, opts = {})
         | 
| 126 | 
            +
             */
         | 
| 127 | 
            +
            static VALUE
         | 
| 128 | 
            +
            ext_dec_init(int argc, VALUE argv[], VALUE dec)
         | 
| 129 | 
            +
            {
         | 
| 130 | 
            +
                struct decoder *p = DATA_PTR(dec);
         | 
| 131 | 
            +
                if (p->decoder) {
         | 
| 132 | 
            +
                    rb_raise(eError,
         | 
| 133 | 
            +
                             "already initialized - #<%s:%p>",
         | 
| 134 | 
            +
                             rb_obj_classname(dec), (void *)dec);
         | 
| 135 | 
            +
                }
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                VALUE outport, opts;
         | 
| 138 | 
            +
                rb_scan_args(argc, argv, "01:", &outport, &opts);
         | 
| 139 | 
            +
                if (NIL_P(outport)) { outport = rb_str_buf_new(0); }
         | 
| 140 | 
            +
                lzham_decompress_params params = aux_conv_decode_params(opts);
         | 
| 141 | 
            +
                p->decoder = lzham_decompress_init(¶ms);
         | 
| 142 | 
            +
                if (!p->decoder) {
         | 
| 143 | 
            +
                    rb_raise(eError,
         | 
| 144 | 
            +
                             "failed lzham_decompress_init - #<%s:%p>",
         | 
| 145 | 
            +
                             rb_obj_classname(dec), (void *)dec);
         | 
| 146 | 
            +
                }
         | 
| 147 | 
            +
             | 
| 148 | 
            +
                p->outbuf = rb_str_buf_new(WORKBUF_SIZE);
         | 
| 149 | 
            +
                p->outport = outport;
         | 
| 150 | 
            +
             | 
| 151 | 
            +
                return dec;
         | 
| 152 | 
            +
            }
         | 
| 153 | 
            +
             | 
| 154 | 
            +
            struct aux_lzham_decompress_nogvl
         | 
| 155 | 
            +
            {
         | 
| 156 | 
            +
                lzham_decompress_state_ptr state;
         | 
| 157 | 
            +
                const lzham_uint8 *inbuf;
         | 
| 158 | 
            +
                size_t *insize;
         | 
| 159 | 
            +
                lzham_uint8 *outbuf;
         | 
| 160 | 
            +
                size_t *outsize;
         | 
| 161 | 
            +
                lzham_bool flags;
         | 
| 162 | 
            +
            };
         | 
| 163 | 
            +
             | 
| 164 | 
            +
            static void *
         | 
| 165 | 
            +
            aux_lzham_decompress_nogvl(void *px)
         | 
| 166 | 
            +
            {
         | 
| 167 | 
            +
                struct aux_lzham_decompress_nogvl *p = px;
         | 
| 168 | 
            +
                return (void *)lzham_decompress(p->state, p->inbuf, p->insize, p->outbuf, p->outsize, p->flags);
         | 
| 169 | 
            +
            }
         | 
| 170 | 
            +
             | 
| 171 | 
            +
            static inline lzham_decompress_status_t
         | 
| 172 | 
            +
            aux_lzham_decompress(lzham_decompress_state_ptr state,
         | 
| 173 | 
            +
                    const lzham_uint8 *inbuf, size_t *insize,
         | 
| 174 | 
            +
                    lzham_uint8 *outbuf, size_t *outsize,
         | 
| 175 | 
            +
                    lzham_bool flags)
         | 
| 176 | 
            +
            {
         | 
| 177 | 
            +
                struct aux_lzham_decompress_nogvl p = {
         | 
| 178 | 
            +
                    .state = state,
         | 
| 179 | 
            +
                    .inbuf = inbuf,
         | 
| 180 | 
            +
                    .insize = insize,
         | 
| 181 | 
            +
                    .outbuf = outbuf,
         | 
| 182 | 
            +
                    .outsize = outsize,
         | 
| 183 | 
            +
                    .flags = flags,
         | 
| 184 | 
            +
                };
         | 
| 185 | 
            +
             | 
| 186 | 
            +
                return (lzham_decompress_status_t)rb_thread_call_without_gvl(aux_lzham_decompress_nogvl, &p, 0, 0);
         | 
| 187 | 
            +
            }
         | 
| 188 | 
            +
             | 
| 189 | 
            +
            struct dec_update_args
         | 
| 190 | 
            +
            {
         | 
| 191 | 
            +
                VALUE decoder;
         | 
| 192 | 
            +
                VALUE src;
         | 
| 193 | 
            +
                int flush;
         | 
| 194 | 
            +
            };
         | 
| 195 | 
            +
             | 
| 196 | 
            +
            static VALUE
         | 
| 197 | 
            +
            dec_update_protected(struct dec_update_args *args)
         | 
| 198 | 
            +
            {
         | 
| 199 | 
            +
                struct decoder *p = aux_decoder_ref(args->decoder);
         | 
| 200 | 
            +
                const char *inbuf, *intail;
         | 
| 201 | 
            +
             | 
| 202 | 
            +
                if (NIL_P(args->src)) {
         | 
| 203 | 
            +
                    inbuf = NULL;
         | 
| 204 | 
            +
                    intail = NULL;
         | 
| 205 | 
            +
                } else {
         | 
| 206 | 
            +
                    inbuf = RSTRING_PTR(args->src);
         | 
| 207 | 
            +
                    intail = inbuf + RSTRING_LEN(args->src);
         | 
| 208 | 
            +
                }
         | 
| 209 | 
            +
             | 
| 210 | 
            +
                lzham_decompress_status_t s;
         | 
| 211 | 
            +
                do {
         | 
| 212 | 
            +
                    size_t insize = intail - inbuf;
         | 
| 213 | 
            +
                    aux_str_reserve(p->outbuf, WORKBUF_SIZE);
         | 
| 214 | 
            +
                    rb_str_locktmp(p->outbuf);
         | 
| 215 | 
            +
                    size_t outsize = rb_str_capacity(p->outbuf);
         | 
| 216 | 
            +
                    s = aux_lzham_decompress(p->decoder,
         | 
| 217 | 
            +
                            (lzham_uint8 *)inbuf, &insize,
         | 
| 218 | 
            +
                            (lzham_uint8 *)RSTRING_PTR(p->outbuf), &outsize, args->flush);
         | 
| 219 | 
            +
                    rb_str_unlocktmp(p->outbuf);
         | 
| 220 | 
            +
            //fprintf(stderr, "%s:%d:%s: status=%s (%d), insize=%zu, outsize=%zu\n", __FILE__, __LINE__, __func__, aux_decode_status_str(s), s, insize, outsize);
         | 
| 221 | 
            +
                    if (!NIL_P(args->src)) {
         | 
| 222 | 
            +
                        inbuf += insize;
         | 
| 223 | 
            +
                    }
         | 
| 224 | 
            +
                    if (s != LZHAM_DECOMP_STATUS_NOT_FINISHED &&
         | 
| 225 | 
            +
                        s != LZHAM_DECOMP_STATUS_HAS_MORE_OUTPUT &&
         | 
| 226 | 
            +
                        s != LZHAM_DECOMP_STATUS_NEEDS_MORE_INPUT &&
         | 
| 227 | 
            +
                        s != LZHAM_DECOMP_STATUS_SUCCESS) {
         | 
| 228 | 
            +
             | 
| 229 | 
            +
                        aux_decode_error(s);
         | 
| 230 | 
            +
                    }
         | 
| 231 | 
            +
                    if (outsize > 0) {
         | 
| 232 | 
            +
                        rb_str_set_len(p->outbuf, outsize);
         | 
| 233 | 
            +
                        rb_funcall2(p->outport, ID_op_lshift, 1, &p->outbuf);
         | 
| 234 | 
            +
                    }
         | 
| 235 | 
            +
                } while (inbuf < intail || s == LZHAM_DECOMP_STATUS_HAS_MORE_OUTPUT);
         | 
| 236 | 
            +
             | 
| 237 | 
            +
                return 0;
         | 
| 238 | 
            +
            }
         | 
| 239 | 
            +
             | 
| 240 | 
            +
            static inline void
         | 
| 241 | 
            +
            dec_update(VALUE dec, VALUE src, int flush)
         | 
| 242 | 
            +
            {
         | 
| 243 | 
            +
                struct dec_update_args args = { dec, src, flush };
         | 
| 244 | 
            +
                if (NIL_P(src)) {
         | 
| 245 | 
            +
                    dec_update_protected(&args);
         | 
| 246 | 
            +
                } else {
         | 
| 247 | 
            +
                    rb_str_locktmp(src);
         | 
| 248 | 
            +
                    int state;
         | 
| 249 | 
            +
                    rb_protect((VALUE (*)(VALUE))dec_update_protected, (VALUE)&args, &state);
         | 
| 250 | 
            +
                    rb_str_unlocktmp(src);
         | 
| 251 | 
            +
                    if (state) {
         | 
| 252 | 
            +
                        rb_jump_tag(state);
         | 
| 253 | 
            +
                    }
         | 
| 254 | 
            +
                }
         | 
| 255 | 
            +
            }
         | 
| 256 | 
            +
             | 
| 257 | 
            +
            /*
         | 
| 258 | 
            +
             * call-seq:
         | 
| 259 | 
            +
             *  update(src, flush = false) -> self
         | 
| 260 | 
            +
             */
         | 
| 261 | 
            +
            static VALUE
         | 
| 262 | 
            +
            ext_dec_update(int argc, VALUE argv[], VALUE dec)
         | 
| 263 | 
            +
            {
         | 
| 264 | 
            +
                VALUE src, flush;
         | 
| 265 | 
            +
                rb_scan_args(argc, argv, "11", &src, &flush);
         | 
| 266 | 
            +
                rb_check_type(src, RUBY_T_STRING);
         | 
| 267 | 
            +
                dec_update(dec, src, RTEST(flush) ? 1 : 0);
         | 
| 268 | 
            +
                return dec;
         | 
| 269 | 
            +
            }
         | 
| 270 | 
            +
             | 
| 271 | 
            +
            static VALUE
         | 
| 272 | 
            +
            ext_dec_finish(VALUE dec)
         | 
| 273 | 
            +
            {
         | 
| 274 | 
            +
                dec_update(dec, Qnil, 1);
         | 
| 275 | 
            +
                return dec;
         | 
| 276 | 
            +
            }
         | 
| 277 | 
            +
             | 
| 278 | 
            +
            static VALUE
         | 
| 279 | 
            +
            ext_dec_op_lshift(VALUE dec, VALUE src)
         | 
| 280 | 
            +
            {
         | 
| 281 | 
            +
                rb_check_type(src, RUBY_T_STRING);
         | 
| 282 | 
            +
                dec_update(dec, src, 0);
         | 
| 283 | 
            +
                return dec;
         | 
| 284 | 
            +
            }
         | 
| 285 | 
            +
             | 
| 286 | 
            +
            static VALUE
         | 
| 287 | 
            +
            ext_dec_get_outport(VALUE dec)
         | 
| 288 | 
            +
            {
         | 
| 289 | 
            +
                struct decoder *p = aux_decoder_ref(dec);
         | 
| 290 | 
            +
                return p->outport;
         | 
| 291 | 
            +
            }
         | 
| 292 | 
            +
             | 
| 293 | 
            +
            static VALUE
         | 
| 294 | 
            +
            ext_dec_set_outport(VALUE dec, VALUE outport)
         | 
| 295 | 
            +
            {
         | 
| 296 | 
            +
                struct decoder *p = aux_decoder_ref(dec);
         | 
| 297 | 
            +
                p->outport = outport;
         | 
| 298 | 
            +
                return outport;
         | 
| 299 | 
            +
            }
         | 
| 300 | 
            +
             | 
| 301 | 
            +
            void
         | 
| 302 | 
            +
            init_decoder(void)
         | 
| 303 | 
            +
            {
         | 
| 304 | 
            +
                cDecoder = rb_define_class_under(mLZHAM, "Decoder", rb_cObject);
         | 
| 305 | 
            +
                rb_include_module(cDecoder, mConsts);
         | 
| 306 | 
            +
                rb_define_alloc_func(cDecoder, ext_dec_alloc);
         | 
| 307 | 
            +
                rb_define_singleton_method(cDecoder, "decode", RUBY_METHOD_FUNC(ext_s_decode), -1);
         | 
| 308 | 
            +
                rb_define_method(cDecoder, "initialize", RUBY_METHOD_FUNC(ext_dec_init), -1);
         | 
| 309 | 
            +
                rb_define_method(cDecoder, "update", RUBY_METHOD_FUNC(ext_dec_update), -1);
         | 
| 310 | 
            +
                rb_define_method(cDecoder, "finish", RUBY_METHOD_FUNC(ext_dec_finish), 0);
         | 
| 311 | 
            +
                rb_define_method(cDecoder, "<<", RUBY_METHOD_FUNC(ext_dec_op_lshift), 1);
         | 
| 312 | 
            +
                rb_define_method(cDecoder, "outport", RUBY_METHOD_FUNC(ext_dec_get_outport), 0);
         | 
| 313 | 
            +
                rb_define_method(cDecoder, "outport=", RUBY_METHOD_FUNC(ext_dec_set_outport), 1);
         | 
| 314 | 
            +
             | 
| 315 | 
            +
            }
         |