msgpack 0.3.7-mswin32 → 0.3.8-mswin32
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/pack.c +11 -0
- data/ext/unpack.c +146 -163
- data/lib/1.8/msgpack.so +0 -0
- data/lib/1.9/msgpack.so +0 -0
- data/msgpack/pack_template.h +3 -3
- data/msgpack/unpack_define.h +3 -2
- data/msgpack/unpack_template.h +43 -3
- data/test/msgpack_test.rb +16 -0
- metadata +3 -3
    
        data/ext/pack.c
    CHANGED
    
    | @@ -112,6 +112,16 @@ static VALUE MessagePack_String_to_msgpack(int argc, VALUE *argv, VALUE self) | |
| 112 112 | 
             
            	return out;
         | 
| 113 113 | 
             
            }
         | 
| 114 114 |  | 
| 115 | 
            +
            static VALUE MessagePack_Symbol_to_msgpack(int argc, VALUE *argv, VALUE self)
         | 
| 116 | 
            +
            {
         | 
| 117 | 
            +
            	ARG_BUFFER(out, argc, argv);
         | 
| 118 | 
            +
            	const char* name = rb_id2name(SYM2ID(self));
         | 
| 119 | 
            +
            	size_t len = strlen(name);
         | 
| 120 | 
            +
            	msgpack_pack_raw(out, len);
         | 
| 121 | 
            +
            	msgpack_pack_raw_body(out, name, len);
         | 
| 122 | 
            +
            	return out;
         | 
| 123 | 
            +
            }
         | 
| 124 | 
            +
             | 
| 115 125 | 
             
            static VALUE MessagePack_Array_to_msgpack(int argc, VALUE *argv, VALUE self)
         | 
| 116 126 | 
             
            {
         | 
| 117 127 | 
             
            	ARG_BUFFER(out, argc, argv);
         | 
| @@ -172,6 +182,7 @@ void Init_msgpack_pack(VALUE mMessagePack) | |
| 172 182 | 
             
            	rb_define_method_id(rb_cString, s_to_msgpack, MessagePack_String_to_msgpack, -1);
         | 
| 173 183 | 
             
            	rb_define_method_id(rb_cArray,  s_to_msgpack, MessagePack_Array_to_msgpack, -1);
         | 
| 174 184 | 
             
            	rb_define_method_id(rb_cHash,   s_to_msgpack, MessagePack_Hash_to_msgpack, -1);
         | 
| 185 | 
            +
            	rb_define_method_id(rb_cSymbol, s_to_msgpack, MessagePack_Symbol_to_msgpack, -1);
         | 
| 175 186 | 
             
            	rb_define_module_function(mMessagePack, "pack", MessagePack_pack, -1);
         | 
| 176 187 | 
             
            }
         | 
| 177 188 |  | 
    
        data/ext/unpack.c
    CHANGED
    
    | @@ -16,16 +16,21 @@ | |
| 16 16 | 
             
             *    limitations under the License.
         | 
| 17 17 | 
             
             */
         | 
| 18 18 | 
             
            #include "ruby.h"
         | 
| 19 | 
            +
             | 
| 19 20 | 
             
            #include "msgpack/unpack_define.h"
         | 
| 20 21 |  | 
| 21 22 | 
             
            static ID s_sysread;
         | 
| 22 23 | 
             
            static ID s_readpartial;
         | 
| 23 24 |  | 
| 25 | 
            +
            #ifdef HAVE_RUBY_ENCODING_H
         | 
| 26 | 
            +
            #include "ruby/encoding.h"
         | 
| 27 | 
            +
            int s_ascii_8bit;
         | 
| 28 | 
            +
            #endif
         | 
| 29 | 
            +
             | 
