msgpack 0.4.3-x86-mingw32 → 0.4.4-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.
- data/ext/compat.h +77 -0
 - data/ext/extconf.rb +1 -1
 - data/ext/pack.c +20 -9
 - data/ext/rbinit.c +15 -0
 - data/ext/unpack.c +219 -67
 - data/ext/version.rb +1 -1
 - data/lib/1.8/msgpack.so +0 -0
 - data/lib/1.9/msgpack.so +0 -0
 - data/msgpack/pack_template.h +32 -32
 - data/msgpack/sysdep.h +6 -4
 - data/test/test_cases.rbc +1152 -0
 - data/test/test_encoding.rb +68 -0
 - data/test/test_helper.rb +3 -1
 - data/test/test_helper.rbc +227 -0
 - data/test/test_pack_unpack.rb +15 -10
 - data/test/test_pack_unpack.rbc +5863 -0
 - metadata +15 -5
 
    
        data/ext/compat.h
    ADDED
    
    | 
         @@ -0,0 +1,77 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            /*
         
     | 
| 
      
 2 
     | 
    
         
            +
             * MessagePack for Ruby
         
     | 
| 
      
 3 
     | 
    
         
            +
             *
         
     | 
| 
      
 4 
     | 
    
         
            +
             * Copyright (C) 2008-2010 FURUHASHI Sadayuki
         
     | 
| 
      
 5 
     | 
    
         
            +
             *
         
     | 
| 
      
 6 
     | 
    
         
            +
             *    Licensed under the Apache License, Version 2.0 (the "License");
         
     | 
| 
      
 7 
     | 
    
         
            +
             *    you may not use this file except in compliance with the License.
         
     | 
| 
      
 8 
     | 
    
         
            +
             *    You may obtain a copy of the License at
         
     | 
| 
      
 9 
     | 
    
         
            +
             *
         
     | 
| 
      
 10 
     | 
    
         
            +
             *        http://www.apache.org/licenses/LICENSE-2.0
         
     | 
| 
      
 11 
     | 
    
         
            +
             *
         
     | 
| 
      
 12 
     | 
    
         
            +
             *    Unless required by applicable law or agreed to in writing, software
         
     | 
| 
      
 13 
     | 
    
         
            +
             *    distributed under the License is distributed on an "AS IS" BASIS,
         
     | 
| 
      
 14 
     | 
    
         
            +
             *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         
     | 
| 
      
 15 
     | 
    
         
            +
             *    See the License for the specific language governing permissions and
         
     | 
| 
      
 16 
     | 
    
         
            +
             *    limitations under the License.
         
     | 
| 
      
 17 
     | 
    
         
            +
             */
         
     | 
| 
      
 18 
     | 
    
         
            +
            #ifndef COMPAT_H__
         
     | 
| 
      
 19 
     | 
    
         
            +
            #define COMPAT_H__
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
      
 23 
     | 
    
         
            +
            #include "ruby/encoding.h"
         
     | 
| 
      
 24 
     | 
    
         
            +
            #define COMPAT_HAVE_ENCODING
         
     | 
| 
      
 25 
     | 
    
         
            +
            extern int s_enc_utf8;
         
     | 
| 
      
 26 
     | 
    
         
            +
            extern int s_enc_ascii8bit;
         
     | 
| 
      
 27 
     | 
    
         
            +
            extern int s_enc_usascii;
         
     | 
| 
      
 28 
     | 
    
         
            +
            extern VALUE s_enc_utf8_value;
         
     | 
| 
      
 29 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            #ifdef RUBY_VM
         
     | 
| 
      
 32 
     | 
    
         
            +
            #define COMPAT_RERAISE rb_exc_raise(rb_errinfo())
         
     | 
| 
      
 33 
     | 
    
         
            +
            #else
         
     | 
| 
      
 34 
     | 
    
         
            +
            #define COMPAT_RERAISE rb_exc_raise(ruby_errinfo)
         
     | 
| 
      
 35 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            /* ruby 1.8 and Rubinius */
         
     | 
| 
      
 39 
     | 
    
         
            +
            #ifndef RBIGNUM_POSITIVE_P
         
     | 
| 
      
 40 
     | 
    
         
            +
            # ifdef RUBINIUS
         
     | 
| 
      
 41 
     | 
    
         
            +
            #  define RBIGNUM_POSITIVE_P(b) (rb_funcall(b, rb_intern(">="), 1, INT2FIX(0)) == Qtrue)
         
     | 
| 
      
 42 
     | 
    
         
            +
            # else
         
     | 
| 
      
 43 
     | 
    
         
            +
            #  define RBIGNUM_POSITIVE_P(b) (RBIGNUM(b)->sign)
         
     | 
| 
      
 44 
     | 
    
         
            +
            # endif
         
     | 
| 
      
 45 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            /* Rubinius */
         
     | 
| 
      
 49 
     | 
    
         
            +
            #ifdef RUBINIUS
         
     | 
| 
      
 50 
     | 
    
         
            +
            static inline void rb_gc_enable() { return; }
         
     | 
| 
      
 51 
     | 
    
         
            +
            static inline void rb_gc_disable() { return; }
         
     | 
| 
      
 52 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            /* ruby 1.8.5 */
         
     | 
| 
      
 56 
     | 
    
         
            +
            #ifndef RSTRING_PTR
         
     | 
| 
      
 57 
     | 
    
         
            +
            #define RSTRING_PTR(s) (RSTRING(s)->ptr)
         
     | 
| 
      
 58 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            /* ruby 1.8.5 */
         
     | 
| 
      
 61 
     | 
    
         
            +
            #ifndef RSTRING_LEN
         
     | 
| 
      
 62 
     | 
    
         
            +
            #define RSTRING_LEN(s) (RSTRING(s)->len)
         
     | 
| 
      
 63 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
            /* ruby 1.8.5 */
         
     | 
| 
      
 66 
     | 
    
         
            +
            #ifndef RARRAY_PTR
         
     | 
| 
      
 67 
     | 
    
         
            +
            #define RARRAY_PTR(s) (RARRAY(s)->ptr)
         
     | 
| 
      
 68 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
            /* ruby 1.8.5 */
         
     | 
| 
      
 71 
     | 
    
         
            +
            #ifndef RARRAY_LEN
         
     | 
| 
      
 72 
     | 
    
         
            +
            #define RARRAY_LEN(s) (RARRAY(s)->len)
         
     | 
| 
      
 73 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            #endif /* compat.h */
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
    
        data/ext/extconf.rb
    CHANGED
    
    
    
        data/ext/pack.c
    CHANGED
    
    | 
         @@ -16,6 +16,8 @@ 
     | 
|
| 
       16 
16 
     | 
    
         
             
             *    limitations under the License.
         
     | 
| 
       17 
17 
     | 
    
         
             
             */
         
     | 
| 
       18 
18 
     | 
    
         
             
            #include "ruby.h"
         
     | 
| 
      
 19 
     | 
    
         
            +
            #include "compat.h"
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
       19 
21 
     | 
    
         
             
            #include "msgpack/pack_define.h"
         
     | 
| 
       20 
22 
     | 
    
         | 
| 
       21 
23 
     | 
    
         
             
            static ID s_to_msgpack;
         
     | 
| 
         @@ -116,10 +118,6 @@ static VALUE MessagePack_Fixnum_to_msgpack(int argc, VALUE *argv, VALUE self) 
     | 
|
| 
       116 
118 
     | 
    
         
             
            }
         
     | 
| 
       117 
119 
     | 
    
         | 
| 
       118 
120 
     | 
    
         | 
| 
       119 
     | 
    
         
            -
            #ifndef RBIGNUM_SIGN  // Ruby 1.8
         
     | 
