static VALUE Buffer_read(int argc, VALUE* argv, VALUE self) { VALUE out = Qnil; unsigned long n = -1; bool all = false; switch(argc) { case 2: out = argv[1]; /* pass through */ case 1: n = FIX2ULONG(argv[0]); break; case 0: all = true; break; default: rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc); } BUFFER(self, b); if(out != Qnil) { CHECK_STRING_TYPE(out); } if(all) { return read_all(b, out); } if(n == 0) { /* do nothing */ MAKE_EMPTY_STRING(out); return out; } #ifndef DISABLE_BUFFER_READ_TO_S_OPTIMIZE if(!msgpack_buffer_has_io(b) && out == Qnil && msgpack_buffer_all_readable_size(b) <= n) { /* same as to_s && clear; optimize */ VALUE str = msgpack_buffer_all_as_string(b); msgpack_buffer_clear(b); if(RSTRING_LEN(str) == 0) { return Qnil; } else { return str; } } #endif MAKE_EMPTY_STRING(out); read_until_eof(b, out, n); if(RSTRING_LEN(out) == 0) { return Qnil; } else { return out; } }
VALUE MessagePack_pack(int argc, VALUE* argv) { VALUE v; if (argc < 0 || argc > 3) { rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..3)", argc); } v = argv[0]; VALUE self = MessagePack_Factory_packer(argc - 1, argv + 1, cMessagePack_DefaultFactory); PACKER(self, pk); msgpack_packer_write_value(pk, v); VALUE retval; if(msgpack_buffer_has_io(PACKER_BUFFER_(pk))) { msgpack_buffer_flush(PACKER_BUFFER_(pk)); retval = Qnil; } else { retval = msgpack_buffer_all_as_string(PACKER_BUFFER_(pk)); } msgpack_buffer_clear(PACKER_BUFFER_(pk)); /* to free rmem before GC */ #ifdef RB_GC_GUARD /* This prevents compilers from optimizing out the `self` variable * from stack. Otherwise GC free()s it. */ RB_GC_GUARD(self); #endif return retval; }
static inline VALUE read_all(msgpack_buffer_t* b, VALUE out) { #ifndef DISABLE_BUFFER_READ_TO_S_OPTIMIZE if(out == Qnil && !msgpack_buffer_has_io(b)) { /* same as to_s && clear; optimize */ VALUE str = msgpack_buffer_all_as_string(b); msgpack_buffer_clear(b); return str; } #endif MAKE_EMPTY_STRING(out); read_until_eof(b, out, 0); return out; }
static VALUE Unpacker_each(VALUE self) { UNPACKER(self, uk); #ifdef RETURN_ENUMERATOR RETURN_ENUMERATOR(self, 0, 0); #endif if(msgpack_buffer_has_io(UNPACKER_BUFFER_(uk))) { return Unpacker_each_impl(self); } else { /* rescue EOFError only if io is set */ return rb_rescue2(Unpacker_each_impl, self, Unpacker_rescue_EOFError, self, rb_eEOFError, NULL); } }
static inline size_t read_until_eof(msgpack_buffer_t* b, VALUE out, unsigned long max) { if(msgpack_buffer_has_io(b)) { size_t sz = 0; VALUE args[4] = { (VALUE)(void*) b, out, (VALUE) max, (VALUE)(void*) &sz }; rb_rescue2(read_until_eof_rescue, (VALUE)(void*) args, read_until_eof_error, (VALUE)(void*) args, rb_eEOFError, NULL); return sz; } else { if(max == 0) { max = ULONG_MAX; } if(out == Qnil) { return msgpack_buffer_skip_nonblock(b, max); } else { return msgpack_buffer_read_to_string_nonblock(b, out, max); } } }