static VALUE rb_thrift_union_write(VALUE self, VALUE protocol) { // call validate rb_funcall(self, validate_method_id, 0); // write struct begin default_write_struct_begin(protocol, rb_class_name(CLASS_OF(self))); VALUE struct_fields = STRUCT_FIELDS(self); VALUE setfield = rb_ivar_get(self, setfield_id); VALUE setvalue = rb_ivar_get(self, setvalue_id); VALUE field_id = rb_funcall(self, name_to_id_method_id, 1, rb_funcall(setfield, to_s_method_id, 0)); VALUE field_info = rb_hash_aref(struct_fields, field_id); VALUE ttype_value = rb_hash_aref(field_info, type_sym); int ttype = FIX2INT(ttype_value); default_write_field_begin(protocol, setfield, ttype_value, field_id); write_anything(ttype, setvalue, protocol, field_info); default_write_field_end(protocol); default_write_field_stop(protocol); // write struct end default_write_struct_end(protocol); return Qnil; }
static VALUE rb_thrift_union_read(VALUE self, VALUE protocol) { // read struct begin mt->read_struct_begin(protocol); VALUE struct_fields = STRUCT_FIELDS(self); VALUE field_header = mt->read_field_begin(protocol); VALUE field_type_value = rb_ary_entry(field_header, 1); int field_type = FIX2INT(field_type_value); // make sure we got a type we expected VALUE field_info = rb_hash_aref(struct_fields, rb_ary_entry(field_header, 2)); if (!NIL_P(field_info)) { int specified_type = FIX2INT(rb_hash_aref(field_info, type_sym)); if (field_type == specified_type) { // read the value VALUE name = rb_hash_aref(field_info, name_sym); rb_iv_set(self, "@setfield", ID2SYM(rb_intern(RSTRING_PTR(name)))); rb_iv_set(self, "@value", read_anything(protocol, field_type, field_info)); } 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 mt->read_field_end(protocol); field_header = mt->read_field_begin(protocol); 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 field end mt->read_field_end(protocol); // read struct end mt->read_struct_end(protocol); // call validate rb_funcall(self, validate_method_id, 0); return Qnil; }
static VALUE rb_thrift_struct_read(VALUE self, VALUE protocol) { // check_native_proto_method_table(protocol); // read struct begin mt->read_struct_begin(protocol); VALUE struct_fields = STRUCT_FIELDS(self); // read each field while (true) { VALUE field_header = mt->read_field_begin(protocol); VALUE field_type_value = rb_ary_entry(field_header, 1); int field_type = FIX2INT(field_type_value); if (field_type == TTYPE_STOP) { break; } // make sure we got a type we expected VALUE field_info = rb_hash_aref(struct_fields, rb_ary_entry(field_header, 2)); if (!NIL_P(field_info)) { int specified_type = FIX2INT(rb_hash_aref(field_info, type_sym)); if (field_type == specified_type) { // read the value VALUE name = rb_hash_aref(field_info, name_sym); set_field_value(self, name, read_anything(protocol, field_type, field_info)); } 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 mt->read_field_end(protocol); } // read struct end mt->read_struct_end(protocol); // call validate rb_funcall(self, validate_method_id, 0); return Qnil; }
static VALUE rb_thrift_struct_write(VALUE self, VALUE protocol) { // call validate rb_funcall(self, validate_method_id, 0); // check_native_proto_method_table(protocol); // write struct begin mt->write_struct_begin(protocol, rb_class_name(CLASS_OF(self))); // iterate through all the fields here VALUE struct_fields = STRUCT_FIELDS(self); VALUE struct_field_ids_unordered = rb_funcall(struct_fields, keys_method_id, 0); VALUE struct_field_ids_ordered = rb_funcall(struct_field_ids_unordered, sort_method_id, 0); int i = 0; for (i=0; i < RARRAY_LEN(struct_field_ids_ordered); i++) { VALUE field_id = rb_ary_entry(struct_field_ids_ordered, i); VALUE field_info = rb_hash_aref(struct_fields, field_id); VALUE ttype_value = rb_hash_aref(field_info, type_sym); int ttype = FIX2INT(ttype_value); VALUE field_name = rb_hash_aref(field_info, name_sym); VALUE field_value = get_field_value(self, field_name); if (!NIL_P(field_value)) { mt->write_field_begin(protocol, field_name, ttype_value, field_id); write_anything(ttype, field_value, protocol, field_info); mt->write_field_end(protocol); } } mt->write_field_stop(protocol); // write struct end mt->write_struct_end(protocol); return Qnil; }