| 24 30 | 
             
            typedef struct {
         | 
| 25 31 | 
             
            	int finished;
         | 
| 26 32 | 
             
            	VALUE source;
         | 
| 27 33 | 
             
            	size_t offset;
         | 
| 28 | 
            -
            	size_t parsed;
         | 
| 29 34 | 
             
            	VALUE buffer;
         | 
| 30 35 | 
             
            	VALUE stream;
         | 
| 31 36 | 
             
            	VALUE streambuf;
         | 
| @@ -138,18 +143,71 @@ static inline int template_callback_raw(unpack_user* u, const char* b, const cha | |
| 138 143 | 
             
            		rb_raise(rb_eTypeError, "instance of String needed"); \
         | 
| 139 144 | 
             
            	}
         | 
| 140 145 |  | 
| 141 | 
            -
            static VALUE cUnpacker;
         | 
| 142 | 
            -
            static VALUE eUnpackError;
         | 
| 143 146 |  | 
| 144 | 
            -
             | 
| 145 | 
            -
            static void init_stack(msgpack_unpack_t* mp)
         | 
| 147 | 
            +
            static VALUE template_execute_rescue(VALUE nouse)
         | 
| 146 148 | 
             
            {
         | 
| 147 | 
            -
            	 | 
| 148 | 
            -
             | 
| 149 | 
            -
             | 
| 150 | 
            -
             | 
| 149 | 
            +
            	rb_gc_enable();
         | 
| 150 | 
            +
            #ifdef RUBY_VM
         | 
| 151 | 
            +
            	rb_exc_raise(rb_errinfo());
         | 
| 152 | 
            +
            #else
         | 
| 153 | 
            +
            	rb_exc_raise(ruby_errinfo);
         | 
| 154 | 
            +
            #endif
         | 
| 155 | 
            +
            }
         | 
| 156 | 
            +
             | 
| 157 | 
            +
            static VALUE template_execute_do(VALUE argv)
         | 
| 158 | 
            +
            {
         | 
| 159 | 
            +
            	VALUE* args = (VALUE*)argv;
         | 
| 160 | 
            +
             | 
| 161 | 
            +
            	msgpack_unpack_t* mp = (msgpack_unpack_t*)args[0];
         | 
| 162 | 
            +
            	char* dptr   = (char*)args[1];
         | 
| 163 | 
            +
            	size_t dlen  = (size_t)args[2];
         | 
| 164 | 
            +
            	size_t* from = (size_t*)args[3];
         | 
| 165 | 
            +
             | 
| 166 | 
            +
            	int ret = template_execute(mp, dptr, dlen, from);
         | 
| 167 | 
            +
             | 
| 168 | 
            +
            	return (VALUE)ret;
         | 
| 169 | 
            +
            }
         | 
| 170 | 
            +
             | 
| 171 | 
            +
            static int template_execute_wrap(msgpack_unpack_t* mp,
         | 
| 172 | 
            +
            		VALUE str, size_t dlen, size_t* from)
         | 
| 173 | 
            +
            {
         | 
| 174 | 
            +
            	VALUE args[4] = {
         | 
| 175 | 
            +
            		(VALUE)mp,
         | 
| 176 | 
            +
            		(VALUE)RSTRING_PTR(str),
         | 
| 177 | 
            +
            		(VALUE)dlen,
         | 
| 178 | 
            +
            		(VALUE)from,
         | 
| 179 | 
            +
            	};
         | 
| 180 | 
            +
             | 
| 181 | 
            +
            #ifdef HAVE_RUBY_ENCODING_H
         | 
| 182 | 
            +
            	// FIXME encodingをASCII-8BITにする
         | 
| 183 | 
            +
            	int enc_orig = rb_enc_get_index(str);
         | 
| 184 | 
            +
            	rb_enc_set_index(str, s_ascii_8bit);
         | 
| 185 | 
            +
            #endif
         | 
| 186 | 
            +
             | 
| 187 | 
            +
            	// FIXME execute実行中はmp->topが更新されないのでGC markが機能しない
         | 
| 188 | 
            +
            	rb_gc_disable();
         | 
| 189 | 
            +
             | 
| 190 | 
            +
            	mp->user.source = str;
         | 
| 191 | 
            +
             | 
| 192 | 
            +
            	int ret = (int)rb_rescue(template_execute_do, (VALUE)args,
         | 
| 193 | 
            +
            			template_execute_rescue, Qnil);
         | 
| 194 | 
            +
             | 
| 195 | 
            +
            	mp->user.source = Qnil;
         | 
| 196 | 
            +
             | 
| 197 | 
            +
            	rb_gc_enable();
         | 
| 198 | 
            +
             | 
| 199 | 
            +
            #ifdef HAVE_RUBY_ENCODING_H
         | 
| 200 | 
            +
            	rb_enc_set_index(str, enc_orig);
         | 
| 201 | 
            +
            #endif
         | 
| 202 | 
            +
             | 
| 203 | 
            +
            	return ret;
         | 
| 151 204 | 
             
            }
         | 
| 152 205 |  | 
| 206 | 
            +
             | 
| 207 | 
            +
            static VALUE cUnpacker;
         | 
| 208 | 
            +
            static VALUE eUnpackError;
         | 
| 209 | 
            +
             | 
| 210 | 
            +
             | 
| 153 211 | 
             
            static void MessagePack_Unpacker_free(void* data)
         | 
| 154 212 | 
             
            {
         | 
| 155 213 | 
             
            	if(data) { free(data); }
         | 
| @@ -163,7 +221,7 @@ static void MessagePack_Unpacker_mark(msgpack_unpack_t *mp) | |
| 163 221 | 
             
            	rb_gc_mark(mp->user.streambuf);
         | 
| 164 222 | 
             
            	for(i=0; i < mp->top; ++i) {
         | 
| 165 223 | 
             
            		rb_gc_mark(mp->stack[i].obj);
         | 
| 166 | 
            -
            		 | 
| 224 | 
            +
            		rb_gc_mark_maybe(mp->stack[i].map_key);
         | 
| 167 225 | 
             
            	}
         | 
| 168 226 | 
             
            }
         | 
| 169 227 |  | 
| @@ -176,15 +234,6 @@ static VALUE MessagePack_Unpacker_alloc(VALUE klass) | |
| 176 234 | 
             
            	return obj;
         | 
| 177 235 | 
             
            }
         | 
| 178 236 |  | 
| 179 | 
            -
            static VALUE MessagePack_Unpacker_reset(VALUE self)
         | 
| 180 | 
            -
            {
         | 
| 181 | 
            -
            	UNPACKER(self, mp);
         | 
| 182 | 
            -
            	template_init(mp);
         | 
| 183 | 
            -
            	init_stack(mp);
         | 
| 184 | 
            -
            	mp->user.finished = 0;
         | 
| 185 | 
            -
            	return self;
         | 
| 186 | 
            -
            }
         | 
| 187 | 
            -
             | 
| 188 237 | 
             
            static ID append_method_of(VALUE stream)
         | 
| 189 238 | 
             
            {
         | 
| 190 239 | 
             
            	if(rb_respond_to(stream, s_sysread)) {
         | 
| @@ -208,10 +257,10 @@ static VALUE MessagePack_Unpacker_initialize(int argc, VALUE *argv, VALUE self) | |
| 208 257 | 
             
            		rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
         | 
| 209 258 | 
             
            	}
         | 
| 210 259 |  | 
| 211 | 
            -
            	MessagePack_Unpacker_reset(self);
         | 
| 212 260 | 
             
            	UNPACKER(self, mp);
         | 
| 261 | 
            +
            	template_init(mp);
         | 
| 262 | 
            +
            	mp->user.finished = 0;
         | 
| 213 263 | 
             
            	mp->user.offset = 0;
         | 
| 214 | 
            -
            	mp->user.parsed = 0;
         | 
| 215 264 | 
             
            	mp->user.buffer = rb_str_new("",0);
         | 
| 216 265 | 
             
            	mp->user.stream = stream;
         | 
| 217 266 | 
             
            	mp->user.streambuf = rb_str_new("",0);
         | 
| @@ -219,94 +268,20 @@ static VALUE MessagePack_Unpacker_initialize(int argc, VALUE *argv, VALUE self) | |
| 219 268 | 
             
            	return self;
         | 
| 220 269 | 
             
            }
         | 
