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;
145 Ret->Name = NewStrBufPlain(Key, keylen);
147 Ret->Value = NewStrBufPlain(HKEY("nulll"));
152 JsonValue *NewJsonBool(const char *Key, long keylen, int value) {
155 Ret = (JsonValue*) malloc(sizeof(JsonValue));
156 memset(Ret, 0, sizeof(JsonValue));
157 Ret->Type = JSON_BOOL;
159 Ret->Name = NewStrBufPlain(Key, keylen);
162 Ret->Value = NewStrBufPlain(HKEY("true"));
165 Ret->Value = NewStrBufPlain(HKEY("false"));
171 void JsonArrayAppend(JsonValue *Array, JsonValue *Val) {
173 if (Array->Type != JSON_ARRAY) {
177 n = GetCount(Array->SubValues);
178 Put(Array->SubValues, LKEY(n), Val, DeleteJSONValue);
182 void JsonObjectAppend(JsonValue *Array, JsonValue *Val) {
183 if ((Array->Type != JSON_OBJECT) || (Val->Name == NULL)) {
186 Put(Array->SubValues, SKEY(Val->Name), Val, DeleteJSONValue);
190 void SerializeJson(StrBuf *Target, JsonValue *Val, int FreeVal) {
191 void *vValue, *vPrevious;
199 StrBufAppendBufPlain(Target, HKEY("\""), 0);
200 StrECMAEscAppend(Target, Val->Value, NULL);
201 StrBufAppendBufPlain(Target, HKEY("\""), 0);
204 StrBufAppendBuf(Target, Val->Value, 0);
207 StrBufAppendBuf(Target, Val->Value, 0);
210 StrBufAppendBuf(Target, Val->Value, 0);
214 StrBufAppendBufPlain(Target, HKEY("["), 0);
215 It = GetNewHashPos(Val->SubValues, 0);
216 while (GetNextHashPos(Val->SubValues, It, &keylen, &Key, &vValue)) {
217 if (vPrevious != NULL) {
218 StrBufAppendBufPlain(Target, HKEY(","), 0);
220 SubVal = (JsonValue*) vValue;
221 SerializeJson(Target, SubVal, 0);
224 StrBufAppendBufPlain(Target, HKEY("]"), 0);
229 StrBufAppendBufPlain(Target, HKEY("{"), 0);
230 It = GetNewHashPos(Val->SubValues, 0);
231 while (GetNextHashPos(Val->SubValues, It, &keylen, &Key, &vValue)) {
232 SubVal = (JsonValue*) vValue;
234 if (vPrevious != NULL) {
235 StrBufAppendBufPlain(Target, HKEY(","), 0);
237 StrBufAppendBufPlain(Target, HKEY("\""), 0);
238 StrBufAppendBuf(Target, SubVal->Name, 0);
239 StrBufAppendBufPlain(Target, HKEY("\":"), 0);
241 SerializeJson(Target, SubVal, 0);
244 StrBufAppendBufPlain(Target, HKEY("}"), 0);
249 DeleteJSONValue(Val);