| 
       120 
     | 
    
         
            -
            #define RBIGNUM_SIGN(b) (RBIGNUM(b)->sign)
         
     | 
| 
       121 
     | 
    
         
            -
            #endif
         
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
121 
     | 
    
         
             
            /*
         
     | 
| 
       124 
122 
     | 
    
         
             
             * Document-method: Bignum#to_msgpack
         
     | 
| 
       125 
123 
     | 
    
         
             
             *
         
     | 
| 
         @@ -131,10 +129,9 @@ static VALUE MessagePack_Fixnum_to_msgpack(int argc, VALUE *argv, VALUE self) 
     | 
|
| 
       131 
129 
     | 
    
         
             
            static VALUE MessagePack_Bignum_to_msgpack(int argc, VALUE *argv, VALUE self)
         
     | 
| 
       132 
130 
     | 
    
         
             
            {
         
     | 
| 
       133 
131 
     | 
    
         
             
            	ARG_BUFFER(out, argc, argv);
         
     | 
| 
       134 
     | 
    
         
            -
            	 
     | 
| 
       135 
     | 
    
         
            -
            	if(RBIGNUM_SIGN(self)) {  // positive
         
     | 
| 
      
 132 
     | 
    
         
            +
            	if(RBIGNUM_POSITIVE_P(self)) {
         
     | 
| 
       136 
133 
     | 
    
         
             
            		msgpack_pack_uint64(out, rb_big2ull(self));
         
     | 
| 
       137 
     | 
    
         
            -
            	} else { 
     | 
| 
      
 134 
     | 
    
         
            +
            	} else {
         
     | 
| 
       138 
135 
     | 
    
         
             
            		msgpack_pack_int64(out, rb_big2ll(self));
         
     | 
| 
       139 
136 
     | 
    
         
             
            	}
         
     | 
| 
       140 
137 
     | 
    
         
             
            	return out;
         
     | 
| 
         @@ -168,6 +165,14 @@ static VALUE MessagePack_Float_to_msgpack(int argc, VALUE *argv, VALUE self) 
     | 
|
| 
       168 
165 
     | 
    
         
             
            static VALUE MessagePack_String_to_msgpack(int argc, VALUE *argv, VALUE self)
         
     | 
| 
       169 
166 
     | 
    
         
             
            {
         
     | 
| 
       170 
167 
     | 
    
         
             
            	ARG_BUFFER(out, argc, argv);
         
     | 
| 
      
 168 
     | 
    
         
            +
            #ifdef COMPAT_HAVE_ENCODING
         
     | 
| 
      
 169 
     | 
    
         
            +
            	int enc = ENCODING_GET(self);
         
     | 
| 
      
 170 
     | 
    
         
            +
            	if(enc != s_enc_utf8 && enc != s_enc_ascii8bit && enc != s_enc_usascii) {
         
     | 
| 
      
 171 
     | 
    
         
            +
            		if(!ENC_CODERANGE_ASCIIONLY(self)) {
         
     | 
| 
      
 172 
     | 
    
         
            +
            			self = rb_str_encode(self, s_enc_utf8_value, 0, Qnil);
         
     | 
| 
      
 173 
     | 
    
         
            +
            		}
         
     | 
| 
      
 174 
     | 
    
         
            +
            	}
         
     | 
| 
      
 175 
     | 
    
         
            +
            #endif
         
     | 
| 
       171 
176 
     | 
    
         
             
            	msgpack_pack_raw(out, RSTRING_LEN(self));
         
     | 
| 
       172 
177 
     | 
    
         
             
            	msgpack_pack_raw_body(out, RSTRING_PTR(self), RSTRING_LEN(self));
         
     | 
| 
       173 
178 
     | 
    
         
             
            	return out;
         
     | 
| 
         @@ -184,12 +189,16 @@ static VALUE MessagePack_String_to_msgpack(int argc, VALUE *argv, VALUE self) 
     | 
|
| 
       184 
189 
     | 
    
         
             
             */
         
     | 
| 
       185 
190 
     | 
    
         
             
            static VALUE MessagePack_Symbol_to_msgpack(int argc, VALUE *argv, VALUE self)
         
     | 
| 
       186 
191 
     | 
    
         
             
            {
         
     | 
| 
      
 192 
     | 
    
         
            +
            #ifdef COMPAT_HAVE_ENCODING
         
     | 
| 
      
 193 
     | 
    
         
            +
            	return MessagePack_String_to_msgpack(argc, argv, rb_id2str(SYM2ID(self)));
         
     | 
| 
      
 194 
     | 
    
         
            +
            #else
         
     | 
| 
       187 
195 
     | 
    
         
             
            	ARG_BUFFER(out, argc, argv);
         
     | 
| 
       188 
196 
     | 
    
         
             
            	const char* name = rb_id2name(SYM2ID(self));
         
     | 
| 
       189 
197 
     | 
    
         
             
            	size_t len = strlen(name);
         
     | 
| 
       190 
198 
     | 
    
         
             
            	msgpack_pack_raw(out, len);
         
     | 
| 
       191 
199 
     | 
    
         
             
            	msgpack_pack_raw_body(out, name, len);
         
     | 
| 
       192 
200 
     | 
    
         
             
            	return out;
         
     | 
| 
      
 201 
     | 
    
         
            +
            #endif
         
     | 
| 
       193 
202 
     | 
    
         
             
            }
         
     | 
| 
       194 
203 
     | 
    
         | 
| 
       195 
204 
     | 
    
         | 
| 
         @@ -205,7 +214,8 @@ static VALUE MessagePack_Symbol_to_msgpack(int argc, VALUE *argv, VALUE self) 
     | 
|
| 
       205 
214 
     | 
    
         
             
            static VALUE MessagePack_Array_to_msgpack(int argc, VALUE *argv, VALUE self)
         
     | 
| 
       206 
