/* write amf data to stream */ size_t amf0_data_write(const amf0_data *data, write_proc_t write_proc, void * user_data) { size_t s = 0; if (data != NULL) { s += write_proc(&(data->type), sizeof(uint8_t), user_data); switch (data->type) { case AMF0_TYPE_NUMBER: s += amf0_number_write(data, write_proc, user_data); break; case AMF0_TYPE_BOOLEAN: s += amf0_boolean_write(data, write_proc, user_data); break; case AMF0_TYPE_STRING: s += amf0_string_write(data, write_proc, user_data); break; case AMF0_TYPE_OBJECT: s += amf0_object_write(data, write_proc, user_data); break; case AMF0_TYPE_MOVIECLIP: /* not supported */ case AMF0_TYPE_NULL: case AMF0_TYPE_UNDEFINED: break; case AMF0_TYPE_REFERENCE: /* TODO */ break; case AMF0_TYPE_ECMA_ARRAY: s += amf0_associative_array_write(data, write_proc, user_data); break; case AMF0_TYPE_OBJECT_END: break; /* end of composite object */ case AMF0_TYPE_STRICT_ARRAY: s += amf0_array_write(data, write_proc, user_data); break; case AMF0_TYPE_DATE: s += amf0_date_write(data, write_proc, user_data); break; case AMF0_TYPE_LONG_STRING: /* TODO */ case AMF0_TYPE_UNSUPPORTED: /* TODO */ case AMF0_TYPE_RECORDSET: /* not supported */ case AMF0_TYPE_XML_DOCUMENT: /* TODO */ case AMF0_TYPE_TYPED_OBJECT: /* TODO */ default: break; } } return s; }
/* write an object */ static size_t amf0_object_write(amf0_data * data, write_proc_t write_proc, void * user_data) { amf0_node * node; size_t w = 0; uint16_t filler = swap_uint16(0); uint8_t terminator = AMF0_TYPE_OBJECT_END; node = amf0_object_first(data); while (node != NULL) { w += amf0_string_write(amf0_object_get_name(node), write_proc, user_data); w += amf0_data_write(amf0_object_get_data(node), write_proc, user_data); node = amf0_object_next(node); } /* empty string is the last element */ w += write_proc(&filler, sizeof(uint16_t), user_data); /* an object ends with 0x09 */ w += write_proc(&terminator, sizeof(uint8_t), user_data); return w; }