• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/json-c/json_visit.c

  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