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

Sources/json-c/tests/test_deep_copy.c

  1 #include <stddef.h>
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include <string.h>
  5 #ifdef NDEBUG
  6 #undef NDEBUG
  7 #endif
  8 #include <assert.h>
  9 #include <errno.h>
 10 #include <time.h>
 11 
 12 #include "json.h"
 13 #include "printbuf.h"
 14 
 15 static void do_benchmark(json_object *src1);
 16 
 17 static const char *json_str1 =
 18     "{"
 19     "    \"glossary\": {"
 20     "        \"title\": \"example glossary\","
 21     "        \"GlossDiv\": {"
 22     "            \"number\": 16446744073709551615,"
 23     "            \"title\": \"S\","
 24     "            \"null_obj\": null, "
 25     "            \"exixt\": false,"
 26     "            \"quantity\":20,"
 27     "            \"univalent\":19.8,"
 28     "            \"GlossList\": {"
 29     "                \"GlossEntry\": {"
 30     "                    \"ID\": \"SGML\","
 31     "                    \"SortAs\": \"SGML\","
 32     "                    \"GlossTerm\": \"Standard Generalized Markup Language\","
 33     "                    \"Acronym\": \"SGML\","
 34     "                    \"Abbrev\": \"ISO 8879:1986\","
 35     "                    \"GlossDef\": {"
 36     "                        \"para\": \"A meta-markup language, used to create markup languages "
 37     "such as DocBook.\","
 38     "                        \"GlossSeeAlso\": [\"GML\", \"XML\"]"
 39     "                    },"
 40     "                    \"GlossSee\": \"markup\""
 41     "                }"
 42     "            }"
 43     "        }"
 44     "    }"
 45     "}";
 46 
 47 static const char *json_str2 =
 48     "{\"menu\": {"
 49     "    \"header\": \"SVG Viewer\","
 50     "    \"items\": ["
 51     "        {\"id\": \"Open\"},"
 52     "        {\"id\": \"OpenNew\", \"label\": \"Open New\"},"
 53     "        null,"
 54     "        {\"id\": \"ZoomIn\", \"label\": \"Zoom In\"},"
 55     "        {\"id\": \"ZoomOut\", \"label\": \"Zoom Out\"},"
 56     "        {\"id\": \"OriginalView\", \"label\": \"Original View\"},"
 57     "        null,"
 58     "        {\"id\": \"Quality\", \"another_null\": null},"
 59     "        {\"id\": \"Pause\"},"
 60     "        {\"id\": \"Mute\"},"
 61     "        null,"
 62     "        {\"id\": \"Find\", \"label\": \"Find...\"},"
 63     "        {\"id\": \"FindAgain\", \"label\": \"Find Again\"},"
 64     "        {\"id\": \"Copy\"},"
 65     "        {\"id\": \"CopyAgain\", \"label\": \"Copy Again\"},"
 66     "        {\"id\": \"CopySVG\", \"label\": \"Copy SVG\"},"
 67     "        {\"id\": \"ViewSVG\", \"label\": \"View SVG\"},"
 68     "        {\"id\": \"ViewSource\", \"label\": \"View Source\"},"
 69     "        {\"id\": \"SaveAs\", \"label\": \"Save As\"},"
 70     "        null,"
 71     "        {\"id\": \"Help\"},"
 72     "        {\"id\": \"About\", \"label\": \"About Adobe CVG Viewer...\"}"
 73     "    ]"
 74     "}}";
 75 
 76 static const char *json_str3 = "{\"menu\": {"
 77                                "  \"id\": \"file\","
 78                                "  \"value\": \"File\","
 79                                "  \"popup\": {"
 80                                "    \"menuitem\": ["
 81                                "      {\"value\": \"New\", \"onclick\": \"CreateNewDoc()\"},"
 82                                "      {\"value\": \"Open\", \"onclick\": \"OpenDoc()\"},"
 83                                "      {\"value\": \"Close\", \"onclick\": \"CloseDoc()\"}"
 84                                "    ]"
 85                                "  }"
 86                                "}}";
 87 
 88 json_object_to_json_string_fn my_custom_serializer;
 89 int my_custom_serializer(struct json_object *jso, struct printbuf *pb, int level, int flags)
 90 {
 91         sprintbuf(pb, "OTHER");
 92         return 0;
 93 }
 94 
 95 json_c_shallow_copy_fn my_shallow_copy;
 96 int my_shallow_copy(json_object *src, json_object *parent, const char *key, size_t index,
 97                     json_object **dst)
 98 {
 99         int rc;
100         rc = json_c_shallow_copy_default(src, parent, key, index, dst);
101         if (rc < 0)
102                 return rc;
103         if (key != NULL && strcmp(key, "with_serializer") == 0)
104         {
105                 printf("CALLED: my_shallow_copy on with_serializer object\n");
106                 void *userdata = json_object_get_userdata(src);
107                 json_object_set_serializer(*dst, my_custom_serializer, userdata, NULL);
108                 return 2;
109         }
110         return rc;
111 }
112 
113 int main(int argc, char **argv)
114 {
115         struct json_object *src1, *src2, *src3;
116         struct json_object *dst1 = NULL, *dst2 = NULL, *dst3 = NULL;
117         int benchmark = 0;
118 
119         if (argc > 1 && strcmp(argv[1], "--benchmark") == 0)
120         {
121                 benchmark = 1;
122         }
123 
124         src1 = json_tokener_parse(json_str1);
125         src2 = json_tokener_parse(json_str2);
126         src3 = json_tokener_parse(json_str3);
127 
128         assert(src1 != NULL);
129         assert(src2 != NULL);
130         assert(src3 != NULL);
131 
132         printf("PASSED - loaded input data\n");
133 
134         /* do this 3 times to make sure overwriting it works */
135         assert(0 == json_object_deep_copy(src1, &dst1, NULL));
136         assert(0 == json_object_deep_copy(src2, &dst2, NULL));
137         assert(0 == json_object_deep_copy(src3, &dst3, NULL));
138 
139         printf("PASSED - all json_object_deep_copy() returned succesful\n");
140 
141         assert(-1 == json_object_deep_copy(src1, &dst1, NULL));
142         assert(errno == EINVAL);
143         assert(-1 == json_object_deep_copy(src2, &dst2, NULL));
144         assert(errno == EINVAL);
145         assert(-1 == json_object_deep_copy(src3, &dst3, NULL));
146         assert(errno == EINVAL);
147 
148         printf("PASSED - all json_object_deep_copy() returned EINVAL for non-null pointer\n");
149 
150         assert(1 == json_object_equal(src1, dst1));
151         assert(1 == json_object_equal(src2, dst2));
152         assert(1 == json_object_equal(src3, dst3));
153 
154         printf("PASSED - all json_object_equal() tests returned succesful\n");
155 
156         assert(0 == strcmp(json_object_to_json_string_ext(src1, JSON_C_TO_STRING_PRETTY),
157                            json_object_to_json_string_ext(dst1, JSON_C_TO_STRING_PRETTY)));
158         assert(0 == strcmp(json_object_to_json_string_ext(src2, JSON_C_TO_STRING_PRETTY),
159                            json_object_to_json_string_ext(dst2, JSON_C_TO_STRING_PRETTY)));
160         assert(0 == strcmp(json_object_to_json_string_ext(src3, JSON_C_TO_STRING_PRETTY),
161                            json_object_to_json_string_ext(dst3, JSON_C_TO_STRING_PRETTY)));
162 
163         printf("PASSED - comparison of string output\n");
164 
165         json_object_get(dst1);
166         assert(-1 == json_object_deep_copy(src1, &dst1, NULL));
167         assert(errno == EINVAL);
168         json_object_put(dst1);
169 
170         printf("PASSED - trying to overrwrite an object that has refcount > 1");
171 
172         printf("\nPrinting JSON objects for visual inspection\n");
173         printf("------------------------------------------------\n");
174         printf(" JSON1\n");
175         printf("%s\n", json_object_to_json_string_ext(dst1, JSON_C_TO_STRING_PRETTY));
176         printf("------------------------------------------------\n");
177 
178         printf("------------------------------------------------\n");
179         printf(" JSON2\n");
180         printf("%s\n", json_object_to_json_string_ext(dst2, JSON_C_TO_STRING_PRETTY));
181         printf("------------------------------------------------\n");
182 
183         printf("------------------------------------------------\n");
184         printf(" JSON3\n");
185         printf("------------------------------------------------\n");
186         printf("%s\n", json_object_to_json_string_ext(dst3, JSON_C_TO_STRING_PRETTY));
187         printf("------------------------------------------------\n");
188 
189         json_object_put(dst1);
190         json_object_put(dst2);
191         json_object_put(dst3);
192 
193         printf("\nTesting deep_copy with a custom serializer set\n");
194         json_object *with_serializer = json_object_new_string("notemitted");
195 
196         char udata[] = "dummy userdata";
197         json_object_set_serializer(with_serializer, my_custom_serializer, udata, NULL);
198         json_object_object_add(src1, "with_serializer", with_serializer);
199         dst1 = NULL;
200         /* With a custom serializer in use, a custom shallow_copy function must also be used */
201         assert(-1 == json_object_deep_copy(src1, &dst1, NULL));
202         assert(0 == json_object_deep_copy(src1, &dst1, my_shallow_copy));
203 
204         json_object *dest_with_serializer = json_object_object_get(dst1, "with_serializer");
205         assert(dest_with_serializer != NULL);
206         char *dst_userdata = json_object_get_userdata(dest_with_serializer);
207         assert(strcmp(dst_userdata, "dummy userdata") == 0);
208 
209         const char *special_output = json_object_to_json_string(dest_with_serializer);
210         assert(strcmp(special_output, "OTHER") == 0);
211         printf("\ndeep_copy with custom serializer worked OK.\n");
212         json_object_put(dst1);
213 
214         if (benchmark)
215         {
216                 do_benchmark(src2);
217         }
218 
219         json_object_put(src1);
220         json_object_put(src2);
221         json_object_put(src3);
222 
223         return 0;
224 }
225 
226 static void do_benchmark(json_object *src2)
227 {
228         json_object *dst2 = NULL;
229 
230         int ii;
231         /**
232          * The numbers that I got are:
233          * BENCHMARK - 1000000 iterations of 'dst2 = json_tokener_parse(json_object_get_string(src2))' took 71 seconds
234          * BENCHMARK - 1000000 iterations of 'json_object_deep_copy(src2, &dst2, NULL)' took 29 seconds
235          */
236 
237         int iterations = 1000000;
238         time_t start = time(NULL);
239 
240         start = time(NULL);
241         for (ii = 0; ii < iterations; ii++)
242         {
243                 dst2 = json_tokener_parse(json_object_get_string(src2));
244                 json_object_put(dst2);
245         }
246         printf("BENCHMARK - %d iterations of 'dst2 = "
247                "json_tokener_parse(json_object_get_string(src2))' took %d seconds\n",
248                iterations, (int)(time(NULL) - start));
249 
250         start = time(NULL);
251         dst2 = NULL;
252         for (ii = 0; ii < iterations; ii++)
253         {
254                 json_object_deep_copy(src2, &dst2, NULL);
255                 json_object_put(dst2);
256                 dst2 = NULL;
257         }
258         printf("BENCHMARK - %d iterations of 'json_object_deep_copy(src2, &dst2, NULL)' took %d "
259                "seconds\n",
260                iterations, (int)(time(NULL) - start));
261 }
262 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt