msgpack 0.7.0dev1-x86-mingw32 → 0.7.0-x86-mingw32
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/.gitignore +1 -0
 - data/.travis.yml +2 -0
 - data/ChangeLog +8 -0
 - data/README.rdoc +36 -2
 - data/ext/java/org/msgpack/jruby/Decoder.java +55 -16
 - data/ext/java/org/msgpack/jruby/Encoder.java +31 -8
 - data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +159 -0
 - data/ext/java/org/msgpack/jruby/Factory.java +117 -0
 - data/ext/java/org/msgpack/jruby/MessagePackLibrary.java +23 -6
 - data/ext/java/org/msgpack/jruby/Packer.java +65 -6
 - data/ext/java/org/msgpack/jruby/Unpacker.java +104 -22
 - data/ext/msgpack/packer_class.c +7 -0
 - data/ext/msgpack/packer_ext_registry.c +0 -8
 - data/ext/msgpack/packer_ext_registry.h +0 -3
 - data/ext/msgpack/unpacker_class.c +14 -0
 - data/ext/msgpack/unpacker_ext_registry.c +0 -6
 - data/ext/msgpack/unpacker_ext_registry.h +0 -3
 - data/lib/msgpack/version.rb +1 -1
 - data/msgpack.gemspec +5 -3
 - data/spec/cruby/unpacker_spec.rb +0 -247
 - data/spec/factory_spec.rb +0 -3
 - data/spec/jruby/{msgpack/unpacker_spec.rb → unpacker_spec.rb} +30 -159
 - data/spec/msgpack_spec.rb +1 -1
 - data/spec/packer_spec.rb +135 -4
 - data/spec/unpacker_spec.rb +465 -6
 - metadata +9 -6
 - data/spec/cruby/packer_spec.rb +0 -138
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 0d0e3d42a5abee5ed3099e8784636b4bcbf10731
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: f40232648f4ec2efa26b3874ebe3de519a2196e5
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: a162332df41c000debc176cdd0d9cce9a67da29d2a20d3e7d9704d3726e541abf89be49517d36e9a4e8c9f6100bd811f793d1ba97e44f8de645bd4f1db50c497
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 9cebb8ccc7f423f20c9784e01718e8ec098a7e3f00f4379ad208e3efddd71b48e275cd137f965e72b74f33067a5d730b3a191429eae4a1288da7cbb83250396f
         
     | 
    
        data/.gitignore
    CHANGED
    
    
    
        data/.travis.yml
    CHANGED
    
    
    
        data/ChangeLog
    CHANGED
    
    | 
         @@ -1,3 +1,11 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            2015-10-24 version 0.7.0:
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            * Add extention types support.
         
     | 
| 
      
 4 
     | 
    
         
            +
            * Fix to share almost all test cases between CRuby and JRuby implementations.
         
     | 
| 
      
 5 
     | 
    
         
            +
            * Fixed JRuby implementation to raise UnknownExtTypeError for unregistered ext type ids
         
     | 
| 
      
 6 
     | 
    
         
            +
              instead to generate MessagePack::ExtensionValue instances.
         
     | 
| 
      
 7 
     | 
    
         
            +
              (Specify `allow_unknown_ext: true` as unpacker option for v0.6.x behavior.)
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
       1 
9 
     | 
    
         
             
            2015-07-22 version 0.6.2:
         
     | 
| 
       2 
10 
     | 
    
         | 
| 
       3 
11 
     | 
    
         
             
            * Fix release workflow: Ruby 2.1 and 2.2 are supported for Windows (2.0 is omitted)
         
     | 
    
        data/README.rdoc
    CHANGED
    
    | 
         @@ -36,7 +36,6 @@ or build msgpack-ruby and install: 
     | 
|
| 
       36 
36 
     | 
    
         
             
            * Exchange objects between software components written in different languages
         
     | 
| 
       37 
37 
     | 
    
         
             
              * You'll need a flexible but efficient format so that components exchange objects while keeping compatibility
         
     | 
| 
       38 
38 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
39 
     | 
    
         
             
            = Portability
         
     | 
| 
       41 
40 
     | 
    
         | 
| 
       42 
41 
     | 
    
         
             
            MessagePack for Ruby should run on x86, ARM, PowerPC, SPARC and other CPU architectures.
         
     | 
| 
         @@ -92,6 +91,32 @@ or event-driven style which works well with EventMachine: 
     | 
|
| 
       92 
91 
     | 
    
         | 
| 
       93 
