Пример #1
0
size_t msgpack_buffer_flush_to_io(msgpack_buffer_t* b, VALUE io, ID write_method, bool consume)
{
    if(msgpack_buffer_top_readable_size(b) == 0) {
        return 0;
    }

    VALUE s = _msgpack_buffer_head_chunk_as_string(b);
    rb_funcall(io, write_method, 1, s);
    size_t sz = RSTRING_LEN(s);

    if(consume) {
        while(_msgpack_buffer_shift_chunk(b)) {
            s = _msgpack_buffer_chunk_as_string(b->head);
            rb_funcall(io, write_method, 1, s);
            sz += RSTRING_LEN(s);
        }
        return sz;

    } else {
        if(b->head == &b->tail) {
            return sz;
        }
        msgpack_buffer_chunk_t* c = b->head->next;
        while(true) {
            s = _msgpack_buffer_chunk_as_string(c);
            rb_funcall(io, write_method, 1, s);
            sz += RSTRING_LEN(s);
            if(c == &b->tail) {
                return sz;
            }
            c = c->next;
        }
    }
}
Пример #2
0
size_t msgpack_buffer_read_nonblock(msgpack_buffer_t* b, char* buffer, size_t length)
{
    /* buffer == NULL means skip */
    size_t const length_orig = length;

    while(true) {
        size_t avail = msgpack_buffer_top_readable_size(b);

        if(length <= avail) {
            if(buffer != NULL) {
                memcpy(buffer, b->read_buffer, length);
            }
            _msgpack_buffer_consumed(b, length);
            return length_orig;
        }

        if(buffer != NULL) {
            memcpy(buffer, b->read_buffer, avail);
            buffer += avail;
        }
        length -= avail;

        if(!_msgpack_buffer_shift_chunk(b)) {
            return length_orig - length;
        }
    }
}
Пример #3
0
VALUE msgpack_buffer_all_as_string(msgpack_buffer_t* b)
{
    if(b->head == &b->tail) {
        return _msgpack_buffer_head_chunk_as_string(b);
    }

    size_t length = msgpack_buffer_all_readable_size(b);
    VALUE string = rb_str_new(NULL, length);
    char* buffer = RSTRING_PTR(string);

    size_t avail = msgpack_buffer_top_readable_size(b);
    memcpy(buffer, b->read_buffer, avail);
    buffer += avail;
    length -= avail;

    msgpack_buffer_chunk_t* c = b->head->next;

    while(true) {
        avail = c->last - c->first;
        memcpy(buffer, c->first, avail);

        if(length <= avail) {
            return string;
        }
        buffer += avail;
        length -= avail;

        c = c->next;
    }
}
Пример #4
0
static VALUE Packer_empty_p(VALUE self)
{
    PACKER(self, pk);
    if(msgpack_buffer_top_readable_size(PACKER_BUFFER_(pk)) == 0) {
        return Qtrue;
    } else {
        return Qfalse;
    }
}
Пример #5
0
static mrb_value Packer_empty_p(mrb_state *mrb, mrb_value self)
{
  PACKER(mrb, self, pk);
  if (msgpack_buffer_top_readable_size(PACKER_BUFFER_(pk)) == 0) {
    return mrb_true_value();
  } else {
    return mrb_false_value();
  }
}
Пример #6
0
static VALUE Buffer_empty_p(VALUE self)
{
    BUFFER(self, b);
    if(msgpack_buffer_top_readable_size(b) == 0) {
        return Qtrue;
    } else {
        return Qfalse;
    }
}
Пример #7
0
size_t msgpack_buffer_read_to_string_nonblock(msgpack_buffer_t* b, VALUE string, size_t length)
{
    size_t avail = msgpack_buffer_top_readable_size(b);

#ifndef DISABLE_BUFFER_READ_REFERENCE_OPTIMIZE
    /* optimize */
    if(length <= avail && RSTRING_LEN(string) == 0 &&
            b->head->mapped_string != NO_MAPPED_STRING &&
            length >= b->read_reference_threshold) {
        VALUE s = _msgpack_buffer_refer_head_mapped_string(b, length);
#ifndef HAVE_RB_STR_REPLACE
        /* TODO MRI 1.8 */
        rb_funcall(string, s_replace, 1, s);
#else
        rb_str_replace(string, s);
#endif
        /* here doesn't have to call ENCODING_SET because
         * encoding of s is always ASCII-8BIT */
        _msgpack_buffer_consumed(b, length);
        return length;
    }
#endif

    size_t const length_orig = length;

    while(true) {
        if(length <= avail) {
            rb_str_buf_cat(string, b->read_buffer, length);
            _msgpack_buffer_consumed(b, length);
            return length_orig;
        }

        rb_str_buf_cat(string, b->read_buffer, avail);
        length -= avail;

        if(!_msgpack_buffer_shift_chunk(b)) {
            return length_orig - length;
        }

        avail = msgpack_buffer_top_readable_size(b);
    }
}
Пример #8
0
VALUE MessagePack_unpack(int argc, VALUE* argv)
{
    VALUE src;

    switch(argc) {
    case 1:
        src = argv[0];
        break;
    default:
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
    }

    VALUE io = Qnil;
    if(rb_type(src) != T_STRING) {
        io = src;
        src = Qnil;
    }

    VALUE self = Unpacker_alloc(cMessagePack_Unpacker);
    UNPACKER(self, uk);
    //msgpack_unpacker_reset(s_unpacker);
    //msgpack_buffer_reset_io(UNPACKER_BUFFER_(s_unpacker));

    /* prefer reference than copying */
    msgpack_buffer_set_write_reference_threshold(UNPACKER_BUFFER_(uk), 0);

    if(io != Qnil) {
        MessagePack_Buffer_initialize(UNPACKER_BUFFER_(uk), io, Qnil);
    }

    if(src != Qnil) {
        /* prefer reference than copying; see MessagePack_Unpacker_module_init */
        msgpack_buffer_append_string(UNPACKER_BUFFER_(uk), src);
    }

    int r = msgpack_unpacker_read(uk, 0);
    if(r < 0) {
        raise_unpacker_error(r);
    }

    /* raise if extra bytes follow */
    if(msgpack_buffer_top_readable_size(UNPACKER_BUFFER_(uk)) > 0) {
        rb_raise(eMalformedFormatError, "extra bytes follow after a deserialized object");
    }

#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 msgpack_unpacker_get_last_object(uk);
}
Пример #9
0
VALUE MessagePack_unpack(int argc, VALUE* argv)
{
    VALUE src;

    switch(argc) {
    case 1:
        src = argv[0];
        break;
    default:
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
    }

    VALUE io = Qnil;
    if(rb_type(src) != T_STRING) {
        io = src;
        src = Qnil;
    }

    // TODO create an instance if io is set for thread safety?
    //VALUE self = Unpacker_alloc(cMessagePack_Unpacker);
    //UNPACKER(self, uk);
    msgpack_unpacker_reset(s_unpacker);
    msgpack_buffer_reset_io(UNPACKER_BUFFER_(s_unpacker));

    if(io != Qnil) {
        MessagePack_Buffer_initialize(UNPACKER_BUFFER_(s_unpacker), io, Qnil);
    }

    if(src != Qnil) {
        /* prefer reference than copying; see MessagePack_Unpacker_module_init */
        msgpack_buffer_append_string(UNPACKER_BUFFER_(s_unpacker), src);
    }

    int r = msgpack_unpacker_read(s_unpacker, 0);
    if(r < 0) {
        raise_unpacker_error(r);
    }

    /* raise if extra bytes follow */
    if(msgpack_buffer_top_readable_size(UNPACKER_BUFFER_(s_unpacker)) > 0) {
        rb_raise(eMalformedFormatError, "extra bytes follow after a deserialized object");
    }

    return msgpack_unpacker_get_last_object(s_unpacker);
}
Пример #10
0
size_t msgpack_buffer_all_readable_size(const msgpack_buffer_t* b)
{
    size_t sz = msgpack_buffer_top_readable_size(b);

    if(b->head == &b->tail) {
        return sz;
    }

    msgpack_buffer_chunk_t* c = b->head->next;

    while(true) {
        sz += c->last - c->first;
        if(c == &b->tail) {
            return sz;
        }
        c = c->next;
    }
}
Пример #11
0
VALUE MessagePack_unpack(int argc, VALUE* argv)
{
    VALUE src;
    VALUE self;

    if (argc < 0 || argc > 2) {
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..2)", argc);
    }
    src = argv[0];

    if(rb_type(src) == T_STRING) {
        self = MessagePack_Factory_unpacker(argc - 1, argv + 1, cMessagePack_DefaultFactory);
        UNPACKER(self, uk);
        msgpack_buffer_append_string(UNPACKER_BUFFER_(uk), src);
    } else {
        self = MessagePack_Factory_unpacker(argc, argv, cMessagePack_DefaultFactory);
    }
    UNPACKER(self, uk);

    /* prefer reference than copying; see MessagePack_Unpacker_module_init */
    msgpack_buffer_set_write_reference_threshold(UNPACKER_BUFFER_(uk), 0);

    int r = msgpack_unpacker_read(uk, 0);
    if(r < 0) {
        raise_unpacker_error(r);
    }

    /* raise if extra bytes follow */
    size_t extra = msgpack_buffer_top_readable_size(UNPACKER_BUFFER_(uk));
    if(extra > 0) {
        rb_raise(eMalformedFormatError, "%zd extra bytes after the deserialized object", extra);
    }

#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 msgpack_unpacker_get_last_object(uk);
}