| 221 270 |  | 
| 222 | 
            -
             | 
| 223 | 
            -
            static VALUE MessagePack_Unpacker_execute_do(VALUE argv)
         | 
| 224 | 
            -
            {
         | 
| 225 | 
            -
            	VALUE* args = (VALUE*)argv;
         | 
| 226 | 
            -
             | 
| 227 | 
            -
            	VALUE self = args[0];
         | 
| 228 | 
            -
            	UNPACKER(self, mp);
         | 
| 229 | 
            -
             | 
| 230 | 
            -
            	VALUE data = args[1];
         | 
| 231 | 
            -
             | 
| 232 | 
            -
            	size_t from = (unsigned long)args[2];
         | 
| 233 | 
            -
            	char* dptr = RSTRING_PTR(data);
         | 
| 234 | 
            -
            	size_t dlen = (unsigned long)args[3];
         | 
| 235 | 
            -
            	int ret;
         | 
| 236 | 
            -
             | 
| 237 | 
            -
            	if(from >= dlen) {
         | 
| 238 | 
            -
            		rb_raise(eUnpackError, "offset is bigger than data buffer size.");
         | 
| 239 | 
            -
            	}
         | 
| 240 | 
            -
             | 
| 241 | 
            -
            	mp->user.source = data;
         | 
| 242 | 
            -
            	ret = template_execute(mp, dptr, dlen, &from);
         | 
| 243 | 
            -
            	mp->user.source = Qnil;
         | 
| 244 | 
            -
             | 
| 245 | 
            -
            	if(ret < 0) {
         | 
| 246 | 
            -
            		rb_raise(eUnpackError, "parse error.");
         | 
| 247 | 
            -
            	} else if(ret > 0) {
         | 
| 248 | 
            -
            		mp->user.finished = 1;
         | 
| 249 | 
            -
            		return ULONG2NUM(from);
         | 
| 250 | 
            -
            	} else {
         | 
| 251 | 
            -
            		mp->user.finished = 0;
         | 
| 252 | 
            -
            		return ULONG2NUM(from);
         | 
| 253 | 
            -
            	}
         | 
| 254 | 
            -
            }
         | 
| 255 | 
            -
             | 
| 256 | 
            -
            static VALUE MessagePack_Unpacker_execute_rescue(VALUE nouse)
         | 
| 257 | 
            -
            {
         | 
| 258 | 
            -
            	rb_gc_enable();
         | 
| 259 | 
            -
            #ifdef RUBY_VM
         | 
| 260 | 
            -
            	rb_exc_raise(rb_errinfo());
         | 
| 261 | 
            -
            #else
         | 
| 262 | 
            -
            	rb_exc_raise(ruby_errinfo);
         | 
| 263 | 
            -
            #endif
         | 
| 264 | 
            -
            }
         | 
| 265 | 
            -
             | 
| 266 | 
            -
            static inline VALUE MessagePack_Unpacker_execute_impl(VALUE self, VALUE data,
         | 
| 267 | 
            -
            		unsigned long off, unsigned long dlen)
         | 
| 268 | 
            -
            {
         | 
| 269 | 
            -
            	// FIXME execute実行中はmp->topが更新されないのでGC markが機能しない
         | 
| 270 | 
            -
            	rb_gc_disable();
         | 
| 271 | 
            -
            	VALUE args[4] = {self, data, (VALUE)off, (VALUE)dlen};
         | 
| 272 | 
            -
            	VALUE ret = rb_rescue(MessagePack_Unpacker_execute_do, (VALUE)args,
         | 
| 273 | 
            -
            			MessagePack_Unpacker_execute_rescue, Qnil);
         | 
| 274 | 
            -
            	rb_gc_enable();
         | 
| 275 | 
            -
             | 
| 276 | 
            -
            	return ret;
         | 
| 277 | 
            -
            }
         | 
| 278 | 
            -
             | 
| 279 | 
            -
            static VALUE MessagePack_Unpacker_execute_limit(VALUE self, VALUE data,
         | 
| 280 | 
            -
            		VALUE off, VALUE limit)
         | 
| 281 | 
            -
            {
         | 
| 282 | 
            -
            	CHECK_STRING_TYPE(data);
         | 
| 283 | 
            -
            	return MessagePack_Unpacker_execute_impl(self, data,
         | 
| 284 | 
            -
            			NUM2ULONG(off), NUM2ULONG(limit));
         | 
| 285 | 
            -
            }
         | 
| 286 | 
            -
             | 
| 287 | 
            -
            static VALUE MessagePack_Unpacker_execute(VALUE self, VALUE data, VALUE off)
         | 
| 288 | 
            -
            {
         | 
| 289 | 
            -
            	CHECK_STRING_TYPE(data);
         | 
| 290 | 
            -
            	return MessagePack_Unpacker_execute_impl(self, data,
         | 
| 291 | 
            -
            			NUM2ULONG(off), RSTRING_LEN(data));
         | 
| 292 | 
            -
            }
         | 
| 293 | 
            -
             | 
| 294 | 
            -
            static VALUE MessagePack_Unpacker_finished_p(VALUE self)
         | 
| 271 | 
            +
            static VALUE MessagePack_Unpacker_stream_get(VALUE self)
         | 
