make sure we propagate an error code in case of wrong number of ms-san
[heimdal.git] / base / json.c
blob78f0ad5d3876b3c5d3b9dbc3666f0d3692195a48
1 /*
2 * Copyright (c) 2010 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Portions Copyright (c) 2010 Apple Inc. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
36 #include "baselocl.h"
39 int
40 heim_base2json(heim_object_t obj,
41 void (*out)(char *, void *), void *ctx)
43 heim_tid_t type = heim_get_tid(obj);
44 __block int fail = 0, needcomma = 0;
46 switch (type) {
47 case HEIM_TID_ARRAY:
48 out("[ ", ctx);
49 heim_array_iterate(obj, ^(heim_object_t sub) {
50 if (needcomma)
51 out(", ", ctx);
52 fail |= heim_base2json(sub, out, ctx);
53 needcomma = 1;
54 });
55 out("]", ctx);
56 break;
58 case HEIM_TID_DICT:
59 out("{ ", ctx);
60 heim_dict_iterate(obj, ^(heim_object_t key, heim_object_t value) {
61 if (needcomma)
62 out(", ", ctx);
63 fail |= heim_base2json(key, out, ctx);
64 out(" = ", ctx);
65 fail |= heim_base2json(value, out, ctx);
66 needcomma = 1;
67 });
68 out("}", ctx);
69 break;
71 case HEIM_TID_STRING:
72 out("\"", ctx);
73 out(heim_string_get_utf8(obj), ctx);
74 out("\"", ctx);
75 break;
77 case HEIM_TID_NUMBER: {
78 char num[16];
79 snprintf(num, sizeof(num), "%d", heim_number_get_int(obj));
80 out(num, ctx);
81 break;
83 case HEIM_TID_NULL:
84 out("null", ctx);
85 break;
86 case HEIM_TID_BOOL:
87 out(heim_bool_val(obj) ? "true" : "false", ctx);
88 break;
89 default:
90 return 1;
92 return fail;
95 static int
96 parse_dict(heim_dict_t dict, char * const *pp, size_t *len)
98 const char *p = *pp;
99 while (*len) {
100 (*len)--;
102 if (*p == '\n') {
103 p += 1;
104 } else if (isspace(*p)) {
105 p += 1;
106 } else if (*p == '}') {
107 *pp = p + 1;
108 return 0;
109 } else {
112 return ENOENT;
116 heim_object_t
117 heim_json2base(const void *data, size_t length)
119 heim_array_t stack;
120 heim_object_t o = NULL;
121 const char *p = data;
122 unsigned long lineno = 1;
124 while (length) {
125 length--;
127 if (*p == '\n') {
128 lineno++;
129 } else if (isspace((int)*p)) {
131 } else if (*p == '{') {
132 o = heim_dict_create();
134 if ((ret = parse_dict(&p, &length)) != 0)
135 goto out;
136 } else
137 abort();
140 out:
141 if (ret && o) {
142 heim_release(o);
143 o = NULL;
146 return o;