bool lsb_read_heka_field(lsb_heka_message *m, lsb_const_string *name, int fi, int ai, lsb_read_value *val) { if (!m || !name || !val) { return false; } int fcnt = 0; const char *p, *e; val->type = LSB_READ_NIL; for (int i = 0; i < m->fields_len; ++i) { if (name->len == m->fields[i].name.len && strncmp(name->s, m->fields[i].name.s, m->fields[i].name.len) == 0) { if (fi == fcnt++) { p = m->fields[i].value.s; e = p + m->fields[i].value.len; switch (m->fields[i].value_type) { case LSB_PB_STRING: case LSB_PB_BYTES: return read_string_value(p, e, ai, val); case LSB_PB_INTEGER: return read_integer_value(p, e, ai, val); case LSB_PB_BOOL: if (read_integer_value(p, e, ai, val)) { val->type = LSB_READ_BOOL; return true; } return false; case LSB_PB_DOUBLE: return read_double_value(p, e, ai, val); default: return false; } } } } return false; }
static mrb_value read_userdef(MarshalContext *ctx) { mrb_state *mrb = ctx->mrb; mrb_value class_path = read_value(ctx); struct RClass *klass = mrb_class_from_path(mrb, class_path); /* Should check here if klass implements '_load()' */ if (!mrb_obj_respond_to(mrb, mrb_class(mrb, mrb_obj_value(klass)), mrb_intern_cstr(mrb, "_load"))) throw Exception(Exception::TypeError, "class %s needs to have method '_load'", RSTRING_PTR(class_path)); mrb_value data = read_string_value(ctx); mrb_value obj = mrb_funcall(mrb, mrb_obj_value(klass), "_load", 1, data); return obj; }
static mrb_value read_value(MarshalContext *ctx) { mrb_state *mrb = ctx->mrb; char type = ctx->readByte(); mrb_value value; if (mrb->arena_idx > maxArena) maxArena = mrb->arena_idx; int arena = mrb_gc_arena_save(mrb); switch (type) { case TYPE_NIL : value = mrb_nil_value(); break; case TYPE_TRUE : value = mrb_true_value(); break; case TYPE_FALSE : value = mrb_false_value(); break; case TYPE_FIXNUM : value = mrb_fixnum_value(read_fixnum(ctx)); break; case TYPE_BIGNUM : value = mrb_fixnum_value(read_bignum(ctx)); break; case TYPE_FLOAT : value = mrb_float_value(mrb, read_float(ctx)); ctx->objects.add(value); break; case TYPE_STRING : value = read_string_value(ctx); ctx->objects.add(value); break; case TYPE_ARRAY : value = read_array(ctx); break; case TYPE_HASH : value = read_hash(ctx); break; case TYPE_SYMBOL : value = mrb_symbol_value(read_symbol(ctx)); break; case TYPE_SYMLINK : value = mrb_symbol_value(read_symlink(ctx)); break; case TYPE_OBJECT : value = read_object(ctx); break; case TYPE_IVAR : value = read_instance_var(ctx); break; case TYPE_LINK : value = read_link(ctx); break; case TYPE_USERDEF : value = read_userdef(ctx); ctx->objects.add(value); break; default : CCLOG( "Marshal.load: unsupported value type '%c',gbufsize %d",type,g_buf_size); CCAssert(false,"f**k"); //exit(0); } mrb_gc_arena_restore(mrb, arena); return value; }