| 295 272 | 
             
            {
         | 
| 296 273 | 
             
            	UNPACKER(self, mp);
         | 
| 297 | 
            -
            	 | 
| 298 | 
            -
            		return Qtrue;
         | 
| 299 | 
            -
            	}
         | 
| 300 | 
            -
            	return Qfalse;
         | 
| 274 | 
            +
            	return mp->user.stream;
         | 
| 301 275 | 
             
            }
         | 
| 302 276 |  | 
| 303 | 
            -
            static VALUE  | 
| 277 | 
            +
            static VALUE MessagePack_Unpacker_stream_set(VALUE self, VALUE val)
         | 
| 304 278 | 
             
            {
         | 
| 305 279 | 
             
            	UNPACKER(self, mp);
         | 
| 306 | 
            -
            	 | 
| 280 | 
            +
            	mp->user.stream = val;
         | 
| 281 | 
            +
            	mp->user.stream_append_method = append_method_of(val);
         | 
| 282 | 
            +
            	return val;
         | 
| 307 283 | 
             
            }
         | 
| 308 284 |  | 
| 309 | 
            -
             | 
| 310 285 | 
             
            static VALUE MessagePack_Unpacker_feed(VALUE self, VALUE data)
         | 
| 311 286 | 
             
            {
         | 
| 312 287 | 
             
            	UNPACKER(self, mp);
         | 
| @@ -315,20 +290,6 @@ static VALUE MessagePack_Unpacker_feed(VALUE self, VALUE data) | |
| 315 290 | 
             
            	return Qnil;
         | 
| 316 291 | 
             
            }
         | 
| 317 292 |  | 
| 318 | 
            -
            static VALUE MessagePack_Unpacker_stream_get(VALUE self)
         | 
| 319 | 
            -
            {
         | 
| 320 | 
            -
            	UNPACKER(self, mp);
         | 
| 321 | 
            -
            	return mp->user.stream;
         | 
| 322 | 
            -
            }
         | 
| 323 | 
            -
             | 
| 324 | 
            -
            static VALUE MessagePack_Unpacker_stream_set(VALUE self, VALUE val)
         | 
| 325 | 
            -
            {
         | 
| 326 | 
            -
            	UNPACKER(self, mp);
         | 
| 327 | 
            -
            	mp->user.stream = val;
         | 
| 328 | 
            -
            	mp->user.stream_append_method = append_method_of(val);
         | 
| 329 | 
            -
            	return val;
         | 
| 330 | 
            -
            }
         | 
| 331 | 
            -
             | 
| 332 293 | 
             
            static VALUE MessagePack_Unpacker_fill(VALUE self)
         | 
| 333 294 | 
             
            {
         | 
| 334 295 | 
             
            	UNPACKER(self, mp);
         | 
| @@ -337,7 +298,7 @@ static VALUE MessagePack_Unpacker_fill(VALUE self) | |
| 337 298 | 
             
            		return Qnil;
         | 
| 338 299 | 
             
            	}
         | 
| 339 300 |  | 
| 340 | 
            -
            	 | 
| 301 | 
            +
            	long len;
         | 
| 341 302 | 
             
            	if(RSTRING_LEN(mp->user.buffer) == 0) {
         | 
| 342 303 | 
             
            		rb_funcall(mp->user.stream, mp->user.stream_append_method, 2,
         | 
| 343 304 | 
             
            				LONG2FIX(64*1024), mp->user.buffer);
         | 
| @@ -372,17 +333,17 @@ static VALUE MessagePack_Unpacker_each(VALUE self) | |
| 372 333 | 
             
            			}
         | 
| 373 334 | 
             
            		}
         | 
| 374 335 |  | 
| 375 | 
            -
            		 | 
| 376 | 
            -
             | 
| 377 | 
            -
            		mp->user.source = Qnil;
         | 
| 336 | 
            +
            		ret = template_execute_wrap(mp, mp->user.buffer,
         | 
| 337 | 
            +
            				RSTRING_LEN(mp->user.buffer), &mp->user.offset);
         | 
| 378 338 |  | 
| 379 339 | 
             
            		if(ret < 0) {
         | 
| 380 340 | 
             
            			rb_raise(eUnpackError, "parse error.");
         | 
| 341 | 
            +
             | 
| 381 342 | 
             
            		} else if(ret > 0) {
         | 
| 382 343 | 
             
            			VALUE data = template_data(mp);
         | 
| 383 344 | 
             
            			template_init(mp);
         | 
| 384 | 
            -
            			init_stack(mp);
         | 
| 385 345 | 
             
            			rb_yield(data);
         | 
| 346 | 
            +
             | 
| 386 347 | 
             
            		} else {
         | 
| 387 348 | 
             
            			goto do_fill;
         | 
| 388 349 | 
             
            		}
         | 
| @@ -391,73 +352,88 @@ static VALUE MessagePack_Unpacker_each(VALUE self) | |
| 391 352 | 
             
            	return Qnil;
         | 
| 392 353 | 
             
            }
         | 
| 393 354 |  | 
| 394 | 
            -
             | 
| 395 | 
            -
            static VALUE MessagePack_unpack_do(VALUE argv)
         | 
| 355 | 
            +
            static inline VALUE MessagePack_unpack_impl(VALUE self, VALUE data, unsigned long dlen)
         | 