215 
     | 
    
         
             
            {
         
     | 
| 
       207 
216 
     | 
    
         
             
            	ARG_BUFFER(out, argc, argv);
         
     | 
| 
       208 
     | 
    
         
            -
            	 
     | 
| 
      
 217 
     | 
    
         
            +
            	// FIXME check sizeof(long) > sizeof(unsigned int) && RARRAY_LEN(self) > UINT_MAX
         
     | 
| 
      
 218 
     | 
    
         
            +
            	msgpack_pack_array(out, (unsigned int)RARRAY_LEN(self));
         
     | 
| 
       209 
219 
     | 
    
         
             
            	VALUE* p = RARRAY_PTR(self);
         
     | 
| 
       210 
220 
     | 
    
         
             
            	VALUE* const pend = p + RARRAY_LEN(self);
         
     | 
| 
       211 
221 
     | 
    
         
             
            	for(;p != pend; ++p) {
         
     | 
| 
         @@ -239,7 +249,8 @@ static int MessagePack_Hash_to_msgpack_foreach(VALUE key, VALUE value, VALUE out 
     | 
|
| 
       239 
249 
     | 
    
         
             
            static VALUE MessagePack_Hash_to_msgpack(int argc, VALUE *argv, VALUE self)
         
     | 
| 
       240 
250 
     | 
    
         
             
            {
         
     | 
| 
       241 
251 
     | 
    
         
             
            	ARG_BUFFER(out, argc, argv);
         
     | 
| 
       242 
     | 
    
         
            -
            	 
     | 
| 
      
 252 
     | 
    
         
            +
            	// FIXME check sizeof(st_index_t) > sizeof(unsigned int) && RARRAY_LEN(self) > UINT_MAX
         
     | 
| 
      
 253 
     | 
    
         
            +
            	msgpack_pack_map(out, (unsigned int)RHASH_SIZE(self));
         
     | 
| 
       243 
254 
     | 
    
         
             
            	rb_hash_foreach(self, MessagePack_Hash_to_msgpack_foreach, out);
         
     | 
| 
       244 
255 
     | 
    
         
             
            	return out;
         
     | 
| 
       245 
256 
     | 
    
         
             
            }
         
     | 
    
        data/ext/rbinit.c
    CHANGED
    
    | 
         @@ -17,9 +17,17 @@ 
     | 
|
| 
       17 
17 
     | 
    
         
             
             */
         
     | 
| 
       18 
18 
     | 
    
         
             
            #include "pack.h"
         
     | 
| 
       19 
19 
     | 
    
         
             
            #include "unpack.h"
         
     | 
| 
      
 20 
     | 
    
         
            +
            #include "compat.h"
         
     | 
| 
       20 
21 
     | 
    
         | 
| 
       21 
22 
     | 
    
         
             
            static VALUE mMessagePack;
         
     | 
| 
       22 
23 
     | 
    
         | 
| 
      
 24 
     | 
    
         
            +
            #ifdef COMPAT_HAVE_ENCODING
         
     | 
| 
      
 25 
     | 
    
         
            +
            int s_enc_utf8;
         
     | 
| 
      
 26 
     | 
    
         
            +
            int s_enc_ascii8bit;
         
     | 
| 
      
 27 
     | 
    
         
            +
            int s_enc_usascii;
         
     | 
| 
      
 28 
     | 
    
         
            +
            VALUE s_enc_utf8_value;
         
     | 
| 
      
 29 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
       23 
31 
     | 
    
         
             
            /**
         
     | 
| 
       24 
32 
     | 
    
         
             
             * Document-module: MessagePack
         
     | 
| 
       25 
33 
     | 
    
         
             
             *
         
     | 
| 
         @@ -46,6 +54,13 @@ void Init_msgpack(void) 
     | 
|
| 
       46 
54 
     | 
    
         | 
| 
       47 
55 
     | 
    
         
             
            	rb_define_const(mMessagePack, "VERSION", rb_str_new2(MESSAGEPACK_VERSION));
         
     | 
| 
       48 
56 
     | 
    
         | 
| 
      
 57 
     | 
    
         
            +
            #ifdef COMPAT_HAVE_ENCODING
         
     | 
| 
      
 58 
     | 
    
         
            +
            	s_enc_ascii8bit = rb_ascii8bit_encindex();
         
     | 
| 
      
 59 
     | 
    
         
            +
            	s_enc_utf8 = rb_utf8_encindex();
         
     | 
| 
      
 60 
     | 
    
         
            +
            	s_enc_usascii = rb_usascii_encindex();
         
     | 
| 
      
 61 
     | 
    
         
            +
            	s_enc_utf8_value = rb_enc_from_encoding(rb_utf8_encoding());
         
     | 
| 
      
 62 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
       49 
64 
     | 
    
         
             
            	Init_msgpack_unpack(mMessagePack);
         
     | 
| 
       50 
65 
     | 
    
         
             
            	Init_msgpack_pack(mMessagePack);
         
     | 
| 
       51 
66 
     | 
    
         
             
            }
         
     | 
    
        data/ext/unpack.c
    CHANGED
    
    | 
         @@ -16,19 +16,15 @@ 
     | 
|
| 
       16 
16 
     | 
    
         
             
             *    limitations under the License.
         
     | 
| 
       17 
17 
     | 
    
         
             
             */
         
     | 
| 
       18 
18 
     | 
    
         
             
            #include "ruby.h"
         
     | 
| 
      
 19 
     | 
    
         
            +
            #include "compat.h"
         
     | 
| 
       19 
20 
     | 
    
         | 
| 
       20 
21 
     | 
    
         
             
            #include "msgpack/unpack_define.h"
         
     | 
| 
       21 
22 
     | 
    
         | 
| 
       22 
23 
     | 
    
         
             
            static ID s_sysread;
         
     | 
| 
       23 
24 
     | 
    
         
             
            static ID s_readpartial;
         
     | 
| 
       24 
25 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       26 
     | 
    
         
            -
            #include "ruby/encoding.h"
         
     | 
| 
       27 
     | 
    
         
            -
            int s_ascii_8bit;
         
     | 
| 
       28 
     | 
    
         
            -
            #endif
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
26 
     | 
    
         
             
            struct unpack_buffer {
         
     | 
| 
       31 
     | 
    
         
            -
            	size_t  
     | 
| 
      
 27 
     | 
    
         
            +
            	size_t used;
         
     | 
| 
       32 
28 
     | 
    
         
             
            	size_t free;
         
     | 
| 
       33 
29 
     | 
    
         
             
            	char* ptr;
         
     | 
| 
       34 
30 
     | 
    
         
             
            };
         
     | 
| 
         @@ -41,6 +37,7 @@ typedef struct { 
     | 
|
| 
       41 
37 
     | 
    
         
             
            	VALUE stream;
         
     | 
| 
       42 
38 
     | 
    
         
             
            	VALUE streambuf;
         
     | 
| 
       43 
39 
     | 
    
         
             
            	ID stream_append_method;
         
     | 
| 
      
 40 
     | 
    
         
            +
            	size_t buffer_free_size;
         
     | 
| 
       44 
41 
     | 
    
         
             
            } unpack_user;
         
     | 
| 
       45 
42 
     | 
    
         | 
| 
       46 
43 
     | 
    
         | 
| 
         @@ -136,6 +133,9 @@ static inline int template_callback_raw(unpack_user* u, const char* b, const cha 
     | 
|
| 
       136 
133 
     | 
    
         
             
            	} else {
         
     | 
| 
       137 
134 
     | 
    
         
             
            		*o = rb_str_substr(u->source, p - b, l);
         
     | 
| 
       138 
135 
     | 
    
         
             
            	}
         
     | 
| 
      
 136 
     | 
    
         
            +
            #ifdef COMPAT_HAVE_ENCODING
         
     | 
| 
      
 137 
     | 
    
         
            +
            	ENCODING_SET(*o, s_enc_utf8);
         
     | 
| 
      
 138 
     | 
    
         
            +
            #endif
         
     | 
| 
       139 
139 
     | 
    
         
             
            	return 0;
         
     | 
| 
       140 
140 
     | 
    
         
             
            }
         
     | 
| 
       141 
141 
     | 
    
         | 
| 
         @@ -156,27 +156,11 @@ static inline int template_callback_raw(unpack_user* u, const char* b, const cha 
     | 
|
| 
       156 
156 
     | 
    
         
             
            		rb_raise(rb_eTypeError, "instance of String needed"); \
         
     | 
| 
       157 
157 
     | 
    
         
             
            	}
         
     | 
| 
       158 
158 
     | 
    
         | 
| 
       159 
     | 
    
         
            -
            #ifdef RUBY_VM
         
     | 
| 
       160 
     | 
    
         
            -
            #define RERAISE rb_exc_raise(rb_errinfo())
         
     | 
| 
       161 
     | 
    
         
            -
            #else
         
     | 
| 
       162 
     | 
    
         
            -
            #define RERAISE rb_exc_raise(ruby_errinfo)
         
     | 
| 
       163 
     | 
    
         
            -
            #endif
         
     | 
| 
       164 
     | 
    
         
            -
             
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       167 
     | 
    
         
            -
            static VALUE template_execute_rescue_enc(VALUE data)
         
     | 
| 
       168 
     | 
    
         
            -
            {
         
     | 
| 
       169 
     | 
    
         
            -
            	rb_gc_enable();
         
     | 
| 
       170 
     | 
    
         
            -
            	VALUE* resc = (VALUE*)data;
         
     | 
| 
       171 
     | 
    
         
            -
            	rb_enc_set_index(resc[0], (int)resc[1]);
         
     | 
| 
       172 
     | 
    
         
            -
            	RERAISE;
         
     | 
| 
       173 
     | 
    
         
            -
            }
         
     | 
| 
       174 
     | 
    
         
            -
            #endif
         
     | 
| 
       175 
159 
     | 
    
         | 
| 
       176 
160 
     | 
    
         
             
            static VALUE template_execute_rescue(VALUE nouse)
         
     | 
| 
       177 
161 
     | 
    
         
             
            {
         
     | 
| 
       178 
162 
     | 
    
         
             
            	rb_gc_enable();
         
     | 
| 
       179 
     | 
    
         
            -
            	 
     | 
| 
      
 163 
     | 
    
         
            +
            	COMPAT_RERAISE;
         
     | 
| 
       180 
164 
     | 
    
         
             
            }
         
     | 
| 
       181 
165 
     | 
    
         | 
| 
       182 
166 
     | 
    
         
             
            static VALUE template_execute_do(VALUE argv)
         
     | 
| 
         @@ -203,31 +187,16 @@ static int template_execute_wrap(msgpack_unpack_t* mp, 
     | 
|
| 
       203 
187 
     | 
    
         
             
            		(VALUE)from,
         
     | 
| 
       204 
188 
     | 
    
         
             
            	};
         
     | 
| 
       205 
189 
     | 
    
         | 
| 
       206 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       207 
     | 
    
         
            -
            	int enc_orig = rb_enc_get_index(str);
         
     | 
| 
       208 
     | 
    
         
            -
            	rb_enc_set_index(str, s_ascii_8bit);
         
     | 
| 
       209 
     | 
    
         
            -
            #endif
         
     | 
| 
       210 
     | 
    
         
            -
             
     | 
| 
       211 
190 
     | 
    
         
             
            	// FIXME execute実行中はmp->topが更新されないのでGC markが機能しない
         
     | 
| 
       212 
191 
     | 
    
         
             
            	rb_gc_disable();
         
     | 
| 
       213 
192 
     | 
    
         | 
| 
       214 
193 
     | 
    
         
             
            	mp->user.source = str;
         
     | 
| 
       215 
194 
     | 
    
         | 
| 
       216 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       217 
     | 
    
         
            -
            	VALUE resc[2] = {str, enc_orig};
         
     | 
| 
       218 
     | 
    
         
            -
            	int ret = (int)rb_rescue(template_execute_do, (VALUE)args,
         
     | 
| 
       219 
     | 
    
         
            -
            			template_execute_rescue_enc, (VALUE)resc);
         
     | 
| 
       220 
     | 
    
         
            -
            #else
         
     | 
| 
       221 
195 
     | 
    
         
             
            	int ret = (int)rb_rescue(template_execute_do, (VALUE)args,
         
     | 
| 
       222 
196 
     | 
    
         
             
            			template_execute_rescue, Qnil);
         
     | 
| 
       223 
     | 
    
         
            -
            #endif
         
     | 
| 
       224 
197 
     | 
    
         | 
| 
       225 
198 
     | 
    
         
             
            	rb_gc_enable();
         
     | 
| 
       226 
199 
     | 
    
         | 
| 
       227 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       228 
     | 
    
         
            -
            	rb_enc_set_index(str, enc_orig);
         
     | 
| 
       229 
     | 
    
         
            -
            #endif
         
     | 
| 
       230 
     | 
    
         
            -
             
     | 
| 
       231 
200 
     | 
    
         
             
            	return ret;
         
     | 
| 
       232 
201 
     | 
    
         
             
            }
         
     | 
| 
       233 
202 
     | 
    
         | 
| 
         @@ -273,6 +242,13 @@ static VALUE eUnpackError; 
     | 
|
| 
       273 
242 
     | 
    
         
             
            #define MSGPACK_UNPACKER_BUFFER_RESERVE_SIZE (8*1024)
         
     | 
| 
       274 
243 
     | 
    
         
             
            #endif
         
     | 
| 
       275 
244 
     | 
    
         | 
| 
      
 245 
     | 
    
         
            +
            /*
         
     | 
| 
      
 246 
     | 
    
         
            +
            #ifndef MSGPACK_BUFFER_FREE_SIZE
         
     | 
| 
      
 247 
     | 
    
         
            +
            #define MSGPACK_BUFFER_FREE_SIZE (1024*1024)
         
     | 
| 
      
 248 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 249 
     | 
    
         
            +
            */
         
     | 
| 
      
 250 
     | 
    
         
            +
            #define MSGPACK_BUFFER_FREE_SIZE 0
         
     | 
| 
      
 251 
     | 
    
         
            +
             
     | 
| 
       276 
252 
     | 
    
         
             
            static void MessagePack_Unpacker_free(void* data)
         
     | 
| 
       277 
253 
     | 
    
         
             
            {
         
     | 
| 
       278 
254 
     | 
    
         
             
            	if(data) {
         
     | 
| 
         @@ -305,7 +281,7 @@ static VALUE MessagePack_Unpacker_alloc(VALUE klass) 
     | 
|
| 
       305 
281 
     | 
    
         | 
| 
       306 
282 
     | 
    
         
             
            	mp->user.finished = 0;
         
     | 
| 
       307 
283 
     | 
    
         
             
            	mp->user.offset = 0;
         
     | 
| 
       308 
     | 
    
         
            -
            	mp->user.buffer. 
     | 
| 
      
 284 
     | 
    
         
            +
            	mp->user.buffer.used = 0;
         
     | 
| 
       309 
285 
     | 
    
         
             
            	mp->user.buffer.free = 0;
         
     | 
| 
       310 
286 
     | 
    
         
             
            	mp->user.buffer.ptr = NULL;
         
     | 
| 
       311 
287 
     | 
    
         | 
| 
         @@ -358,6 +334,7 @@ static VALUE MessagePack_Unpacker_initialize(int argc, VALUE *argv, VALUE self) 
     | 
|
| 
       358 
334 
     | 
    
         
             
            	mp->user.stream = stream;
         
     | 
| 
       359 
335 
     | 
    
         
             
            	mp->user.streambuf = rb_str_buf_new(MSGPACK_UNPACKER_BUFFER_RESERVE_SIZE);
         
     | 
| 
       360 
336 
     | 
    
         
             
            	mp->user.stream_append_method = append_method_of(stream);
         
     | 
| 
      
 337 
     | 
    
         
            +
            	mp->user.buffer_free_size = MSGPACK_BUFFER_FREE_SIZE;
         
     | 
| 
       361 
338 
     | 
    
         | 
| 
       362 
339 
     | 
    
         
             
            	return self;
         
     | 
| 
       363 
340 
     | 
    
         
             
            }
         
     | 
| 
         @@ -398,22 +375,27 @@ static void reserve_buffer(msgpack_unpack_t* mp, size_t require) 
     | 
|
| 
       398 
375 
     | 
    
         
             
            {
         
     | 
| 
       399 
376 
     | 
    
         
             
            	struct unpack_buffer* buffer = &mp->user.buffer;
         
     | 
| 
       400 
377 
     | 
    
         | 
| 
       401 
     | 
    
         
            -
            	if(buffer-> 
     | 
| 
       402 
     | 
    
         
            -
            		 
     | 
| 
      
 378 
     | 
    
         
            +
            	if(buffer->used == 0) {
         
     | 
| 
      
 379 
     | 
    
         
            +
            		if(require <= buffer->free) {
         
     | 
| 
      
 380 
     | 
    
         
            +
            			/* enough free space */
         
     | 
| 
      
 381 
     | 
    
         
            +
            			return;
         
     | 
| 
      
 382 
     | 
    
         
            +
            		}
         
     | 
| 
      
 383 
     | 
    
         
            +
            		/* no used buffer: realloc only */
         
     | 
| 
      
 384 
     | 
    
         
            +
            		size_t nsize = buffer->free == 0 ?
         
     | 
| 
      
 385 
     | 
    
         
            +
            			MSGPACK_UNPACKER_BUFFER_INIT_SIZE : buffer->free*2;
         
     | 
| 
       403 
386 
     | 
    
         
             
            		while(nsize < require) {
         
     | 
| 
       404 
387 
     | 
    
         
             
            			nsize *= 2;
         
     | 
| 
       405 
388 
     | 
    
         
             
            		}
         
     | 
| 
       406 
     | 
    
         
            -
            		char* tmp =  
     | 
| 
       407 
     | 
    
         
            -
            		buffer->ptr = tmp;
         
     | 
| 
      
 389 
     | 
    
         
            +
            		char* tmp = REALLOC_N(buffer->ptr, char, nsize);
         
     | 
| 
       408 
390 
     | 
    
         
             
            		buffer->free = nsize;
         
     | 
| 
       409 
     | 
    
         
            -
            		buffer-> 
     | 
| 
      
 391 
     | 
    
         
            +
            		buffer->ptr = tmp;
         
     | 
| 
       410 
392 
     | 
    
         
             
            		return;
         
     | 
| 
       411 
393 
     | 
    
         
             
            	}
         
     | 
| 
       412 
394 
     | 
    
         | 
| 
       413 
     | 
    
         
            -
            	if(buffer-> 
     | 
| 
      
 395 
     | 
    
         
            +
            	if(buffer->used <= mp->user.offset) {
         
     | 
| 
       414 
396 
     | 
    
         
             
            		/* clear buffer and rewind offset */
         
     | 
| 
       415 
     | 
    
         
            -
            		buffer->free += buffer-> 
     | 
| 
       416 
     | 
    
         
            -
            		buffer-> 
     | 
| 
      
 397 
     | 
    
         
            +
            		buffer->free += buffer->used;
         
     | 
| 
      
 398 
     | 
    
         
            +
            		buffer->used = 0;
         
     | 
| 
       417 
399 
     | 
    
         
             
            		mp->user.offset = 0;
         
     | 
| 
       418 
400 
     | 
    
         
             
            	}
         
     | 
| 
       419 
401 
     | 
    
         | 
| 
         @@ -422,41 +404,91 @@ static void reserve_buffer(msgpack_unpack_t* mp, size_t require) 
     | 
|
| 
       422 
404 
     | 
    
         
             
            		return;
         
     | 
| 
       423 
405 
     | 
    
         
             
            	}
         
     | 
| 
       424 
406 
     | 
    
         | 
| 
       425 
     | 
    
         
            -
            	size_t nsize = (buffer-> 
     | 
| 
      
 407 
     | 
    
         
            +
            	size_t nsize = (buffer->used + buffer->free) * 2;
         
     | 
| 
       426 
408 
     | 
    
         | 
| 
       427 
     | 
    
         
            -
            	if(mp->user.offset <= buffer-> 
     | 
| 
      
 409 
     | 
    
         
            +
            	if(mp->user.offset <= buffer->used / 2) {
         
     | 
| 
       428 
410 
     | 
    
         
             
            		/* parsed less than half: realloc only */
         
     | 
| 
       429 
     | 
    
         
            -
            		while(nsize < buffer-> 
     | 
| 
      
 411 
     | 
    
         
            +
            		while(nsize < buffer->used + require) {
         
     | 
| 
       430 
412 
     | 
    
         
             
            			nsize *= 2;
         
     | 
| 
       431 
413 
     | 
    
         
             
            		}
         
     | 
| 
       432 
414 
     | 
    
         
             
            		char* tmp = REALLOC_N(buffer->ptr, char, nsize);
         
     | 
| 
       433 
     | 
    
         
            -
            		buffer->free = nsize - buffer-> 
     | 
| 
      
 415 
     | 
    
         
            +
            		buffer->free = nsize - buffer->used;
         
     | 
| 
       434 
416 
     | 
    
         
             
            		buffer->ptr = tmp;
         
     | 
| 
       435 
417 
     | 
    
         | 
| 
       436 
418 
     | 
    
         
             
            	} else {
         
     | 
| 
       437 
419 
     | 
    
         
             
            		/* parsed more than half: realloc and move */
         
     | 
| 
       438 
     | 
    
         
            -
            		size_t not_parsed = buffer-> 
     | 
| 
      
 420 
     | 
    
         
            +
            		size_t not_parsed = buffer->used - mp->user.offset;
         
     | 
| 
       439 
421 
     | 
    
         
             
            		while(nsize < not_parsed + require) {
         
     | 
| 
       440 
422 
     | 
    
         
             
            			nsize *= 2;
         
     | 
| 
       441 
423 
     | 
    
         
             
            		}
         
     | 
| 
       442 
424 
     | 
    
         
             
            		char* tmp = REALLOC_N(buffer->ptr, char, nsize);
         
     | 
| 
       443 
425 
     | 
    
         
             
            		memcpy(tmp, tmp + mp->user.offset, not_parsed);
         
     | 
| 
       444 
     | 
    
         
            -
            		buffer->free = nsize -  
     | 
| 
       445 
     | 
    
         
            -
            		buffer-> 
     | 
| 
      
 426 
     | 
    
         
            +
            		buffer->free = nsize - not_parsed;
         
     | 
| 
      
 427 
     | 
    
         
            +
            		buffer->used = not_parsed;
         
     | 
| 
       446 
428 
     | 
    
         
             
            		buffer->ptr = tmp;
         
     | 
| 
       447 
429 
     | 
    
         
             
            		mp->user.offset = 0;
         
     | 
| 
       448 
430 
     | 
    
         
             
            	}
         
     | 
| 
       449 
431 
     | 
    
         
             
            }
         
     | 
| 
       450 
432 
     | 
    
         | 
| 
       451 
     | 
    
         
            -
            static inline void  
     | 
| 
      
 433 
     | 
    
         
            +
            static inline void try_free_buffer(msgpack_unpack_t* mp, size_t require)
         
     | 
| 
       452 
434 
     | 
    
         
             
            {
         
     | 
| 
      
 435 
     | 
    
         
            +
            	if(mp->user.buffer_free_size == 0) {
         
     | 
| 
      
 436 
     | 
    
         
            +
            		return;
         
     | 
| 
      
 437 
     | 
    
         
            +
            	}
         
     | 
| 
      
 438 
     | 
    
         
            +
             
     | 
| 
       453 
439 
     | 
    
         
             
            	struct unpack_buffer* buffer = &mp->user.buffer;
         
     | 
| 
      
 440 
     | 
    
         
            +
            	size_t csize = buffer->used + buffer->free;
         
     | 
| 
       454 
441 
     | 
    
         | 
| 
       455 
     | 
    
         
            -
            	if( 
     | 
| 
       456 
     | 
    
         
            -
            		 
     | 
| 
      
 442 
     | 
    
         
            +
            	if(csize <= mp->user.buffer_free_size) {
         
     | 
| 
      
 443 
     | 
    
         
            +
            		return;
         
     | 
| 
       457 
444 
     | 
    
         
             
            	}
         
     | 
| 
       458 
     | 
    
         
            -
             
     | 
| 
       459 
     | 
    
         
            -
            	buffer-> 
     | 
| 
      
 445 
     | 
    
         
            +
             
     | 
| 
      
 446 
     | 
    
         
            +
            	if(mp->user.offset <= buffer->used / 2) {
         
     | 
| 
      
 447 
     | 
    
         
            +
            		/* parsed less than half: do nothing */
         
     | 
| 
      
 448 
     | 
    
         
            +
             
     | 
| 
      
 449 
     | 
    
         
            +
            	} else if(mp->user.offset < buffer->used) {
         
     | 
| 
      
 450 
     | 
    
         
            +
            		/* parsed more than half but not all: realloc and move */
         
     | 
| 
      
 451 
     | 
    
         
            +
            		size_t nsize = MSGPACK_UNPACKER_BUFFER_INIT_SIZE;
         
     | 
| 
      
 452 
     | 
    
         
            +
            		size_t not_parsed = buffer->used - mp->user.offset;
         
     | 
| 
      
 453 
     | 
    
         
            +
            		while(nsize < not_parsed + require) {
         
     | 
| 
      
 454 
     | 
    
         
            +
            			nsize *= 2;
         
     | 
| 
      
 455 
     | 
    
         
            +
            		}
         
     | 
| 
      
 456 
     | 
    
         
            +
             
     | 
| 
      
 457 
     | 
    
         
            +
            		if(nsize >= csize) {
         
     | 
| 
      
 458 
     | 
    
         
            +
            			return;
         
     | 
| 
      
 459 
     | 
    
         
            +
            		}
         
     | 
| 
      
 460 
     | 
    
         
            +
             
     | 
| 
      
 461 
     | 
    
         
            +
            		char* tmp;
         
     | 
| 
      
 462 
     | 
    
         
            +
            		if(mp->user.offset == 0) {
         
     | 
| 
      
 463 
     | 
    
         
            +
            			tmp = ALLOC_N(char, nsize);
         
     | 
| 
      
 464 
     | 
    
         
            +
            			memcpy(tmp, buffer->ptr + mp->user.offset, not_parsed);
         
     | 
| 
      
 465 
     | 
    
         
            +
            			free(buffer->ptr);
         
     | 
| 
      
 466 
     | 
    
         
            +
            		} else {
         
     | 
| 
      
 467 
     | 
    
         
            +
            			tmp = REALLOC_N(buffer->ptr, char, nsize);
         
     | 
| 
      
 468 
     | 
    
         
            +
            		}
         
     | 
| 
      
 469 
     | 
    
         
            +
            		buffer->free = nsize - not_parsed;
         
     | 
| 
      
 470 
     | 
    
         
            +
            		buffer->used = not_parsed;
         
     | 
| 
      
 471 
     | 
    
         
            +
            		buffer->ptr = tmp;
         
     | 
| 
      
 472 
     | 
    
         
            +
            		mp->user.offset = 0;
         
     | 
| 
      
 473 
     | 
    
         
            +
             
     | 
| 
      
 474 
     | 
    
         
            +
            	} else {
         
     | 
| 
      
 475 
     | 
    
         
            +
            		/* all parsed: free all */
         
     | 
| 
      
 476 
     | 
    
         
            +
            		free(buffer->ptr);
         
     | 
| 
      
 477 
     | 
    
         
            +
            		buffer->free = 0;
         
     | 
| 
      
 478 
     | 
    
         
            +
            		buffer->used = 0;
         
     | 
| 
      
 479 
     | 
    
         
            +
            		buffer->ptr = NULL;
         
     | 
| 
      
 480 
     | 
    
         
            +
            		mp->user.offset = 0;
         
     | 
| 
      
 481 
     | 
    
         
            +
            	}
         
     | 
| 
      
 482 
     | 
    
         
            +
            }
         
     | 
| 
      
 483 
     | 
    
         
            +
             
     | 
| 
      
 484 
     | 
    
         
            +
            static void feed_buffer(msgpack_unpack_t* mp, const char* ptr, size_t len)
         
     | 
| 
      
 485 
     | 
    
         
            +
            {
         
     | 
| 
      
 486 
     | 
    
         
            +
            	struct unpack_buffer* buffer = &mp->user.buffer;
         
     | 
| 
      
 487 
     | 
    
         
            +
             
     | 
| 
      
 488 
     | 
    
         
            +
            	reserve_buffer(mp, len);
         
     | 
| 
      
 489 
     | 
    
         
            +
             
     | 
| 
      
 490 
     | 
    
         
            +
            	memcpy(buffer->ptr + buffer->used, ptr, len);
         
     | 
| 
      
 491 
     | 
    
         
            +
            	buffer->used += len;
         
     | 
| 
       460 
492 
     | 
    
         
             
            	buffer->free -= len;
         
     | 
| 
       461 
493 
     | 
    
         
             
            }
         
     | 
| 
       462 
494 
     | 
    
         | 
| 
         @@ -530,7 +562,7 @@ static VALUE MessagePack_Unpacker_each(VALUE self) 
     | 
|
| 
       530 
562 
     | 
    
         
             
            #endif
         
     | 
| 
       531 
563 
     | 
    
         | 
| 
       532 
564 
     | 
    
         
             
            	while(1) {
         
     | 
| 
       533 
     | 
    
         
            -
            		if(mp->user.buffer. 
     | 
| 
      
 565 
     | 
    
         
            +
            		if(mp->user.buffer.used <= mp->user.offset) {
         
     | 
| 
       534 
566 
     | 
    
         
             
            			do_fill:
         
     | 
| 
       535 
567 
     | 
    
         
             
            			{
         
     | 
| 
       536 
568 
     | 
    
         
             
            				VALUE len = MessagePack_Unpacker_fill(self);
         
     | 
| 
         @@ -541,7 +573,7 @@ static VALUE MessagePack_Unpacker_each(VALUE self) 
     | 
|
| 
       541 
573 
     | 
    
         
             
            		}
         
     | 
| 
       542 
574 
     | 
    
         | 
| 
       543 
575 
     | 
    
         
             
            		ret = template_execute_wrap_each(mp,
         
     | 
| 
       544 
     | 
    
         
            -
            				mp->user.buffer.ptr, mp->user.buffer. 
     | 
| 
      
 576 
     | 
    
         
            +
            				mp->user.buffer.ptr, mp->user.buffer.used,
         
     | 
| 
       545 
577 
     | 
    
         
             
            				&mp->user.offset);
         
     | 
| 
       546 
578 
     | 
    
         | 
| 
       547 
579 
     | 
    
         
             
            		if(ret < 0) {
         
     | 
| 
         @@ -557,9 +589,131 @@ static VALUE MessagePack_Unpacker_each(VALUE self) 
     | 
|
| 
       557 
589 
     | 
    
         
             
            		}
         
     | 
| 
       558 
590 
     | 
    
         
             
            	}
         
     | 
| 
       559 
591 
     | 
    
         | 
| 
      
 592 
     | 
    
         
            +
            	try_free_buffer(mp, 0);
         
     | 
| 
      
 593 
     | 
    
         
            +
             
     | 
| 
       560 
594 
     | 
    
         
             
            	return Qnil;
         
     | 
| 
       561 
595 
     | 
    
         
             
            }
         
     | 
| 
       562 
596 
     | 
    
         | 
| 
      
 597 
     | 
    
         
            +
            /**
         
     | 
| 
      
 598 
     | 
    
         
            +
             * Document-method: MessagePack::Unpacker#feed_each
         
     | 
| 
      
 599 
     | 
    
         
            +
             *
         
     | 
| 
      
 600 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 601 
     | 
    
         
            +
             *   unpacker.feed_each(data) {|object| }
         
     | 
| 
      
 602 
     | 
    
         
            +
             *
         
     | 
| 
      
 603 
     | 
    
         
            +
             * Same as feed(data) + each {|object| }, but tries to avoid copying of the buffer.
         
     | 
| 
      
 604 
     | 
    
         
            +
             */
         
     | 
| 
      
 605 
     | 
    
         
            +
            static VALUE feed_each_impl(VALUE args)
         
     | 
| 
      
 606 
     | 
    
         
            +
            {
         
     | 
| 
      
 607 
     | 
    
         
            +
            	VALUE self = ((VALUE*)args)[0];
         
     | 
| 
      
 608 
     | 
    
         
            +
            	VALUE data = ((VALUE*)args)[1];
         
     | 
| 
      
 609 
     | 
    
         
            +
            	size_t* pconsumed = (size_t*)((VALUE*)args)[2];
         
     | 
| 
      
 610 
     | 
    
         
            +
             
     | 
| 
      
 611 
     | 
    
         
            +
            	UNPACKER(self, mp);
         
     | 
| 
      
 612 
     | 
    
         
            +
            	int ret;
         
     | 
| 
      
 613 
     | 
    
         
            +
            	const char* ptr = RSTRING_PTR(data);
         
     | 
| 
      
 614 
     | 
    
         
            +
            	size_t len = RSTRING_LEN(data);
         
     | 
| 
      
 615 
     | 
    
         
            +
             
     | 
| 
      
 616 
     | 
    
         
            +
            	if(mp->user.buffer.used > 0) {
         
     | 
| 
      
 617 
     | 
    
         
            +
            		while(1) {
         
     | 
| 
      
 618 
     | 
    
         
            +
            			ret = template_execute_wrap_each(mp,
         
     | 
| 
      
 619 
     | 
    
         
            +
            					mp->user.buffer.ptr, mp->user.buffer.used,
         
     | 
| 
      
 620 
     | 
    
         
            +
            					&mp->user.offset);
         
     | 
| 
      
 621 
     | 
    
         
            +
             
     | 
| 
      
 622 
     | 
    
         
            +
            			if(ret < 0) {
         
     | 
| 
      
 623 
     | 
    
         
            +
            				rb_raise(eUnpackError, "parse error.");
         
     | 
| 
      
 624 
     | 
    
         
            +
             
     | 
| 
      
 625 
     | 
    
         
            +
            			} else if(ret > 0) {
         
     | 
| 
      
 626 
     | 
    
         
            +
            				VALUE data = template_data(mp);
         
     | 
| 
      
 627 
     | 
    
         
            +
            				template_init(mp);
         
     | 
| 
      
 628 
     | 
    
         
            +
            				rb_yield(data);
         
     | 
| 
      
 629 
     | 
    
         
            +
             
     | 
| 
      
 630 
     | 
    
         
            +
            			} else {
         
     | 
| 
      
 631 
     | 
    
         
            +
            				break;
         
     | 
| 
      
 632 
     | 
    
         
            +
            			}
         
     | 
| 
      
 633 
     | 
    
         
            +
            		}
         
     | 
| 
      
 634 
     | 
    
         
            +
            	}
         
     | 
| 
      
 635 
     | 
    
         
            +
             
     | 
| 
      
 636 
     | 
    
         
            +
            	if(len <= 0) {
         
     | 
| 
      
 637 
     | 
    
         
            +
            		return Qnil;
         
     | 
| 
      
 638 
     | 
    
         
            +
            	}
         
     | 
| 
      
 639 
     | 
    
         
            +
             
     | 
| 
      
 640 
     | 
    
         
            +
            	if(mp->user.buffer.used <= mp->user.offset) {
         
     | 
| 
      
 641 
     | 
    
         
            +
            		// wrap & execute & feed
         
     | 
| 
      
 642 
     | 
    
         
            +
            		while(1) {
         
     | 
| 
      
 643 
     | 
    
         
            +
            			ret = template_execute_wrap_each(mp,
         
     | 
| 
      
 644 
     | 
    
         
            +
            					ptr, len, pconsumed);
         
     | 
| 
      
 645 
     | 
    
         
            +
             
     | 
| 
      
 646 
     | 
    
         
            +
            			if(ret < 0) {
         
     | 
| 
      
 647 
     | 
    
         
            +
            				rb_raise(eUnpackError, "parse error.");
         
     | 
| 
      
 648 
     | 
    
         
            +
             
     | 
| 
      
 649 
     | 
    
         
            +
            			} else if(ret > 0) {
         
     | 
| 
      
 650 
     | 
    
         
            +
            				VALUE data = template_data(mp);
         
     | 
| 
      
 651 
     | 
    
         
            +
            				template_init(mp);
         
     | 
| 
      
 652 
     | 
    
         
            +
            				rb_yield(data);
         
     | 
| 
      
 653 
     | 
    
         
            +
             
     | 
| 
      
 654 
     | 
    
         
            +
            			} else {
         
     | 
| 
      
 655 
     | 
    
         
            +
            				break;
         
     | 
| 
      
 656 
     | 
    
         
            +
            			}
         
     | 
| 
      
 657 
     | 
    
         
            +
            		}
         
     | 
| 
      
 658 
     | 
    
         
            +
             
     | 
| 
      
 659 
     | 
    
         
            +
            	} else {
         
     | 
| 
      
 660 
     | 
    
         
            +
            		// feed & execute
         
     | 
| 
      
 661 
     | 
    
         
            +
            		feed_buffer(mp, ptr, len);
         
     | 
| 
      
 662 
     | 
    
         
            +
            		*pconsumed = len;
         
     | 
| 
      
 663 
     | 
    
         
            +
             
     | 
| 
      
 664 
     | 
    
         
            +
            		while(1) {
         
     | 
| 
      
 665 
     | 
    
         
            +
            			ret = template_execute_wrap_each(mp,
         
     | 
| 
      
 666 
     | 
    
         
            +
            					mp->user.buffer.ptr, mp->user.buffer.used,
         
     | 
| 
      
 667 
     | 
    
         
            +
            					&mp->user.offset);
         
     | 
| 
      
 668 
     | 
    
         
            +
             
     | 
| 
      
 669 
     | 
    
         
            +
            			if(ret < 0) {
         
     | 
| 
      
 670 
     | 
    
         
            +
            				rb_raise(eUnpackError, "parse error.");
         
     | 
| 
      
 671 
     | 
    
         
            +
             
     | 
| 
      
 672 
     | 
    
         
            +
            			} else if(ret > 0) {
         
     | 
| 
      
 673 
     | 
    
         
            +
            				VALUE data = template_data(mp);
         
     | 
| 
      
 674 
     | 
    
         
            +
            				template_init(mp);
         
     | 
| 
      
 675 
     | 
    
         
            +
            				rb_yield(data);
         
     | 
| 
      
 676 
     | 
    
         
            +
             
     | 
| 
      
 677 
     | 
    
         
            +
            			} else {
         
     | 
| 
      
 678 
     | 
    
         
            +
            				break;
         
     | 
| 
      
 679 
     | 
    
         
            +
            			}
         
     | 
| 
      
 680 
     | 
    
         
            +
            		}
         
     | 
| 
      
 681 
     | 
    
         
            +
            	}
         
     | 
| 
      
 682 
     | 
    
         
            +
             
     | 
| 
      
 683 
     | 
    
         
            +
            	return Qnil;
         
     | 
| 
      
 684 
     | 
    
         
            +
            }
         
     | 
| 
      
 685 
     | 
    
         
            +
             
     | 
| 
      
 686 
     | 
    
         
            +
            static VALUE feed_each_ensure(VALUE args) {
         
     | 
| 
      
 687 
     | 
    
         
            +
            	VALUE self = ((VALUE*)args)[0];
         
     | 
| 
      
 688 
     | 
    
         
            +
            	VALUE data = ((VALUE*)args)[1];
         
     | 
| 
      
 689 
     | 
    
         
            +
            	size_t* pconsumed = (size_t*)((VALUE*)args)[2];
         
     | 
| 
      
 690 
     | 
    
         
            +
             
     | 
| 
      
 691 
     | 
    
         
            +
            	const char* dptr = RSTRING_PTR(data) + *pconsumed;
         
     | 
| 
      
 692 
     | 
    
         
            +
            	size_t dlen = RSTRING_LEN(data) - *pconsumed;
         
     | 
| 
      
 693 
     | 
    
         
            +
             
     | 
| 
      
 694 
     | 
    
         
            +
            	if(dlen > 0) {
         
     | 
| 
      
 695 
     | 
    
         
            +
            		UNPACKER(self, mp);
         
     | 
| 
      
 696 
     | 
    
         
            +
            		try_free_buffer(mp, dlen);
         
     | 
| 
      
 697 
     | 
    
         
            +
            		feed_buffer(mp, dptr, dlen);
         
     | 
| 
      
 698 
     | 
    
         
            +
            	}
         
     | 
| 
      
 699 
     | 
    
         
            +
             
     | 
| 
      
 700 
     | 
    
         
            +
            	return Qnil;
         
     | 
| 
      
 701 
     | 
    
         
            +
            }
         
     | 
| 
      
 702 
     | 
    
         
            +
             
     | 
| 
      
 703 
     | 
    
         
            +
            static VALUE MessagePack_Unpacker_feed_each(VALUE self, VALUE data)
         
     | 
| 
      
 704 
     | 
    
         
            +
            {
         
     | 
| 
      
 705 
     | 
    
         
            +
            	size_t consumed = 0;
         
     | 
| 
      
 706 
     | 
    
         
            +
            	StringValue(data);
         
     | 
| 
      
 707 
     | 
    
         
            +
             
     | 
| 
      
 708 
     | 
    
         
            +
            	VALUE args[3];
         
     | 
| 
      
 709 
     | 
    
         
            +
            	args[0] = self;
         
     | 
| 
      
 710 
     | 
    
         
            +
            	args[1] = data;
         
     | 
| 
      
 711 
     | 
    
         
            +
            	args[2] = (VALUE)&consumed;
         
     | 
| 
      
 712 
     | 
    
         
            +
             
     | 
| 
      
 713 
     | 
    
         
            +
            	return rb_ensure(feed_each_impl, (VALUE)args,
         
     | 
| 
      
 714 
     | 
    
         
            +
            			feed_each_ensure, (VALUE)args);
         
     | 
| 
      
 715 
     | 
    
         
            +
            }
         
     | 
| 
      
 716 
     | 
    
         
            +
             
     | 
| 
       563 
717 
     | 
    
         | 
| 
       564 
718 
     | 
    
         
             
            static inline VALUE MessagePack_unpack_impl(VALUE self, VALUE data, unsigned long dlen)
         
     | 
| 
       565 
719 
     | 
    
         
             
            {
         
     | 
| 
         @@ -652,7 +806,7 @@ static VALUE MessagePack_Unpacker_execute_impl(VALUE self, VALUE data, 
     | 
|
| 
       652 
806 
     | 
    
         
             
             *
         
     | 
| 
       653 
807 
     | 
    
         
             
             * This method doesn't use the internal buffer.
         
     | 
| 
       654 
808 
     | 
    
         
             
             *
         
     | 
| 
       655 
     | 
    
         
            -
             * Call *reset 
     | 
| 
      
 809 
     | 
    
         
            +
             * Call *reset* method before calling this method again.
         
     | 
| 
       656 
810 
     | 
    
         
             
             *
         
     | 
| 
       657 
811 
     | 
    
         
             
             * UnpackError is throw when parse error is occured.
         
     | 
| 
       658 
812 
     | 
    
         
             
             */
         
     | 
| 
         @@ -674,7 +828,7 @@ static VALUE MessagePack_Unpacker_execute_limit(VALUE self, VALUE data, 
     | 
|
| 
       674 
828 
     | 
    
         
             
             *
         
     | 
| 
       675 
829 
     | 
    
         
             
             * This method doesn't use the internal buffer.
         
     | 
| 
       676 
830 
     | 
    
         
             
             *
         
     | 
| 
       677 
     | 
    
         
            -
             * Call *reset 
     | 
| 
      
 831 
     | 
    
         
            +
             * Call *reset* method before calling this method again.
         
     | 
| 
       678 
832 
     | 
    
         
             
             *
         
     | 
| 
       679 
833 
     | 
    
         
             
             * This returns offset that was parsed to.
         
     | 
| 
       680 
834 
     | 
    
         
             
             * Use *finished?* method to check an object is deserialized and call *data*
         
     | 
| 
         @@ -737,6 +891,7 @@ static VALUE MessagePack_Unpacker_reset(VALUE self) 
     | 
|
| 
       737 
891 
     | 
    
         
             
            	UNPACKER(self, mp);
         
     | 
| 
       738 
892 
     | 
    
         
             
            	template_init(mp);
         
     | 
| 
       739 
893 
     | 
    
         
             
            	mp->user.finished = 0;
         
     | 
| 
      
 894 
     | 
    
         
            +
            	try_free_buffer(mp, 0);
         
     | 
| 
       740 
895 
     | 
    
         
             
            	return self;
         
     | 
| 
       741 
896 
     | 
    
         
             
            }
         
     | 
| 
       742 
897 
     | 
    
         | 
| 
         @@ -746,10 +901,6 @@ void Init_msgpack_unpack(VALUE mMessagePack) 
     | 
|
| 
       746 
901 
     | 
    
         
             
            	s_sysread = rb_intern("sysread");
         
     | 
| 
       747 
902 
     | 
    
         
             
            	s_readpartial = rb_intern("readpartial");
         
     | 
| 
       748 
903 
     | 
    
         | 
| 
       749 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       750 
     | 
    
         
            -
            	s_ascii_8bit = rb_enc_find_index("ASCII-8BIT");
         
     | 
| 
       751 
     | 
    
         
            -
            #endif
         
     | 
| 
       752 
     | 
    
         
            -
             
     | 
| 
       753 
904 
     | 
    
         
             
            	eUnpackError = rb_define_class_under(mMessagePack, "UnpackError", rb_eStandardError);
         
     | 
| 
       754 
905 
     | 
    
         
             
            	cUnpacker = rb_define_class_under(mMessagePack, "Unpacker", rb_cObject);
         
     | 
| 
       755 
906 
     | 
    
         
             
            	rb_define_alloc_func(cUnpacker, MessagePack_Unpacker_alloc);
         
     | 
| 
         @@ -762,6 +913,7 @@ void Init_msgpack_unpack(VALUE mMessagePack) 
     | 
|
| 
       762 
913 
     | 
    
         
             
            	rb_define_method(cUnpacker, "each", MessagePack_Unpacker_each, 0);
         
     | 
| 
       763 
914 
     | 
    
         
             
            	rb_define_method(cUnpacker, "stream", MessagePack_Unpacker_stream_get, 0);
         
     | 
| 
       764 
915 
     | 
    
         
             
            	rb_define_method(cUnpacker, "stream=", MessagePack_Unpacker_stream_set, 1);
         
     | 
| 
      
 916 
     | 
    
         
            +
            	rb_define_method(cUnpacker, "feed_each", MessagePack_Unpacker_feed_each, 1);
         
     | 
| 
       765 
917 
     | 
    
         | 
| 
       766 
918 
     | 
    
         
             
            	/* Unbuffered API */
         
     | 
| 
       767 
919 
     | 
    
         
             
            	rb_define_method(cUnpacker, "execute", MessagePack_Unpacker_execute, 2);
         
     |