static void test_json_render(void *p) { struct JsonContext *ctx; struct JsonValue *list, *dict; ctx = json_new_context(NULL, 128); tt_assert(ctx); list = json_new_list(ctx); tt_assert(json_list_append(list, json_new_null(ctx))); tt_assert(json_list_append(list, json_new_bool(ctx, 1))); tt_assert(json_list_append(list, json_new_bool(ctx, 0))); tt_assert(json_list_append(list, json_new_int(ctx, 600))); tt_assert(json_list_append(list, json_new_float(ctx, -0.5))); tt_assert(json_list_append(list, json_new_string(ctx, "q\\we"))); str_check(render(list), "[null,true,false,600,-0.5,\"q\\\\we\"]"); dict = json_new_dict(ctx); tt_assert(dict); str_check(render(dict), "{}"); tt_assert(json_dict_put(dict, "k", json_new_list(ctx))); str_check(render(dict), "{\"k\":[]}"); tt_assert(json_dict_put_null(dict, "n")); tt_assert(json_dict_put_bool(dict, "b", 1)); tt_assert(json_dict_put_int(dict, "i", 22)); tt_assert(json_dict_put_float(dict, "f", 1)); tt_assert(json_dict_put_string(dict, "s", "qwe")); str_check(render(dict), "{\"b\":true,\"f\":1.0,\"i\":22,\"k\":[],\"n\":null,\"s\":\"qwe\"}"); str_check(render(json_new_string(ctx, "\"\\ low:\a\b\f\n\r\t")), "\"\\\"\\\\ low:\\u0007\\b\\f\\n\\r\\t\""); list = json_new_list(ctx); tt_assert(json_list_append_null(list)); tt_assert(json_list_append_bool(list, false)); tt_assert(json_list_append_int(list, -1)); tt_assert(json_list_append_float(list, -2)); tt_assert(json_list_append_string(list, "qz\0foo")); str_check(render(list), "[null,false,-1,-2.0,\"qz\"]"); json_free_context(ctx); end:; }
/* JSON metadata dumping */ static void amf_to_json(const amf_data * data, json_t ** object) { if (data != NULL) { json_t * value; amf_node * node; time_t time; struct tm * t; char str[128]; char * escaped_str; switch (data->type) { case AMF_TYPE_NUMBER: sprintf(str, "%.12g", data->number_data); *object = json_new_number(str); break; case AMF_TYPE_BOOLEAN: *object = (data->boolean_data) ? json_new_true() : json_new_false(); break; case AMF_TYPE_STRING: escaped_str = json_escape((char *)amf_string_get_bytes(data)); *object = json_new_string(escaped_str); free(escaped_str); break; case AMF_TYPE_OBJECT: *object = json_new_object(); node = amf_object_first(data); while (node != NULL) { amf_to_json(amf_object_get_data(node), &value); escaped_str = json_escape((char *)amf_string_get_bytes(amf_object_get_name(node))); json_insert_pair_into_object(*object, escaped_str, value); free(escaped_str); node = amf_object_next(node); } break; case AMF_TYPE_NULL: case AMF_TYPE_UNDEFINED: *object = json_new_null(); break; case AMF_TYPE_ASSOCIATIVE_ARRAY: *object = json_new_object(); node = amf_associative_array_first(data); while (node != NULL) { amf_to_json(amf_associative_array_get_data(node), &value); json_insert_pair_into_object(*object, (const char *)amf_string_get_bytes(amf_associative_array_get_name(node)), value); node = amf_associative_array_next(node); } break; case AMF_TYPE_ARRAY: *object = json_new_array(); node = amf_array_first(data); while (node != NULL) { amf_to_json(amf_array_get(node), &value); json_insert_child(*object, value); node = amf_array_next(node); } break; case AMF_TYPE_DATE: time = amf_date_to_time_t(data); tzset(); t = localtime(&time); strftime(str, sizeof(str), "%Y-%m-%dT%H:%M:%S", t); *object = json_new_string(str); break; case AMF_TYPE_XML: break; case AMF_TYPE_CLASS: break; default: break; } } }