VALUE read_tuple(unsigned char **pData, unsigned int arity, VALUE forceToEncoding) { if(arity > 0) { VALUE tag = read_any_raw(pData, forceToEncoding); if(SYM2ID(tag) == rb_intern("bert")) { return read_complex_type(pData, arity, forceToEncoding); } else { VALUE tuple = rb_funcall(cTuple, rb_intern("new"), 1, INT2NUM(arity)); rb_ary_store(tuple, 0, tag); int i; for(i = 1; i < arity; ++i) { rb_ary_store(tuple, i, read_any_raw(pData, forceToEncoding)); } return tuple; } } else { return rb_funcall(cTuple, rb_intern("new"), 0); } }
VALUE method_read_any_from(VALUE klass, VALUE rString) { unsigned char *data = (unsigned char *) StringValuePtr(rString); unsigned char **pData = &data; // check protocol version if(read_1(pData) != ERL_VERSION) { rb_raise(rb_eStandardError, "Bad Magic"); } return read_any_raw(pData); }
VALUE read_complex_type(unsigned char **pData, int arity, VALUE forceToEncoding) { VALUE type = read_any_raw(pData, forceToEncoding); ID id = SYM2ID(type); if(id == rb_intern("nil")) { return Qnil; } else if(id == rb_intern("true")) { return Qtrue; } else if(id == rb_intern("false")) { return Qfalse; } else if(id == rb_intern("time")) { VALUE megasecs = read_any_raw(pData, forceToEncoding); VALUE msecs = rb_funcall(megasecs, rb_intern("*"), 1, INT2NUM(1000000)); VALUE secs = read_any_raw(pData, forceToEncoding); VALUE microsecs = read_any_raw(pData, forceToEncoding); VALUE stamp = rb_funcall(msecs, rb_intern("+"), 1, secs); return rb_funcall(rb_cTime, rb_intern("at"), 2, stamp, microsecs); } else if(id == rb_intern("regex")) { VALUE source = read_any_raw(pData, forceToEncoding); VALUE opts = read_any_raw(pData, forceToEncoding); int flags = 0; if(rb_ary_includes(opts, ID2SYM(rb_intern("caseless")))) flags = flags | 1; if(rb_ary_includes(opts, ID2SYM(rb_intern("extended")))) flags = flags | 2; if(rb_ary_includes(opts, ID2SYM(rb_intern("multiline")))) flags = flags | 4; return rb_funcall(rb_cRegexp, rb_intern("new"), 2, source, INT2NUM(flags)); } else if(id == rb_intern("dict")) { return read_dict(pData, forceToEncoding); } else { return Qnil; } }
VALUE read_large_tuple(unsigned char **pData) { if(read_1(pData) != ERL_LARGE_TUPLE) { rb_raise(rb_eStandardError, "Invalid Type, not a large tuple"); } int arity = read_4(pData); VALUE array = rb_ary_new2(arity); int i; for(i = 0; i < arity; ++i) { rb_ary_store(array, i, read_any_raw(pData)); } return array; }
VALUE method_decode(int argc, VALUE *argv, VALUE self) { VALUE rString = Qnil; VALUE forceToEncoding = Qnil; rb_scan_args(argc, argv, "11", &rString, &forceToEncoding); unsigned char *data = (unsigned char *) StringValuePtr(rString); unsigned char **pData = &data; // check protocol version if(read_1(pData) != ERL_VERSION) { rb_raise(rb_eStandardError, "Bad Magic"); } return read_any_raw(pData, forceToEncoding); }
VALUE read_list(unsigned char **pData) { if(read_1(pData) != ERL_LIST) { rb_raise(rb_eStandardError, "Invalid Type, not an erlang list"); } int size = read_4(pData); VALUE array = rb_ary_new2(size); int i; for(i = 0; i < size; ++i) { rb_ary_store(array, i, read_any_raw(pData)); } read_1(pData); return array; }
VALUE read_list(unsigned char **pData) { if(read_1(pData) != ERL_LIST) { rb_raise(rb_eStandardError, "Invalid Type, not an erlang list"); } unsigned int size = read_4(pData); VALUE newref_class = rb_const_get(mErlectricity, rb_intern("List")); VALUE array = rb_funcall(newref_class, rb_intern("new"), 1, INT2NUM(size)); int i; for(i = 0; i < size; ++i) { rb_ary_store(array, i, read_any_raw(pData)); } read_1(pData); return array; }