12910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/* 22910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * QObject JSON integration 32910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * 42910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Copyright IBM, Corp. 2009 52910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * 62910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Authors: 72910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Anthony Liguori <aliguori@us.ibm.com> 82910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * 92910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. 102910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * See the COPYING.LIB file in the top-level directory. 112910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * 122910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */ 132910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 142910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#include "json-lexer.h" 152910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#include "json-parser.h" 162910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#include "json-streamer.h" 172910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#include "qjson.h" 182910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#include "qint.h" 192910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#include "qlist.h" 202910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#include "qbool.h" 212910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#include "qfloat.h" 222910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#include "qdict.h" 232910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 242910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnertypedef struct JSONParsingState 252910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 262910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner JSONMessageParser parser; 272910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner va_list *ap; 282910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QObject *result; 292910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} JSONParsingState; 302910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 312910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic void parse_json(JSONMessageParser *parser, QList *tokens) 322910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 332910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner JSONParsingState *s = container_of(parser, JSONParsingState, parser); 342910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner s->result = json_parser_parse(tokens, s->ap); 352910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 362910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 372910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' TurnerQObject *qobject_from_jsonv(const char *string, va_list *ap) 382910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 392910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner JSONParsingState state = {}; 402910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 412910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner state.ap = ap; 422910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 432910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner json_message_parser_init(&state.parser, parse_json); 442910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner json_message_parser_feed(&state.parser, string, strlen(string)); 452910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner json_message_parser_flush(&state.parser); 462910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner json_message_parser_destroy(&state.parser); 472910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 482910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return state.result; 492910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 502910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 512910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' TurnerQObject *qobject_from_json(const char *string) 522910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 532910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return qobject_from_jsonv(string, NULL); 542910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 552910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 569251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner/* 579251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner * IMPORTANT: This function aborts on error, thus it must not 589251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner * be used with untrusted arguments. 599251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner */ 602910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' TurnerQObject *qobject_from_jsonf(const char *string, ...) 612910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 622910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QObject *obj; 632910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner va_list ap; 642910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 652910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner va_start(ap, string); 662910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner obj = qobject_from_jsonv(string, &ap); 672910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner va_end(ap); 682910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 699251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner assert(obj != NULL); 702910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return obj; 712910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 722910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 732910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnertypedef struct ToJsonIterState 742910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 75f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner int indent; 76f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner int pretty; 772910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner int count; 782910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QString *str; 792910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} ToJsonIterState; 802910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 81f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turnerstatic void to_json(const QObject *obj, QString *str, int pretty, int indent); 822910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 832910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic void to_json_dict_iter(const char *key, QObject *obj, void *opaque) 842910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 852910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner ToJsonIterState *s = opaque; 862910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QString *qkey; 87f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner int j; 882910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 89f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner if (s->count) 902910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qstring_append(s->str, ", "); 91f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner 92f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner if (s->pretty) { 93f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner qstring_append(s->str, "\n"); 94f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner for (j = 0 ; j < s->indent ; j++) 95f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner qstring_append(s->str, " "); 962910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 972910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 982910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qkey = qstring_from_str(key); 99f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner to_json(QOBJECT(qkey), s->str, s->pretty, s->indent); 1002910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QDECREF(qkey); 1012910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1022910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qstring_append(s->str, ": "); 103f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner to_json(obj, s->str, s->pretty, s->indent); 1042910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner s->count++; 1052910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 1062910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1072910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic void to_json_list_iter(QObject *obj, void *opaque) 1082910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 1092910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner ToJsonIterState *s = opaque; 110f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner int j; 1112910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 112f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner if (s->count) 1132910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qstring_append(s->str, ", "); 114f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner 115f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner if (s->pretty) { 116f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner qstring_append(s->str, "\n"); 117f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner for (j = 0 ; j < s->indent ; j++) 118f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner qstring_append(s->str, " "); 1192910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 1202910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 121f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner to_json(obj, s->str, s->pretty, s->indent); 1222910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner s->count++; 1232910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 1242910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 125f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turnerstatic void to_json(const QObject *obj, QString *str, int pretty, int indent) 1262910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 1272910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner switch (qobject_type(obj)) { 1282910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner case QTYPE_QINT: { 1292910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QInt *val = qobject_to_qint(obj); 1302910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner char buffer[1024]; 1312910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1322910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner snprintf(buffer, sizeof(buffer), "%" PRId64, qint_get_int(val)); 1332910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qstring_append(str, buffer); 1342910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 1352910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 1362910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner case QTYPE_QSTRING: { 1372910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QString *val = qobject_to_qstring(obj); 1382910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner const char *ptr; 1392910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1402910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner ptr = qstring_get_str(val); 1412910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qstring_append(str, "\""); 1422910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner while (*ptr) { 1432910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if ((ptr[0] & 0xE0) == 0xE0 && 1442910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner (ptr[1] & 0x80) && (ptr[2] & 0x80)) { 1452910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner uint16_t wchar; 1462910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner char escape[7]; 1472910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1482910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner wchar = (ptr[0] & 0x0F) << 12; 1492910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner wchar |= (ptr[1] & 0x3F) << 6; 1502910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner wchar |= (ptr[2] & 0x3F); 1512910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner ptr += 2; 1522910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1532910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner snprintf(escape, sizeof(escape), "\\u%04X", wchar); 1542910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qstring_append(str, escape); 1552910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } else if ((ptr[0] & 0xE0) == 0xC0 && (ptr[1] & 0x80)) { 1562910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner uint16_t wchar; 1572910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner char escape[7]; 1582910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1592910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner wchar = (ptr[0] & 0x1F) << 6; 1602910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner wchar |= (ptr[1] & 0x3F); 1612910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner ptr++; 1622910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1632910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner snprintf(escape, sizeof(escape), "\\u%04X", wchar); 1642910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qstring_append(str, escape); 1652910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } else switch (ptr[0]) { 1662910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner case '\"': 1672910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qstring_append(str, "\\\""); 1682910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 1692910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner case '\\': 1702910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qstring_append(str, "\\\\"); 1712910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 1722910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner case '\b': 1732910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qstring_append(str, "\\b"); 1742910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 175fd4c0076b7470f5962ff462bae9cd9f208e059b7David Turner case '\f': 176fd4c0076b7470f5962ff462bae9cd9f208e059b7David Turner qstring_append(str, "\\f"); 177fd4c0076b7470f5962ff462bae9cd9f208e059b7David Turner break; 1782910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner case '\n': 1792910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qstring_append(str, "\\n"); 1802910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 1812910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner case '\r': 1822910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qstring_append(str, "\\r"); 1832910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 1842910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner case '\t': 1852910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qstring_append(str, "\\t"); 1862910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 1872910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner default: { 1882910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (ptr[0] <= 0x1F) { 1892910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner char escape[7]; 1902910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner snprintf(escape, sizeof(escape), "\\u%04X", ptr[0]); 1912910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qstring_append(str, escape); 1922910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } else { 1932910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner char buf[2] = { ptr[0], 0 }; 1942910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qstring_append(str, buf); 1952910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 1962910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 1972910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 1982910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 1992910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner ptr++; 2002910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 2012910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qstring_append(str, "\""); 2022910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 2032910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 2042910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner case QTYPE_QDICT: { 2052910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner ToJsonIterState s; 2062910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QDict *val = qobject_to_qdict(obj); 2072910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 2082910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner s.count = 0; 2092910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner s.str = str; 210f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner s.indent = indent + 1; 211f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner s.pretty = pretty; 2122910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qstring_append(str, "{"); 2132910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qdict_iter(val, to_json_dict_iter, &s); 214f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner if (pretty) { 215f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner int j; 216f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner qstring_append(str, "\n"); 217f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner for (j = 0 ; j < indent ; j++) 218f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner qstring_append(str, " "); 219f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner } 2202910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qstring_append(str, "}"); 2212910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 2222910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 2232910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner case QTYPE_QLIST: { 2242910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner ToJsonIterState s; 2252910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QList *val = qobject_to_qlist(obj); 2262910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 2272910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner s.count = 0; 2282910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner s.str = str; 229f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner s.indent = indent + 1; 230f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner s.pretty = pretty; 2312910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qstring_append(str, "["); 2322910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qlist_iter(val, (void *)to_json_list_iter, &s); 233f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner if (pretty) { 234f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner int j; 235f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner qstring_append(str, "\n"); 236f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner for (j = 0 ; j < indent ; j++) 237f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner qstring_append(str, " "); 238f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner } 2392910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qstring_append(str, "]"); 2402910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 2412910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 2422910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner case QTYPE_QFLOAT: { 2432910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QFloat *val = qobject_to_qfloat(obj); 2442910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner char buffer[1024]; 2452910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner int len; 2462910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 2472910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner len = snprintf(buffer, sizeof(buffer), "%f", qfloat_get_double(val)); 2482910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner while (len > 0 && buffer[len - 1] == '0') { 2492910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner len--; 2502910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 2512910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 2522910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (len && buffer[len - 1] == '.') { 2532910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner buffer[len - 1] = 0; 2542910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } else { 2552910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner buffer[len] = 0; 2562910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 2572910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 2582910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qstring_append(str, buffer); 2592910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 2602910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 2612910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner case QTYPE_QBOOL: { 2622910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QBool *val = qobject_to_qbool(obj); 2632910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 2642910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (qbool_get_int(val)) { 2652910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qstring_append(str, "true"); 2662910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } else { 2672910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qstring_append(str, "false"); 2682910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 2692910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 2702910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 2712910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner case QTYPE_QERROR: 2722910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner /* XXX: should QError be emitted? */ 2732910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner case QTYPE_NONE: 2742910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner break; 2752910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 2762910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 2772910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 2782910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' TurnerQString *qobject_to_json(const QObject *obj) 2792910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 2802910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QString *str = qstring_new(); 2812910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 282f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner to_json(obj, str, 0, 0); 283f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner 284f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner return str; 285f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner} 286f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner 287f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' TurnerQString *qobject_to_json_pretty(const QObject *obj) 288f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner{ 289f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner QString *str = qstring_new(); 290f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner 291f0753acaab4309557754ec19d3e839fe6b5e356cDavid 'Digit' Turner to_json(obj, str, 1, 0); 2922910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 2932910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return str; 2942910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 295