92 
     | 
    
         
             
            See {API reference}[http://ruby.msgpack.org/MessagePack/Unpacker.html] for details.
         
     | 
| 
       94 
93 
     | 
    
         | 
| 
      
 94 
     | 
    
         
            +
            = Extension Types
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
            Packer and Unpacker support {Extension types of MessagePack}[https://github.com/msgpack/msgpack/blob/master/spec.md#types-extension-type].
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                # register how to serialize custom class at first
         
     | 
| 
      
 99 
     | 
    
         
            +
                pk = MessagePack::Packer.new(io)
         
     | 
| 
      
 100 
     | 
    
         
            +
                pk.register_type(0x01, MyClass1, :to_msgpack_ext) # equal to pk.register_type(0x01, MyClass)
         
     | 
| 
      
 101 
     | 
    
         
            +
                pk.register_type(0x02, MyClass2){|obj| obj.how_to_serialize() } # blocks also available
         
     | 
| 
      
 102 
     | 
    
         
            +
                
         
     | 
| 
      
 103 
     | 
    
         
            +
                # almost same API for unpacker
         
     | 
| 
      
 104 
     | 
    
         
            +
                uk = MessagePack::Unpacker.new()
         
     | 
| 
      
 105 
     | 
    
         
            +
                uk.register_type(0x01, MyClass1, :from_msgpack_ext)
         
     | 
| 
      
 106 
     | 
    
         
            +
                uk.register_type(0x02){|data| MyClass2.create_from_serialized_data(data) }
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
            MessagePack::Factory is to create packer and unpacker which have same extention types.
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
                factory = MessagePack::Factory.new
         
     | 
| 
      
 111 
     | 
    
         
            +
                factory.register_type(0x01, MyClass1) # same with next line
         
     | 
| 
      
 112 
     | 
    
         
            +
                factory.register_type(0x01, MyClass1, packer: :to_msgpack_ext, unpacker: :from_msgpack_ext)
         
     | 
| 
      
 113 
     | 
    
         
            +
                pk = factory.packer(options_for_packer)
         
     | 
| 
      
 114 
     | 
    
         
            +
                uk = factory.unpacker(options_for_unpacker)
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
            For *MessagePack.pack* and *MessagePack.unpack*, default packer/unpacker refer *MessagePack::DefaultFactory*. Call *MessagePack::DefaultFactory.register_type* to enable types process globally.
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                MessagePack::DefaultFactory.register_type(0x03, MyClass3)
         
     | 
| 
      
 119 
     | 
    
         
            +
                MessagePack.unpack(data_with_ext_typeid_03) #=> MyClass3 instance
         
     | 
| 
       95 
120 
     | 
    
         | 
| 
       96 
121 
     | 
    
         
             
            = Buffer API
         
     | 
| 
       97 
122 
     | 
    
         | 
| 
         @@ -129,9 +154,18 @@ MessagePack mingw32/64 rubygems build process uses {rake-compiler-dock}[https:// 
     | 
|
| 
       129 
154 
     | 
    
         | 
| 
       130 
155 
     | 
    
         
             
            Once this step successes, target gems exist in pkg/msgpack-*-{x86,x64}-mingw32.gem.
         
     | 
| 
       131 
156 
     | 
    
         | 
| 
      
 157 
     | 
    
         
            +
            == Updating documents
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
            Online documents (http://ruby.msgpack.org) is generated from gh-pages branch.
         
     | 
| 
      
 160 
     | 
    
         
            +
            Following commands update documents in gh-pages branch:
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
                bundle exec rake doc
         
     | 
| 
      
 163 
     | 
    
         
            +
                git checkout gh-pages
         
     | 
| 
      
 164 
     | 
    
         
            +
                cp doc/* ./ -a
         
     | 
| 
      
 165 
     | 
    
         
            +
             
     | 
| 
       132 
166 
     | 
    
         
             
            = Copyright
         
     | 
| 
       133 
167 
     | 
    
         | 
| 
       134 
168 
     | 
    
         
             
            Author::    Sadayuki Furuhashi <frsyuki@gmail.com>
         
     | 
| 
       135 
     | 
    
         
            -
            Copyright:: Copyright (c) 2008- 
     | 
| 
      
 169 
     | 
    
         
            +
            Copyright:: Copyright (c) 2008-2015 Sadayuki Furuhashi
         
     | 
| 
       136 
170 
     | 
    
         
             
            License::   Apache License, Version 2.0
         
     | 
| 
       137 
171 
     | 
    
         | 
| 
         @@ -12,6 +12,7 @@ import org.jruby.RubyObject; 
     | 
|
| 
       12 
12 
     | 
    
         
             
            import org.jruby.RubyClass;
         
     | 
| 
       13 
13 
     | 
    
         
             
            import org.jruby.RubyBignum;
         
     | 
| 
       14 
14 
     | 
    
         
             
            import org.jruby.RubyString;
         
     | 
| 
      
 15 
     | 
    
         
            +
            import org.jruby.RubyArray;
         
     | 
| 
       15 
16 
     | 
    
         
             
            import org.jruby.RubyHash;
         
     | 
| 
       16 
17 
     | 
    
         
             
            import org.jruby.exceptions.RaiseException;
         
     | 
| 
       17 
18 
     | 
    
         
             
            import org.jruby.runtime.builtin.IRubyObject;
         
     | 
| 
         @@ -29,33 +30,58 @@ public class Decoder implements Iterator<IRubyObject> { 
     | 
|
| 
       29 
30 
     | 
    
         
             
              private final Encoding utf8Encoding;
         
     | 
| 
       30 
31 
     | 
    
         
             
              private final RubyClass unpackErrorClass;
         
     | 
| 
       31 
32 
     | 
    
         
             
              private final RubyClass underflowErrorClass;
         
     | 
| 
      
 33 
     | 
    
         
            +
              private final RubyClass malformedFormatErrorClass;
         
     | 
| 
      
 34 
     | 
    
         
            +
              private final RubyClass stackErrorClass;
         
     | 
| 
       32 
35 
     | 
    
         
             
              private final RubyClass unexpectedTypeErrorClass;
         
     | 
| 
      
 36 
     | 
    
         
            +
              private final RubyClass unknownExtTypeErrorClass;
         
     | 
| 
       33 
37 
     | 
    
         | 
| 
      
 38 
     | 
    
         
            +
              private ExtensionRegistry registry;
         
     | 
| 
       34 
39 
     | 
    
         
             
              private ByteBuffer buffer;
         
     | 
| 
       35 
40 
     | 
    
         
             
              private boolean symbolizeKeys;
         
     | 
| 
      
 41 
     | 
    
         
            +
              private boolean allowUnknownExt;
         
     | 
| 
       36 
42 
     | 
    
         | 
| 
       37 
43 
     | 
    
         
             
              public Decoder(Ruby runtime) {
         
     | 
| 
       38 
     | 
    
         
            -
                this(runtime, new byte[] {}, 0, 0);
         
     | 
| 
      
 44 
     | 
    
         
            +
                this(runtime, null, new byte[] {}, 0, 0, false, false);
         
     | 
| 
      
 45 
     | 
    
         
            +
              }
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
              public Decoder(Ruby runtime, ExtensionRegistry registry) {
         
     | 
| 
      
 48 
     | 
    
         
            +
                this(runtime, registry, new byte[] {}, 0, 0, false, false);
         
     | 
| 
       39 
49 
     | 
    
         
             
              }
         
     | 
| 
       40 
50 
     | 
    
         | 
| 
       41 
51 
     | 
    
         
             
              public Decoder(Ruby runtime, byte[] bytes) {
         
     | 
| 
       42 
     | 
    
         
            -
                this(runtime, bytes, 0, bytes.length);
         
     | 
| 
      
 52 
     | 
    
         
            +
                this(runtime, null, bytes, 0, bytes.length, false, false);
         
     | 
| 
      
 53 
     | 
    
         
            +
              }
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
              public Decoder(Ruby runtime, ExtensionRegistry registry, byte[] bytes) {
         
     | 
| 
      
 56 
     | 
    
         
            +
                this(runtime, registry, bytes, 0, bytes.length, false, false);
         
     | 
| 
      
 57 
     | 
    
         
            +
              }
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
              public Decoder(Ruby runtime, ExtensionRegistry registry, byte[] bytes, boolean symbolizeKeys, boolean allowUnknownExt) {
         
     | 
| 
      
 60 
     | 
    
         
            +
                this(runtime, registry, bytes, 0, bytes.length, symbolizeKeys, allowUnknownExt);
         
     | 
| 
      
 61 
     | 
    
         
            +
              }
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
              public Decoder(Ruby runtime, ExtensionRegistry registry, byte[] bytes, int offset, int length) {
         
     | 
| 
      
 64 
     | 
    
         
            +
                this(runtime, registry, bytes, offset, length, false, false);
         
     | 
| 
       43 
65 
     | 
    
         
             
              }
         
     | 
| 
       44 
66 
     | 
    
         | 
| 
       45 
     | 
    
         
            -
              public Decoder(Ruby runtime, byte[] bytes, int offset, int length) {
         
     | 
| 
      
 67 
     | 
    
         
            +
              public Decoder(Ruby runtime, ExtensionRegistry registry, byte[] bytes, int offset, int length, boolean symbolizeKeys, boolean allowUnknownExt) {
         
     | 
| 
       46 
68 
     | 
    
         
             
                this.runtime = runtime;
         
     | 
| 
      
 69 
     | 
    
         
            +
                this.registry = registry;
         
     | 
| 
      
 70 
     | 
    
         
            +
                this.symbolizeKeys = symbolizeKeys;
         
     | 
| 
      
 71 
     | 
    
         
            +
                this.allowUnknownExt = allowUnknownExt;
         
     | 
| 
       47 
72 
     | 
    
         
             
                this.binaryEncoding = runtime.getEncodingService().getAscii8bitEncoding();
         
     | 
| 
       48 
73 
     | 
    
         
             
                this.utf8Encoding = UTF8Encoding.INSTANCE;
         
     | 
| 
       49 
74 
     | 
    
         
             
                this.unpackErrorClass = runtime.getModule("MessagePack").getClass("UnpackError");
         
     | 
| 
       50 
75 
     | 
    
         
             
                this.underflowErrorClass = runtime.getModule("MessagePack").getClass("UnderflowError");
         
     | 
| 
      
 76 
     | 
    
         
            +
                this.malformedFormatErrorClass = runtime.getModule("MessagePack").getClass("MalformedFormatError");
         
     | 
| 
      
 77 
     | 
    
         
            +
                this.stackErrorClass = runtime.getModule("MessagePack").getClass("StackError");
         
     | 
| 
       51 
78 
     | 
    
         
             
                this.unexpectedTypeErrorClass = runtime.getModule("MessagePack").getClass("UnexpectedTypeError");
         
     | 
| 
      
 79 
     | 
    
         
            +
                this.unknownExtTypeErrorClass = runtime.getModule("MessagePack").getClass("UnknownExtTypeError");
         
     | 
| 
      
 80 
     | 
    
         
            +
                this.symbolizeKeys = symbolizeKeys;
         
     | 
| 
      
 81 
     | 
    
         
            +
                this.allowUnknownExt = allowUnknownExt;
         
     | 
| 
       52 
82 
     | 
    
         
             
                feed(bytes, offset, length);
         
     | 
| 
       53 
83 
     | 
    
         
             
              }
         
     | 
| 
       54 
84 
     | 
    
         | 
| 
       55 
     | 
    
         
            -
              public void symbolizeKeys(boolean symbolize) {
         
     | 
| 
       56 
     | 
    
         
            -
                this.symbolizeKeys = symbolize;
         
     | 
| 
       57 
     | 
    
         
            -
              }
         
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
85 
     | 
    
         
             
              public void feed(byte[] bytes) {
         
     | 
| 
       60 
86 
     | 
    
         
             
                feed(bytes, 0, bytes.length);
         
     | 
| 
       61 
87 
     | 
    
         
             
              }
         
     | 
| 
         @@ -73,7 +99,7 @@ public class Decoder implements Iterator<IRubyObject> { 
     | 
|
| 
       73 
99 
     | 
    
         
             
              }
         
     | 
| 
       74 
100 
     | 
    
         | 
| 
       75 
101 
     | 
    
         
             
              public void reset() {
         
     | 
| 
       76 
     | 
    
         
            -
                buffer 
     | 
| 
      
 102 
     | 
    
         
            +
                buffer = null;
         
     | 
| 
       77 
103 
     | 
    
         
             
              }
         
     | 
| 
       78 
104 
     | 
    
         | 
| 
       79 
105 
     | 
    
         
             
              public int offset() {
         
     | 
| 
         @@ -118,7 +144,20 @@ public class Decoder implements Iterator<IRubyObject> { 
     | 
|
| 
       118 
144 
     | 
    
         
             
              private IRubyObject consumeExtension(int size) {
         
     | 
| 
       119 
145 
     | 
    
         
             
                int type = buffer.get();
         
     | 
| 
       120 
146 
     | 
    
         
             
                byte[] payload = readBytes(size);
         
     | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
                if (registry != null) {
         
     | 
| 
      
 149 
     | 
    
         
            +
                  IRubyObject proc = registry.lookupUnpackerByTypeId(type);
         
     | 
| 
      
 150 
     | 
    
         
            +
                  if (proc != null) {
         
     | 
| 
      
 151 
     | 
    
         
            +
                    ByteList byteList = new ByteList(payload, runtime.getEncodingService().getAscii8bitEncoding());
         
     | 
| 
      
 152 
     | 
    
         
            +
                    return proc.callMethod(runtime.getCurrentContext(), "call", runtime.newString(byteList));
         
     | 
| 
      
 153 
     | 
    
         
            +
                  }
         
     | 
| 
      
 154 
     | 
    
         
            +
                }
         
     | 
| 
      
 155 
     | 
    
         
            +
             
     | 
| 
      
 156 
     | 
    
         
            +
                if (this.allowUnknownExt) {
         
     | 
| 
      
 157 
     | 
    
         
            +
                  return ExtensionValue.newExtensionValue(runtime, type, payload);
         
     | 
| 
      
 158 
     | 
    
         
            +
                }
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
                throw runtime.newRaiseException(unknownExtTypeErrorClass, "unexpected extension type");
         
     | 
| 
       122 
161 
     | 
    
         
             
              }
         
     | 
| 
       123 
162 
     | 
    
         | 
| 
       124 
163 
     | 
    
         
             
              private byte[] readBytes(int size) {
         
     | 
| 
         @@ -142,11 +181,11 @@ public class Decoder implements Iterator<IRubyObject> { 
     | 
|
| 
       142 
181 
     | 
    
         
             
                try {
         
     | 
| 
       143 
182 
     | 
    
         
             
                  byte b = buffer.get();
         
     | 
| 
       144 
183 
     | 
    
         
             
                  if ((b & 0xf0) == 0x90) {
         
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
      
 184 
     | 
    
         
            +
                    return runtime.newFixnum(b & 0x0f);
         
     | 
| 
       146 
185 
     | 
    
         
             
                  } else if (b == ARY16) {
         
     | 
| 
       147 
     | 
    
         
            -
             
     | 
| 
      
 186 
     | 
    
         
            +
                    return runtime.newFixnum(buffer.getShort() & 0xffff);
         
     | 
| 
       148 
187 
     | 
    
         
             
                  } else if (b == ARY32) {
         
     | 
| 
       149 
     | 
    
         
            -
             
     | 
| 
      
 188 
     | 
    
         
            +
                    return runtime.newFixnum(buffer.getInt());
         
     | 
| 
       150 
189 
     | 
    
         
             
                  }
         
     | 
| 
       151 
190 
     | 
    
         
             
                  throw runtime.newRaiseException(unexpectedTypeErrorClass, "unexpected type");
         
     | 
| 
       152 
191 
     | 
    
         
             
                } catch (RaiseException re) {
         
     | 
| 
         @@ -163,11 +202,11 @@ public class Decoder implements Iterator<IRubyObject> { 
     | 
|
| 
       163 
202 
     | 
    
         
             
                try {
         
     | 
| 
       164 
203 
     | 
    
         
             
                  byte b = buffer.get();
         
     | 
| 
       165 
204 
     | 
    
         
             
                  if ((b & 0xf0) == 0x80) {
         
     | 
| 
       166 
     | 
    
         
            -
             
     | 
| 
      
 205 
     | 
    
         
            +
                    return runtime.newFixnum(b & 0x0f);
         
     | 
| 
       167 
206 
     | 
    
         
             
                  } else if (b == MAP16) {
         
     | 
| 
       168 
     | 
    
         
            -
             
     | 
| 
      
 207 
     | 
    
         
            +
                    return runtime.newFixnum(buffer.getShort() & 0xffff);
         
     | 
| 
       169 
208 
     | 
    
         
             
                  } else if (b == MAP32) {
         
     | 
| 
       170 
     | 
    
         
            -
             
     | 
| 
      
 209 
     | 
    
         
            +
                    return runtime.newFixnum(buffer.getInt());
         
     | 
| 
       171 
210 
     | 
    
         
             
                  }
         
     | 
| 
       172 
211 
     | 
    
         
             
                  throw runtime.newRaiseException(unexpectedTypeErrorClass, "unexpected type");
         
     | 
| 
       173 
212 
     | 
    
         
             
                } catch (RaiseException re) {
         
     | 
| 
         @@ -233,7 +272,7 @@ public class Decoder implements Iterator<IRubyObject> { 
     | 
|
| 
       233 
272 
     | 
    
         
             
                  default: return runtime.newFixnum(b);
         
     | 
| 
       234 
273 
     | 
    
         
             
                  }
         
     | 
| 
       235 
274 
     | 
    
         
             
                  buffer.position(position);
         
     | 
| 
       236 
     | 
    
         
            -
                  throw runtime.newRaiseException( 
     | 
| 
      
 275 
     | 
    
         
            +
                  throw runtime.newRaiseException(malformedFormatErrorClass, "Illegal byte sequence");
         
     | 
| 
       237 
276 
     | 
    
         
             
                } catch (RaiseException re) {
         
     | 
| 
       238 
277 
     | 
    
         
             
                  buffer.position(position);
         
     | 
| 
       239 
278 
     | 
    
         
             
                  throw re;
         
     | 
| 
         @@ -34,15 +34,21 @@ public class Encoder { 
     | 
|
| 
       34 
34 
     | 
    
         
             
              private final Encoding binaryEncoding;
         
     | 
| 
       35 
35 
     | 
    
         
             
              private final Encoding utf8Encoding;
         
     | 
| 
       36 
36 
     | 
    
         
             
              private final boolean compatibilityMode;
         
     | 
| 
      
 37 
     | 
    
         
            +
              private final ExtensionRegistry registry;
         
     | 
| 
       37 
38 
     | 
    
         | 
| 
       38 
39 
     | 
    
         
             
              private ByteBuffer buffer;
         
     | 
| 
       39 
40 
     | 
    
         | 
| 
       40 
     | 
    
         
            -
              public Encoder(Ruby runtime, boolean compatibilityMode) {
         
     | 
| 
      
 41 
     | 
    
         
            +
              public Encoder(Ruby runtime, boolean compatibilityMode, ExtensionRegistry registry) {
         
     | 
| 
       41 
42 
     | 
    
         
             
                this.runtime = runtime;
         
     | 
| 
       42 
43 
     | 
    
         
             
                this.buffer = ByteBuffer.allocate(CACHE_LINE_SIZE - ARRAY_HEADER_SIZE);
         
     | 
| 
       43 
44 
     | 
    
         
             
                this.binaryEncoding = runtime.getEncodingService().getAscii8bitEncoding();
         
     | 
| 
       44 
45 
     | 
    
         
             
                this.utf8Encoding = UTF8Encoding.INSTANCE;
         
     | 
| 
       45 
46 
     | 
    
         
             
                this.compatibilityMode = compatibilityMode;
         
     | 
| 
      
 47 
     | 
    
         
            +
                this.registry = registry;
         
     | 
| 
      
 48 
     | 
    
         
            +
              }
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
              public boolean isCompatibilityMode() {
         
     | 
| 
      
 51 
     | 
    
         
            +
                return compatibilityMode;
         
     | 
| 
       46 
52 
     | 
    
         
             
              }
         
     | 
| 
       47 
53 
     | 
    
         | 
| 
       48 
54 
     | 
    
         
             
              private void ensureRemainingCapacity(int c) {
         
     | 
| 
         @@ -107,7 +113,7 @@ public class Encoder { 
     | 
|
| 
       107 
113 
     | 
    
         
             
                } else if (object instanceof ExtensionValue) {
         
     | 
| 
       108 
114 
     | 
    
         
             
                  appendExtensionValue((ExtensionValue) object);
         
     | 
| 
       109 
115 
     | 
    
         
             
                } else {
         
     | 
| 
       110 
     | 
    
         
            -
                   
     | 
| 
      
 116 
     | 
    
         
            +
                  appendOther(object, destination);
         
     | 
| 
       111 
117 
     | 
    
         
             
                }
         
     | 
| 
       112 
118 
     | 
    
         
             
              }
         
     | 
| 
       113 
119 
     | 
    
         | 
| 
         @@ -295,12 +301,7 @@ public class Encoder { 
     | 
|
| 
       295 
301 
     | 
    
         
             
                }
         
     | 
| 
       296 
302 
     | 
    
         
             
              }
         
     | 
| 
       297 
303 
     | 
    
         | 
| 
       298 
     | 
    
         
            -
              private void  
     | 
| 
       299 
     | 
    
         
            -
                long type = ((RubyFixnum)object.get_type()).getLongValue();
         
     | 
| 
       300 
     | 
    
         
            -
                if (type < -128 || type > 127) {
         
     | 
| 
       301 
     | 
    
         
            -
            	    throw object.getRuntime().newRangeError(String.format("integer %d too big to convert to `signed char'", type));
         
     | 
| 
       302 
     | 
    
         
            -
                }
         
     | 
| 
       303 
     | 
    
         
            -
                ByteList payloadBytes = ((RubyString)object.payload()).getByteList();
         
     | 
| 
      
 304 
     | 
    
         
            +
              private void appendExt(int type, ByteList payloadBytes) {
         
     | 
| 
       304 
305 
     | 
    
         
             
                int payloadSize = payloadBytes.length();
         
     | 
| 
       305 
306 
     | 
    
         
             
                int outputSize = 0;
         
     | 
| 
       306 
307 
     | 
    
         
             
                boolean fixSize = payloadSize == 1 || payloadSize == 2 || payloadSize == 4 || payloadSize == 8 || payloadSize == 16;
         
     | 
| 
         @@ -338,6 +339,28 @@ public class Encoder { 
     | 
|
| 
       338 
339 
     | 
    
         
             
                buffer.put(payloadBytes.unsafeBytes(), payloadBytes.begin(), payloadSize);
         
     | 
| 
       339 
340 
     | 
    
         
             
              }
         
     | 
| 
       340 
341 
     | 
    
         | 
| 
      
 342 
     | 
    
         
            +
              private void appendExtensionValue(ExtensionValue object) {
         
     | 
| 
      
 343 
     | 
    
         
            +
                long type = ((RubyFixnum)object.get_type()).getLongValue();
         
     | 
| 
      
 344 
     | 
    
         
            +
                if (type < -128 || type > 127) {
         
     | 
| 
      
 345 
     | 
    
         
            +
                  throw object.getRuntime().newRangeError(String.format("integer %d too big to convert to `signed char'", type));
         
     | 
| 
      
 346 
     | 
    
         
            +
                }
         
     | 
| 
      
 347 
     | 
    
         
            +
                ByteList payloadBytes = ((RubyString)object.payload()).getByteList();
         
     | 
| 
      
 348 
     | 
    
         
            +
                appendExt((int) type, payloadBytes);
         
     | 
| 
      
 349 
     | 
    
         
            +
              }
         
     | 
| 
      
 350 
     | 
    
         
            +
             
     | 
| 
      
 351 
     | 
    
         
            +
              private void appendOther(IRubyObject object, IRubyObject destination) {
         
     | 
| 
      
 352 
     | 
    
         
            +
                if (registry != null) {
         
     | 
| 
      
 353 
     | 
    
         
            +
                  IRubyObject[] pair = registry.lookupPackerByClass(object.getType());
         
     | 
| 
      
 354 
     | 
    
         
            +
                  if (pair != null) {
         
     | 
| 
      
 355 
     | 
    
         
            +
                    RubyString bytes = pair[0].callMethod(runtime.getCurrentContext(), "call", object).asString();
         
     | 
| 
      
 356 
     | 
    
         
            +
                    int type = (int) ((RubyFixnum) pair[1]).getLongValue();
         
     | 
| 
      
 357 
     | 
    
         
            +
                    appendExt(type, bytes.getByteList());
         
     | 
| 
      
 358 
     | 
    
         
            +
                    return;
         
     | 
| 
      
 359 
     | 
    
         
            +
                  }
         
     | 
| 
      
 360 
     | 
    
         
            +
                }
         
     | 
| 
      
 361 
     | 
    
         
            +
                appendCustom(object, destination);
         
     | 
| 
      
 362 
     | 
    
         
            +
              }
         
     | 
| 
      
 363 
     | 
    
         
            +
             
     | 
| 
       341 
364 
     | 
    
         
             
              private void appendCustom(IRubyObject object, IRubyObject destination) {
         
     | 
| 
       342 
365 
     | 
    
         
             
                if (destination == null) {
         
     | 
| 
       343 
366 
     | 
    
         
             
                  IRubyObject result = object.callMethod(runtime.getCurrentContext(), "to_msgpack");
         
     | 
| 
         @@ -0,0 +1,159 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            package org.msgpack.jruby;
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            import org.jruby.Ruby;
         
     | 
| 
      
 4 
     | 
    
         
            +
            import org.jruby.RubyHash;
         
     | 
| 
      
 5 
     | 
    
         
            +
            import org.jruby.RubyArray;
         
     | 
| 
      
 6 
     | 
    
         
            +
            import org.jruby.RubyClass;
         
     | 
| 
      
 7 
     | 
    
         
            +
            import org.jruby.RubyFixnum;
         
     | 
| 
      
 8 
     | 
    
         
            +
            import org.jruby.runtime.ThreadContext;
         
     | 
| 
      
 9 
     | 
    
         
            +
            import org.jruby.runtime.builtin.IRubyObject;
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            import java.util.Map;
         
     | 
| 
      
 12 
     | 
    
         
            +
            import java.util.HashMap;
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            public class ExtensionRegistry {
         
     | 
| 
      
 15 
     | 
    
         
            +
              private final Map<RubyClass, ExtensionEntry> extensionsByClass;
         
     | 
| 
      
 16 
     | 
    
         
            +
              private final Map<RubyClass, ExtensionEntry> extensionsByAncestor;
         
     | 
| 
      
 17 
     | 
    
         
            +
              private final ExtensionEntry[] extensionsByTypeId;
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              public ExtensionRegistry() {
         
     | 
| 
      
 20 
     | 
    
         
            +
                this(new HashMap<RubyClass, ExtensionEntry>());
         
     | 
| 
      
 21 
     | 
    
         
            +
              }
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              private ExtensionRegistry(Map<RubyClass, ExtensionEntry> extensionsByClass) {
         
     | 
| 
      
 24 
     | 
    
         
            +
                this.extensionsByClass = new HashMap<RubyClass, ExtensionEntry>(extensionsByClass);
         
     | 
| 
      
 25 
     | 
    
         
            +
                this.extensionsByAncestor = new HashMap<RubyClass, ExtensionEntry>();
         
     | 
| 
      
 26 
     | 
    
         
            +
                this.extensionsByTypeId = new ExtensionEntry[256];
         
     | 
| 
      
 27 
     | 
    
         
            +
                for (ExtensionEntry entry : extensionsByClass.values()) {
         
     | 
| 
      
 28 
     | 
    
         
            +
                  if (entry.hasUnpacker()) {
         
     | 
| 
      
 29 
     | 
    
         
            +
                    extensionsByTypeId[entry.getTypeId() + 128] = entry;
         
     | 
| 
      
 30 
     | 
    
         
            +
                  }
         
     | 
| 
      
 31 
     | 
    
         
            +
                }
         
     | 
| 
      
 32 
     | 
    
         
            +
              }
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
              public ExtensionRegistry dup() {
         
     | 
| 
      
 35 
     | 
    
         
            +
                return new ExtensionRegistry(extensionsByClass);
         
     | 
| 
      
 36 
     | 
    
         
            +
              }
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
              public IRubyObject toInternalPackerRegistry(ThreadContext ctx) {
         
     | 
| 
      
 39 
     | 
    
         
            +
                RubyHash hash = RubyHash.newHash(ctx.getRuntime());
         
     | 
| 
      
 40 
     | 
    
         
            +
                for (RubyClass extensionClass : extensionsByClass.keySet()) {
         
     | 
| 
      
 41 
     | 
    
         
            +
                  ExtensionEntry entry = extensionsByClass.get(extensionClass);
         
     | 
| 
      
 42 
     | 
    
         
            +
                  if (entry.hasPacker()) {
         
     | 
| 
      
 43 
     | 
    
         
            +
                    hash.put(extensionClass, entry.toPackerTuple(ctx));
         
     | 
| 
      
 44 
     | 
    
         
            +
                  }
         
     | 
| 
      
 45 
     | 
    
         
            +
                }
         
     | 
| 
      
 46 
     | 
    
         
            +
                return hash;
         
     | 
| 
      
 47 
     | 
    
         
            +
              }
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
              public IRubyObject toInternalUnpackerRegistry(ThreadContext ctx) {
         
     | 
| 
      
 50 
     | 
    
         
            +
                RubyHash hash = RubyHash.newHash(ctx.getRuntime());
         
     | 
| 
      
 51 
     | 
    
         
            +
                for (int typeIdIndex = 0 ; typeIdIndex < 256 ; typeIdIndex++) {
         
     | 
| 
      
 52 
     | 
    
         
            +
                  ExtensionEntry entry = extensionsByTypeId[typeIdIndex];
         
     | 
| 
      
 53 
     | 
    
         
            +
                  if (entry != null && entry.hasUnpacker()) {
         
     | 
| 
      
 54 
     | 
    
         
            +
                    IRubyObject typeId = RubyFixnum.newFixnum(ctx.getRuntime(), typeIdIndex - 128);
         
     | 
| 
      
 55 
     | 
    
         
            +
                    hash.put(typeId, entry.toUnpackerTuple(ctx));
         
     | 
| 
      
 56 
     | 
    
         
            +
                  }
         
     | 
| 
      
 57 
     | 
    
         
            +
                }
         
     | 
| 
      
 58 
     | 
    
         
            +
                return hash;
         
     | 
| 
      
 59 
     | 
    
         
            +
              }
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
              public void put(RubyClass cls, int typeId, IRubyObject packerProc, IRubyObject packerArg, IRubyObject unpackerProc, IRubyObject unpackerArg) {
         
     | 
| 
      
 62 
     | 
    
         
            +
                ExtensionEntry entry = new ExtensionEntry(cls, typeId, packerProc, packerArg, unpackerProc, unpackerArg);
         
     | 
| 
      
 63 
     | 
    
         
            +
                extensionsByClass.put(cls, entry);
         
     | 
| 
      
 64 
     | 
    
         
            +
                extensionsByTypeId[typeId + 128] = entry;
         
     | 
| 
      
 65 
     | 
    
         
            +
                extensionsByAncestor.clear();
         
     | 
| 
      
 66 
     | 
    
         
            +
              }
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
              public IRubyObject lookupUnpackerByTypeId(int typeId) {
         
     | 
| 
      
 69 
     | 
    
         
            +
                ExtensionEntry e = extensionsByTypeId[typeId + 128];
         
     | 
| 
      
 70 
     | 
    
         
            +
                if (e != null && e.hasUnpacker()) {
         
     | 
| 
      
 71 
     | 
    
         
            +
                  return e.getUnpackerProc();
         
     | 
| 
      
 72 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 73 
     | 
    
         
            +
                  return null;
         
     | 
| 
      
 74 
     | 
    
         
            +
                }
         
     | 
| 
      
 75 
     | 
    
         
            +
              }
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
              public IRubyObject[] lookupPackerByClass(RubyClass cls) {
         
     | 
| 
      
 78 
     | 
    
         
            +
                ExtensionEntry e = extensionsByClass.get(cls);
         
     | 
| 
      
 79 
     | 
    
         
            +
                if (e == null) {
         
     | 
| 
      
 80 
     | 
    
         
            +
                  e = extensionsByAncestor.get(cls);
         
     | 
| 
      
 81 
     | 
    
         
            +
                }
         
     | 
| 
      
 82 
     | 
    
         
            +
                if (e == null) {
         
     | 
| 
      
 83 
     | 
    
         
            +
                  e = findEntryByClassOrAncestor(cls);
         
     | 
| 
      
 84 
     | 
    
         
            +
                  if (e != null) {
         
     | 
| 
      
 85 
     | 
    
         
            +
                    extensionsByAncestor.put(e.getExtensionClass(), e);
         
     | 
| 
      
 86 
     | 
    
         
            +
                  }
         
     | 
| 
      
 87 
     | 
    
         
            +
                }
         
     | 
| 
      
 88 
     | 
    
         
            +
                if (e != null && e.hasPacker()) {
         
     | 
| 
      
 89 
     | 
    
         
            +
                  return e.toPackerProcTypeIdPair(cls.getRuntime().getCurrentContext());
         
     | 
| 
      
 90 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 91 
     | 
    
         
            +
                  return null;
         
     | 
| 
      
 92 
     | 
    
         
            +
                }
         
     | 
| 
      
 93 
     | 
    
         
            +
              }
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
              private ExtensionEntry findEntryByClassOrAncestor(final RubyClass cls) {
         
     | 
| 
      
 96 
     | 
    
         
            +
                ThreadContext ctx = cls.getRuntime().getCurrentContext();
         
     | 
| 
      
 97 
     | 
    
         
            +
                for (RubyClass extensionClass : extensionsByClass.keySet()) {
         
     | 
| 
      
 98 
     | 
    
         
            +
                  RubyArray ancestors = (RubyArray) cls.callMethod(ctx, "ancestors");
         
     | 
| 
      
 99 
     | 
    
         
            +
                  if (ancestors.callMethod(ctx, "include?", extensionClass).isTrue()) {
         
     | 
| 
      
 100 
     | 
    
         
            +
                    return extensionsByClass.get(extensionClass);
         
     | 
| 
      
 101 
     | 
    
         
            +
                  }
         
     | 
| 
      
 102 
     | 
    
         
            +
                }
         
     | 
| 
      
 103 
     | 
    
         
            +
                return null;
         
     | 
| 
      
 104 
     | 
    
         
            +
              }
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
              private static class ExtensionEntry {
         
     | 
| 
      
 107 
     | 
    
         
            +
                private final RubyClass cls;
         
     | 
| 
      
 108 
     | 
    
         
            +
                private final int typeId;
         
     | 
| 
      
 109 
     | 
    
         
            +
                private final IRubyObject packerProc;
         
     | 
| 
      
 110 
     | 
    
         
            +
                private final IRubyObject packerArg;
         
     | 
| 
      
 111 
     | 
    
         
            +
                private final IRubyObject unpackerProc;
         
     | 
| 
      
 112 
     | 
    
         
            +
                private final IRubyObject unpackerArg;
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                public ExtensionEntry(RubyClass cls, int typeId, IRubyObject packerProc, IRubyObject packerArg, IRubyObject unpackerProc, IRubyObject unpackerArg) {
         
     | 
| 
      
 115 
     | 
    
         
            +
                  this.cls = cls;
         
     | 
| 
      
 116 
     | 
    
         
            +
                  this.typeId = typeId;
         
     | 
| 
      
 117 
     | 
    
         
            +
                  this.packerProc = packerProc;
         
     | 
| 
      
 118 
     | 
    
         
            +
                  this.packerArg = packerArg;
         
     | 
| 
      
 119 
     | 
    
         
            +
                  this.unpackerProc = unpackerProc;
         
     | 
| 
      
 120 
     | 
    
         
            +
                  this.unpackerArg = unpackerArg;
         
     | 
| 
      
 121 
     | 
    
         
            +
                }
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                public RubyClass getExtensionClass() {
         
     | 
| 
      
 124 
     | 
    
         
            +
                  return cls;
         
     | 
| 
      
 125 
     | 
    
         
            +
                }
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
                public int getTypeId() {
         
     | 
| 
      
 128 
     | 
    
         
            +
                  return typeId;
         
     | 
| 
      
 129 
     | 
    
         
            +
                }
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
                public boolean hasPacker() {
         
     | 
| 
      
 132 
     | 
    
         
            +
                  return packerProc != null;
         
     | 
| 
      
 133 
     | 
    
         
            +
                }
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
                public boolean hasUnpacker() {
         
     | 
| 
      
 136 
     | 
    
         
            +
                  return unpackerProc != null;
         
     | 
| 
      
 137 
     | 
    
         
            +
                }
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
                public IRubyObject getPackerProc() {
         
     | 
| 
      
 140 
     | 
    
         
            +
                  return packerProc;
         
     | 
| 
      
 141 
     | 
    
         
            +
                }
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
                public IRubyObject getUnpackerProc() {
         
     | 
| 
      
 144 
     | 
    
         
            +
                  return unpackerProc;
         
     | 
| 
      
 145 
     | 
    
         
            +
                }
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
                public RubyArray toPackerTuple(ThreadContext ctx) {
         
     | 
| 
      
 148 
     | 
    
         
            +
                  return RubyArray.newArray(ctx.getRuntime(), new IRubyObject[] {RubyFixnum.newFixnum(ctx.getRuntime(), typeId), packerProc, packerArg});
         
     | 
| 
      
 149 
     | 
    
         
            +
                }
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                public RubyArray toUnpackerTuple(ThreadContext ctx) {
         
     | 
| 
      
 152 
     | 
    
         
            +
                  return RubyArray.newArray(ctx.getRuntime(), new IRubyObject[] {cls, unpackerProc, unpackerArg});
         
     | 
| 
      
 153 
     | 
    
         
            +
                }
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
                public IRubyObject[] toPackerProcTypeIdPair(ThreadContext ctx) {
         
     | 
| 
      
 156 
     | 
    
         
            +
                  return new IRubyObject[] {packerProc, RubyFixnum.newFixnum(ctx.getRuntime(), typeId)};
         
     | 
| 
      
 157 
     | 
    
         
            +
                }
         
     | 
| 
      
 158 
     | 
    
         
            +
              }
         
     | 
| 
      
 159 
     | 
    
         
            +
            }
         
     |