From f0e6b0183e4739e5fe35fbc8bd116c7b219c0ab7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Wilfried=20G=C3=B6esgens?= Date: Sun, 25 Jan 2009 16:03:49 +0000 Subject: [PATCH] + add C-to-Json serializer + add Wildfire implementation --- libcitadel/Makefile.in | 6 +- libcitadel/configure.in | 11 + libcitadel/debian/rules | 2 + libcitadel/lib/json.c | 249 +++++++++++++++++ libcitadel/lib/libcitadel.h | 77 ++++++ libcitadel/lib/wildfire.c | 513 ++++++++++++++++++++++++++++++++++++ 6 files changed, 857 insertions(+), 1 deletion(-) create mode 100644 libcitadel/lib/json.c create mode 100644 libcitadel/lib/wildfire.c diff --git a/libcitadel/Makefile.in b/libcitadel/Makefile.in index 0d80c40e0..a0730d2e7 100755 --- a/libcitadel/Makefile.in +++ b/libcitadel/Makefile.in @@ -57,7 +57,7 @@ install-pkgconfigDATA: $(pkgconfig_DATA) clean: - cd lib && rm -f $(LIBRARY) *.o *.lo && rm -rf .libs _libs + cd lib && rm -f $(LIBRARY) *.o *.lo && rm -rf .libs _libs xdgmime/*.o xdgmime/*.lo xdgmime/.libs rm -rf .libs libcitadel.la clobber: clean @@ -110,6 +110,8 @@ LIB_OBJS = lib/libcitadel.lo \ lib/hash.lo \ lib/lookup3.lo \ lib/stringbuf.lo \ + lib/json.lo \ + lib/wildfire.lo \ lib/xdgmime/xdgmime.lo \ lib/xdgmime/xdgmimeglob.lo \ lib/xdgmime/xdgmimeint.lo \ @@ -129,6 +131,8 @@ lib/vcard.lo: lib/vcard.c lib/libcitadel.h lib/vnote.lo: lib/vnote.c lib/libcitadel.h lib/lookup3.lo: lib/lookup3.c lib/libcitadel.h lib/hash.lo: lib/hash.c lib/libcitadel.h +lib/json.lo: lib/json.c lib/libcitadel.h +lib/wildfire.lo: lib/wildfire.c lib/libcitadel.h lib/xdgmime/xdgmime.lo: lib/xdgmime/xdgmime.c lib/xdgmime/xdgmimeglob.lo: lib/xdgmime/xdgmimeglob.c lib/xdgmime/xdgmimeint.lo: lib/xdgmime/xdgmimeint.c diff --git a/libcitadel/configure.in b/libcitadel/configure.in index 8d8e27490..432b4de3a 100755 --- a/libcitadel/configure.in +++ b/libcitadel/configure.in @@ -131,6 +131,17 @@ else AC_MSG_RESULT(libcitadel will be built without character set conversion.) fi +dnl disable backtrace if we don't want it. +AC_ARG_WITH(backtrace, + [ --with-backtrace enable backtrace dumps in the syslog], + [ if test "x$withval" != "xno" ; then + CFLAGS="$CFLAGS -rdynamic " + LDFLAGS="$LDFLAGS -rdynamic " + AC_CHECK_FUNCS(backtrace) + fi + ] +) + AC_ARG_WITH(with_zlib, [ --with-zlib use zlib compression if present]) dnl Checks for the zlib compression library. diff --git a/libcitadel/debian/rules b/libcitadel/debian/rules index 4b88c184f..f2977731a 100755 --- a/libcitadel/debian/rules +++ b/libcitadel/debian/rules @@ -13,6 +13,7 @@ CFLAGS = -Wall -g LDFALGS = ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS))) CFLAGS += -O0 -ggdb -rdynamic -MD -MP -D DEBUG -D VALGRIND + EXTRA_ARGS = --with-backtrace else CFLAGS += -O2 endif @@ -28,6 +29,7 @@ build-stamp: # ./configure CFLAGS="$(CFLAGS)"; LDFLAGS="$(LDFLAGS)"; ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) \ + $(EXTRA_ARGS) \ --prefix=/usr # Build libcitadel diff --git a/libcitadel/lib/json.c b/libcitadel/lib/json.c new file mode 100644 index 000000000..044be9cdf --- /dev/null +++ b/libcitadel/lib/json.c @@ -0,0 +1,249 @@ +/* + * $Id: wildfire.c 6962 2009-01-18 19:33:45Z dothebart $ + */ +/** + * \defgroup Subst Variable substitution type stuff + * \ingroup CitadelConfig + */ + +/*@{*/ + +#include "sysdep.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libcitadel.h" + + +#define JSON_STRING 0 +#define JSON_NUM 1 +#define JSON_NULL 2 +#define JSON_BOOL 3 +#define JSON_ARRAY 4 +#define JSON_OBJECT 7 + +struct JsonValue { + int Type; + StrBuf *Name; + StrBuf *Value; + HashList *SubValues; +}; + + +void DeleteJSONValue(void *vJsonValue) +{ + JsonValue *Val = (JsonValue*) vJsonValue; + FreeStrBuf(&Val->Name); + FreeStrBuf(&Val->Value); + DeleteHash(&Val->SubValues); + free(Val); +} + +JsonValue *NewJsonObject(const char *Key, long keylen) +{ + JsonValue *Ret; + + Ret = (JsonValue*) malloc(sizeof(JsonValue)); + memset(Ret, 0, sizeof(JsonValue)); + Ret->Type = JSON_OBJECT; + if (Key != NULL) + Ret->Name = NewStrBufPlain(Key, keylen); + Ret->SubValues = NewHash(1, NULL); + return Ret; +} + +JsonValue *NewJsonArray(const char *Key, long keylen) +{ + JsonValue *Ret; + + Ret = (JsonValue*) malloc(sizeof(JsonValue)); + memset(Ret, 0, sizeof(JsonValue)); + Ret->Type = JSON_ARRAY; + if (Key != NULL) + Ret->Name = NewStrBufPlain(Key, keylen); + Ret->SubValues = NewHash(1, Flathash); + return Ret; +} + + +JsonValue *NewJsonNumber(const char *Key, long keylen, long Number) +{ + JsonValue *Ret; + + Ret = (JsonValue*) malloc(sizeof(JsonValue)); + memset(Ret, 0, sizeof(JsonValue)); + Ret->Type = JSON_NUM; + if (Key != NULL) + Ret->Name = NewStrBufPlain(Key, keylen); + Ret->Value = NewStrBufPlain(NULL, 64); + StrBufPrintf(Ret->Value, "%ld", Number); + return Ret; +} + + + +JsonValue *NewJsonBigNumber(const char *Key, long keylen, double Number) +{ + JsonValue *Ret; + + Ret = (JsonValue*) malloc(sizeof(JsonValue)); + memset(Ret, 0, sizeof(JsonValue)); + Ret->Type = JSON_NUM; + if (Key != NULL) + Ret->Name = NewStrBufPlain(Key, keylen); + Ret->Value = NewStrBufPlain(NULL, 128); + StrBufPrintf(Ret->Value, "%f", Number); + return Ret; +} + +JsonValue *NewJsonString(const char *Key, long keylen, StrBuf *CopyMe) +{ + JsonValue *Ret; + + Ret = (JsonValue*) malloc(sizeof(JsonValue)); + memset(Ret, 0, sizeof(JsonValue)); + Ret->Type = JSON_STRING; + if (Key != NULL) + Ret->Name = NewStrBufPlain(Key, keylen); + Ret->Value = NewStrBufDup(CopyMe); + return Ret; +} + +JsonValue *NewJsonPlainString(const char *Key, long keylen, const char *CopyMe, long len) +{ + JsonValue *Ret; + + Ret = (JsonValue*) malloc(sizeof(JsonValue)); + memset(Ret, 0, sizeof(JsonValue)); + Ret->Type = JSON_STRING; + if (Key != NULL) + Ret->Name = NewStrBufPlain(Key, keylen); + Ret->Value = NewStrBufPlain(CopyMe, len); + return Ret; +} + +JsonValue *NewJsonNull(const char *Key, long keylen) +{ + JsonValue *Ret; + + Ret = (JsonValue*) malloc(sizeof(JsonValue)); + memset(Ret, 0, sizeof(JsonValue)); + Ret->Type = JSON_NULL; + if (Key != NULL) + Ret->Name = NewStrBufPlain(Key, keylen); + Ret->Value = NewStrBufPlain(HKEY("nulll")); + return Ret; +} + +JsonValue *NewJsonBool(const char *Key, long keylen, int value) +{ + JsonValue *Ret; + + Ret = (JsonValue*) malloc(sizeof(JsonValue)); + memset(Ret, 0, sizeof(JsonValue)); + Ret->Type = JSON_BOOL; + if (Key != NULL) + Ret->Name = NewStrBufPlain(Key, keylen); + if (value) + Ret->Value = NewStrBufPlain(HKEY("true")); + else + Ret->Value = NewStrBufPlain(HKEY("false")); + return Ret; +} + +void JsonArrayAppend(JsonValue *Array, JsonValue *Val) +{ + long n; + if (Array->Type != JSON_ARRAY) + return; /* todo assert! */ + + n = GetCount(Array->SubValues); + Put(Array->SubValues, (const char*) &n, sizeof(n), Val, DeleteJSONValue); +} + +void JsonObjectAppend(JsonValue *Array, JsonValue *Val) +{ + if ((Array->Type != JSON_OBJECT) || (Val->Name == NULL)) + return; /* todo assert! */ + + Put(Array->SubValues, SKEY(Val->Name), Val, DeleteJSONValue); +} + + + + + +void SerializeJson(StrBuf *Target, JsonValue *Val) +{ + void *vValue, *vPrevious; + JsonValue *SubVal; + HashPos *It; + const char *Key; + long keylen; + + + switch (Val->Type) { + case JSON_STRING: + StrBufAppendBufPlain(Target, HKEY("\""), 0); + StrECMAEscAppend(Target, Val->Value, NULL); + StrBufAppendBufPlain(Target, HKEY("\""), 0); + break; + case JSON_NUM: + StrBufAppendBuf(Target, Val->Value, 0); + break; + case JSON_BOOL: + StrBufAppendBuf(Target, Val->Value, 0); + break; + case JSON_NULL: + StrBufAppendBuf(Target, Val->Value, 0); + break; + case JSON_ARRAY: + vPrevious = NULL; + StrBufAppendBufPlain(Target, HKEY("["), 0); + It = GetNewHashPos(Val->SubValues, 0); + while (GetNextHashPos(Val->SubValues, + It, + &keylen, &Key, + &vValue)){ + if (vPrevious != NULL) + StrBufAppendBufPlain(Target, HKEY(","), 0); + + SubVal = (JsonValue*) vValue; + SerializeJson(Target, SubVal); + vPrevious = vValue; + } + StrBufAppendBufPlain(Target, HKEY("]"), 0); + break; + case JSON_OBJECT: + vPrevious = NULL; + StrBufAppendBufPlain(Target, HKEY("{"), 0); + It = GetNewHashPos(Val->SubValues, 0); + while (GetNextHashPos(Val->SubValues, + It, + &keylen, &Key, + &vValue)){ + SubVal = (JsonValue*) vValue; + + if (vPrevious != NULL) { + StrBufAppendBufPlain(Target, HKEY(","), 0); + } + StrBufAppendBufPlain(Target, HKEY("\""), 0); + StrBufAppendBuf(Target, SubVal->Name, 0); + StrBufAppendBufPlain(Target, HKEY("\":"), 0); + + SerializeJson(Target, SubVal); + vPrevious = vValue; + } + StrBufAppendBufPlain(Target, HKEY("}"), 0); + break; + } + +} + + diff --git a/libcitadel/lib/libcitadel.h b/libcitadel/lib/libcitadel.h index 78b3e68ea..a20bf1a1d 100644 --- a/libcitadel/lib/libcitadel.h +++ b/libcitadel/lib/libcitadel.h @@ -454,4 +454,81 @@ char *vnote_serialize(struct vnote *v); void vnote_serialize_output_field(char *append_to, char *field, char *label); + + +/* + * Create JSON style structures in C plus serialize them to one string + */ + +typedef struct JsonValue JsonValue; + + +void DeleteJSONValue(void *vJsonValue); + +JsonValue *NewJsonObject(const char *Key, long keylen); + +JsonValue *NewJsonArray(const char *Key, long keylen); + +JsonValue *NewJsonNumber(const char *Key, long keylen, long Number); + +JsonValue *NewJsonBigNumber(const char *Key, long keylen, double Number); + +JsonValue *NewJsonString(const char *Key, long keylen, StrBuf *CopyMe); + +JsonValue *NewJsonPlainString(const char *Key, long keylen, const char *CopyMe, long len); + +JsonValue *NewJsonNull(const char *Key, long keylen); + +JsonValue *NewJsonBool(const char *Key, long keylen, int value); + +void JsonArrayAppend(JsonValue *Array, JsonValue *Val); + +void JsonObjectAppend(JsonValue *Array, JsonValue *Val); + +void SerializeJson(StrBuf *Target, JsonValue *Val); + + + +/* + * Citadels Wildfire implementation, see + * http://www.firephp.org/Wiki/Reference/Protocol + * and http://wildfirehq.org/ for details + */ +typedef void (*AddHeaderFunc)(const char *HdrName, const char *HdrValue); + +typedef enum _WF_MessageType { + eLOG, + eINFO, + eWARN, + eERROR, + eTRACE, + eEXCEPTION +} WF_MessageType; + +JsonValue *WildFireException(StrBuf *Message, + const char *Filename, long FileLen, + long LineNo, + int StackOffset); + +void WildFireAddArray(JsonValue *ReportBase, JsonValue *Array, WF_MessageType Type); + +JsonValue *WildFireMessagePlain(const char *Filename, long fnlen, + long LineNo, + const char *Message, long len, + WF_MessageType Type); + +JsonValue *WildFireMessage(const char *Filename, long fnlen, + long lineno, + StrBuf *Msg, + WF_MessageType Type); + +void WildFireInitBacktrace(const char *argvNull, int AddBaseFrameSkip); + +void WildFireSerializePayload(StrBuf *JsonBuffer, StrBuf *OutBuf, int *MsgCount, AddHeaderFunc AddHdr); + +#define WF_MAJOR "1" +#define WF_STRUCTINDEX "1" +#define WF_SUB "1" + + #endif // LIBCITADEL_H diff --git a/libcitadel/lib/wildfire.c b/libcitadel/lib/wildfire.c new file mode 100644 index 000000000..9fe53faa2 --- /dev/null +++ b/libcitadel/lib/wildfire.c @@ -0,0 +1,513 @@ +/* + * $Id: wildfire.c 6962 2009-01-18 19:33:45Z dothebart $ + */ + +/*@{*/ + +#include "sysdep.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#if HAVE_BACKTRACE +#include +#endif + +#include "libcitadel.h" + + + +ConstStr WF_MsgStrs[] = { + {HKEY("INFO")}, + {HKEY("WARN")}, + {HKEY("ERROR")}, + {HKEY("LOG")}, + {HKEY("TRACE")}, + {HKEY("EXCEPTION")} +}; + +static JsonValue *WFInfo(const char *Filename, long fnlen, + long LineNo, + WF_MessageType Type) +{ + JsonValue *Val; + + Val = NewJsonObject(NULL, 0); + JsonObjectAppend(Val, + NewJsonPlainString(HKEY("Type"), + WF_MsgStrs[Type].Key, + WF_MsgStrs[Type].len)); + JsonObjectAppend(Val, + NewJsonPlainString(HKEY("File"), + Filename, fnlen)); + JsonObjectAppend(Val, + NewJsonNumber(HKEY("Line"), LineNo)); + return Val; +} + + +JsonValue *WildFireMessage(const char *Filename, long fnlen, + long LineNo, + StrBuf *Msg, + WF_MessageType Type) +{ + JsonValue *Ret; + + Ret = NewJsonArray(NULL, 0); + JsonArrayAppend(Ret, WFInfo(Filename, fnlen, + LineNo, Type)); + + JsonArrayAppend(Ret, + NewJsonString(NULL, 0, Msg)); + return Ret; +} + +JsonValue *WildFireMessagePlain(const char *Filename, long fnlen, + long LineNo, + const char *Message, long len, + WF_MessageType Type) +{ + JsonValue *Val; + Val = NewJsonArray(NULL, 0); + + JsonArrayAppend(Val, WFInfo(Filename, fnlen, + LineNo, Type)); + JsonArrayAppend(Val, + NewJsonPlainString(NULL, 0, Message, len)); + return Val; +} + +void WildFireAddArray(JsonValue *ReportBase, JsonValue *Array, WF_MessageType Type) +{ + JsonValue *Val; + Val = NewJsonArray(NULL, 0); + JsonArrayAppend(Val, + NewJsonPlainString(NULL, 0, + WF_MsgStrs[Type].Key, + WF_MsgStrs[Type].len)); + + JsonArrayAppend(Val, Array); +} + +int addr2line_write_pipe[2]; +int addr2line_read_pipe[2]; +pid_t addr2line_pid; + +#ifdef HAVE_BACKTRACE +/* + * Start up the addr2line daemon so we can decode function pointers + */ +static void start_addr2line_daemon(const char *binary) +{ + struct stat filestats; + int i; + const char *addr2line = "/usr/bin/addr2line"; + const char minuse[] = "-e"; + + printf("Starting addr2line daemon for decoding of backtraces\n"); + + if ((stat(addr2line, &filestats)==-1) || + (filestats.st_size==0)){ + printf("didn't find addr2line daemon in %s: %s\n", addr2line, strerror(errno)); + abort(); + } + if (pipe(addr2line_write_pipe) != 0) { + printf("Unable to create pipe for addr2line daemon: %s\n", strerror(errno)); + abort(); + } + if (pipe(addr2line_read_pipe) != 0) { + printf("Unable to create pipe for addr2line daemon: %s\n", strerror(errno)); + abort(); + } + + addr2line_pid = fork(); + if (addr2line_pid < 0) { + printf("Unable to fork addr2line daemon: %s\n", strerror(errno)); + abort(); + } + if (addr2line_pid == 0) { + dup2(addr2line_write_pipe[0], 0); + dup2(addr2line_read_pipe[1], 1); + for (i=2; i<256; ++i) close(i); + execl(addr2line, addr2line, minuse, binary, NULL); + printf("Unable to exec addr2line daemon: %s\n", strerror(errno)); + abort(); + exit(errno); + } +} + +static int addr2lineBacktrace(StrBuf *Function, + StrBuf *FileName, + StrBuf *Pointer, + StrBuf *Buf, + unsigned int *FunctionLine) + +{ + const char *err; + const char *pch, *pche; + + write(addr2line_write_pipe[1], SKEY(Pointer)); + if (StrBufTCP_read_line(Buf, &addr2line_read_pipe[0], 0, &err) <= 0) + { + StrBufAppendBufPlain(Buf, err, -1, 0); + return 0; + } + pch = ChrPtr(Buf); + pche = strchr(pch, ':'); + FlushStrBuf(FileName); + StrBufAppendBufPlain(FileName, pch, pche - pch, 0); + pche++; + *FunctionLine = atoi(pche); + + return 1; +} + +static int ParseBacktrace(char *Line, + StrBuf *Function, + StrBuf *FileName, + unsigned int *FunctionLine) +{ + char *pch, *pche; + + pch = Line; + pche = strchr(pch, '('); + if (pche == NULL) return 0; + StrBufAppendBufPlain(FileName, pch, pche - pch, 0); + pch = pche + 1; + pche = strchr(pch, '+'); + if (pche == NULL) return 0; + StrBufAppendBufPlain(Function, pch, pche - pch, 0); + pch = pche + 1; + pche = strchr(pch, ')'); + if (pche == NULL) return 0; + *pche = '\0'; + sscanf(pch, "%x", FunctionLine); + StrBufAppendBufPlain(Function, pche + 1, -1, 0); + return 1; +} +#endif +long BaseFrames = 0; +StrBuf *FullBinaryName = NULL; + +void WildFireInitBacktrace(const char *argvNull, int AddBaseFrameSkip) +{ + +#ifdef HAVE_BACKTRACE + void *stack_frames[100]; + size_t size; + long i; + char **strings; + StrBuf *FileName; + StrBuf *Function; + StrBuf *Pointer; + StrBuf *Buf; + unsigned int FunctionLine; + struct stat filestats; + + FileName = NewStrBuf(); + Function = NewStrBuf(); + Pointer = NewStrBuf(); + Buf = NewStrBuf(); + + BaseFrames = size = backtrace(stack_frames, sizeof(stack_frames) / sizeof(void*)); + BaseFrames --; + BaseFrames += AddBaseFrameSkip; + strings = backtrace_symbols(stack_frames, size); + for (i = 0; i < size; i++) { + if (strings != NULL){ + ParseBacktrace(strings[i], Function, + FileName, + &FunctionLine); + FullBinaryName = NewStrBufDup(FileName); + size = i; + } + else { + char path[256]; + getcwd(path, sizeof(path)); + FullBinaryName = NewStrBufPlain(path, -1); + StrBufAppendBufPlain(FullBinaryName, HKEY("/"), 0); + StrBufAppendBufPlain(FullBinaryName, argvNull, -1, 0); + i = size; + } + } + if ((stat(ChrPtr(FullBinaryName), &filestats)==-1) || + (filestats.st_size==0)){ + FlushStrBuf(FullBinaryName); + StrBufAppendBufPlain(FullBinaryName, argvNull, -1, 0); + if ((stat(ChrPtr(FullBinaryName), &filestats)==-1) || + (filestats.st_size==0)){ + FlushStrBuf(FullBinaryName); + fprintf(stderr, "unable to open my binary for addr2line checking, verbose backtraces won't work.\n"); + } + } + free(strings); + FreeStrBuf(&FileName); + FreeStrBuf(&Function); + FreeStrBuf(&Pointer); + FreeStrBuf(&Buf); + if (StrLength(FullBinaryName) > 0) + start_addr2line_daemon(ChrPtr(FullBinaryName)); +#endif + + +} + + +JsonValue *WildFireException(StrBuf *Message, + const char *Filename, long FileLen, + long LineNo, + int StackOffset) +{ + JsonValue *ExcClass; + JsonValue *Val; + Val = NewJsonArray(NULL, 0); + + JsonArrayAppend(Val, WFInfo(Filename, FileLen, + LineNo, eEXCEPTION)); + + ExcClass = NewJsonObject(WF_MsgStrs[eTRACE].Key, + WF_MsgStrs[eTRACE].len); + + JsonArrayAppend(Val, ExcClass); + JsonObjectAppend(ExcClass, + NewJsonPlainString(HKEY("Class"), + HKEY("Exception"))); + JsonObjectAppend(ExcClass, + NewJsonString(HKEY("Message"), Message)); + JsonObjectAppend(ExcClass, + NewJsonPlainString(HKEY("File"), + Filename, FileLen)); +/* + JsonObjectAppend(ExcClass, + NewJsonPlainString(HKEY("Type"), + HKEY("throw"))); +*/ + JsonObjectAppend(ExcClass, + NewJsonNumber(HKEY("Line"), LineNo)); + +#ifdef HAVE_BACKTRACE + { + void *stack_frames[100]; + size_t size; + long i; + char **strings; + JsonValue *Trace; + JsonValue *Frame; + StrBuf *FileName; + StrBuf *Function; + StrBuf *Pointer; + StrBuf *Buf; + unsigned int FunctionLine; + + Trace = NewJsonArray(HKEY("Trace")); + JsonObjectAppend(ExcClass, Trace); + FileName = NewStrBuf(); + Function = NewStrBuf(); + Pointer = NewStrBuf(); + Buf = NewStrBuf(); + + size = backtrace(stack_frames, sizeof(stack_frames) / sizeof(void*)); + strings = backtrace_symbols(stack_frames, size); + for (i = StackOffset + 1; i < size; i++) { + if (strings != NULL){ + ParseBacktrace(strings[i], Function, + FileName, + &FunctionLine); + + } + StrBufPrintf(Pointer, "%p\n", stack_frames[i]); + + addr2lineBacktrace(Function, + FileName, + Pointer, + Buf, + &FunctionLine); + + Frame = NewJsonObject(NULL, 0); + JsonArrayAppend(Trace, Frame); + JsonObjectAppend(Frame, + NewJsonString(HKEY("function"), Function)); + JsonObjectAppend(Frame, + NewJsonString(HKEY("file"), FileName)); + JsonObjectAppend(Frame, + NewJsonNumber(HKEY("line"), FunctionLine)); + JsonObjectAppend(Frame, + NewJsonArray(HKEY("args")));/* not supportet... */ + + FunctionLine = 0; + FlushStrBuf(FileName); + FlushStrBuf(Function); + FlushStrBuf(Pointer); + } + free(strings); + FreeStrBuf(&FileName); + FreeStrBuf(&Function); + FreeStrBuf(&Pointer); + FreeStrBuf(&Buf); + } +#endif + return Val; +} + +void WildFireSerializePayload(StrBuf *JsonBuffer, StrBuf *OutBuf, int *MsgCount, AddHeaderFunc AddHdr) +{ + int n = *MsgCount; + StrBuf *Buf; + StrBuf *HeaderName; + StrBuf *N; + const char Concatenate[] = "\\"; + const char empty[] = ""; + const char *Cat; + StrBuf *Header; + + if (*MsgCount == 0) { + if (OutBuf != NULL) { + StrBufAppendBufPlain(OutBuf, + HKEY( + "X-Wf-Protocol-1" + ": " + "http://meta.wildfirehq.org/Protocol/JsonStream/0.2\r\n"), 0); + StrBufAppendBufPlain(OutBuf, + HKEY( + "X-Wf-1-Plugin-1" + ": " + "http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.2.0\r\n"), 0); + StrBufAppendBufPlain(OutBuf, + HKEY( + "X-Wf-1-Structure-1" + ": " + "http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1\r\n"), 0); + } + else { + Header = NewStrBuf(); + AddHdr("X-Wf-Protocol-1", + "http://meta.wildfirehq.org/Protocol/JsonStream/0.2"); + AddHdr("X-Wf-1-Plugin-1", + "http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.2.0"); + AddHdr("X-Wf-1-Structure-1", + "http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1"); + } + } + + N = NewStrBuf(); + StrBufPrintf(N, "%d", StrLength(JsonBuffer)); + Buf = NewStrBufPlain(NULL, 1024); + HeaderName = NewStrBuf(); + + while (StrLength(JsonBuffer) > 0) { + FlushStrBuf(Buf); + StrBufPrintf(HeaderName, "X-Wf-"WF_MAJOR"-"WF_STRUCTINDEX"-"WF_SUB"-%d", n); + if (StrLength(JsonBuffer) > 800) { + StrBufAppendBufPlain(Buf, ChrPtr(JsonBuffer), 800, 0); + StrBufCutLeft(JsonBuffer, 800); + Cat = Concatenate; + } + else { + StrBufAppendBuf(Buf, JsonBuffer, 0); + FlushStrBuf(JsonBuffer); + Cat = empty; + } + if (OutBuf != NULL) { + StrBufAppendPrintf(OutBuf, + "%s: %s|%s|%s\r\n", + ChrPtr(HeaderName), + ChrPtr(N), + ChrPtr(Buf), + Cat); + } + else { + StrBufAppendPrintf(Header, + "%s|%s|%s", + ChrPtr(N), + ChrPtr(Buf), + Cat); + AddHdr(ChrPtr(HeaderName), ChrPtr(Header)); + + } + + FlushStrBuf(N); + n++; + } + *MsgCount = n; + if (OutBuf == NULL) { + FreeStrBuf(&Header); + } +} + + + + + + +/* this is how we do it... +void CreateWildfireSampleMessage(void) +{ + JsonValue *Error; + + StrBuf *Buf; + StrBuf *Header; + StrBuf *Json; + int n = 1; + + Header = NewStrBuf(); + Json = NewStrBuf(); + + Error = WildFireMessagePlain(HKEY(__FILE__), __LINE__, HKEY("Info message"), eINFO); + SerializeJson(Json, Error); + WildFireSerializePayload(Json, Header, &n, NULL); + StrBufAppendBuf(WC->HBuf, Header, 0); + DeleteJSONValue(Error); + FlushStrBuf(Json); + FlushStrBuf(Header); + + Error = WildFireMessagePlain(HKEY(__FILE__), __LINE__, HKEY("Warn message"), eWARN); + SerializeJson(Json, Error); + WildFireSerializePayload(Json, Header, &n, NULL); + StrBufAppendBuf(WC->HBuf, Header, 0); + DeleteJSONValue(Error); + FlushStrBuf(Json); + FlushStrBuf(Header); + + Error = WildFireMessagePlain(HKEY(__FILE__), __LINE__, HKEY("Error message"), eERROR); + SerializeJson(Json, Error); + WildFireSerializePayload(Json, Header, &n, NULL); + StrBufAppendBuf(WC->HBuf, Header, 0); + DeleteJSONValue(Error); + FlushStrBuf(Json); + FlushStrBuf(Header); + + Error = WildFireMessagePlain(HKEY(__FILE__), __LINE__, HKEY("Info message"), eINFO); + SerializeJson(Json, Error); + WildFireSerializePayload(Json, Header, &n, NULL); + StrBufAppendBuf(WC->HBuf, Header, 0); + DeleteJSONValue(Error); + FlushStrBuf(Json); + FlushStrBuf(Header); + + Error = WildFireMessagePlain(HKEY(__FILE__), __LINE__, HKEY("Info message"), eINFO); + SerializeJson(Json, Error); + WildFireSerializePayload(Json, Header, &n, NULL); + StrBufAppendBuf(WC->HBuf, Header, 0); + DeleteJSONValue(Error); + FlushStrBuf(Json); + FlushStrBuf(Header); + + + Buf = NewStrBufPlain(HKEY("test error message")); + Error = WildFireException(Buf, HKEY(__FILE__), __LINE__, 1); + SerializeJson(Json, Error); + WildFireSerializePayload(Json, Header, &n, NULL); + StrBufAppendBuf(WC->HBuf, Header, 0); + DeleteJSONValue(Error); + + FlushStrBuf(Json); + FlushStrBuf(Header); + +} + +*/ -- 2.30.2