#include #include #include #include #include static void print_callback (void *ctx, const char *str, size_t len) { FILE *f = (FILE *) ctx; fwrite (str, 1, len, f); } static void check_status (yajl_gen_status status) { if (status != yajl_gen_status_ok) { fprintf (stderr, "yajl_gen_status was %d\n", (int) status); exit (EXIT_FAILURE); } } static void serialize_value (yajl_gen gen, yajl_val val, int parse_numbers) { size_t i; switch (val->type) { case yajl_t_string: check_status (yajl_gen_string (gen, (const unsigned char *) val->u.string, strlen (val->u.string))); break; case yajl_t_number: if (parse_numbers && YAJL_IS_INTEGER (val)) check_status (yajl_gen_integer (gen, YAJL_GET_INTEGER (val))); else if (parse_numbers && YAJL_IS_DOUBLE (val)) check_status (yajl_gen_double (gen, YAJL_GET_DOUBLE (val))); else check_status (yajl_gen_number (gen, YAJL_GET_NUMBER (val), strlen (YAJL_GET_NUMBER (val)))); break; case yajl_t_object: check_status (yajl_gen_map_open (gen)); for (i = 0 ; i < val->u.object.len ; i++) { check_status (yajl_gen_string (gen, (const unsigned char *) val->u.object.keys[i], strlen (val->u.object.keys[i]))); serialize_value (gen, val->u.object.values[i], parse_numbers); } check_status (yajl_gen_map_close (gen)); break; case yajl_t_array: check_status (yajl_gen_array_open (gen)); for (i = 0 ; i < val->u.array.len ; i++) serialize_value (gen, val->u.array.values[i], parse_numbers); check_status (yajl_gen_array_close (gen)); break; case yajl_t_true: check_status (yajl_gen_bool (gen, 1)); break; case yajl_t_false: check_status (yajl_gen_bool (gen, 0)); break; case yajl_t_null: check_status (yajl_gen_null (gen)); break; default: fprintf (stderr, "unexpectedly got type %d\n", (int) val->type); exit (EXIT_FAILURE); } } static void print_tree (FILE *f, yajl_val tree, int parse_numbers) { yajl_gen gen; gen = yajl_gen_alloc (NULL); if (! gen) { fprintf (stderr, "yajl_gen_alloc failed\n"); exit (EXIT_FAILURE); } if (0 == yajl_gen_config (gen, yajl_gen_beautify, 1) || 0 == yajl_gen_config (gen, yajl_gen_validate_utf8, 1) || 0 == yajl_gen_config (gen, yajl_gen_print_callback, print_callback, f)) { fprintf (stderr, "yajl_gen_config failed\n"); exit (EXIT_FAILURE); } serialize_value (gen, tree, parse_numbers); yajl_gen_free (gen); } int main (int argc, char **argv) { char err_buf[200]; const char *json = "{\"pi\": 3.14, \"large number\": 123456789123456789123456789, " "\"an array\": [-1, true, false, null, \"foo\"]}"; yajl_val tree; tree = yajl_tree_parse (json, err_buf, sizeof (err_buf)); if (! tree) { fprintf (stderr, "parsing failed because: %s\n", err_buf); return EXIT_FAILURE; } printf ("Treating numbers as strings...\n"); print_tree (stdout, tree, 0); printf ("Parsing numbers to long long or double...\n"); print_tree (stdout, tree, 1); yajl_tree_free (tree); return EXIT_SUCCESS; }