/* * Internal C deserialize call. Takes deserializer and a char for the type * marker. */ static VALUE des0_deserialize(VALUE self, char type) { AMF_DESERIALIZER *des; Data_Get_Struct(self, AMF_DESERIALIZER, des); long tmp; VALUE ret = Qnil; switch(type) { case AMF0_STRING_MARKER: ret = des_read_string(des, des_read_uint16(des)); break; case AMF0_AMF3_MARKER: ret = des0_read_amf3(self); break; case AMF0_NUMBER_MARKER: ret = rb_float_new(des_read_double(des)); break; case AMF0_BOOLEAN_MARKER: ret = des_read_byte(des) == 0 ? Qfalse : Qtrue; break; case AMF0_NULL_MARKER: case AMF0_UNDEFINED_MARKER: case AMF0_UNSUPPORTED_MARKER: ret = Qnil; break; case AMF0_OBJECT_MARKER: ret = des0_read_object(self); break; case AMF0_TYPED_OBJECT_MARKER: ret = des0_read_typed_object(self); break; case AMF0_HASH_MARKER: ret = des0_read_hash(self); break; case AMF0_STRICT_ARRAY_MARKER: ret = des0_read_array(self); break; case AMF0_REFERENCE_MARKER: tmp = des_read_uint16(des); if(tmp >= RARRAY_LEN(des->obj_cache)) rb_raise(rb_eRangeError, "reference index beyond end"); ret = RARRAY_PTR(des->obj_cache)[tmp]; break; case AMF0_DATE_MARKER: ret = des0_read_time(self); break; case AMF0_XML_MARKER: case AMF0_LONG_STRING_MARKER: ret = des_read_string(des, des_read_uint32(des)); break; default: rb_raise(rb_eRuntimeError, "Not supported: %d", type); break; } return ret; }
static VALUE des0_read_typed_object(VALUE self) { AMF_DESERIALIZER *des; Data_Get_Struct(self, AMF_DESERIALIZER, des); // Create object and add to cache VALUE class_name = des_read_string(des, des_read_uint16(des)); VALUE obj = rb_funcall(des->class_mapper, id_get_ruby_obj, 1, class_name); rb_ary_push(des->obj_cache, obj); // Populate object VALUE props = rb_hash_new(); des0_read_props(self, props, des_read_sym); rb_funcall(des->class_mapper, id_populate_ruby_obj, 2, obj, props); return obj; }
static VALUE des0_read_typed_object(VALUE self) { static VALUE class_mapper = 0; if(class_mapper == 0) class_mapper = rb_const_get(mRocketAMF, rb_intern("ClassMapper")); AMF_DESERIALIZER *des; Data_Get_Struct(self, AMF_DESERIALIZER, des); // Create object and add to cache VALUE class_name = des_read_string(des, des_read_uint16(des)); VALUE obj = rb_funcall(class_mapper, id_get_ruby_obj, 1, class_name); rb_ary_push(des->obj_cache, obj); int translate_case = rb_funcall(class_mapper, id_get_ruby_option, 2, obj, rb_str_new2("translate_case")) == Qtrue; // Populate object VALUE props = rb_hash_new(); des0_read_props(self, props, des_read_sym, translate_case); rb_funcall(class_mapper, id_populate_ruby_obj, 2, obj, props); return obj; }