2 // JSON data type and serializer for Citadel
4 // Copyright (c) 1987-2018 by the citadel.org team
6 // This program is open source software. Use, duplication, or disclosure
7 // is subject to the terms of the GNU General Public License, version 3.
10 #include <sys/types.h>
18 #include "libcitadel.h"
35 void DeleteJSONValue(void *vJsonValue) {
36 JsonValue *Val = (JsonValue*) vJsonValue;
37 FreeStrBuf(&Val->Name);
38 FreeStrBuf(&Val->Value);
39 DeleteHash(&Val->SubValues);
44 JsonValue *NewJsonObject(const char *Key, long keylen) {
47 Ret = (JsonValue*) malloc(sizeof(JsonValue));
48 memset(Ret, 0, sizeof(JsonValue));
49 Ret->Type = JSON_OBJECT;
51 Ret->Name = NewStrBufPlain(Key, keylen);
53 Ret->SubValues = NewHash(1, NULL);
58 JsonValue *NewJsonArray(const char *Key, long keylen) {
61 Ret = (JsonValue*) malloc(sizeof(JsonValue));
62 memset(Ret, 0, sizeof(JsonValue));
63 Ret->Type = JSON_ARRAY;
65 Ret->Name = NewStrBufPlain(Key, keylen);
67 Ret->SubValues = NewHash(1, lFlathash);
72 JsonValue *NewJsonNumber(const char *Key, long keylen, long Number) {
75 Ret = (JsonValue*) malloc(sizeof(JsonValue));
76 memset(Ret, 0, sizeof(JsonValue));
79 Ret->Name = NewStrBufPlain(Key, keylen);
81 Ret->Value = NewStrBufPlain(NULL, 64);
82 StrBufPrintf(Ret->Value, "%ld", Number);
87 JsonValue *NewJsonBigNumber(const char *Key, long keylen, double Number) {
90 Ret = (JsonValue*) malloc(sizeof(JsonValue));
91 memset(Ret, 0, sizeof(JsonValue));
94 Ret->Name = NewStrBufPlain(Key, keylen);
96 Ret->Value = NewStrBufPlain(NULL, 128);
97 StrBufPrintf(Ret->Value, "%f", Number);
102 JsonValue *NewJsonString(const char *Key, long keylen, StrBuf *CopyMe, int copy_or_smash) {
105 Ret = (JsonValue*) malloc(sizeof(JsonValue));
106 memset(Ret, 0, sizeof(JsonValue));
107 Ret->Type = JSON_STRING;
109 Ret->Name = NewStrBufPlain(Key, keylen);
111 if (copy_or_smash == NEWJSONSTRING_COPYBUF) {
112 Ret->Value = NewStrBufDup(CopyMe);
114 else if (copy_or_smash == NEWJSONSTRING_SMASHBUF) {
118 Ret->Value = NULL; // error condition
124 JsonValue *NewJsonPlainString(const char *Key, long keylen, const char *CopyMe, long len) {
127 Ret = (JsonValue*) malloc(sizeof(JsonValue));
128 memset(Ret, 0, sizeof(JsonValue));
129 Ret->Type = JSON_STRING;
131 Ret->Name = NewStrBufPlain(Key, keylen);
133 Ret->Value = NewStrBufPlain(CopyMe, len);
138 JsonValue *NewJsonNull(const char *Key, long keylen) {
141 Ret = (JsonValue*) malloc(sizeof(JsonValue));
142 memset(Ret, 0, sizeof(JsonValue));
143 Ret->Type = JSON_NULL;
146 Ret->Name = NewStrBufPlain(Key, keylen);
148 Ret->Value = NewStrBufPlain(HKEY("nulll"));
153 JsonValue *NewJsonBool(const char *Key, long keylen, int value) {
156 Ret = (JsonValue*) malloc(sizeof(JsonValue));
157 memset(Ret, 0, sizeof(JsonValue));
158 Ret->Type = JSON_BOOL;
160 Ret->Name = NewStrBufPlain(Key, keylen);
163 Ret->Value = NewStrBufPlain(HKEY("true"));
166 Ret->Value = NewStrBufPlain(HKEY("false"));
172 void JsonArrayAppend(JsonValue *Array, JsonValue *Val) {
174 if (Array->Type != JSON_ARRAY) {
178 n = GetCount(Array->SubValues);
179 Put(Array->SubValues, LKEY(n), Val, DeleteJSONValue);
183 void JsonObjectAppend(JsonValue *Array, JsonValue *Val) {
184 if ((Array->Type != JSON_OBJECT) || (Val->Name == NULL)) {
187 Put(Array->SubValues, SKEY(Val->Name), Val, DeleteJSONValue);
191 void SerializeJson(StrBuf *Target, JsonValue *Val, int FreeVal) {
192 void *vValue, *vPrevious;
202 StrBufAppendBufPlain(Target, HKEY("\""), 0);
203 StrECMAEscAppend(Target, Val->Value, NULL);
204 StrBufAppendBufPlain(Target, HKEY("\""), 0);
207 StrBufAppendBuf(Target, Val->Value, 0);
210 StrBufAppendBuf(Target, Val->Value, 0);
213 StrBufAppendBuf(Target, Val->Value, 0);
217 StrBufAppendBufPlain(Target, HKEY("["), 0);
218 It = GetNewHashPos(Val->SubValues, 0);
219 while (GetNextHashPos(Val->SubValues, It, &keylen, &Key, &vValue)) {
220 if (vPrevious != NULL) {
221 StrBufAppendBufPlain(Target, HKEY(","), 0);
223 SubVal = (JsonValue*) vValue;
224 SerializeJson(Target, SubVal, 0);
227 StrBufAppendBufPlain(Target, HKEY("]"), 0);
232 StrBufAppendBufPlain(Target, HKEY("{"), 0);
233 It = GetNewHashPos(Val->SubValues, 0);
234 while (GetNextHashPos(Val->SubValues, It, &keylen, &Key, &vValue)) {
235 SubVal = (JsonValue*) vValue;
237 if (vPrevious != NULL) {
238 StrBufAppendBufPlain(Target, HKEY(","), 0);
240 StrBufAppendBufPlain(Target, HKEY("\""), 0);
241 StrBufAppendBuf(Target, SubVal->Name, 0);
242 StrBufAppendBufPlain(Target, HKEY("\":"), 0);
244 SerializeJson(Target, SubVal, 0);
247 StrBufAppendBufPlain(Target, HKEY("}"), 0);
252 DeleteJSONValue(Val);