Branch data Line data Source code
1 : : /**
2 : : * \defgroup Subst Variable substitution type stuff
3 : : * \ingroup CitadelConfig
4 : : */
5 : :
6 : : /*@{*/
7 : :
8 : : #include "sysdep.h"
9 : : #include <sys/types.h>
10 : : #include <sys/stat.h>
11 : : #include <unistd.h>
12 : : #include <dirent.h>
13 : : #include <errno.h>
14 : : #include <stdio.h>
15 : : #include <stdarg.h>
16 : : #include <string.h>
17 : :
18 : : #include "libcitadel.h"
19 : :
20 : :
21 : : #define JSON_STRING 0
22 : : #define JSON_NUM 1
23 : : #define JSON_NULL 2
24 : : #define JSON_BOOL 3
25 : : #define JSON_ARRAY 4
26 : : #define JSON_OBJECT 7
27 : :
28 : : struct JsonValue {
29 : : int Type;
30 : : StrBuf *Name;
31 : : StrBuf *Value;
32 : : HashList *SubValues;
33 : : };
34 : :
35 : :
36 : 203 : void DeleteJSONValue(void *vJsonValue)
37 : : {
38 : 203 : JsonValue *Val = (JsonValue*) vJsonValue;
39 : 203 : FreeStrBuf(&Val->Name);
40 : 203 : FreeStrBuf(&Val->Value);
41 : 203 : DeleteHash(&Val->SubValues);
42 : 203 : free(Val);
43 : 203 : }
44 : :
45 : 38 : JsonValue *NewJsonObject(const char *Key, long keylen)
46 : : {
47 : : JsonValue *Ret;
48 : :
49 : 38 : Ret = (JsonValue*) malloc(sizeof(JsonValue));
50 : 38 : memset(Ret, 0, sizeof(JsonValue));
51 : 38 : Ret->Type = JSON_OBJECT;
52 [ + + ]: 38 : if (Key != NULL)
53 : 8 : Ret->Name = NewStrBufPlain(Key, keylen);
54 : 38 : Ret->SubValues = NewHash(1, NULL);
55 : 38 : return Ret;
56 : : }
57 : :
58 : 38 : JsonValue *NewJsonArray(const char *Key, long keylen)
59 : : {
60 : : JsonValue *Ret;
61 : :
62 : 38 : Ret = (JsonValue*) malloc(sizeof(JsonValue));
63 : 38 : memset(Ret, 0, sizeof(JsonValue));
64 : 38 : Ret->Type = JSON_ARRAY;
65 [ + + ]: 38 : if (Key != NULL)
66 : 25 : Ret->Name = NewStrBufPlain(Key, keylen);
67 : 38 : Ret->SubValues = NewHash(1, Flathash);
68 : 38 : return Ret;
69 : : }
70 : :
71 : :
72 : 38 : JsonValue *NewJsonNumber(const char *Key, long keylen, long Number)
73 : : {
74 : : JsonValue *Ret;
75 : :
76 : 38 : Ret = (JsonValue*) malloc(sizeof(JsonValue));
77 : 38 : memset(Ret, 0, sizeof(JsonValue));
78 : 38 : Ret->Type = JSON_NUM;
79 [ + - ]: 38 : if (Key != NULL)
80 : 38 : Ret->Name = NewStrBufPlain(Key, keylen);
81 : 38 : Ret->Value = NewStrBufPlain(NULL, 64);
82 : 38 : StrBufPrintf(Ret->Value, "%ld", Number);
83 : 38 : return Ret;
84 : : }
85 : :
86 : :
87 : :
88 : 0 : JsonValue *NewJsonBigNumber(const char *Key, long keylen, double Number)
89 : : {
90 : : JsonValue *Ret;
91 : :
92 : 0 : Ret = (JsonValue*) malloc(sizeof(JsonValue));
93 : 0 : memset(Ret, 0, sizeof(JsonValue));
94 : 0 : Ret->Type = JSON_NUM;
95 [ # # ]: 0 : if (Key != NULL)
96 : 0 : Ret->Name = NewStrBufPlain(Key, keylen);
97 : 0 : Ret->Value = NewStrBufPlain(NULL, 128);
98 : 0 : StrBufPrintf(Ret->Value, "%f", Number);
99 : 0 : return Ret;
100 : : }
101 : :
102 : 42 : JsonValue *NewJsonString(const char *Key, long keylen, StrBuf *CopyMe)
103 : : {
104 : : JsonValue *Ret;
105 : :
106 : 42 : Ret = (JsonValue*) malloc(sizeof(JsonValue));
107 : 42 : memset(Ret, 0, sizeof(JsonValue));
108 : 42 : Ret->Type = JSON_STRING;
109 [ + - ]: 42 : if (Key != NULL)
110 : 42 : Ret->Name = NewStrBufPlain(Key, keylen);
111 : 42 : Ret->Value = NewStrBufDup(CopyMe);
112 : 42 : return Ret;
113 : : }
114 : :
115 : 47 : JsonValue *NewJsonPlainString(const char *Key, long keylen, const char *CopyMe, long len)
116 : : {
117 : : JsonValue *Ret;
118 : :
119 : 47 : Ret = (JsonValue*) malloc(sizeof(JsonValue));
120 : 47 : memset(Ret, 0, sizeof(JsonValue));
121 : 47 : Ret->Type = JSON_STRING;
122 [ + + ]: 47 : if (Key != NULL)
123 : 42 : Ret->Name = NewStrBufPlain(Key, keylen);
124 : 47 : Ret->Value = NewStrBufPlain(CopyMe, len);
125 : 47 : return Ret;
126 : : }
127 : :
128 : 0 : JsonValue *NewJsonNull(const char *Key, long keylen)
129 : : {
130 : : JsonValue *Ret;
131 : :
132 : 0 : Ret = (JsonValue*) malloc(sizeof(JsonValue));
133 : 0 : memset(Ret, 0, sizeof(JsonValue));
134 : 0 : Ret->Type = JSON_NULL;
135 [ # # ]: 0 : if (Key != NULL)
136 : 0 : Ret->Name = NewStrBufPlain(Key, keylen);
137 : 0 : Ret->Value = NewStrBufPlain(HKEY("nulll"));
138 : 0 : return Ret;
139 : : }
140 : :
141 : 0 : JsonValue *NewJsonBool(const char *Key, long keylen, int value)
142 : : {
143 : : JsonValue *Ret;
144 : :
145 : 0 : Ret = (JsonValue*) malloc(sizeof(JsonValue));
146 : 0 : memset(Ret, 0, sizeof(JsonValue));
147 : 0 : Ret->Type = JSON_BOOL;
148 [ # # ]: 0 : if (Key != NULL)
149 : 0 : Ret->Name = NewStrBufPlain(Key, keylen);
150 [ # # ]: 0 : if (value)
151 : 0 : Ret->Value = NewStrBufPlain(HKEY("true"));
152 : : else
153 : 0 : Ret->Value = NewStrBufPlain(HKEY("false"));
154 : 0 : return Ret;
155 : : }
156 : :
157 : 43 : void JsonArrayAppend(JsonValue *Array, JsonValue *Val)
158 : : {
159 : : long n;
160 [ - + ]: 43 : if (Array->Type != JSON_ARRAY)
161 : 0 : return; /* todo assert! */
162 : :
163 : 43 : n = GetCount(Array->SubValues);
164 : 43 : Put(Array->SubValues, (const char*) &n, sizeof(n), Val, DeleteJSONValue);
165 : : }
166 : :
167 : 147 : void JsonObjectAppend(JsonValue *Array, JsonValue *Val)
168 : : {
169 [ + - ][ - + ]: 147 : if ((Array->Type != JSON_OBJECT) || (Val->Name == NULL))
170 : 0 : return; /* todo assert! */
171 : :
172 : 147 : Put(Array->SubValues, SKEY(Val->Name), Val, DeleteJSONValue);
173 : : }
174 : :
175 : :
176 : :
177 : :
178 : :
179 : 203 : void SerializeJson(StrBuf *Target, JsonValue *Val, int FreeVal)
180 : : {
181 : : void *vValue, *vPrevious;
182 : : JsonValue *SubVal;
183 : : HashPos *It;
184 : : const char *Key;
185 : : long keylen;
186 : :
187 : :
188 [ + + - - + : 203 : switch (Val->Type) {
+ - ]
189 : : case JSON_STRING:
190 : 89 : StrBufAppendBufPlain(Target, HKEY("\""), 0);
191 : 89 : StrECMAEscAppend(Target, Val->Value, NULL);
192 : 89 : StrBufAppendBufPlain(Target, HKEY("\""), 0);
193 : 89 : break;
194 : : case JSON_NUM:
195 : 38 : StrBufAppendBuf(Target, Val->Value, 0);
196 : 38 : break;
197 : : case JSON_BOOL:
198 : 0 : StrBufAppendBuf(Target, Val->Value, 0);
199 : 0 : break;
200 : : case JSON_NULL:
201 : 0 : StrBufAppendBuf(Target, Val->Value, 0);
202 : 0 : break;
203 : : case JSON_ARRAY:
204 : 38 : vPrevious = NULL;
205 : 38 : StrBufAppendBufPlain(Target, HKEY("["), 0);
206 : 38 : It = GetNewHashPos(Val->SubValues, 0);
207 [ + + ]: 81 : while (GetNextHashPos(Val->SubValues,
208 : : It,
209 : : &keylen, &Key,
210 : : &vValue)){
211 [ + + ]: 43 : if (vPrevious != NULL)
212 : 22 : StrBufAppendBufPlain(Target, HKEY(","), 0);
213 : :
214 : 43 : SubVal = (JsonValue*) vValue;
215 : 43 : SerializeJson(Target, SubVal, 0);
216 : 43 : vPrevious = vValue;
217 : : }
218 : 38 : StrBufAppendBufPlain(Target, HKEY("]"), 0);
219 : 38 : DeleteHashPos(&It);
220 : 38 : break;
221 : : case JSON_OBJECT:
222 : 38 : vPrevious = NULL;
223 : 38 : StrBufAppendBufPlain(Target, HKEY("{"), 0);
224 : 38 : It = GetNewHashPos(Val->SubValues, 0);
225 [ + + ]: 185 : while (GetNextHashPos(Val->SubValues,
226 : : It,
227 : : &keylen, &Key,
228 : : &vValue)){
229 : 147 : SubVal = (JsonValue*) vValue;
230 : :
231 [ + + ]: 147 : if (vPrevious != NULL) {
232 : 109 : StrBufAppendBufPlain(Target, HKEY(","), 0);
233 : : }
234 : 147 : StrBufAppendBufPlain(Target, HKEY("\""), 0);
235 : 147 : StrBufAppendBuf(Target, SubVal->Name, 0);
236 : 147 : StrBufAppendBufPlain(Target, HKEY("\":"), 0);
237 : :
238 : 147 : SerializeJson(Target, SubVal, 0);
239 : 147 : vPrevious = vValue;
240 : : }
241 : 38 : StrBufAppendBufPlain(Target, HKEY("}"), 0);
242 : 38 : DeleteHashPos(&It);
243 : : break;
244 : : }
245 [ + + ]: 203 : if(FreeVal) {
246 : 13 : DeleteJSONValue(Val);
247 : : }
248 : 203 : }
249 : :
250 : :
|