1 /* $NetBSD: json.c,v 1.1.1.1 2011/04/13 18:14:32 elric 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 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 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 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