static VALUE union_write(VALUE self, VALUE protocol, protocol_method_table *pmt) { DEBUG_FUNCTION_ENTRY(); // call validate rb_funcall(self, validate_method_id, 0); // write struct begin fastcall_call(pmt->write_struct_begin, protocol, rb_class_name(CLASS_OF(self))); struct_metadata* md = getStructMetadata(CLASS_OF(self)); VALUE setfield = rb_ivar_get(self, setfield_id); VALUE setvalue = rb_ivar_get(self, setvalue_id); field_metadata* fmd = getFieldMetadataByName(md, RSTRING_PTR(rb_funcall(setfield, to_s_method_id, 0))); int ttype = fmd->type; int field_id = fmd->id; fastcall_call(pmt->write_field_begin, protocol, setfield, INT2NUM(ttype), INT2NUM(field_id)); write_anything(setvalue, protocol, fmd, pmt); fastcall_call(pmt->write_field_end, protocol, Qnil); fastcall_call(pmt->write_field_stop, protocol, Qnil); // write struct end fastcall_call(pmt->write_struct_end, protocol, Qnil); fastcall_call(pmt->flush, protocol, Qnil); DEBUG_FUNCTION_EXIT(); return Qnil; }
static void write_anything(VALUE value, VALUE protocol, field_metadata* fmd, protocol_method_table *pmt) { DEBUG_FUNCTION_ENTRY(); if (fmd->type == TTYPE_BOOL) { fastcall_call(pmt->write_bool, protocol, value); } else if (fmd->type == TTYPE_BYTE) { fastcall_call(pmt->write_byte, protocol, value); } else if (fmd->type == TTYPE_I16) { fastcall_call(pmt->write_i16, protocol, value); } else if (fmd->type == TTYPE_I32) { fastcall_call(pmt->write_i32, protocol, value); } else if (fmd->type == TTYPE_I64) { fastcall_call(pmt->write_i64, protocol, value); } else if (fmd->type == TTYPE_DOUBLE) { fastcall_call(pmt->write_double, protocol, value); } else if (fmd->type == TTYPE_STRING) { fastcall_call(pmt->write_string, protocol, value); } else if (IS_CONTAINER(fmd->type)) { write_container(fmd, value, protocol, pmt); } else if (fmd->type == TTYPE_STRUCT) { if (rb_obj_is_kind_of(value, thrift_union_class)) { union_write(value, protocol, pmt); } else { struct_write(value, protocol, pmt); } } else { rb_raise(rb_eNotImpError, "Unknown type for binary_encoding: %d", fmd->type); } DEBUG_FUNCTION_EXIT(); }
static VALUE union_read(VALUE self, VALUE protocol, protocol_method_table *pmt) { DEBUG_FUNCTION_ENTRY(); // read struct begin fastcall_call(pmt->read_struct_begin, protocol, Qnil); struct_metadata* md = getStructMetadata(CLASS_OF(self)); VALUE field_header = fastcall_call(pmt->read_field_begin, protocol, Qnil); VALUE field_type_value = rb_ary_entry(field_header, 1); VALUE field_id_value = rb_ary_entry(field_header, 2); int field_type = FIX2INT(field_type_value); int field_id = FIX2INT(field_id_value); field_metadata *fmd = getFieldMetadataByID(md, field_id); // make sure we got a type we expected if (fmd) { int specified_type = fmd->type; if (field_type == specified_type) { // read the value char* name = fmd->name; rb_iv_set(self, "@setfield", ID2SYM(rb_intern(name))); rb_iv_set(self, "@value", read_anything(protocol, fmd, pmt)); } else { rb_funcall(protocol, skip_method_id, 1, field_type_value); } } else { rb_funcall(protocol, skip_method_id, 1, field_type_value); } // read field end fastcall_call(pmt->read_field_end, protocol, Qnil); field_header = fastcall_call(pmt->read_field_begin, protocol, Qnil); field_type_value = rb_ary_entry(field_header, 1); field_type = FIX2INT(field_type_value); if (field_type != TTYPE_STOP) { rb_raise(rb_eRuntimeError, "too many fields in union!"); } // read struct end fastcall_call(pmt->read_struct_end, protocol, Qnil); // call validate rb_funcall(self, validate_method_id, 0); DEBUG_FUNCTION_EXIT(); return Qnil; }
static VALUE struct_write(VALUE self, VALUE protocol, protocol_method_table* pmt) { DEBUG_FUNCTION_ENTRY(); // call validate rb_funcall(self, validate_method_id, 0); // write struct begin fastcall_call(pmt->write_struct_begin, protocol, rb_class_name(CLASS_OF(self))); // iterate through all the fields here struct_metadata* md = getStructMetadata(CLASS_OF(self)); int i = 0; for (i=0; i < getMetadataFieldCount(md); i++) { field_metadata* fmd = getFieldMetadataByIndex(md, i); DEBUGF("name=%s", fmd->name); VALUE field_value = rb_ivar_get(self, fmd->name_id); VALUE field_name = rb_str_new_cstr(fmd->name); DEBUGF("type=%d", TYPE(field_value)); DEBUG_FUNCTION_PROGRESS(); if (!NIL_P(field_value)) { DEBUG_FUNCTION_PROGRESS(); fastcall_call(pmt->write_field_begin, protocol, field_name, INT2NUM(fmd->type), INT2NUM(fmd->id)); DEBUG_FUNCTION_PROGRESS(); write_anything(field_value, protocol, fmd, pmt); DEBUG_FUNCTION_PROGRESS(); fastcall_call(pmt->write_field_end, protocol, Qnil); DEBUG_FUNCTION_PROGRESS(); } } DEBUG_FUNCTION_PROGRESS(); fastcall_call(pmt->write_field_stop, protocol, Qnil); DEBUG_FUNCTION_PROGRESS(); // write struct end fastcall_call(pmt->write_struct_end, protocol, Qnil); DEBUG_FUNCTION_PROGRESS(); fastcall_call(pmt->flush, protocol, Qnil); DEBUG_FUNCTION_EXIT(); return Qnil; }
static VALUE rb_struct_read(VALUE self, VALUE protocol) { DEBUG_FUNCTION_ENTRY(); protocol_method_table *pmt; //We haven't been supplied with a method table, try retrieving it... int has_gmt = rb_respond_to(protocol, rb_intern("get_protocol_method_table")); if (has_gmt) pmt = NUM2PTR(rb_funcall(protocol, get_protocol_method_table_ID, 0)); else pmt = &default_table; VALUE ret = struct_read(self, protocol, pmt); DEBUG_FUNCTION_EXIT(); return ret; }
ejsval _ejs_invoke_closure (ejsval closure, ejsval _this, uint32_t argc, ejsval* args) { if (!EJSVAL_IS_FUNCTION(closure)) { #if DEBUG_LAST_LOOKUP extern jschar* last_lookup; if (last_lookup) { char *last_utf8 = ucs2_to_utf8(last_lookup); _ejs_log ("last property lookup was for: %s\n", last_utf8); free (last_utf8); } #endif _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "object not a function"); } if (!EJSVAL_IS_NULL_OR_UNDEFINED(_this) && EJSVAL_IS_PRIMITIVE(_this)) { _this = ToObject(_this); } EJSFunction *fun = (EJSFunction*)EJSVAL_TO_OBJECT(closure); return fun->func (fun->env, _this, argc, args); #if not_anymore if (fun->bound_argc > 0) { ejsval* new_args = (ejsval*)malloc(sizeof(ejsval) * (fun->bound_argc + argc)); memmove (new_args, fun->bound_args, sizeof(ejsval) * fun->bound_argc); memmove (&new_args[fun->bound_argc], args, argc); args = new_args; argc += fun->bound_argc; } DEBUG_FUNCTION_ENTER (closure); ejsval rv = fun->func (fun->env, fun->bound_this, argc, args); DEBUG_FUNCTION_EXIT (closure); if (fun->bound_argc > 0) free (args); return rv; #endif }
static void write_container(field_metadata *fmd, VALUE value, VALUE protocol, protocol_method_table* pmt) { int sz, i; DEBUG_FUNCTION_ENTRY(); if (fmd->type == TTYPE_MAP) { DEBUG_FUNCTION_PROGRESS(); VALUE keys; VALUE key; VALUE val; Check_Type(value, T_HASH); field_metadata* key_md = fmd->key; int keytype = key_md->type; field_metadata* value_md = fmd->value; int valuetype = value_md->type; keys = rb_funcall(value, keys_method_id, 0); sz = RARRAY_LEN(keys); fastcall_call(pmt->write_map_begin, protocol, INT2FIX(keytype), INT2FIX(valuetype), INT2FIX(sz)); for (i = 0; i < sz; i++) { key = rb_ary_entry(keys, i); val = rb_hash_aref(value, key); write_anything(key, protocol, key_md, pmt); write_anything(val, protocol, value_md, pmt); } fastcall_call(pmt->write_map_end, protocol, Qnil); } else if (fmd->type == TTYPE_LIST) { DEBUG_FUNCTION_PROGRESS(); Check_Type(value, T_ARRAY); DEBUG_FUNCTION_PROGRESS(); sz = RARRAY_LEN(value); DEBUG_FUNCTION_PROGRESS(); field_metadata* element_md = fmd->element; int elementtype = element_md->type; DEBUG_FUNCTION_PROGRESS(); fastcall_call(pmt->write_list_begin, protocol, INT2FIX(elementtype), INT2FIX(sz)); DEBUG_FUNCTION_PROGRESS(); for (i = 0; i < sz; ++i) { DEBUG_FUNCTION_PROGRESS(); VALUE val = rb_ary_entry(value, i); DEBUG_FUNCTION_PROGRESS(); write_anything(val, protocol, element_md, pmt); DEBUG_FUNCTION_PROGRESS(); } DEBUG_FUNCTION_PROGRESS(); fastcall_call(pmt->write_list_end, protocol, Qnil); } else if (fmd->type == TTYPE_SET) { DEBUG_FUNCTION_PROGRESS(); VALUE items; if (TYPE(value) == T_ARRAY) { items = value; } else { if (rb_cSet == CLASS_OF(value)) { items = rb_funcall(value, entries_method_id, 0); } else { Check_Type(value, T_HASH); items = rb_funcall(value, keys_method_id, 0); } } sz = RARRAY_LEN(items); field_metadata* element_md = fmd->element; int elementtype = element_md->type; fastcall_call(pmt->write_set_begin, protocol, INT2FIX(elementtype), INT2FIX(sz)); for (i = 0; i < sz; i++) { VALUE val = rb_ary_entry(items, i); write_anything(val, protocol, element_md, pmt); } fastcall_call(pmt->write_set_end, protocol, Qnil); } else { rb_raise(rb_eNotImpError, "can't write container of type: %d", fmd->type); } DEBUG_FUNCTION_EXIT(); }