| 396 356 | 
             
            {
         | 
| 397 | 
            -
            	 | 
| 357 | 
            +
            	msgpack_unpack_t mp;
         | 
| 358 | 
            +
            	template_init(&mp);
         | 
| 398 359 |  | 
| 399 | 
            -
            	 | 
| 400 | 
            -
            	VALUE data = args[1];
         | 
| 360 | 
            +
            	mp.user.finished = 0;
         | 
| 401 361 |  | 
| 402 362 | 
             
            	size_t from = 0;
         | 
| 403 | 
            -
            	 | 
| 404 | 
            -
            	size_t dlen = (unsigned long)args[2];
         | 
| 405 | 
            -
            	int ret;
         | 
| 406 | 
            -
             | 
| 407 | 
            -
            	mp->user.source = data;
         | 
| 408 | 
            -
            	ret = template_execute(mp, dptr, dlen, &from);
         | 
| 409 | 
            -
            	mp->user.source = Qnil;
         | 
| 363 | 
            +
            	int ret = template_execute_wrap(&mp, data, dlen, &from);
         | 
| 410 364 |  | 
| 411 365 | 
             
            	if(ret < 0) {
         | 
| 412 366 | 
             
            		rb_raise(eUnpackError, "parse error.");
         | 
| 367 | 
            +
             | 
| 413 368 | 
             
            	} else if(ret == 0) {
         | 
| 414 369 | 
             
            		rb_raise(eUnpackError, "insufficient bytes.");
         | 
| 370 | 
            +
             | 
| 415 371 | 
             
            	} else {
         | 
| 416 372 | 
             
            		if(from < dlen) {
         | 
| 417 373 | 
             
            			rb_raise(eUnpackError, "extra bytes.");
         | 
| 418 374 | 
             
            		}
         | 
| 419 | 
            -
            		return template_data(mp);
         | 
| 375 | 
            +
            		return template_data(&mp);
         | 
| 420 376 | 
             
            	}
         | 
| 421 377 | 
             
            }
         | 
| 422 378 |  | 
| 423 | 
            -
            static VALUE  | 
| 379 | 
            +
            static VALUE MessagePack_unpack_limit(VALUE self, VALUE data, VALUE limit)
         | 
| 424 380 | 
             
            {
         | 
| 425 | 
            -
            	 | 
| 426 | 
            -
             | 
| 427 | 
            -
            	rb_exc_raise(rb_errinfo());
         | 
| 428 | 
            -
            #else
         | 
| 429 | 
            -
            	rb_exc_raise(ruby_errinfo);
         | 
| 430 | 
            -
            #endif
         | 
| 381 | 
            +
            	CHECK_STRING_TYPE(data);
         | 
| 382 | 
            +
            	return MessagePack_unpack_impl(self, data, NUM2ULONG(limit));
         | 
| 431 383 | 
             
            }
         | 
| 432 384 |  | 
| 433 | 
            -
            static  | 
| 385 | 
            +
            static VALUE MessagePack_unpack(VALUE self, VALUE data)
         | 
| 434 386 | 
             
            {
         | 
| 435 | 
            -
            	 | 
| 436 | 
            -
            	 | 
| 437 | 
            -
             | 
| 438 | 
            -
            	unpack_user u = {0, Qnil, 0, 0, Qnil, Qnil, Qnil};
         | 
| 439 | 
            -
            	mp.user = u;
         | 
| 387 | 
            +
            	CHECK_STRING_TYPE(data);
         | 
| 388 | 
            +
            	return MessagePack_unpack_impl(self, data, RSTRING_LEN(data));
         | 
| 389 | 
            +
            }
         | 
| 440 390 |  | 
| 441 | 
            -
            	// FIXME execute実行中はmp->topが更新されないのでGC markが機能しない
         | 
| 442 | 
            -
            	rb_gc_disable();
         | 
| 443 | 
            -
            	VALUE args[3] = {(VALUE)&mp, data, (VALUE)dlen};
         | 
| 444 | 
            -
            	VALUE ret = rb_rescue(MessagePack_unpack_do, (VALUE)args,
         | 
| 445 | 
            -
            			MessagePack_unpack_rescue, Qnil);
         | 
| 446 | 
            -
            	rb_gc_enable();
         | 
| 447 391 |  | 
| 448 | 
            -
             | 
| 392 | 
            +
            /* compat */
         | 
| 393 | 
            +
            static VALUE MessagePack_Unpacker_execute_limit(VALUE self, VALUE data,
         | 
| 394 | 
            +
            		VALUE off, VALUE limit)
         | 
| 395 | 
            +
            {
         | 
| 396 | 
            +
            	CHECK_STRING_TYPE(data);
         | 
| 397 | 
            +
            	UNPACKER(self, mp);
         | 
| 398 | 
            +
            	size_t from = (size_t)NUM2ULONG(off);
         | 
| 399 | 
            +
            	int ret = template_execute_wrap(mp, data, NUM2ULONG(limit), &from);
         | 
| 400 | 
            +
            	return INT2FIX(ret);
         | 
| 449 401 | 
             
            }
         | 
| 450 402 |  | 
| 451 | 
            -
             | 
| 403 | 
            +
            /* compat */
         | 
| 404 | 
            +
            static VALUE MessagePack_Unpacker_execute(VALUE self, VALUE data, VALUE off)
         | 
| 452 405 | 
             
            {
         | 
| 453 406 | 
             
            	CHECK_STRING_TYPE(data);
         | 
| 454 | 
            -
            	 | 
| 407 | 
            +
            	UNPACKER(self, mp);
         | 
| 408 | 
            +
            	size_t from = (size_t)NUM2ULONG(off);
         | 
| 409 | 
            +
            	int ret = template_execute_wrap(mp, data, RSTRING_LEN(data), &from);
         | 
| 410 | 
            +
            	return INT2FIX(ret);
         | 
| 455 411 | 
             
            }
         | 
| 456 412 |  | 
| 457 | 
            -
             | 
| 413 | 
            +
            /* compat */
         | 
| 414 | 
            +
            static VALUE MessagePack_Unpacker_finished_p(VALUE self)
         | 
| 458 415 | 
             
            {
         | 
| 459 | 
            -
            	 | 
| 460 | 
            -
            	 | 
| 416 | 
            +
            	UNPACKER(self, mp);
         | 
| 417 | 
            +
            	if(mp->user.finished) {
         | 
| 418 | 
            +
            		return Qtrue;
         | 
| 419 | 
            +
            	}
         | 
| 420 | 
            +
            	return Qfalse;
         | 
| 421 | 
            +
            }
         | 
