1 /* 2 * Copyright (c) 2016 Eric Haszlakiewicz 3 * 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. 6 */ 7 8 #include <stdio.h> 9 10 #include "config.h" 11 #include "json_inttypes.h" 12 #include "json_object.h" 13 #include "json_visit.h" 14 #include "linkhash.h" 15 16 static int _json_c_visit(json_object *jso, json_object *parent_jso, const char *jso_key, 17 size_t *jso_index, json_c_visit_userfunc *userfunc, void *userarg); 18 19 int json_c_visit(json_object *jso, int future_flags, json_c_visit_userfunc *userfunc, void *userarg) 20 { 21 int ret = _json_c_visit(jso, NULL, NULL, NULL, userfunc, userarg); 22 switch (ret) 23 { 24 case JSON_C_VISIT_RETURN_CONTINUE: 25 case JSON_C_VISIT_RETURN_SKIP: 26 case JSON_C_VISIT_RETURN_POP: 27 case JSON_C_VISIT_RETURN_STOP: return 0; 28 default: return JSON_C_VISIT_RETURN_ERROR; 29 } 30 } 31 static int _json_c_visit(json_object *jso, json_object *parent_jso, const char *jso_key, 32 size_t *jso_index, json_c_visit_userfunc *userfunc, void *userarg) 33 { 34 int userret = userfunc(jso, 0, parent_jso, jso_key, jso_index, userarg); 35 switch (userret) 36 { 37 case JSON_C_VISIT_RETURN_CONTINUE: break; 38 case JSON_C_VISIT_RETURN_SKIP: 39 case JSON_C_VISIT_RETURN_POP: 40 case JSON_C_VISIT_RETURN_STOP: 41 case JSON_C_VISIT_RETURN_ERROR: return userret; 42 default: 43 fprintf(stderr, "ERROR: invalid return value from json_c_visit userfunc: %d\n", 44 userret); 45 return JSON_C_VISIT_RETURN_ERROR; 46 } 47 48 switch (json_object_get_type(jso)) 49 { 50 case json_type_null: 51 case json_type_boolean: 52 case json_type_double: 53 case json_type_int: 54 case json_type_string: 55 // we already called userfunc above, move on to the next object 56 return JSON_C_VISIT_RETURN_CONTINUE; 57 58 case json_type_object: 59 { 60 json_object_object_foreach(jso, key, child) 61 { 62 userret = _json_c_visit(child, jso, key, NULL, userfunc, userarg); 63 if (userret == JSON_C_VISIT_RETURN_POP) 64 break; 65 if (userret == JSON_C_VISIT_RETURN_STOP || 66 userret == JSON_C_VISIT_RETURN_ERROR) 67 return userret; 68 if (userret != JSON_C_VISIT_RETURN_CONTINUE && 69 userret != JSON_C_VISIT_RETURN_SKIP) 70 { 71 fprintf(stderr, "INTERNAL ERROR: _json_c_visit returned %d\n", 72 userret); 73 return JSON_C_VISIT_RETURN_ERROR; 74 } 75 } 76 break; 77 } 78 case json_type_array: 79 { 80 size_t array_len = json_object_array_length(jso); 81 size_t ii; 82 for (ii = 0; ii < array_len; ii++) 83 { 84 json_object *child = json_object_array_get_idx(jso, ii); 85 userret = _json_c_visit(child, jso, NULL, &ii, userfunc, userarg); 86 if (userret == JSON_C_VISIT_RETURN_POP) 87 break; 88 if (userret == JSON_C_VISIT_RETURN_STOP || 89 userret == JSON_C_VISIT_RETURN_ERROR) 90 return userret; 91 if (userret != JSON_C_VISIT_RETURN_CONTINUE && 92 userret != JSON_C_VISIT_RETURN_SKIP) 93 { 94 fprintf(stderr, "INTERNAL ERROR: _json_c_visit returned %d\n", 95 userret); 96 return JSON_C_VISIT_RETURN_ERROR; 97 } 98 } 99 break; 100 } 101 default: 102 fprintf(stderr, "INTERNAL ERROR: _json_c_visit found object of unknown type: %d\n", 103 json_object_get_type(jso)); 104 return JSON_C_VISIT_RETURN_ERROR; 105 } 106 107 // Call userfunc for the second type on container types, after all 108 // members of the container have been visited. 109 // Non-container types will have already returned before this point. 110 111 userret = userfunc(jso, JSON_C_VISIT_SECOND, parent_jso, jso_key, jso_index, userarg); 112 switch (userret) 113 { 114 case JSON_C_VISIT_RETURN_SKIP: 115 case JSON_C_VISIT_RETURN_POP: 116 // These are not really sensible during JSON_C_VISIT_SECOND, 117 // but map them to JSON_C_VISIT_CONTINUE anyway. 118 // FALLTHROUGH 119 case JSON_C_VISIT_RETURN_CONTINUE: return JSON_C_VISIT_RETURN_CONTINUE; 120 case JSON_C_VISIT_RETURN_STOP: 121 case JSON_C_VISIT_RETURN_ERROR: return userret; 122 default: 123 fprintf(stderr, "ERROR: invalid return value from json_c_visit userfunc: %d\n", 124 userret); 125 return JSON_C_VISIT_RETURN_ERROR; 126 } 127 // NOTREACHED 128 } 129
This page was automatically generated by LXR 0.3.1. • OpenWrt