2 * Copyright (c) 2016 Eric Haszlakiewicz
4 * This is free software; you can redistribute it and/or modify
5 * it under the terms of the MIT license. See COPYING for details.
11 #include "json_inttypes.h"
12 #include "json_object.h"
13 #include "json_visit.h"
16 static int _json_c_visit(json_object *jso, json_object *parent_jso,
17 const char *jso_key, size_t *jso_index,
18 json_c_visit_userfunc *userfunc, void *userarg);
20 int json_c_visit(json_object *jso, int future_flags,
21 json_c_visit_userfunc *userfunc, void *userarg)
23 int ret = _json_c_visit(jso, NULL, NULL, NULL, userfunc, userarg);
26 case JSON_C_VISIT_RETURN_CONTINUE:
27 case JSON_C_VISIT_RETURN_SKIP:
28 case JSON_C_VISIT_RETURN_POP:
29 case JSON_C_VISIT_RETURN_STOP:
32 return JSON_C_VISIT_RETURN_ERROR;
35 static int _json_c_visit(json_object *jso, json_object *parent_jso,
36 const char *jso_key, size_t *jso_index,
37 json_c_visit_userfunc *userfunc, void *userarg)
39 int userret = userfunc(jso, 0, parent_jso, jso_key, jso_index, userarg);
42 case JSON_C_VISIT_RETURN_CONTINUE:
44 case JSON_C_VISIT_RETURN_SKIP:
45 case JSON_C_VISIT_RETURN_POP:
46 case JSON_C_VISIT_RETURN_STOP:
47 case JSON_C_VISIT_RETURN_ERROR:
50 fprintf(stderr, "ERROR: invalid return value from json_c_visit userfunc: %d\n", userret);
51 return JSON_C_VISIT_RETURN_ERROR;
54 switch(json_object_get_type(jso))
57 case json_type_boolean:
58 case json_type_double:
60 case json_type_string:
61 // we already called userfunc above, move on to the next object
62 return JSON_C_VISIT_RETURN_CONTINUE;
64 case json_type_object:
66 json_object_object_foreach(jso, key, child)
68 userret = _json_c_visit(child, jso, key, NULL, userfunc, userarg);
69 if (userret == JSON_C_VISIT_RETURN_POP)
71 if (userret == JSON_C_VISIT_RETURN_STOP ||
72 userret == JSON_C_VISIT_RETURN_ERROR)
74 if (userret != JSON_C_VISIT_RETURN_CONTINUE &&
75 userret != JSON_C_VISIT_RETURN_SKIP)
77 fprintf(stderr, "INTERNAL ERROR: _json_c_visit returned %d\n", userret);
78 return JSON_C_VISIT_RETURN_ERROR;
85 size_t array_len = json_object_array_length(jso);
87 for (ii = 0; ii < array_len; ii++)
89 json_object *child = json_object_array_get_idx(jso, ii);
90 userret = _json_c_visit(child, jso, NULL, &ii, userfunc, userarg);
91 if (userret == JSON_C_VISIT_RETURN_POP)
93 if (userret == JSON_C_VISIT_RETURN_STOP ||
94 userret == JSON_C_VISIT_RETURN_ERROR)
96 if (userret != JSON_C_VISIT_RETURN_CONTINUE &&
97 userret != JSON_C_VISIT_RETURN_SKIP)
99 fprintf(stderr, "INTERNAL ERROR: _json_c_visit returned %d\n", userret);
100 return JSON_C_VISIT_RETURN_ERROR;
106 fprintf(stderr, "INTERNAL ERROR: _json_c_visit found object of unknown type: %d\n", json_object_get_type(jso));
107 return JSON_C_VISIT_RETURN_ERROR;
110 // Call userfunc for the second type on container types, after all
111 // members of the container have been visited.
112 // Non-container types will have already returned before this point.
114 userret = userfunc(jso, JSON_C_VISIT_SECOND, parent_jso, jso_key, jso_index, userarg);
117 case JSON_C_VISIT_RETURN_SKIP:
118 case JSON_C_VISIT_RETURN_POP:
119 // These are not really sensible during JSON_C_VISIT_SECOND,
120 // but map them to JSON_C_VISIT_CONTINUE anyway.
122 case JSON_C_VISIT_RETURN_CONTINUE:
123 return JSON_C_VISIT_RETURN_CONTINUE;
124 case JSON_C_VISIT_RETURN_STOP:
125 case JSON_C_VISIT_RETURN_ERROR:
128 fprintf(stderr, "ERROR: invalid return value from json_c_visit userfunc: %d\n", userret);
129 return JSON_C_VISIT_RETURN_ERROR;