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