| 422 | 
            +
             | 
| 423 | 
            +
            /* compat */
         | 
| 424 | 
            +
            static VALUE MessagePack_Unpacker_data(VALUE self)
         | 
| 425 | 
            +
            {
         | 
| 426 | 
            +
            	UNPACKER(self, mp);
         | 
| 427 | 
            +
            	return template_data(mp);
         | 
| 428 | 
            +
            }
         | 
| 429 | 
            +
             | 
| 430 | 
            +
            /* compat */
         | 
| 431 | 
            +
            static VALUE MessagePack_Unpacker_reset(VALUE self)
         | 
| 432 | 
            +
            {
         | 
| 433 | 
            +
            	UNPACKER(self, mp);
         | 
| 434 | 
            +
            	template_init(mp);
         | 
| 435 | 
            +
            	mp->user.finished = 0;
         | 
| 436 | 
            +
            	return self;
         | 
| 461 437 | 
             
            }
         | 
| 462 438 |  | 
| 463 439 |  | 
| @@ -465,15 +441,15 @@ void Init_msgpack_unpack(VALUE mMessagePack) | |
| 465 441 | 
             
            {
         | 
| 466 442 | 
             
            	s_sysread = rb_intern("sysread");
         | 
| 467 443 | 
             
            	s_readpartial = rb_intern("readpartial");
         | 
| 444 | 
            +
             | 
| 445 | 
            +
            #ifdef HAVE_RUBY_ENCODING_H
         | 
| 446 | 
            +
            	s_ascii_8bit = rb_enc_find_index("ASCII-8BIT");
         | 
| 447 | 
            +
            #endif
         | 
| 448 | 
            +
             | 
| 468 449 | 
             
            	eUnpackError = rb_define_class_under(mMessagePack, "UnpackError", rb_eStandardError);
         | 
| 469 450 | 
             
            	cUnpacker = rb_define_class_under(mMessagePack, "Unpacker", rb_cObject);
         | 
| 470 451 | 
             
            	rb_define_alloc_func(cUnpacker, MessagePack_Unpacker_alloc);
         | 
| 471 452 | 
             
            	rb_define_method(cUnpacker, "initialize", MessagePack_Unpacker_initialize, -1);
         | 
| 472 | 
            -
            	rb_define_method(cUnpacker, "execute", MessagePack_Unpacker_execute, 2);
         | 
| 473 | 
            -
            	rb_define_method(cUnpacker, "execute_limit", MessagePack_Unpacker_execute_limit, 3);
         | 
| 474 | 
            -
            	rb_define_method(cUnpacker, "finished?", MessagePack_Unpacker_finished_p, 0);
         | 
| 475 | 
            -
            	rb_define_method(cUnpacker, "data", MessagePack_Unpacker_data, 0);
         | 
| 476 | 
            -
            	rb_define_method(cUnpacker, "reset", MessagePack_Unpacker_reset, 0);
         | 
| 477 453 | 
             
            	rb_define_method(cUnpacker, "feed", MessagePack_Unpacker_feed, 1);
         | 
| 478 454 | 
             
            	rb_define_method(cUnpacker, "fill", MessagePack_Unpacker_fill, 0);
         | 
| 479 455 | 
             
            	rb_define_method(cUnpacker, "each", MessagePack_Unpacker_each, 0);
         | 
| @@ -481,5 +457,12 @@ void Init_msgpack_unpack(VALUE mMessagePack) | |
| 481 457 | 
             
            	rb_define_method(cUnpacker, "stream=", MessagePack_Unpacker_stream_set, 1);
         | 
| 482 458 | 
             
            	rb_define_module_function(mMessagePack, "unpack", MessagePack_unpack, 1);
         | 
| 483 459 | 
             
            	rb_define_module_function(mMessagePack, "unpack_limit", MessagePack_unpack_limit, 2);
         | 
| 460 | 
            +
             | 
| 461 | 
            +
            	/* backward compatibility */
         | 
| 462 | 
            +
            	rb_define_method(cUnpacker, "execute", MessagePack_Unpacker_execute, 2);
         | 
| 463 | 
            +
            	rb_define_method(cUnpacker, "execute_limit", MessagePack_Unpacker_execute_limit, 3);
         | 
| 464 | 
            +
            	rb_define_method(cUnpacker, "finished?", MessagePack_Unpacker_finished_p, 0);
         | 
| 465 | 
            +
            	rb_define_method(cUnpacker, "data", MessagePack_Unpacker_data, 0);
         | 
| 466 | 
            +
            	rb_define_method(cUnpacker, "reset", MessagePack_Unpacker_reset, 0);
         | 
| 484 467 | 
             
            }
         | 
| 485 468 |  | 
    
        data/lib/1.8/msgpack.so
    CHANGED
    
    | Binary file | 
    
        data/lib/1.9/msgpack.so
    CHANGED
    
    | Binary file | 
    
        data/msgpack/pack_template.h
    CHANGED
    
    | @@ -113,17 +113,17 @@ do { \ | |
| 113 113 | 
             
            		} \
         | 
