Back to index

libcitadel  8.12
json.c
Go to the documentation of this file.
00001 
00023 
00024 #include "sysdep.h"
00025 #include <sys/types.h>
00026 #include <sys/stat.h>
00027 #include <unistd.h>
00028 #include <dirent.h>
00029 #include <errno.h>
00030 #include <stdio.h>
00031 #include <stdarg.h>
00032 #include <string.h>
00033 
00034 #include "libcitadel.h"
00035 
00036 
00037 #define JSON_STRING 0
00038 #define JSON_NUM 1
00039 #define JSON_NULL 2
00040 #define JSON_BOOL 3
00041 #define JSON_ARRAY 4
00042 #define JSON_OBJECT 7
00043 
00044 struct JsonValue {
00045        int Type;
00046        StrBuf *Name;
00047        StrBuf *Value;
00048        HashList *SubValues;
00049 };
00050 
00051 
00052 void DeleteJSONValue(void *vJsonValue)
00053 {
00054        JsonValue *Val = (JsonValue*) vJsonValue;
00055        FreeStrBuf(&Val->Name);
00056        FreeStrBuf(&Val->Value);
00057        DeleteHash(&Val->SubValues);
00058        free(Val);
00059 }
00060 
00061 JsonValue *NewJsonObject(const char *Key, long keylen)
00062 {
00063        JsonValue *Ret;
00064 
00065        Ret = (JsonValue*) malloc(sizeof(JsonValue));
00066        memset(Ret, 0, sizeof(JsonValue));
00067        Ret->Type = JSON_OBJECT;
00068        if (Key != NULL)
00069               Ret->Name = NewStrBufPlain(Key, keylen);
00070        Ret->SubValues = NewHash(1, NULL);
00071        return Ret;
00072 }
00073 
00074 JsonValue *NewJsonArray(const char *Key, long keylen)
00075 {
00076        JsonValue *Ret;
00077 
00078        Ret = (JsonValue*) malloc(sizeof(JsonValue));
00079        memset(Ret, 0, sizeof(JsonValue));
00080        Ret->Type = JSON_ARRAY;
00081        if (Key != NULL)
00082               Ret->Name = NewStrBufPlain(Key, keylen);
00083        Ret->SubValues = NewHash(1, Flathash);
00084        return Ret;
00085 }
00086 
00087 
00088 JsonValue *NewJsonNumber(const char *Key, long keylen, long Number)
00089 {
00090        JsonValue *Ret;
00091 
00092        Ret = (JsonValue*) malloc(sizeof(JsonValue));
00093        memset(Ret, 0, sizeof(JsonValue));
00094        Ret->Type = JSON_NUM;
00095        if (Key != NULL)
00096               Ret->Name = NewStrBufPlain(Key, keylen);
00097        Ret->Value = NewStrBufPlain(NULL, 64);
00098        StrBufPrintf(Ret->Value, "%ld", Number);
00099        return Ret;
00100 }
00101 
00102 
00103 
00104 JsonValue *NewJsonBigNumber(const char *Key, long keylen, double Number)
00105 {
00106        JsonValue *Ret;
00107 
00108        Ret = (JsonValue*) malloc(sizeof(JsonValue));
00109        memset(Ret, 0, sizeof(JsonValue));
00110        Ret->Type = JSON_NUM;
00111        if (Key != NULL)
00112               Ret->Name = NewStrBufPlain(Key, keylen);
00113        Ret->Value = NewStrBufPlain(NULL, 128);
00114        StrBufPrintf(Ret->Value, "%f", Number);
00115        return Ret;
00116 }
00117 
00118 JsonValue *NewJsonString(const char *Key, long keylen, StrBuf *CopyMe)
00119 {
00120        JsonValue *Ret;
00121 
00122        Ret = (JsonValue*) malloc(sizeof(JsonValue));
00123        memset(Ret, 0, sizeof(JsonValue));
00124        Ret->Type = JSON_STRING;
00125        if (Key != NULL)
00126               Ret->Name = NewStrBufPlain(Key, keylen);
00127        Ret->Value = NewStrBufDup(CopyMe);
00128        return Ret;
00129 }
00130 
00131 JsonValue *NewJsonPlainString(const char *Key, long keylen, const char *CopyMe, long len)
00132 {
00133        JsonValue *Ret;
00134 
00135        Ret = (JsonValue*) malloc(sizeof(JsonValue));
00136        memset(Ret, 0, sizeof(JsonValue));
00137        Ret->Type = JSON_STRING;
00138        if (Key != NULL)
00139               Ret->Name = NewStrBufPlain(Key, keylen);
00140        Ret->Value = NewStrBufPlain(CopyMe, len);
00141        return Ret;
00142 }
00143 
00144 JsonValue *NewJsonNull(const char *Key, long keylen)
00145 {
00146        JsonValue *Ret;
00147 
00148        Ret = (JsonValue*) malloc(sizeof(JsonValue));
00149        memset(Ret, 0, sizeof(JsonValue));
00150        Ret->Type = JSON_NULL;
00151        if (Key != NULL)
00152               Ret->Name = NewStrBufPlain(Key, keylen);
00153        Ret->Value = NewStrBufPlain(HKEY("nulll"));
00154        return Ret;
00155 }
00156 
00157 JsonValue *NewJsonBool(const char *Key, long keylen, int value)
00158 {
00159        JsonValue *Ret;
00160 
00161        Ret = (JsonValue*) malloc(sizeof(JsonValue));
00162        memset(Ret, 0, sizeof(JsonValue));
00163        Ret->Type = JSON_BOOL;
00164        if (Key != NULL)
00165               Ret->Name = NewStrBufPlain(Key, keylen);
00166        if (value)
00167               Ret->Value = NewStrBufPlain(HKEY("true"));
00168        else
00169               Ret->Value = NewStrBufPlain(HKEY("false"));
00170        return Ret;
00171 }
00172 
00173 void JsonArrayAppend(JsonValue *Array, JsonValue *Val)
00174 {
00175        long n;
00176        if (Array->Type != JSON_ARRAY)
00177               return; /* todo assert! */
00178 
00179        n = GetCount(Array->SubValues);
00180        Put(Array->SubValues, (const char*) &n, sizeof(n), Val, DeleteJSONValue);
00181 }
00182 
00183 void JsonObjectAppend(JsonValue *Array, JsonValue *Val)
00184 {
00185        if ((Array->Type != JSON_OBJECT) || (Val->Name == NULL))
00186               return; /* todo assert! */
00187 
00188        Put(Array->SubValues, SKEY(Val->Name), Val, DeleteJSONValue);
00189 }
00190 
00191 
00192 
00193 
00194 
00195 void SerializeJson(StrBuf *Target, JsonValue *Val, int FreeVal)
00196 {
00197        void *vValue, *vPrevious;
00198        JsonValue *SubVal;
00199        HashPos *It;
00200        const char *Key;
00201        long keylen;
00202 
00203 
00204        switch (Val->Type) {
00205        case JSON_STRING:
00206               StrBufAppendBufPlain(Target, HKEY("\""), 0);
00207               StrECMAEscAppend(Target, Val->Value, NULL);
00208               StrBufAppendBufPlain(Target, HKEY("\""), 0);
00209               break;
00210        case JSON_NUM:
00211               StrBufAppendBuf(Target, Val->Value, 0);
00212               break;
00213        case JSON_BOOL:
00214               StrBufAppendBuf(Target, Val->Value, 0);
00215               break;
00216        case JSON_NULL:
00217               StrBufAppendBuf(Target, Val->Value, 0);
00218               break;
00219        case JSON_ARRAY:
00220               vPrevious = NULL;
00221               StrBufAppendBufPlain(Target, HKEY("["), 0);
00222               It = GetNewHashPos(Val->SubValues, 0);
00223               while (GetNextHashPos(Val->SubValues, 
00224                                   It,
00225                                   &keylen, &Key, 
00226                                   &vValue)){
00227                      if (vPrevious != NULL) 
00228                             StrBufAppendBufPlain(Target, HKEY(","), 0);
00229 
00230                      SubVal = (JsonValue*) vValue;
00231                      SerializeJson(Target, SubVal, 0);
00232                      vPrevious = vValue;
00233               }
00234               StrBufAppendBufPlain(Target, HKEY("]"), 0);
00235               DeleteHashPos(&It);
00236               break;
00237        case JSON_OBJECT:
00238               vPrevious = NULL;
00239               StrBufAppendBufPlain(Target, HKEY("{"), 0);
00240               It = GetNewHashPos(Val->SubValues, 0);
00241               while (GetNextHashPos(Val->SubValues, 
00242                                   It,
00243                                   &keylen, &Key, 
00244                                   &vValue)){
00245                      SubVal = (JsonValue*) vValue;
00246 
00247                      if (vPrevious != NULL) {
00248                             StrBufAppendBufPlain(Target, HKEY(","), 0);
00249                      }
00250                      StrBufAppendBufPlain(Target, HKEY("\""), 0);
00251                      StrBufAppendBuf(Target, SubVal->Name, 0);
00252                      StrBufAppendBufPlain(Target, HKEY("\":"), 0);
00253 
00254                      SerializeJson(Target, SubVal, 0);
00255                      vPrevious = vValue;
00256               }
00257               StrBufAppendBufPlain(Target, HKEY("}"), 0);
00258               DeleteHashPos(&It);
00259               break;
00260        }
00261        if(FreeVal) {
00262               DeleteJSONValue(Val);
00263        }
00264 }
00265 
00266