ext/asciipack/unpacker.c in asciipack-0.2.2 vs ext/asciipack/unpacker.c in asciipack-0.2.3
- old
+ new
@@ -1,10 +1,10 @@
#include "unpacker.h"
VALUE cAsciiPack_Unpacker;
-static VALUE Unpacker_read(unpacker_t* ptr);
+static VALUE Unpacker_buffer_read(unpacker_t* ptr);
static void
unpacker_mark(unpacker_t* ptr)
{
}
@@ -23,12 +23,12 @@
if (!ptr) {
rb_raise(rb_eArgError, "unallocated unpacker");
}
- ptr->buffer = RSTRING_PTR(obj);
- ptr->ch = ptr->buffer;
+ ptr->buffer = NULL;
+ ptr->ch = NULL;
return self;
}
static VALUE
@@ -98,40 +98,40 @@
Unpacker_str (unpacker_t* ptr, size_t len)
{
char* head = ptr->ch;
VALUE str = rb_str_new(head, len);
- rb_funcall(str, rb_intern("force_encoding"), 1, rb_str_new2("utf-8"));
ptr->ch += len;
+ rb_funcall(str, rb_intern("force_encoding"), 1, rb_str_new2("utf-8"));
return str;
}
static VALUE
Unpacker_map (unpacker_t* ptr, size_t len)
{
VALUE map = rb_hash_new();
VALUE key, value;
while (len--) {
- key = Unpacker_read(ptr);
- value = Unpacker_read(ptr);
+ key = Unpacker_buffer_read(ptr);
+ value = Unpacker_buffer_read(ptr);
rb_hash_aset(map, key, value);
}
return map;
}
static VALUE
Unpacker_array (unpacker_t* ptr, size_t len)
{
VALUE array = rb_ary_new2(len);
while (len--) {
- rb_ary_push(array, Unpacker_read(ptr));
+ rb_ary_push(array, Unpacker_buffer_read(ptr));
}
return array;
}
static VALUE
-Unpacker_read (unpacker_t* ptr)
+Unpacker_buffer_read (unpacker_t* ptr)
{
uint64_t num;
switch (*ptr->ch++) {
case 'a': // int 4
@@ -268,30 +268,80 @@
rb_raise(rb_eArgError, "undefined type:%c,data:%s,at:%ld", *(ptr->ch), ptr->buffer, ptr->ch - ptr->buffer);
return Qnil;
}
static VALUE
-Unpacker_unpack (VALUE self)
+Unpacker_read (VALUE self)
{
UNPACKER(self, ptr);
- return Unpacker_read(ptr);
+
+ return Unpacker_buffer_read(ptr);
}
+static void
+Unpacker_buffer_feed (unpacker_t* ptr, VALUE obj)
+{
+ if (rb_type(obj) != T_STRING) {
+ rb_raise(rb_eArgError, "can not unpack object");
+ }
+
+ char* p = RSTRING_PTR(obj);
+
+ ptr->buffer = p;
+ ptr->ch = p;
+}
+
static VALUE
-AsciiPack_unpack (int argc, VALUE *argv, VALUE self)
+Unpacker_feed (VALUE self, VALUE obj)
{
- VALUE unpacker = rb_funcall(cAsciiPack_Unpacker, rb_intern("new"), 1, argv[0]);
- return rb_funcall(unpacker, rb_intern("unpack"), 0);
+ UNPACKER(self, ptr);
+
+ Unpacker_buffer_feed(ptr, obj);
+
+ return self;
}
+static void
+Unpacker_buffer_clear (unpacker_t* ptr)
+{
+ ptr->buffer = NULL;
+ ptr->ch = NULL;
+}
+
+static VALUE
+Unpacker_clear (VALUE self)
+{
+ UNPACKER(self, ptr);
+
+ Unpacker_buffer_clear(ptr);
+
+ return self;
+}
+
+static VALUE
+AsciiPack_unpack (int argc, VALUE *argv)
+{
+ VALUE v = argv[0];
+ VALUE self = Unpacker_alloc(cAsciiPack_Unpacker);
+
+ UNPACKER(self, ptr);
+
+ Unpacker_buffer_feed(ptr, v);
+
+ return Unpacker_buffer_read(ptr);
+}
+
void
AsciiPack_Unpacker_init(VALUE mAsciiPack)
{
cAsciiPack_Unpacker = rb_define_class_under(mAsciiPack, "Unpacker", rb_cObject);
rb_define_alloc_func(cAsciiPack_Unpacker, Unpacker_alloc);
rb_define_method(cAsciiPack_Unpacker, "initialize", Unpacker_initialize, -1);
- rb_define_method(cAsciiPack_Unpacker, "unpack", Unpacker_unpack, 0);
+ rb_define_method(cAsciiPack_Unpacker, "feed", Unpacker_feed, 1);
+ rb_define_method(cAsciiPack_Unpacker, "read", Unpacker_read, 0);
+ rb_define_alias(cAsciiPack_Unpacker, "<<", "feed");
+ rb_define_method(cAsciiPack_Unpacker, "clear", Unpacker_clear, 0);
rb_define_module_function(mAsciiPack, "unpack", AsciiPack_unpack, -1);
}