| 114 114 | 
             
            	} else { \
         | 
| 115 115 | 
             
            		if(d < (1ULL<<16)) { \
         | 
| 116 | 
            -
            			/*  | 
| 116 | 
            +
            			/* unsigned 16 */ \
         | 
| 117 117 | 
             
            			unsigned char buf[3]; \
         | 
| 118 118 | 
             
            			buf[0] = 0xcd; _msgpack_store16(&buf[1], d); \
         | 
| 119 119 | 
             
            			msgpack_pack_append_buffer(x, buf, 3); \
         | 
| 120 120 | 
             
            		} else if(d < (1ULL<<32)) { \
         | 
| 121 | 
            -
            			/*  | 
| 121 | 
            +
            			/* unsigned 32 */ \
         | 
| 122 122 | 
             
            			unsigned char buf[5]; \
         | 
| 123 123 | 
             
            			buf[0] = 0xce; _msgpack_store32(&buf[1], d); \
         | 
| 124 124 | 
             
            			msgpack_pack_append_buffer(x, buf, 5); \
         | 
| 125 125 | 
             
            		} else { \
         | 
| 126 | 
            -
            			/*  | 
| 126 | 
            +
            			/* unsigned 64 */ \
         | 
| 127 127 | 
             
            			unsigned char buf[9]; \
         | 
| 128 128 | 
             
            			buf[0] = 0xcf; _msgpack_store64(&buf[1], d); \
         | 
| 129 129 | 
             
            			msgpack_pack_append_buffer(x, buf, 9); \
         | 
    
        data/msgpack/unpack_define.h
    CHANGED
    
    | @@ -19,6 +19,7 @@ | |
| 19 19 | 
             
            #define MSGPACK_UNPACK_DEFINE_H__
         | 
| 20 20 |  | 
| 21 21 | 
             
            #include "msgpack/sysdep.h"
         | 
| 22 | 
            +
            #include <stdlib.h>
         | 
| 22 23 | 
             
            #include <string.h>
         | 
| 23 24 | 
             
            #include <assert.h>
         | 
| 24 25 | 
             
            #include <stdio.h>
         | 
| @@ -28,8 +29,8 @@ extern "C" { | |
| 28 29 | 
             
            #endif
         | 
| 29 30 |  | 
| 30 31 |  | 
| 31 | 
            -
            #ifndef  | 
| 32 | 
            -
            #define  | 
| 32 | 
            +
            #ifndef MSGPACK_EMBED_STACK_SIZE
         | 
| 33 | 
            +
            #define MSGPACK_EMBED_STACK_SIZE 32
         | 
| 33 34 | 
             
            #endif
         | 
| 34 35 |  | 
| 35 36 |  | 
    
        data/msgpack/unpack_template.h
    CHANGED
    
    | @@ -58,7 +58,12 @@ msgpack_unpack_struct_decl(_context) { | |
| 58 58 | 
             
            	unsigned int cs;
         | 
| 59 59 | 
             
            	unsigned int trail;
         | 
| 60 60 | 
             
            	unsigned int top;
         | 
| 61 | 
            -
            	 | 
| 61 | 
            +
            	/*
         | 
| 62 | 
            +
            	msgpack_unpack_struct(_stack)* stack;
         | 
| 63 | 
            +
            	unsigned int stack_size;
         | 
| 64 | 
            +
            	msgpack_unpack_struct(_stack) embed_stack[MSGPACK_EMBED_STACK_SIZE];
         | 
| 65 | 
            +
            	*/
         | 
| 66 | 
            +
            	msgpack_unpack_struct(_stack) stack[MSGPACK_EMBED_STACK_SIZE];
         | 
| 62 67 | 
             
            };
         | 
| 63 68 |  | 
| 64 69 |  | 
| @@ -67,9 +72,22 @@ msgpack_unpack_func(void, _init)(msgpack_unpack_struct(_context)* ctx) | |
| 67 72 | 
             
            	ctx->cs = CS_HEADER;
         | 
| 68 73 | 
             
            	ctx->trail = 0;
         | 
| 69 74 | 
             
            	ctx->top = 0;
         | 
| 75 | 
            +
            	/*
         | 
| 76 | 
            +
            	ctx->stack = ctx->embed_stack;
         | 
| 77 | 
            +
            	ctx->stack_size = MSGPACK_EMBED_STACK_SIZE;
         | 
| 78 | 
            +
            	*/
         | 
| 70 79 | 
             
            	ctx->stack[0].obj = msgpack_unpack_callback(_root)(&ctx->user);
         | 
| 71 80 | 
             
            }
         | 
| 72 81 |  | 
| 82 | 
            +
            /*
         | 
| 83 | 
            +
            msgpack_unpack_func(void, _destroy)(msgpack_unpack_struct(_context)* ctx)
         | 
| 84 | 
            +
            {
         | 
| 85 | 
            +
            	if(ctx->stack_size != MSGPACK_EMBED_STACK_SIZE) {
         | 
| 86 | 
            +
            		free(ctx->stack);
         | 
| 87 | 
            +
            	}
         | 
| 88 | 
            +
            }
         | 
| 89 | 
            +
            */
         | 
| 90 | 
            +
             | 
| 73 91 | 
             
            msgpack_unpack_func(msgpack_unpack_object, _data)(msgpack_unpack_struct(_context)* ctx)
         | 
| 74 92 | 
             
            {
         | 
| 75 93 | 
             
            	return (ctx)->stack[0].obj;
         | 
| @@ -88,6 +106,9 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c | |
| 88 106 | 
             
            	unsigned int cs = ctx->cs;
         | 
| 89 107 | 
             
            	unsigned int top = ctx->top;
         | 
| 90 108 | 
             
            	msgpack_unpack_struct(_stack)* stack = ctx->stack;
         | 
| 109 | 
            +
            	/*
         | 
| 110 | 
            +
            	unsigned int stack_size = ctx->stack_size;
         | 
| 111 | 
            +
            	*/
         | 
| 91 112 | 
             
            	msgpack_unpack_user* user = &ctx->user;
         | 
| 92 113 |  | 
| 93 114 | 
             
            	msgpack_unpack_object obj;
         | 
| @@ -117,14 +138,33 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c | |
| 117 138 | 
             
            	goto _fixed_trail_again
         | 
| 118 139 |  | 
| 119 140 | 
             
            #define start_container(func, count_, ct_) \
         | 
| 141 | 
            +
            	if(top >= MSGPACK_EMBED_STACK_SIZE) { goto _failed; } /* FIXME */ \
         | 
| 120 142 | 
             
            	if(msgpack_unpack_callback(func)(user, count_, &stack[top].obj) < 0) { goto _failed; } \
         | 
| 121 143 | 
             
            	if((count_) == 0) { obj = stack[top].obj; goto _push; } \
         | 
| 122 | 
            -
            	if(top >= MSGPACK_MAX_STACK_SIZE) { goto _failed; } \
         | 
| 123 144 | 
             
            	stack[top].ct = ct_; \
         | 
| 124 145 | 
             
            	stack[top].count = count_; \
         | 
| 146 | 
            +
            	++top; \
         | 
| 125 147 | 
             
            	/*printf("container %d count %d stack %d\n",stack[top].obj,count_,top);*/ \
         | 
| 126 148 | 
             
            	/*printf("stack push %d\n", top);*/ \
         | 
| 127 | 
            -
            	 | 
| 149 | 
            +
            	/* FIXME \
         | 
| 150 | 
            +
            	if(top >= stack_size) { \
         | 
| 151 | 
            +
            		if(stack_size == MSGPACK_EMBED_STACK_SIZE) { \
         | 
| 152 | 
            +
            			size_t csize = sizeof(msgpack_unpack_struct(_stack)) * MSGPACK_EMBED_STACK_SIZE; \
         | 
| 153 | 
            +
            			size_t nsize = csize * 2; \
         | 
| 154 | 
            +
            			msgpack_unpack_struct(_stack)* tmp = (msgpack_unpack_struct(_stack)*)malloc(nsize); \
         | 
| 155 | 
            +
            			if(tmp == NULL) { goto _failed; } \
         | 
| 156 | 
            +
            			memcpy(tmp, ctx->stack, csize); \
         | 
| 157 | 
            +
            			ctx->stack = stack = tmp; \
         | 
| 158 | 
            +
            			ctx->stack_size = stack_size = MSGPACK_EMBED_STACK_SIZE * 2; \
         | 
| 159 | 
            +
            		} else { \
         | 
| 160 | 
            +
            			size_t nsize = sizeof(msgpack_unpack_struct(_stack)) * ctx->stack_size * 2; \
         | 
| 161 | 
            +
            			msgpack_unpack_struct(_stack)* tmp = (msgpack_unpack_struct(_stack)*)realloc(ctx->stack, nsize); \
         | 
| 162 | 
            +
            			if(tmp == NULL) { goto _failed; } \
         | 
| 163 | 
            +
            			ctx->stack = stack = tmp; \
         | 
| 164 | 
            +
            			ctx->stack_size = stack_size = stack_size * 2; \
         | 
| 165 | 
            +
            		} \
         | 
| 166 | 
            +
            	} \
         | 
| 167 | 
            +
            	*/ \
         | 
| 128 168 | 
             
            	goto _header_again
         | 
| 129 169 |  | 
| 130 170 | 
             
            #define NEXT_CS(p) \
         | 
    
        data/test/msgpack_test.rb
    CHANGED
    
    | @@ -202,6 +202,22 @@ class MessagePackTestFormat < Test::Unit::TestCase | |
| 202 202 | 
             
            #		#check_map 5, (1<<32)-1  # memory error
         | 
| 203 203 | 
             
            #	end
         | 
| 204 204 |  | 
| 205 | 
            +
            	it "gc mark" do
         | 
| 206 | 
            +
            		obj = [{["a","b"]=>["c","d"]}, ["e","f"], "d"]
         | 
| 207 | 
            +
            		pac = MessagePack::Unpacker.new
         | 
| 208 | 
            +
            		parsed = 0
         | 
| 209 | 
            +
            		obj.to_msgpack.split(//).each do |b|
         | 
| 210 | 
            +
            			pac.feed(b)
         | 
| 211 | 
            +
            			pac.each {|o|
         | 
| 212 | 
            +
            				GC.start
         | 
| 213 | 
            +
            				assert_equal(obj, o)
         | 
| 214 | 
            +
            				parsed += 1
         | 
| 215 | 
            +
            			}
         | 
| 216 | 
            +
            			GC.start
         | 
| 217 | 
            +
            		end
         | 
| 218 | 
            +
            		assert_equal(parsed, 1)
         | 
| 219 | 
            +
            	end
         | 
| 220 | 
            +
             | 
| 205 221 | 
             
            	private
         | 
| 206 222 | 
             
            	def check(len, obj)
         | 
| 207 223 | 
             
            		v = obj.to_msgpack
         | 
    
        metadata
    CHANGED
    
    | @@ -4,8 +4,8 @@ version: !ruby/object:Gem::Version | |
| 4 4 | 
             
              segments: 
         | 
| 5 5 | 
             
              - 0
         | 
| 6 6 | 
             
              - 3
         | 
| 7 | 
            -
              -  | 
| 8 | 
            -
              version: 0.3. | 
| 7 | 
            +
              - 8
         | 
| 8 | 
            +
              version: 0.3.8
         | 
| 9 9 | 
             
            platform: mswin32
         | 
| 10 10 | 
             
            authors: 
         | 
| 11 11 | 
             
            - FURUHASHI Sadayuki
         | 
| @@ -13,7 +13,7 @@ autorequire: | |
| 13 13 | 
             
            bindir: bin
         | 
| 14 14 | 
             
            cert_chain: []
         | 
| 15 15 |  | 
| 16 | 
            -
            date: 2010-04- | 
| 16 | 
            +
            date: 2010-04-22 00:00:00 +09:00
         | 
| 17 17 | 
             
            default_executable: 
         | 
| 18 18 | 
             
            dependencies: []
         | 
| 19 19 |  |