jsonification into the core and ESL (part 2)
This commit is contained in:
parent
c5086b1517
commit
7048c16fc4
10
Makefile.am
10
Makefile.am
|
@ -169,6 +169,7 @@ library_include_HEADERS = \
|
||||||
src/include/switch_xml.h \
|
src/include/switch_xml.h \
|
||||||
src/include/switch_xml_config.h \
|
src/include/switch_xml_config.h \
|
||||||
src/include/switch_cpp.h \
|
src/include/switch_cpp.h \
|
||||||
|
src/include/switch_json.h\
|
||||||
libs/libteletone/src/libteletone_detect.h \
|
libs/libteletone/src/libteletone_detect.h \
|
||||||
libs/libteletone/src/libteletone_generate.h \
|
libs/libteletone/src/libteletone_generate.h \
|
||||||
libs/libteletone/src/libteletone.h \
|
libs/libteletone/src/libteletone.h \
|
||||||
|
@ -230,6 +231,7 @@ libfreeswitch_la_SOURCES = \
|
||||||
src/g711.c \
|
src/g711.c \
|
||||||
src/switch_pcm.c \
|
src/switch_pcm.c \
|
||||||
src/switch_profile.c\
|
src/switch_profile.c\
|
||||||
|
src/switch_json.c\
|
||||||
libs/stfu/stfu.c \
|
libs/stfu/stfu.c \
|
||||||
libs/libteletone/src/libteletone_detect.c \
|
libs/libteletone/src/libteletone_detect.c \
|
||||||
libs/libteletone/src/libteletone_generate.c \
|
libs/libteletone/src/libteletone_generate.c \
|
||||||
|
@ -268,9 +270,9 @@ bin_PROGRAMS = freeswitch fs_cli fs_ivrd
|
||||||
##
|
##
|
||||||
## fs_cli ()
|
## fs_cli ()
|
||||||
##
|
##
|
||||||
fs_cli_SOURCES = libs/esl/src/esl.c libs/esl/src/esl_config.c libs/esl/src/esl_event.c libs/esl/src/esl_threadmutex.c libs/esl/fs_cli.c
|
fs_cli_SOURCES = libs/esl/src/esl.c libs/esl/src/esl_config.c libs/esl/src/esl_event.c libs/esl/src/esl_threadmutex.c libs/esl/fs_cli.c libs/esl/src/esl_json.c
|
||||||
fs_cli_CFLAGS = $(AM_CFLAGS) -I$(switch_srcdir)/libs/esl/src/include
|
fs_cli_CFLAGS = $(AM_CFLAGS) -I$(switch_srcdir)/libs/esl/src/include
|
||||||
fs_cli_LDFLAGS = $(AM_LDFLAGS) -lpthread $(ESL_LDFLAGS)
|
fs_cli_LDFLAGS = $(AM_LDFLAGS) -lpthread $(ESL_LDFLAGS) -lm
|
||||||
|
|
||||||
if HAVE_LIBEDIT
|
if HAVE_LIBEDIT
|
||||||
fs_cli_CFLAGS += -DHAVE_EDITLINE -I$(switch_srcdir)/libs/libedit/src
|
fs_cli_CFLAGS += -DHAVE_EDITLINE -I$(switch_srcdir)/libs/libedit/src
|
||||||
|
@ -280,9 +282,9 @@ endif
|
||||||
##
|
##
|
||||||
## fs_ivrd ()
|
## fs_ivrd ()
|
||||||
##
|
##
|
||||||
fs_ivrd_SOURCES = libs/esl/src/esl.c libs/esl/src/esl_config.c libs/esl/src/esl_event.c libs/esl/src/esl_threadmutex.c libs/esl/ivrd.c
|
fs_ivrd_SOURCES = libs/esl/src/esl.c libs/esl/src/esl_config.c libs/esl/src/esl_event.c libs/esl/src/esl_threadmutex.c libs/esl/ivrd.c libs/esl/src/esl_json.c
|
||||||
fs_ivrd_CFLAGS = $(AM_CFLAGS) -I$(switch_srcdir)/libs/esl/src/include
|
fs_ivrd_CFLAGS = $(AM_CFLAGS) -I$(switch_srcdir)/libs/esl/src/include
|
||||||
fs_ivrd_LDFLAGS = $(AM_LDFLAGS) -lpthread $(ESL_LDFLAGS)
|
fs_ivrd_LDFLAGS = $(AM_LDFLAGS) -lpthread $(ESL_LDFLAGS) -lm
|
||||||
|
|
||||||
##
|
##
|
||||||
## freeswitch ()
|
## freeswitch ()
|
||||||
|
|
|
@ -7,11 +7,11 @@ PICKY=-O2 -ffast-math -Wall -Werror -Wunused-variable -Wwrite-strings -Wstrict-p
|
||||||
CFLAGS=$(BASE_FLAGS) $(PICKY)
|
CFLAGS=$(BASE_FLAGS) $(PICKY)
|
||||||
CXXFLAGS=$(BASE_FLAGS) -Wall -Werror -Wno-unused-variable
|
CXXFLAGS=$(BASE_FLAGS) -Wall -Werror -Wno-unused-variable
|
||||||
MYLIB=libesl.a
|
MYLIB=libesl.a
|
||||||
LIBS=-lncurses -lpthread -lesl
|
LIBS=-lncurses -lpthread -lesl -lm
|
||||||
LDFLAGS=-L.
|
LDFLAGS=-L.
|
||||||
OBJS=src/esl.o src/esl_event.o src/esl_threadmutex.o src/esl_config.o
|
OBJS=src/esl.o src/esl_event.o src/esl_threadmutex.o src/esl_config.o src/esl_json.o
|
||||||
SRC=src/esl.c src/esl_event.c src/esl_threadmutex.c src/esl_config.c src/esl_oop.cpp
|
SRC=src/esl.c src/esl_json.c src/esl_event.c src/esl_threadmutex.c src/esl_config.c src/esl_oop.cpp src/esl_json.c
|
||||||
HEADERS=src/include/esl_config.h src/include/esl_event.h src/include/esl.h src/include/esl_threadmutex.h src/include/esl_oop.h
|
HEADERS=src/include/esl_config.h src/include/esl_event.h src/include/esl.h src/include/esl_threadmutex.h src/include/esl_oop.h src/include/esl_json.h
|
||||||
SOLINK=-shared -Xlinker -x
|
SOLINK=-shared -Xlinker -x
|
||||||
# comment the next line to disable c++ (no swig mods for you then)
|
# comment the next line to disable c++ (no swig mods for you then)
|
||||||
OBJS += src/esl_oop.o
|
OBJS += src/esl_oop.o
|
||||||
|
|
|
@ -527,6 +527,8 @@ ESL_DECLARE(esl_status_t) esl_events(esl_handle_t *handle, esl_event_type_t etyp
|
||||||
|
|
||||||
if (etype == ESL_EVENT_TYPE_XML) {
|
if (etype == ESL_EVENT_TYPE_XML) {
|
||||||
type = "xml";
|
type = "xml";
|
||||||
|
} else if (etype == ESL_EVENT_TYPE_JSON) {
|
||||||
|
type = "json";
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(send_buf, sizeof(send_buf), "event %s %s\n\n", type, value);
|
snprintf(send_buf, sizeof(send_buf), "event %s %s\n\n", type, value);
|
||||||
|
@ -979,63 +981,67 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_
|
||||||
if (!esl_safe_strcasecmp(hval, "text/disconnect-notice") && revent->body) {
|
if (!esl_safe_strcasecmp(hval, "text/disconnect-notice") && revent->body) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!esl_safe_strcasecmp(hval, "text/event-plain") && revent->body) {
|
if (revent->body) {
|
||||||
esl_event_types_t et = ESL_EVENT_CLONE;
|
if (!esl_safe_strcasecmp(hval, "text/event-plain")) {
|
||||||
char *body = strdup(revent->body);
|
esl_event_types_t et = ESL_EVENT_CLONE;
|
||||||
|
char *body = strdup(revent->body);
|
||||||
|
|
||||||
esl_event_create(&handle->last_ievent, et);
|
esl_event_create(&handle->last_ievent, et);
|
||||||
|
|
||||||
beg = body;
|
beg = body;
|
||||||
|
|
||||||
while(beg) {
|
while(beg) {
|
||||||
if (!(c = strchr(beg, '\n'))) {
|
if (!(c = strchr(beg, '\n'))) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
hname = beg;
|
hname = beg;
|
||||||
hval = col = NULL;
|
hval = col = NULL;
|
||||||
|
|
||||||
if (hname && (col = strchr(hname, ':'))) {
|
if (hname && (col = strchr(hname, ':'))) {
|
||||||
hval = col + 1;
|
hval = col + 1;
|
||||||
*col = '\0';
|
*col = '\0';
|
||||||
while(*hval == ' ') hval++;
|
while(*hval == ' ') hval++;
|
||||||
}
|
|
||||||
|
|
||||||
*c = '\0';
|
|
||||||
|
|
||||||
if (hname && hval) {
|
|
||||||
esl_url_decode(hval);
|
|
||||||
esl_log(ESL_LOG_DEBUG, "RECV INNER HEADER [%s] = [%s]\n", hname, hval);
|
|
||||||
if (!strcasecmp(hname, "event-name")) {
|
|
||||||
esl_event_del_header(handle->last_ievent, "event-name");
|
|
||||||
}
|
}
|
||||||
esl_event_add_header_string(handle->last_ievent, ESL_STACK_BOTTOM, hname, hval);
|
|
||||||
esl_name_event(hval, &handle->last_ievent->event_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
beg = c + 1;
|
*c = '\0';
|
||||||
|
|
||||||
|
if (hname && hval) {
|
||||||
|
esl_url_decode(hval);
|
||||||
|
esl_log(ESL_LOG_DEBUG, "RECV INNER HEADER [%s] = [%s]\n", hname, hval);
|
||||||
|
if (!strcasecmp(hname, "event-name")) {
|
||||||
|
esl_event_del_header(handle->last_ievent, "event-name");
|
||||||
|
}
|
||||||
|
esl_event_add_header_string(handle->last_ievent, ESL_STACK_BOTTOM, hname, hval);
|
||||||
|
esl_name_event(hval, &handle->last_ievent->event_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
beg = c + 1;
|
||||||
|
|
||||||
if (*beg == '\n') {
|
if (*beg == '\n') {
|
||||||
beg++;
|
beg++;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ((cl = esl_event_get_header(handle->last_ievent, "content-length"))) {
|
if ((cl = esl_event_get_header(handle->last_ievent, "content-length"))) {
|
||||||
handle->last_ievent->body = strdup(beg);
|
handle->last_ievent->body = strdup(beg);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(body);
|
free(body);
|
||||||
|
|
||||||
if (esl_log_level >= 7) {
|
if (esl_log_level >= 7) {
|
||||||
char *foo;
|
char *foo;
|
||||||
esl_event_serialize(handle->last_ievent, &foo, ESL_FALSE);
|
esl_event_serialize(handle->last_ievent, &foo, ESL_FALSE);
|
||||||
esl_log(ESL_LOG_DEBUG, "RECV EVENT\n%s\n", foo);
|
esl_log(ESL_LOG_DEBUG, "RECV EVENT\n%s\n", foo);
|
||||||
free(foo);
|
free(foo);
|
||||||
|
}
|
||||||
|
} else if (!esl_safe_strcasecmp(hval, "text/event-json")) {
|
||||||
|
esl_event_create_json(&handle->last_ievent, revent->body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (esl_log_level >= 7) {
|
if (esl_log_level >= 7) {
|
||||||
char *foo;
|
char *foo;
|
||||||
esl_event_serialize(revent, &foo, ESL_FALSE);
|
esl_event_serialize(revent, &foo, ESL_FALSE);
|
||||||
|
|
|
@ -437,6 +437,73 @@ ESL_DECLARE(esl_status_t) esl_event_dup(esl_event_t **event, esl_event_t *todup)
|
||||||
return ESL_SUCCESS;
|
return ESL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ESL_DECLARE(esl_status_t) esl_event_create_json(esl_event_t **event, const char *json)
|
||||||
|
{
|
||||||
|
esl_event_t *new_event;
|
||||||
|
cJSON *cj, *cjp;
|
||||||
|
|
||||||
|
|
||||||
|
if (!(cj = cJSON_Parse(json))) {
|
||||||
|
return ESL_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esl_event_create(&new_event, ESL_EVENT_CLONE) != ESL_SUCCESS) {
|
||||||
|
cJSON_Delete(cj);
|
||||||
|
return ESL_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (cjp = cj->child; cjp; cjp = cjp->next) {
|
||||||
|
char *name = cjp->string;
|
||||||
|
char *value = cjp->valuestring;
|
||||||
|
|
||||||
|
if (name && value) {
|
||||||
|
if (!strcasecmp(name, "_body")) {
|
||||||
|
esl_event_add_body(new_event, value);
|
||||||
|
} else {
|
||||||
|
if (!strcasecmp(name, "event-name")) {
|
||||||
|
esl_event_del_header(new_event, "event-name");
|
||||||
|
}
|
||||||
|
|
||||||
|
esl_name_event(value, &new_event->event_id);
|
||||||
|
esl_event_add_header_string(new_event, ESL_STACK_BOTTOM, name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_Delete(cj);
|
||||||
|
*event = new_event;
|
||||||
|
return ESL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESL_DECLARE(esl_status_t) esl_event_serialize_json(esl_event_t *event, char **str)
|
||||||
|
{
|
||||||
|
esl_event_header_t *hp;
|
||||||
|
cJSON *cj;
|
||||||
|
|
||||||
|
*str = NULL;
|
||||||
|
|
||||||
|
cj = cJSON_CreateObject();
|
||||||
|
|
||||||
|
for (hp = event->headers; hp; hp = hp->next) {
|
||||||
|
cJSON_AddItemToObject(cj, hp->name, cJSON_CreateString(hp->value));
|
||||||
|
}
|
||||||
|
if (event->body) {
|
||||||
|
int blen = (int) strlen(event->body);
|
||||||
|
char tmp[25];
|
||||||
|
|
||||||
|
esl_snprintf(tmp, sizeof(tmp), "%d", blen);
|
||||||
|
|
||||||
|
cJSON_AddItemToObject(cj, "Content-Length", cJSON_CreateString(tmp));
|
||||||
|
cJSON_AddItemToObject(cj, "_body", cJSON_CreateString(event->body));
|
||||||
|
}
|
||||||
|
|
||||||
|
*str = cJSON_Print(cj);
|
||||||
|
cJSON_Delete(cj);
|
||||||
|
|
||||||
|
return ESL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
ESL_DECLARE(esl_status_t) esl_event_serialize(esl_event_t *event, char **str, esl_bool_t encode)
|
ESL_DECLARE(esl_status_t) esl_event_serialize(esl_event_t *event, char **str, esl_bool_t encode)
|
||||||
{
|
{
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
|
@ -0,0 +1,484 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2009 Dave Gamble
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// cJSON
|
||||||
|
// JSON parser in C.
|
||||||
|
|
||||||
|
#include "esl.h"
|
||||||
|
#include <float.h>
|
||||||
|
|
||||||
|
static int cJSON_strcasecmp(const char *s1,const char *s2)
|
||||||
|
{
|
||||||
|
if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
|
||||||
|
for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0;
|
||||||
|
return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *(*cJSON_malloc)(size_t sz) = malloc;
|
||||||
|
static void (*cJSON_free)(void *ptr) = free;
|
||||||
|
|
||||||
|
static char* cJSON_strdup(const char* str)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
char* copy;
|
||||||
|
|
||||||
|
len = strlen(str) + 1;
|
||||||
|
if (!(copy = (char*)cJSON_malloc(len))) return 0;
|
||||||
|
memcpy(copy,str,len);
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cJSON_InitHooks(cJSON_Hooks* hooks)
|
||||||
|
{
|
||||||
|
if (!hooks) { /* Reset hooks */
|
||||||
|
cJSON_malloc = malloc;
|
||||||
|
cJSON_free = free;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
|
||||||
|
cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal constructor.
|
||||||
|
static cJSON *cJSON_New_Item(void)
|
||||||
|
{
|
||||||
|
cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
|
||||||
|
if (node) memset(node,0,sizeof(cJSON));
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete a cJSON structure.
|
||||||
|
void cJSON_Delete(cJSON *c)
|
||||||
|
{
|
||||||
|
cJSON *next;
|
||||||
|
while (c)
|
||||||
|
{
|
||||||
|
next=c->next;
|
||||||
|
if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
|
||||||
|
if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
|
||||||
|
if (c->string) cJSON_free(c->string);
|
||||||
|
cJSON_free(c);
|
||||||
|
c=next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the input text to generate a number, and populate the result into item.
|
||||||
|
static const char *parse_number(cJSON *item,const char *num)
|
||||||
|
{
|
||||||
|
double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
|
||||||
|
|
||||||
|
// Could use sscanf for this?
|
||||||
|
if (*num=='-') sign=-1,num++; // Has sign?
|
||||||
|
if (*num=='0') num++; // is zero
|
||||||
|
if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); // Number?
|
||||||
|
if (*num=='.') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} // Fractional part?
|
||||||
|
if (*num=='e' || *num=='E') // Exponent?
|
||||||
|
{ num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; // With sign?
|
||||||
|
while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); // Number?
|
||||||
|
}
|
||||||
|
|
||||||
|
n=sign*n*pow(10.0,(scale+subscale*signsubscale)); // number = +/- number.fraction * 10^+/- exponent
|
||||||
|
|
||||||
|
item->valuedouble=n;
|
||||||
|
item->valueint=(int)n;
|
||||||
|
item->type=cJSON_Number;
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render the number nicely from the given item into a string.
|
||||||
|
static char *print_number(cJSON *item)
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
double d=item->valuedouble;
|
||||||
|
if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
|
||||||
|
{
|
||||||
|
str=(char*)cJSON_malloc(21); // 2^64+1 can be represented in 21 chars.
|
||||||
|
sprintf(str,"%d",item->valueint);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
str=(char*)cJSON_malloc(64); // This is a nice tradeoff.
|
||||||
|
if (fabs(floor(d)-d)<=DBL_EPSILON) sprintf(str,"%.0f",d);
|
||||||
|
else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);
|
||||||
|
else sprintf(str,"%f",d);
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the input text into an unescaped cstring, and populate item.
|
||||||
|
static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
||||||
|
static const char *parse_string(cJSON *item,const char *str)
|
||||||
|
{
|
||||||
|
const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc;
|
||||||
|
if (*str!='\"') return 0; // not a string!
|
||||||
|
|
||||||
|
while (*ptr!='\"' && (unsigned char)*ptr>31 && ++len) if (*ptr++ == '\\') ptr++; // Skip escaped quotes.
|
||||||
|
|
||||||
|
out=(char*)cJSON_malloc(len+1); // This is how long we need for the string, roughly.
|
||||||
|
if (!out) return 0;
|
||||||
|
|
||||||
|
ptr=str+1;ptr2=out;
|
||||||
|
while (*ptr!='\"' && (unsigned char)*ptr>31)
|
||||||
|
{
|
||||||
|
if (*ptr!='\\') *ptr2++=*ptr++;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptr++;
|
||||||
|
switch (*ptr)
|
||||||
|
{
|
||||||
|
case 'b': *ptr2++='\b'; break;
|
||||||
|
case 'f': *ptr2++='\f'; break;
|
||||||
|
case 'n': *ptr2++='\n'; break;
|
||||||
|
case 'r': *ptr2++='\r'; break;
|
||||||
|
case 't': *ptr2++='\t'; break;
|
||||||
|
case 'u': // transcode utf16 to utf8. DOES NOT SUPPORT SURROGATE PAIRS CORRECTLY.
|
||||||
|
sscanf(ptr+1,"%4x",&uc); // get the unicode char.
|
||||||
|
len=3;if (uc<0x80) len=1;else if (uc<0x800) len=2;ptr2+=len;
|
||||||
|
|
||||||
|
switch (len) {
|
||||||
|
case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
||||||
|
case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
||||||
|
case 1: *--ptr2 =(uc | firstByteMark[len]);
|
||||||
|
}
|
||||||
|
ptr2+=len;ptr+=4;
|
||||||
|
break;
|
||||||
|
default: *ptr2++=*ptr; break;
|
||||||
|
}
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*ptr2=0;
|
||||||
|
if (*ptr=='\"') ptr++;
|
||||||
|
item->valuestring=out;
|
||||||
|
item->type=cJSON_String;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render the cstring provided to an escaped version that can be printed.
|
||||||
|
static char *print_string_ptr(const char *str)
|
||||||
|
{
|
||||||
|
const char *ptr;char *ptr2,*out;int len=0;
|
||||||
|
|
||||||
|
if (!str) return cJSON_strdup("");
|
||||||
|
ptr=str;while (*ptr && ++len) {if ((unsigned char)*ptr<32 || *ptr=='\"' || *ptr=='\\') len++;ptr++;}
|
||||||
|
|
||||||
|
out=(char*)cJSON_malloc(len+3);
|
||||||
|
ptr2=out;ptr=str;
|
||||||
|
*ptr2++='\"';
|
||||||
|
while (*ptr)
|
||||||
|
{
|
||||||
|
if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*ptr2++='\\';
|
||||||
|
switch (*ptr++)
|
||||||
|
{
|
||||||
|
case '\\': *ptr2++='\\'; break;
|
||||||
|
case '\"': *ptr2++='\"'; break;
|
||||||
|
case '\b': *ptr2++='b'; break;
|
||||||
|
case '\f': *ptr2++='f'; break;
|
||||||
|
case '\n': *ptr2++='n'; break;
|
||||||
|
case '\r': *ptr2++='r'; break;
|
||||||
|
case '\t': *ptr2++='t'; break;
|
||||||
|
default: ptr2--; break; // eviscerate with prejudice.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*ptr2++='\"';*ptr2++=0;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
// Invote print_string_ptr (which is useful) on an item.
|
||||||
|
static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);}
|
||||||
|
|
||||||
|
// Predeclare these prototypes.
|
||||||
|
static const char *parse_value(cJSON *item,const char *value);
|
||||||
|
static char *print_value(cJSON *item,int depth,int fmt);
|
||||||
|
static const char *parse_array(cJSON *item,const char *value);
|
||||||
|
static char *print_array(cJSON *item,int depth,int fmt);
|
||||||
|
static const char *parse_object(cJSON *item,const char *value);
|
||||||
|
static char *print_object(cJSON *item,int depth,int fmt);
|
||||||
|
|
||||||
|
// Utility to jump whitespace and cr/lf
|
||||||
|
static const char *skip(const char *in) {while (in && (unsigned char)*in<=32) in++; return in;}
|
||||||
|
|
||||||
|
// Parse an object - create a new root, and populate.
|
||||||
|
cJSON *cJSON_Parse(const char *value)
|
||||||
|
{
|
||||||
|
cJSON *c=cJSON_New_Item();
|
||||||
|
if (!c) return 0; /* memory fail */
|
||||||
|
|
||||||
|
if (!parse_value(c,skip(value))) {cJSON_Delete(c);return 0;}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render a cJSON item/entity/structure to text.
|
||||||
|
char *cJSON_Print(cJSON *item) {return print_value(item,0,1);}
|
||||||
|
char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);}
|
||||||
|
|
||||||
|
// Parser core - when encountering text, process appropriately.
|
||||||
|
static const char *parse_value(cJSON *item,const char *value)
|
||||||
|
{
|
||||||
|
if (!value) return 0; // Fail on null.
|
||||||
|
if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; }
|
||||||
|
if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; }
|
||||||
|
if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; }
|
||||||
|
if (*value=='\"') { return parse_string(item,value); }
|
||||||
|
if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); }
|
||||||
|
if (*value=='[') { return parse_array(item,value); }
|
||||||
|
if (*value=='{') { return parse_object(item,value); }
|
||||||
|
|
||||||
|
return 0; // failure.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render a value to text.
|
||||||
|
static char *print_value(cJSON *item,int depth,int fmt)
|
||||||
|
{
|
||||||
|
char *out=0;
|
||||||
|
if (!item) return 0;
|
||||||
|
switch ((item->type)&255)
|
||||||
|
{
|
||||||
|
case cJSON_NULL: out=cJSON_strdup("null"); break;
|
||||||
|
case cJSON_False: out=cJSON_strdup("false");break;
|
||||||
|
case cJSON_True: out=cJSON_strdup("true"); break;
|
||||||
|
case cJSON_Number: out=print_number(item);break;
|
||||||
|
case cJSON_String: out=print_string(item);break;
|
||||||
|
case cJSON_Array: out=print_array(item,depth,fmt);break;
|
||||||
|
case cJSON_Object: out=print_object(item,depth,fmt);break;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build an array from input text.
|
||||||
|
static const char *parse_array(cJSON *item,const char *value)
|
||||||
|
{
|
||||||
|
cJSON *child;
|
||||||
|
if (*value!='[') return 0; // not an array!
|
||||||
|
|
||||||
|
item->type=cJSON_Array;
|
||||||
|
value=skip(value+1);
|
||||||
|
if (*value==']') return value+1; // empty array.
|
||||||
|
|
||||||
|
item->child=child=cJSON_New_Item();
|
||||||
|
if (!item->child) return 0; // memory fail
|
||||||
|
value=skip(parse_value(child,skip(value))); // skip any spacing, get the value.
|
||||||
|
if (!value) return 0;
|
||||||
|
|
||||||
|
while (*value==',')
|
||||||
|
{
|
||||||
|
cJSON *new_item;
|
||||||
|
if (!(new_item=cJSON_New_Item())) return 0; // memory fail
|
||||||
|
child->next=new_item;new_item->prev=child;child=new_item;
|
||||||
|
value=skip(parse_value(child,skip(value+1)));
|
||||||
|
if (!value) return 0; // memory fail
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*value==']') return value+1; // end of array
|
||||||
|
return 0; // malformed.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render an array to text
|
||||||
|
static char *print_array(cJSON *item,int depth,int fmt)
|
||||||
|
{
|
||||||
|
char **entries;
|
||||||
|
char *out=0,*ptr,*ret;int len=5;
|
||||||
|
cJSON *child=item->child;
|
||||||
|
int numentries=0,i=0,fail=0;
|
||||||
|
|
||||||
|
// How many entries in the array?
|
||||||
|
while (child) numentries++,child=child->next;
|
||||||
|
// Allocate an array to hold the values for each
|
||||||
|
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
|
||||||
|
if (!entries) return 0;
|
||||||
|
memset(entries,0,numentries*sizeof(char*));
|
||||||
|
// Retrieve all the results:
|
||||||
|
child=item->child;
|
||||||
|
while (child && !fail)
|
||||||
|
{
|
||||||
|
ret=print_value(child,depth+1,fmt);
|
||||||
|
entries[i++]=ret;
|
||||||
|
if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
|
||||||
|
child=child->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we didn't fail, try to malloc the output string
|
||||||
|
if (!fail) out=cJSON_malloc(len);
|
||||||
|
// If that fails, we fail.
|
||||||
|
if (!out) fail=1;
|
||||||
|
|
||||||
|
// Handle failure.
|
||||||
|
if (fail)
|
||||||
|
{
|
||||||
|
for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
|
||||||
|
cJSON_free(entries);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compose the output array.
|
||||||
|
*out='[';
|
||||||
|
ptr=out+1;*ptr=0;
|
||||||
|
for (i=0;i<numentries;i++)
|
||||||
|
{
|
||||||
|
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
|
||||||
|
if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}
|
||||||
|
cJSON_free(entries[i]);
|
||||||
|
}
|
||||||
|
cJSON_free(entries);
|
||||||
|
*ptr++=']';*ptr++=0;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build an object from the text.
|
||||||
|
static const char *parse_object(cJSON *item,const char *value)
|
||||||
|
{
|
||||||
|
cJSON *child;
|
||||||
|
if (*value!='{') return 0; // not an object!
|
||||||
|
|
||||||
|
item->type=cJSON_Object;
|
||||||
|
value=skip(value+1);
|
||||||
|
if (*value=='}') return value+1; // empty array.
|
||||||
|
|
||||||
|
item->child=child=cJSON_New_Item();
|
||||||
|
value=skip(parse_string(child,skip(value)));
|
||||||
|
if (!value) return 0;
|
||||||
|
child->string=child->valuestring;child->valuestring=0;
|
||||||
|
if (*value!=':') return 0; // fail!
|
||||||
|
value=skip(parse_value(child,skip(value+1))); // skip any spacing, get the value.
|
||||||
|
if (!value) return 0;
|
||||||
|
|
||||||
|
while (*value==',')
|
||||||
|
{
|
||||||
|
cJSON *new_item;
|
||||||
|
if (!(new_item=cJSON_New_Item())) return 0; // memory fail
|
||||||
|
child->next=new_item;new_item->prev=child;child=new_item;
|
||||||
|
value=skip(parse_string(child,skip(value+1)));
|
||||||
|
if (!value) return 0;
|
||||||
|
child->string=child->valuestring;child->valuestring=0;
|
||||||
|
if (*value!=':') return 0; // fail!
|
||||||
|
value=skip(parse_value(child,skip(value+1))); // skip any spacing, get the value.
|
||||||
|
if (!value) return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*value=='}') return value+1; // end of array
|
||||||
|
return 0; // malformed.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render an object to text.
|
||||||
|
static char *print_object(cJSON *item,int depth,int fmt)
|
||||||
|
{
|
||||||
|
char **entries=0,**names=0;
|
||||||
|
char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
|
||||||
|
cJSON *child=item->child;
|
||||||
|
int numentries=0,fail=0;
|
||||||
|
// Count the number of entries.
|
||||||
|
while (child) numentries++,child=child->next;
|
||||||
|
// Allocate space for the names and the objects
|
||||||
|
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
|
||||||
|
if (!entries) return 0;
|
||||||
|
names=(char**)cJSON_malloc(numentries*sizeof(char*));
|
||||||
|
if (!names) {cJSON_free(entries);return 0;}
|
||||||
|
memset(entries,0,sizeof(char*)*numentries);
|
||||||
|
memset(names,0,sizeof(char*)*numentries);
|
||||||
|
|
||||||
|
// Collect all the results into our arrays:
|
||||||
|
child=item->child;depth++;if (fmt) len+=depth;
|
||||||
|
while (child)
|
||||||
|
{
|
||||||
|
names[i]=str=print_string_ptr(child->string);
|
||||||
|
entries[i++]=ret=print_value(child,depth,fmt);
|
||||||
|
if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
|
||||||
|
child=child->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to allocate the output string
|
||||||
|
if (!fail) out=(char*)cJSON_malloc(len);
|
||||||
|
if (!out) fail=1;
|
||||||
|
|
||||||
|
// Handle failure
|
||||||
|
if (fail)
|
||||||
|
{
|
||||||
|
for (i=0;i<numentries;i++) {if (names[i]) free(names[i]);if (entries[i]) free(entries[i]);}
|
||||||
|
free(names);free(entries);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compose the output:
|
||||||
|
*out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
|
||||||
|
for (i=0;i<numentries;i++)
|
||||||
|
{
|
||||||
|
if (fmt) for (j=0;j<depth;j++) *ptr++='\t';
|
||||||
|
strcpy(ptr,names[i]);ptr+=strlen(names[i]);
|
||||||
|
*ptr++=':';if (fmt) *ptr++='\t';
|
||||||
|
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
|
||||||
|
if (i!=numentries-1) *ptr++=',';
|
||||||
|
if (fmt) *ptr++='\n';*ptr=0;
|
||||||
|
cJSON_free(names[i]);cJSON_free(entries[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_free(names);cJSON_free(entries);
|
||||||
|
if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
|
||||||
|
*ptr++='}';*ptr++=0;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Array size/item / object item.
|
||||||
|
int cJSON_GetArraySize(cJSON *array) {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
|
||||||
|
cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;}
|
||||||
|
cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
|
||||||
|
|
||||||
|
// Utility for array list handling.
|
||||||
|
static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
|
||||||
|
// Utility for handling references.
|
||||||
|
static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
|
||||||
|
|
||||||
|
// Add item to array/object.
|
||||||
|
void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
|
||||||
|
void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
|
||||||
|
void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));}
|
||||||
|
void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));}
|
||||||
|
|
||||||
|
cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
|
||||||
|
if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}
|
||||||
|
void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
|
||||||
|
cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
|
||||||
|
void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
|
||||||
|
|
||||||
|
// Replace array/object items with new ones.
|
||||||
|
void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
|
||||||
|
newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
|
||||||
|
if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
|
||||||
|
void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
|
||||||
|
|
||||||
|
// Create basic types:
|
||||||
|
cJSON *cJSON_CreateNull() {cJSON *item=cJSON_New_Item();item->type=cJSON_NULL;return item;}
|
||||||
|
cJSON *cJSON_CreateTrue() {cJSON *item=cJSON_New_Item();item->type=cJSON_True;return item;}
|
||||||
|
cJSON *cJSON_CreateFalse() {cJSON *item=cJSON_New_Item();item->type=cJSON_False;return item;}
|
||||||
|
cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;return item;}
|
||||||
|
cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();item->type=cJSON_String;item->valuestring=cJSON_strdup(string);return item;}
|
||||||
|
cJSON *cJSON_CreateArray() {cJSON *item=cJSON_New_Item();item->type=cJSON_Array;return item;}
|
||||||
|
cJSON *cJSON_CreateObject() {cJSON *item=cJSON_New_Item();item->type=cJSON_Object;return item;}
|
||||||
|
|
||||||
|
// Create Arrays:
|
||||||
|
cJSON *cJSON_CreateIntArray(int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||||
|
cJSON *cJSON_CreateFloatArray(float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||||
|
cJSON *cJSON_CreateDoubleArray(double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||||
|
cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
|
@ -249,6 +249,8 @@ int ESLconnection::events(const char *etype, const char *value)
|
||||||
|
|
||||||
if (!strcmp(etype, "xml")) {
|
if (!strcmp(etype, "xml")) {
|
||||||
type_id = ESL_EVENT_TYPE_XML;
|
type_id = ESL_EVENT_TYPE_XML;
|
||||||
|
} else if (!strcmp(etype, "json")) {
|
||||||
|
type_id = ESL_EVENT_TYPE_JSON;
|
||||||
}
|
}
|
||||||
|
|
||||||
return esl_events(&handle, type_id, value);
|
return esl_events(&handle, type_id, value);
|
||||||
|
@ -263,22 +265,32 @@ ESLevent::ESLevent(const char *type, const char *subclass_name)
|
||||||
|
|
||||||
event_construct_common();
|
event_construct_common();
|
||||||
|
|
||||||
if (esl_name_event(type, &event_id) != ESL_SUCCESS) {
|
if (!strcasecmp(type, "json") && !esl_strlen_zero(subclass_name)) {
|
||||||
event_id = ESL_EVENT_MESSAGE;
|
if (esl_event_create_json(&event, subclass_name) != ESL_SUCCESS) {
|
||||||
}
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
event_id = event->event_id;
|
||||||
|
} else {
|
||||||
|
|
||||||
if (!esl_strlen_zero(subclass_name) && event_id != ESL_EVENT_CUSTOM) {
|
if (esl_name_event(type, &event_id) != ESL_SUCCESS) {
|
||||||
esl_log(ESL_LOG_WARNING, "Changing event type to custom because you specified a subclass name!\n");
|
event_id = ESL_EVENT_MESSAGE;
|
||||||
event_id = ESL_EVENT_CUSTOM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (esl_event_create_subclass(&event, event_id, subclass_name) != ESL_SUCCESS) {
|
if (!esl_strlen_zero(subclass_name) && event_id != ESL_EVENT_CUSTOM) {
|
||||||
esl_log(ESL_LOG_ERROR, "Failed to create event!\n");
|
esl_log(ESL_LOG_WARNING, "Changing event type to custom because you specified a subclass name!\n");
|
||||||
event = NULL;
|
event_id = ESL_EVENT_CUSTOM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (esl_event_create_subclass(&event, event_id, subclass_name) != ESL_SUCCESS) {
|
||||||
|
esl_log(ESL_LOG_ERROR, "Failed to create event!\n");
|
||||||
|
event = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
serialized_string = NULL;
|
serialized_string = NULL;
|
||||||
mine = 1;
|
mine = 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ESLevent::ESLevent(esl_event_t *wrap_me, int free_me)
|
ESLevent::ESLevent(esl_event_t *wrap_me, int free_me)
|
||||||
|
@ -289,7 +301,6 @@ ESLevent::ESLevent(esl_event_t *wrap_me, int free_me)
|
||||||
serialized_string = NULL;
|
serialized_string = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ESLevent::ESLevent(ESLevent *me)
|
ESLevent::ESLevent(ESLevent *me)
|
||||||
{
|
{
|
||||||
/* workaround for silly php thing */
|
/* workaround for silly php thing */
|
||||||
|
@ -344,6 +355,11 @@ const char *ESLevent::serialize(const char *format)
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strcasecmp(format, "json")) {
|
||||||
|
esl_event_serialize_json(event, &serialized_string);
|
||||||
|
return serialized_string;
|
||||||
|
}
|
||||||
|
|
||||||
if (esl_event_serialize(event, &serialized_string, ESL_TRUE) == ESL_SUCCESS) {
|
if (esl_event_serialize(event, &serialized_string, ESL_TRUE) == ESL_SUCCESS) {
|
||||||
return serialized_string;
|
return serialized_string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,8 @@ typedef struct esl_event esl_event_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ESL_EVENT_TYPE_PLAIN,
|
ESL_EVENT_TYPE_PLAIN,
|
||||||
ESL_EVENT_TYPE_XML
|
ESL_EVENT_TYPE_XML,
|
||||||
|
ESL_EVENT_TYPE_JSON
|
||||||
} esl_event_type_t;
|
} esl_event_type_t;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
@ -246,6 +247,9 @@ typedef ssize_t esl_ssize_t;
|
||||||
typedef int esl_filehandle_t;
|
typedef int esl_filehandle_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "math.h"
|
||||||
|
#include "esl_json.h"
|
||||||
|
|
||||||
typedef int16_t esl_port_t;
|
typedef int16_t esl_port_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -273,7 +273,8 @@ ESL_DECLARE(esl_status_t) esl_name_event(const char *name, esl_event_types_t *ty
|
||||||
\note you must free the resulting string when you are finished with it
|
\note you must free the resulting string when you are finished with it
|
||||||
*/
|
*/
|
||||||
ESL_DECLARE(esl_status_t) esl_event_serialize(esl_event_t *event, char **str, esl_bool_t encode);
|
ESL_DECLARE(esl_status_t) esl_event_serialize(esl_event_t *event, char **str, esl_bool_t encode);
|
||||||
|
ESL_DECLARE(esl_status_t) esl_event_serialize_json(esl_event_t *event, char **str);
|
||||||
|
ESL_DECLARE(esl_status_t) esl_event_create_json(esl_event_t **event, const char *json);
|
||||||
/*!
|
/*!
|
||||||
\brief Add a body to an event
|
\brief Add a body to an event
|
||||||
\param event the event to add to body to
|
\param event the event to add to body to
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2009 Dave Gamble
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "esl.h"
|
||||||
|
|
||||||
|
#ifndef cJSON__h
|
||||||
|
#define cJSON__h
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// cJSON Types:
|
||||||
|
#define cJSON_False 0
|
||||||
|
#define cJSON_True 1
|
||||||
|
#define cJSON_NULL 2
|
||||||
|
#define cJSON_Number 3
|
||||||
|
#define cJSON_String 4
|
||||||
|
#define cJSON_Array 5
|
||||||
|
#define cJSON_Object 6
|
||||||
|
|
||||||
|
#define cJSON_IsReference 256
|
||||||
|
|
||||||
|
// The cJSON structure:
|
||||||
|
typedef struct cJSON {
|
||||||
|
struct cJSON *next,*prev; // next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem
|
||||||
|
struct cJSON *child; // An array or object item will have a child pointer pointing to a chain of the items in the array/object.
|
||||||
|
|
||||||
|
int type; // The type of the item, as above.
|
||||||
|
|
||||||
|
char *valuestring; // The item's string, if type==cJSON_String
|
||||||
|
int valueint; // The item's number, if type==cJSON_Number
|
||||||
|
double valuedouble; // The item's number, if type==cJSON_Number
|
||||||
|
|
||||||
|
char *string; // The item's name string, if this item is the child of, or is in the list of subitems of an object.
|
||||||
|
} cJSON;
|
||||||
|
|
||||||
|
typedef struct cJSON_Hooks {
|
||||||
|
void *(*malloc_fn)(size_t sz);
|
||||||
|
void (*free_fn)(void *ptr);
|
||||||
|
} cJSON_Hooks;
|
||||||
|
|
||||||
|
// Supply malloc, realloc and free functions to cJSON
|
||||||
|
extern void cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||||
|
|
||||||
|
|
||||||
|
// Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished.
|
||||||
|
extern cJSON *cJSON_Parse(const char *value);
|
||||||
|
// Render a cJSON entity to text for transfer/storage. Free the char* when finished.
|
||||||
|
extern char *cJSON_Print(cJSON *item);
|
||||||
|
// Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished.
|
||||||
|
extern char *cJSON_PrintUnformatted(cJSON *item);
|
||||||
|
// Delete a cJSON entity and all subentities.
|
||||||
|
extern void cJSON_Delete(cJSON *c);
|
||||||
|
|
||||||
|
// Returns the number of items in an array (or object).
|
||||||
|
extern int cJSON_GetArraySize(cJSON *array);
|
||||||
|
// Retrieve item number "item" from array "array". Returns NULL if unsuccessful.
|
||||||
|
extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
|
||||||
|
// Get item "string" from object. Case insensitive.
|
||||||
|
extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
|
||||||
|
|
||||||
|
// These calls create a cJSON item of the appropriate type.
|
||||||
|
extern cJSON *cJSON_CreateNull(void);
|
||||||
|
extern cJSON *cJSON_CreateTrue(void);
|
||||||
|
extern cJSON *cJSON_CreateFalse(void);
|
||||||
|
extern cJSON *cJSON_CreateNumber(double num);
|
||||||
|
extern cJSON *cJSON_CreateString(const char *string);
|
||||||
|
extern cJSON *cJSON_CreateArray(void);
|
||||||
|
extern cJSON *cJSON_CreateObject(void);
|
||||||
|
|
||||||
|
// These utilities create an Array of count items.
|
||||||
|
extern cJSON *cJSON_CreateIntArray(int *numbers,int count);
|
||||||
|
extern cJSON *cJSON_CreateFloatArray(float *numbers,int count);
|
||||||
|
extern cJSON *cJSON_CreateDoubleArray(double *numbers,int count);
|
||||||
|
extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
|
||||||
|
|
||||||
|
// Append item to the specified array/object.
|
||||||
|
extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||||
|
extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
|
||||||
|
// Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON.
|
||||||
|
extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||||
|
extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
|
||||||
|
|
||||||
|
// Remove/Detatch items from Arrays/Objects.
|
||||||
|
extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
|
||||||
|
extern void cJSON_DeleteItemFromArray(cJSON *array,int which);
|
||||||
|
extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
|
||||||
|
extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);
|
||||||
|
|
||||||
|
// Update array items.
|
||||||
|
extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
|
||||||
|
extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||||
|
|
||||||
|
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
|
||||||
|
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
|
||||||
|
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
|
||||||
|
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
|
||||||
|
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue