* When converting cid: URL's in to /webcit/mimepart... URL's, prefix the inserted...
[citadel.git] / libcitadel / lib / json.c
blob9c941bc626436755706e0fce9749d76b3152f8e2
1 /*
2 * $Id: wildfire.c 6962 2009-01-18 19:33:45Z dothebart $
3 */
4 /**
5 * \defgroup Subst Variable substitution type stuff
6 * \ingroup CitadelConfig
7 */
9 /*@{*/
11 #include "sysdep.h"
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <unistd.h>
15 #include <dirent.h>
16 #include <errno.h>
17 #include <stdio.h>
18 #include <stdarg.h>
19 #include <string.h>
21 #include "libcitadel.h"
24 #define JSON_STRING 0
25 #define JSON_NUM 1
26 #define JSON_NULL 2
27 #define JSON_BOOL 3
28 #define JSON_ARRAY 4
29 #define JSON_OBJECT 7
31 struct JsonValue {
32 int Type;
33 StrBuf *Name;
34 StrBuf *Value;
35 HashList *SubValues;
39 void DeleteJSONValue(void *vJsonValue)
41 JsonValue *Val = (JsonValue*) vJsonValue;
42 FreeStrBuf(&Val->Name);
43 FreeStrBuf(&Val->Value);
44 DeleteHash(&Val->SubValues);
45 free(Val);
48 JsonValue *NewJsonObject(const char *Key, long keylen)
50 JsonValue *Ret;
52 Ret = (JsonValue*) malloc(sizeof(JsonValue));
53 memset(Ret, 0, sizeof(JsonValue));
54 Ret->Type = JSON_OBJECT;
55 if (Key != NULL)
56 Ret->Name = NewStrBufPlain(Key, keylen);
57 Ret->SubValues = NewHash(1, NULL);
58 return Ret;
61 JsonValue *NewJsonArray(const char *Key, long keylen)
63 JsonValue *Ret;
65 Ret = (JsonValue*) malloc(sizeof(JsonValue));
66 memset(Ret, 0, sizeof(JsonValue));
67 Ret->Type = JSON_ARRAY;
68 if (Key != NULL)
69 Ret->Name = NewStrBufPlain(Key, keylen);
70 Ret->SubValues = NewHash(1, Flathash);
71 return Ret;
75 JsonValue *NewJsonNumber(const char *Key, long keylen, long Number)
77 JsonValue *Ret;
79 Ret = (JsonValue*) malloc(sizeof(JsonValue));
80 memset(Ret, 0, sizeof(JsonValue));
81 Ret->Type = JSON_NUM;
82 if (Key != NULL)
83 Ret->Name = NewStrBufPlain(Key, keylen);
84 Ret->Value = NewStrBufPlain(NULL, 64);
85 StrBufPrintf(Ret->Value, "%ld", Number);
86 return Ret;
91 JsonValue *NewJsonBigNumber(const char *Key, long keylen, double Number)
93 JsonValue *Ret;
95 Ret = (JsonValue*) malloc(sizeof(JsonValue));
96 memset(Ret, 0, sizeof(JsonValue));
97 Ret->Type = JSON_NUM;
98 if (Key != NULL)
99 Ret->Name = NewStrBufPlain(Key, keylen);
100 Ret->Value = NewStrBufPlain(NULL, 128);
101 StrBufPrintf(Ret->Value, "%f", Number);
102 return Ret;
105 JsonValue *NewJsonString(const char *Key, long keylen, StrBuf *CopyMe)
107 JsonValue *Ret;
109 Ret = (JsonValue*) malloc(sizeof(JsonValue));
110 memset(Ret, 0, sizeof(JsonValue));
111 Ret->Type = JSON_STRING;
112 if (Key != NULL)
113 Ret->Name = NewStrBufPlain(Key, keylen);
114 Ret->Value = NewStrBufDup(CopyMe);
115 return Ret;
118 JsonValue *NewJsonPlainString(const char *Key, long keylen, const char *CopyMe, long len)
120 JsonValue *Ret;
122 Ret = (JsonValue*) malloc(sizeof(JsonValue));
123 memset(Ret, 0, sizeof(JsonValue));
124 Ret->Type = JSON_STRING;
125 if (Key != NULL)
126 Ret->Name = NewStrBufPlain(Key, keylen);
127 Ret->Value = NewStrBufPlain(CopyMe, len);
128 return Ret;
131 JsonValue *NewJsonNull(const char *Key, long keylen)
133 JsonValue *Ret;
135 Ret = (JsonValue*) malloc(sizeof(JsonValue));
136 memset(Ret, 0, sizeof(JsonValue));
137 Ret->Type = JSON_NULL;
138 if (Key != NULL)
139 Ret->Name = NewStrBufPlain(Key, keylen);
140 Ret->Value = NewStrBufPlain(HKEY("nulll"));
141 return Ret;
144 JsonValue *NewJsonBool(const char *Key, long keylen, int value)
146 JsonValue *Ret;
148 Ret = (JsonValue*) malloc(sizeof(JsonValue));
149 memset(Ret, 0, sizeof(JsonValue));
150 Ret->Type = JSON_BOOL;
151 if (Key != NULL)
152 Ret->Name = NewStrBufPlain(Key, keylen);
153 if (value)
154 Ret->Value = NewStrBufPlain(HKEY("true"));
155 else
156 Ret->Value = NewStrBufPlain(HKEY("false"));
157 return Ret;
160 void JsonArrayAppend(JsonValue *Array, JsonValue *Val)
162 long n;
163 if (Array->Type != JSON_ARRAY)
164 return; /* todo assert! */
166 n = GetCount(Array->SubValues);
167 Put(Array->SubValues, (const char*) &n, sizeof(n), Val, DeleteJSONValue);
170 void JsonObjectAppend(JsonValue *Array, JsonValue *Val)
172 if ((Array->Type != JSON_OBJECT) || (Val->Name == NULL))
173 return; /* todo assert! */
175 Put(Array->SubValues, SKEY(Val->Name), Val, DeleteJSONValue);
182 void SerializeJson(StrBuf *Target, JsonValue *Val, int FreeVal)
184 void *vValue, *vPrevious;
185 JsonValue *SubVal;
186 HashPos *It;
187 const char *Key;
188 long keylen;
191 switch (Val->Type) {
192 case JSON_STRING:
193 StrBufAppendBufPlain(Target, HKEY("\""), 0);
194 StrECMAEscAppend(Target, Val->Value, NULL);
195 StrBufAppendBufPlain(Target, HKEY("\""), 0);
196 break;
197 case JSON_NUM:
198 StrBufAppendBuf(Target, Val->Value, 0);
199 break;
200 case JSON_BOOL:
201 StrBufAppendBuf(Target, Val->Value, 0);
202 break;
203 case JSON_NULL:
204 StrBufAppendBuf(Target, Val->Value, 0);
205 break;
206 case JSON_ARRAY:
207 vPrevious = NULL;
208 StrBufAppendBufPlain(Target, HKEY("["), 0);
209 It = GetNewHashPos(Val->SubValues, 0);
210 while (GetNextHashPos(Val->SubValues,
212 &keylen, &Key,
213 &vValue)){
214 if (vPrevious != NULL)
215 StrBufAppendBufPlain(Target, HKEY(","), 0);
217 SubVal = (JsonValue*) vValue;
218 SerializeJson(Target, SubVal, 0);
219 vPrevious = vValue;
221 StrBufAppendBufPlain(Target, HKEY("]"), 0);
222 DeleteHashPos(&It);
223 break;
224 case JSON_OBJECT:
225 vPrevious = NULL;
226 StrBufAppendBufPlain(Target, HKEY("{"), 0);
227 It = GetNewHashPos(Val->SubValues, 0);
228 while (GetNextHashPos(Val->SubValues,
230 &keylen, &Key,
231 &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);
242 vPrevious = vValue;
244 StrBufAppendBufPlain(Target, HKEY("}"), 0);
245 DeleteHashPos(&It);
246 break;
248 if(FreeVal) {
249 DeleteJSONValue(Val);