From 02112152f042a3452336e004b4298cda2b2fe012 Mon Sep 17 00:00:00 2001 From: erickson Date: Wed, 31 Aug 2005 18:32:56 +0000 Subject: [PATCH] new json api changes new config reader code created and inserted git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@512 9efc2488-bf62-4759-914b-345cdb29e865 --- examples/opensrf_core.xml.example | 9 +- examples/srfsh.xml.example | 2 +- src/gateway/Makefile | 19 +- src/gateway/mod_ils_gateway.c | 12 +- src/libstack/Makefile | 15 +- src/libstack/osrf_app_session.c | 15 +- src/libstack/osrf_app_session.h | 10 +- src/libstack/osrf_config.c | 143 ------- src/libstack/osrf_config.h | 50 --- src/libstack/osrf_message.c | 183 +++++---- src/libstack/osrf_message.h | 9 +- src/libstack/osrf_prefork.c | 24 +- src/libstack/osrf_prefork.h | 1 + src/libstack/osrf_settings.c | 64 +-- src/libstack/osrf_settings.h | 9 +- src/libstack/osrf_stack.c | 11 +- src/libstack/osrf_system.c | 60 ++- src/libstack/osrf_system.h | 10 +- src/objson/Makefile | 6 + src/objson/json_parser.c | 127 +++--- src/objson/json_parser.h | 29 +- src/objson/object.c | 635 +++++++++++++++--------------- src/objson/object.h | 272 +++++++------ src/objson/objson_test.c | 112 +++--- src/router/router.c | 193 ++++----- src/router/router.h | 9 +- src/srfsh/srfsh.c | 46 ++- src/srfsh/srfsh.h | 1 - src/utils/Makefile | 1 + src/utils/string_array.c | 60 +-- src/utils/string_array.h | 18 +- src/utils/utils.c | 4 +- src/utils/utils.h | 45 ++- 33 files changed, 1021 insertions(+), 1183 deletions(-) delete mode 100644 src/libstack/osrf_config.c delete mode 100644 src/libstack/osrf_config.h diff --git a/examples/opensrf_core.xml.example b/examples/opensrf_core.xml.example index a29f5f1..4bf56ce 100644 --- a/examples/opensrf_core.xml.example +++ b/examples/opensrf_core.xml.example @@ -11,7 +11,7 @@ - 127.0.0.1 + 127.0.0.1 @@ -34,7 +34,7 @@ router - 127.0.0.1 + 127.0.0.1 mylogin mypassword @@ -44,7 +44,6 @@ 3 - @@ -52,9 +51,9 @@ - 127.0.0.1 + 127.0.0.1 - 127.0.0.1 + 127.0.0.1 diff --git a/examples/srfsh.xml.example b/examples/srfsh.xml.example index 7056454..5bc1e2d 100644 --- a/examples/srfsh.xml.example +++ b/examples/srfsh.xml.example @@ -2,7 +2,7 @@ router - 127.0.0.1 + 127.0.0.1 myusername mypassword diff --git a/src/gateway/Makefile b/src/gateway/Makefile index 38e898e..74827bf 100644 --- a/src/gateway/Makefile +++ b/src/gateway/Makefile @@ -9,10 +9,9 @@ CC_OPTS += -DASSUME_STATELESS LD_OPTS += -lc_utils -lobjson -lxml2 -lopensrf_transport -lopensrf_stack -all: msg ils_gateway rest_gateway +all: msg ils_gateway ils_gateway: libmod_ils_gateway.so -rest_gateway: libmod_ils_rest_gateway.so msg: echo "-> $$(pwd)" @@ -20,29 +19,15 @@ msg: install: echo installing ils_gateway $(APXS2) -i -a -n ils_gateway libmod_ils_gateway.so - echo installing ils_rest_gateway - $(APXS2) -i -a -n ils_rest_gateway libmod_ils_rest_gateway.so libmod_ils_gateway.so: mod_ils_gateway.o echo $@ $(CC) $(LD_OPTS) -shared -W1 mod_ils_gateway.o -o libmod_ils_gateway.so -libmod_ils_rest_gateway.so: rest_xml.o mod_ils_gateway.c - echo $@ - $(CC) -c -DRESTGATEWAY $(CC_OPTS) -o mod_ils_rest_gateway.o mod_ils_gateway.c - $(CC) $(LD_OPTS) -shared -W1 rest_xml.o mod_ils_rest_gateway.o -o libmod_ils_rest_gateway.so - -rest_xml.c: - ./fieldmapper-c-xml-out.pl rest_xml.h rest_xml.c - -rest_xml.o: rest_xml.c rest_xml.h - echo $@ - $(CC) -c $(CC_OPTS) -o rest_xml.o rest_xml.c - mod_ils_gateway.o: mod_ils_gateway.c echo $@ $(CC) -c $(CC_OPTS) mod_ils_gateway.c clean: - /bin/rm -f *.o *.so rest_xml.c rest_xml.h + /bin/rm -f *.o *.so diff --git a/src/gateway/mod_ils_gateway.c b/src/gateway/mod_ils_gateway.c index c6a68a6..84a5ffe 100644 --- a/src/gateway/mod_ils_gateway.c +++ b/src/gateway/mod_ils_gateway.c @@ -62,7 +62,7 @@ static int mod_ils_gateway_method_handler (request_rec *r) { char* method = NULL; /* method to perform */ //json* exception = NULL; /* returned in error conditions */ - object* exception = NULL; /* returned in error conditions */ + jsonObject* exception = NULL; /* returned in error conditions */ string_array* sarray = init_string_array(12); /* method parameters */ growing_buffer* buffer = NULL; /* POST data */ @@ -169,7 +169,7 @@ static int mod_ils_gateway_method_handler (request_rec *r) { while((omsg = osrf_app_session_request_recv( session, req_id, 60 ))) { if( omsg->_result_content ) { - char* content = object_to_json(omsg->_result_content); + char* content = jsonObjectToJSON(omsg->_result_content); buffer_add(result_data, content); buffer_add( result_data, ","); free(content); @@ -191,8 +191,8 @@ static int mod_ils_gateway_method_handler (request_rec *r) { buffer_add( exc_buffer, code ); exception = json_parse_string("{}"); - exception->add_key(exception, "is_err", json_parse_string("1")); - exception->add_key(exception, "err_msg", new_object(exc_buffer->buf) ); + jsonObjectSetKey(exception, "is_err", json_parse_string("1")); + jsonObjectSetKey(exception, "err_msg", jsonNewObject(exc_buffer->buf) ); warning_handler("*** Looks like we got a " "server exception\n%s", exc_buffer->buf ); @@ -217,8 +217,8 @@ static int mod_ils_gateway_method_handler (request_rec *r) { char* content = NULL; if(exception) { - content = exception->to_json(exception); - free_object(exception); + content = jsonObjectToJSON(exception); + jsonObjectFree(exception); } #ifdef RESTGATEWAY diff --git a/src/libstack/Makefile b/src/libstack/Makefile index d86a348..98df8fe 100644 --- a/src/libstack/Makefile +++ b/src/libstack/Makefile @@ -1,11 +1,10 @@ CC_OPTS += -DASSUME_STATELESS LD_OPTS += -lxml2 -lopensrf_transport -lopensrf_stack -lobjson -lc_utils -SOURCES = osrf_message.c osrf_app_session.c osrf_stack.c osrf_system.c osrf_config.c osrf_settings.c osrf_prefork.c -TARGETS = osrf_message.o osrf_app_session.o osrf_stack.o osrf_system.o osrf_config.o osrf_settings.o osrf_prefork.o -HEADERS = osrf_message.h osrf_app_session.h osrf_stack.h osrf_system.h osrf_config.h osrf_settings.h osrf_prefork.h +TARGETS = osrf_message.o osrf_app_session.o osrf_stack.o osrf_system.o osrf_settings.o osrf_prefork.o osrfConfig.o xml_utils.o +HEADERS = osrf_message.h osrf_app_session.h osrf_stack.h osrf_system.h osrf_settings.h osrf_prefork.h osrfConfig.h xml_utils.h -all: msg libopensrf_stack.so test +all: msg xml_utils.o libopensrf_stack.so test msg: echo "-> $$(pwd)" @@ -45,9 +44,6 @@ osrf_stack.o: osrf_stack.c osrf_stack.h osrf_system.o: osrf_system.c osrf_system.h echo $@; $(CC) -c $(CC_OPTS) osrf_system.c -o $@ -osrf_config.o: osrf_config.c osrf_config.h - echo $@; $(CC) -c $(CC_OPTS) osrf_config.c -o $@ - osrf_settings.o: osrf_settings.c osrf_settings.h echo $@; $(CC) -c $(CC_OPTS) osrf_settings.c -o $@ @@ -55,10 +51,13 @@ osrf_prefork.o: osrf_prefork.c osrf_prefork.h echo $@; $(CC) -c $(CC_OPTS) osrf_prefork.c -o $@ +osrfConfig.o: osrfConfig.c osrfConfig.h xml_utils.o + echo $@; $(CC) -c $(CC_OPTS) osrfConfig.c -o $@ + install: echo installing libopensrf_stack.so cp $(HEADERS) $(INCLUDEDIR)/$(OPENSRF) cp $(TMPDIR)/libopensrf_stack.so $(LIBDIR)/ clean: - /bin/rm -f *.o libopensrf_stack.so test + /bin/rm -f *.o libopensrf_stack.so test xml_utils.h xml_utils.c diff --git a/src/libstack/osrf_app_session.c b/src/libstack/osrf_app_session.c index 0421878..6080561 100644 --- a/src/libstack/osrf_app_session.c +++ b/src/libstack/osrf_app_session.c @@ -247,10 +247,17 @@ osrf_app_session* osrf_app_client_session_init( char* remote_service ) { char target_buf[512]; memset(target_buf,0,512); - char* domain = config_value( "opensrf.bootstrap", "//%s/domains/domain1", osrf_get_config_context() ); /* just the first for now */ - char* router_name = config_value( "opensrf.bootstrap", "//%s/router_name", osrf_get_config_context() ); + //char* domain = config_value( "opensrf.bootstrap", "//%s/domains/domain1", osrf_get_config_context() ); /* just the first for now */ + //char* router_name = config_value( "opensrf.bootstrap", "//%s/router_name", osrf_get_config_context() ); + + osrfStringArray* arr = osrfNewStringArray(8); + osrfConfigGetValueList(NULL, arr, "/domains/domain"); + char* domain = osrfStringArrayGetString(arr, 0); + char* router_name = osrfConfigGetValue(NULL, "/router_name"); + osrfStringArrayFree(arr); + sprintf( target_buf, "%s@%s/%s", router_name, domain, remote_service ); - free(domain); + //free(domain); free(router_name); session->request_queue = NULL; @@ -338,7 +345,7 @@ void _osrf_app_session_free( osrf_app_session* session ){ } int osrf_app_session_make_req( - osrf_app_session* session, object* params, + osrf_app_session* session, jsonObject* params, char* method_name, int protocol, string_array* param_strings ) { if(session == NULL) return -1; diff --git a/src/libstack/osrf_app_session.h b/src/libstack/osrf_app_session.h index bdb1644..6d8626b 100644 --- a/src/libstack/osrf_app_session.h +++ b/src/libstack/osrf_app_session.h @@ -1,14 +1,16 @@ +#ifndef _OSRF_APP_SESSION +#define _OSRF_APP_SESSION + #include "opensrf/transport_client.h" #include "osrf_message.h" #include "osrf_system.h" #include "string_array.h" -#include "osrf_config.h" +//#include "osrf_config.h" +#include "osrfConfig.h" #include "objson/object.h" #include "objson/json_parser.h" -#ifndef OSRF_APP_SESSION -#define OSRF_APP_SESSION #define DEF_RECV_TIMEOUT 6 /* receive timeout */ @@ -101,7 +103,7 @@ osrf_app_session* osrf_app_session_find_session( char* session_id ); * requeset. */ int osrf_app_session_make_req( - osrf_app_session* session, object* params, + osrf_app_session* session, jsonObject* params, char* method_name, int protocol, string_array* param_strings); /** Sets the given request to complete state */ diff --git a/src/libstack/osrf_config.c b/src/libstack/osrf_config.c deleted file mode 100644 index 84e90da..0000000 --- a/src/libstack/osrf_config.c +++ /dev/null @@ -1,143 +0,0 @@ -#include "osrf_config.h" - -void config_reader_init( char* name, char* config_file ) { - - if( name == NULL || config_file == NULL || strlen(config_file) == 0 ) { - fatal_handler( "config_reader_init(): No config file specified" ); - return; - } - - config_reader* reader = - (config_reader*) safe_malloc(sizeof(config_reader)); - - reader->config_doc = xmlParseFile( config_file ); - reader->xpathCx = xmlXPathNewContext( reader->config_doc ); - reader->name = strdup(name); - reader->next = NULL; - - if( reader->xpathCx == NULL ) { - fprintf( stderr, "config_reader_init(): Unable to create xpath context\n"); - return; - } - - if( conf_reader == NULL ) { - conf_reader = reader; - } else { - config_reader* tmp = conf_reader; - conf_reader = reader; - reader->next = tmp; - } -} - - -char* config_value( const char* config_name, const char* xp_query, ... ) { - - if( conf_reader == NULL || xp_query == NULL ) { - fatal_handler( "config_value(): NULL conf_reader or NULL param(s)" ); - return NULL; - } - - config_reader* reader = conf_reader; - while( reader != NULL ) { - if( !strcmp(reader->name, config_name)) - break; - reader = reader->next; - } - - if( reader == NULL ) { - fprintf(stderr, "No Config file with name %s\n", config_name ); - return NULL; - } - - int slen = strlen(xp_query) + 512;/* this is unsafe ... */ - char xpath_query[ slen ]; - memset( xpath_query, 0, slen ); - va_list va_args; - va_start(va_args, xp_query); - vsprintf(xpath_query, xp_query, va_args); - va_end(va_args); - - - char* val; - int len = strlen(xpath_query) + 100; - char alert_buffer[len]; - memset( alert_buffer, 0, len ); - - // build the xpath object - xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression( BAD_CAST xpath_query, reader->xpathCx ); - - if( xpathObj == NULL ) { - sprintf( alert_buffer, "Could not build xpath object: %s", xpath_query ); - fatal_handler( alert_buffer ); - return NULL; - } - - - if( xpathObj->type == XPATH_NODESET ) { - - // ---------------------------------------------------------------------------- - // Grab nodeset from xpath query, then first node, then first text node and - // finaly the text node's value - // ---------------------------------------------------------------------------- - xmlNodeSet* node_list = xpathObj->nodesetval; - if( node_list == NULL ) { - sprintf( alert_buffer, "Could not build xpath object: %s", xpath_query ); - warning_handler(alert_buffer); - return NULL; - } - - if( node_list->nodeNr == 0 ) { - sprintf( alert_buffer, "Config XPATH query returned 0 results: %s", xpath_query ); - warning_handler(alert_buffer); - return NULL; - } - - - xmlNodePtr element_node = *(node_list)->nodeTab; - if( element_node == NULL ) { - sprintf( alert_buffer, "Config XPATH query returned 0 results: %s", xpath_query ); - warning_handler(alert_buffer); - return NULL; - } - - xmlNodePtr text_node = element_node->children; - if( text_node == NULL ) { - sprintf( alert_buffer, "Config variable has no value: %s", xpath_query ); - warning_handler(alert_buffer); - return NULL; - } - - val = text_node->content; - if( val == NULL ) { - sprintf( alert_buffer, "Config variable has no value: %s", xpath_query ); - warning_handler(alert_buffer); - return NULL; - } - - - } else { - sprintf( alert_buffer, "Xpath evaluation failed: %s", xpath_query ); - warning_handler(alert_buffer); - return NULL; - } - - char* value = strdup(val); - if( value == NULL ) { warning_handler( "config_value(): Empty config value or Out of Memory!" ); } - - // Free XPATH structures - if( xpathObj != NULL ) xmlXPathFreeObject( xpathObj ); - - return value; -} - - -void config_reader_free() { - while( conf_reader != NULL ) { - xmlXPathFreeContext( conf_reader->xpathCx ); - xmlFreeDoc( conf_reader->config_doc ); - free(conf_reader->name ); - config_reader* tmp = conf_reader->next; - free( conf_reader ); - conf_reader = tmp; - } -} diff --git a/src/libstack/osrf_config.h b/src/libstack/osrf_config.h deleted file mode 100644 index c6bb5a3..0000000 --- a/src/libstack/osrf_config.h +++ /dev/null @@ -1,50 +0,0 @@ -#include - -#include -#include -#include -#include - -#include "logging.h" -#include "utils.h" - -/* libxml stuff for the config reader */ -#include -#include -#include -//#include -#include - -#include "utils.h" - -#ifndef GENERIC_UTILS_H -#define GENERIC_UTILS_H - -#define equals(a,b) !strcmp(a,b) - -// --------------------------------------------------------------------------------- -// Config file module -// --------------------------------------------------------------------------------- -struct config_reader_struct { - xmlDocPtr config_doc; - xmlXPathContextPtr xpathCx; - char* name; - struct config_reader_struct* next; -}; -typedef struct config_reader_struct config_reader; -config_reader* conf_reader; - -//void config_reader_init( char* config_file ); -void config_reader_init( char* name, char* config_file ); - -void config_reader_free(); - -// allocastes a char*. FREE me. -char* config_value( const char* config_name, const char* xp_query, ... ); - - -char* osrf_config_value(char* path); -void _osrf_config_grab_config(); - -#endif - diff --git a/src/libstack/osrf_message.c b/src/libstack/osrf_message.c index 8aca4eb..49b6ea1 100644 --- a/src/libstack/osrf_message.c +++ b/src/libstack/osrf_message.c @@ -21,27 +21,27 @@ void osrf_message_set_method( osrf_message* msg, char* method_name ) { } -void osrf_message_add_object_param( osrf_message* msg, object* o ) { +void osrf_message_add_object_param( osrf_message* msg, jsonObject* o ) { if(!msg|| !o) return; if(!msg->_params) - msg->_params = json_parse_string("[]"); - char* j = o->to_json(o); - msg->_params->push(msg->_params, json_parse_string(j)); + msg->_params = jsonParseString("[]"); + char* j = jsonObjectToJSON(o); + jsonObjectPush(msg->_params, jsonParseString(j)); free(j); } -void osrf_message_set_params( osrf_message* msg, object* o ) { +void osrf_message_set_params( osrf_message* msg, jsonObject* o ) { if(!msg || !o) return; - if(!o->is_array) { + if(!o->type == JSON_ARRAY) { warning_handler("passing non-array to osrf_message_set_params()"); return; } - if(msg->_params) free_object(msg->_params); + if(msg->_params) jsonObjectFree(msg->_params); - char* j = o->to_json(o); - msg->_params = json_parse_string(j); + char* j = jsonObjectToJSON(o); + msg->_params = jsonParseString(j); free(j); } @@ -49,8 +49,8 @@ void osrf_message_set_params( osrf_message* msg, object* o ) { /* only works if parse_json_params is false */ void osrf_message_add_param( osrf_message* msg, char* param_string ) { if(msg == NULL || param_string == NULL) return; - if(!msg->_params) msg->_params = new_object(NULL); - msg->_params->push(msg->_params, json_parse_string(param_string)); + if(!msg->_params) msg->_params = jsonNewObject(NULL); + jsonObjectPush(msg->_params, jsonParseString(param_string)); } @@ -75,7 +75,7 @@ void osrf_message_set_result_content( osrf_message* msg, char* json_string ) { warning_handler( "Bad params to osrf_message_set_result_content()" ); msg->result_string = strdup(json_string); - if(json_string) msg->_result_content = json_parse_string(json_string); + if(json_string) msg->_result_content = jsonParseString(json_string); } @@ -91,7 +91,7 @@ void osrf_message_free( osrf_message* msg ) { free(msg->status_text); if( msg->_result_content != NULL ) - free_object( msg->_result_content ); + jsonObjectFree( msg->_result_content ); if( msg->result_string != NULL ) free( msg->result_string); @@ -100,100 +100,110 @@ void osrf_message_free( osrf_message* msg ) { free(msg->method_name); if( msg->_params != NULL ) - free_object(msg->_params); + jsonObjectFree(msg->_params); free(msg); } char* osrf_message_serialize(osrf_message* msg) { if( msg == NULL ) return NULL; - object* json = new_object(NULL); - json->set_class(json, "osrfMessage"); - object* payload; + jsonObject* json = jsonNewObject(NULL); + jsonObjectSetClass(json, "osrfMessage"); + jsonObject* payload; char sc[64]; memset(sc,0,64); char* str; - char tt[64]; - memset(tt,0,64); - sprintf(tt,"%d",msg->thread_trace); - json->add_key(json, "threadTrace", new_object(tt)); + INT_TO_STRING(msg->thread_trace); + jsonObjectSetKey(json, "threadTrace", jsonNewObject(INTSTR)); switch(msg->m_type) { case CONNECT: - json->add_key(json, "type", new_object("CONNECT")); + jsonObjectSetKey(json, "type", jsonNewObject("CONNECT")); break; case DISCONNECT: - json->add_key(json, "type", new_object("DISCONNECT")); + jsonObjectSetKey(json, "type", jsonNewObject("DISCONNECT")); break; case STATUS: - json->add_key(json, "type", new_object("STATUS")); - payload = new_object(NULL); - payload->set_class(payload, msg->status_name); - payload->add_key(payload, "status", new_object(msg->status_text)); + jsonObjectSetKey(json, "type", jsonNewObject("STATUS")); + payload = jsonNewObject(NULL); + jsonObjectSetClass(payload, msg->status_name); + jsonObjectSetKey(payload, "status", jsonNewObject(msg->status_text)); sprintf(sc,"%d",msg->status_code); - payload->add_key(payload, "statusCode", new_object(sc)); - json->add_key(json, "payload", payload); + jsonObjectSetKey(payload, "statusCode", jsonNewObject(sc)); + jsonObjectSetKey(json, "payload", payload); break; case REQUEST: - json->add_key(json, "type", new_object("REQUEST")); - payload = new_object(NULL); - payload->set_class(payload, "osrfMethod"); - payload->add_key(payload, "method", new_object(msg->method_name)); - str = object_to_json(msg->_params); - payload->add_key(payload, "params", json_parse_string(str)); + jsonObjectSetKey(json, "type", jsonNewObject("REQUEST")); + payload = jsonNewObject(NULL); + jsonObjectSetClass(payload, "osrfMethod"); + jsonObjectSetKey(payload, "method", jsonNewObject(msg->method_name)); + str = jsonObjectToJSON(msg->_params); + jsonObjectSetKey(payload, "params", jsonParseString(str)); free(str); - json->add_key(json, "payload", payload); + jsonObjectSetKey(json, "payload", payload); break; case RESULT: - json->add_key(json, "type", new_object("RESULT")); - payload = new_object(NULL); - payload->set_class(payload,"osrfResult"); - payload->add_key(payload, "status", new_object(msg->status_text)); + jsonObjectSetKey(json, "type", jsonNewObject("RESULT")); + payload = jsonNewObject(NULL); + jsonObjectSetClass(payload,"osrfResult"); + jsonObjectSetKey(payload, "status", jsonNewObject(msg->status_text)); sprintf(sc,"%d",msg->status_code); - payload->add_key(payload, "statusCode", new_object(sc)); - str = object_to_json(msg->_result_content); - payload->add_key(payload, "content", json_parse_string(str)); + jsonObjectSetKey(payload, "statusCode", jsonNewObject(sc)); + str = jsonObjectToJSON(msg->_result_content); + jsonObjectSetKey(payload, "content", jsonParseString(str)); free(str); - json->add_key(json, "payload", payload); + jsonObjectSetKey(json, "payload", payload); break; } - object* wrapper = new_object(NULL); - wrapper->push(wrapper, json); - char* j = wrapper->to_json(wrapper); - free_object(wrapper); + jsonObject* wrapper = jsonNewObject(NULL); + jsonObjectPush(wrapper, json); + char* j = jsonObjectToJSON(wrapper); + jsonObjectFree(wrapper); return j; } int osrf_message_deserialize(char* string, osrf_message* msgs[], int count) { + if(!string || !msgs || count <= 0) return 0; int numparsed = 0; - object* json = json_parse_string(string); - if(json == NULL) return 0; - int x; + jsonObject* json = jsonParseString(string); + + if(!json) { + warning_handler( + "osrf_message_deserialize() unable to parse data: \n%s\n", string); + return 0; + } + + int x; for( x = 0; x < json->size && x < count; x++ ) { - object* message = json->get_index(json, x); + jsonObject* message = jsonObjectGetIndex(json, x); + + char* j = jsonObjectToJSON(message); + debug_handler("deserialize parsed message \n%s\n", j ); + free(j); + - if(message && !message->is_null && + if(message && message->type != JSON_NULL && message->classname && !strcmp(message->classname, "osrfMessage")) { osrf_message* new_msg = safe_malloc(sizeof(osrf_message)); - object* tmp = message->get_key(message, "type"); + jsonObject* tmp = jsonObjectGetKey(message, "type"); - if(tmp && tmp->string_data) { - char* t = tmp->string_data; + char* t; + if( ( t = jsonObjectGetString(tmp)) ) { if(!strcmp(t, "CONNECT")) new_msg->m_type = CONNECT; if(!strcmp(t, "DISCONNECT")) new_msg->m_type = DISCONNECT; @@ -202,63 +212,66 @@ int osrf_message_deserialize(char* string, osrf_message* msgs[], int count) { if(!strcmp(t, "RESULT")) new_msg->m_type = RESULT; } - tmp = message->get_key(message, "threadTrace"); + tmp = jsonObjectGetKey(message, "threadTrace"); if(tmp) { - if(tmp->is_number) - new_msg->thread_trace = tmp->num_value; - if(tmp->is_string) - new_msg->thread_trace = atoi(tmp->string_data); + if(tmp->type == JSON_NUMBER) + new_msg->thread_trace = (int) jsonObjectGetNumber(tmp); + if(tmp->type == JSON_STRING) + new_msg->thread_trace = atoi(jsonObjectGetString(tmp)); } - tmp = message->get_key(message, "protocol"); + tmp = jsonObjectGetKey(message, "protocol"); + if(tmp) { - if(tmp->is_number) - new_msg->protocol = tmp->num_value; - if(tmp->is_string) - new_msg->protocol = atoi(tmp->string_data); + if(tmp->type == JSON_NUMBER) + new_msg->protocol = (int) jsonObjectGetNumber(tmp); + if(tmp->type == JSON_STRING) + new_msg->protocol = atoi(jsonObjectGetString(tmp)); } - tmp = message->get_key(message, "payload"); + tmp = jsonObjectGetKey(message, "payload"); if(tmp) { if(tmp->classname) new_msg->status_name = strdup(tmp->classname); - object* tmp0 = tmp->get_key(tmp,"method"); - if(tmp0 && tmp0->string_data) - new_msg->method_name = strdup(tmp0->string_data); + jsonObject* tmp0 = jsonObjectGetKey(tmp,"method"); + if(jsonObjectGetString(tmp0)) + new_msg->method_name = strdup(jsonObjectGetString(tmp0)); - tmp0 = tmp->get_key(tmp,"params"); + tmp0 = jsonObjectGetKey(tmp,"params"); if(tmp0) { - char* s = tmp0->to_json(tmp0); - new_msg->_params = json_parse_string(s); + char* s = jsonObjectToJSON(tmp0); + new_msg->_params = jsonParseString(s); free(s); } - tmp0 = tmp->get_key(tmp,"status"); - if(tmp0 && tmp0->string_data) - new_msg->status_text = strdup(tmp0->string_data); + tmp0 = jsonObjectGetKey(tmp,"status"); + if(jsonObjectGetString(tmp0)) + new_msg->status_text = strdup(jsonObjectGetString(tmp0)); - tmp0 = tmp->get_key(tmp,"statusCode"); + tmp0 = jsonObjectGetKey(tmp,"statusCode"); if(tmp0) { - if(tmp0->is_string && tmp0->string_data) - new_msg->status_code = atoi(tmp0->string_data); - if(tmp0->is_number) - new_msg->status_code = tmp0->num_value; + if(jsonObjectGetString(tmp0)) + new_msg->status_code = atoi(jsonObjectGetString(tmp0)); + if(tmp0->type == JSON_NUMBER) + new_msg->status_code = (int) jsonObjectGetNumber(tmp0); } - tmp0 = tmp->get_key(tmp,"content"); + tmp0 = jsonObjectGetKey(tmp,"content"); if(tmp0) { - char* s = tmp0->to_json(tmp0); - new_msg->_result_content = json_parse_string(s); + char* s = jsonObjectToJSON(tmp0); + new_msg->_result_content = jsonParseString(s); free(s); } } msgs[numparsed++] = new_msg; + debug_handler("deserialize has parsed %d messages", numparsed); } } - free_object(json); + + jsonObjectFree(json); return numparsed; } diff --git a/src/libstack/osrf_message.h b/src/libstack/osrf_message.h index 46638d8..637c8b1 100644 --- a/src/libstack/osrf_message.h +++ b/src/libstack/osrf_message.h @@ -1,7 +1,6 @@ #include "string_array.h" #include "utils.h" #include "logging.h" -#include "osrf_config.h" #include "objson/object.h" #include "objson/json_parser.h" @@ -62,7 +61,7 @@ struct osrf_message_struct { /* if we're a RESULT */ //json* result_content; - object* _result_content; + jsonObject* _result_content; /* unparsed json string */ char* result_string; @@ -70,7 +69,7 @@ struct osrf_message_struct { /* if we're a REQUEST */ char* method_name; //json* params; - object* _params; + jsonObject* _params; /* in case anyone wants to make a list of us. we won't touch this variable */ @@ -100,9 +99,9 @@ int osrf_message_deserialize(char* json, osrf_message* msgs[], int count); */ int osrf_message_from_xml( char* xml, osrf_message* msgs[] ); -void osrf_message_set_params( osrf_message* msg, object* o ); +void osrf_message_set_params( osrf_message* msg, jsonObject* o ); void osrf_message_set_method( osrf_message* msg, char* method_name ); -void osrf_message_add_object_param( osrf_message* msg, object* o ); +void osrf_message_add_object_param( osrf_message* msg, jsonObject* o ); void osrf_message_add_param( osrf_message*, char* param_string ); diff --git a/src/libstack/osrf_prefork.c b/src/libstack/osrf_prefork.c index 1d829ad..8e718be 100644 --- a/src/libstack/osrf_prefork.c +++ b/src/libstack/osrf_prefork.c @@ -18,28 +18,27 @@ int osrf_prefork_run(char* appname) { info_handler("Loading config in osrf_forker for app %s", appname); - object* max_req = osrf_settings_host_value_object("/apps/%s/unix_config/max_requests", appname); - object* min_children = osrf_settings_host_value_object("/apps/%s/unix_config/min_children", appname); - object* max_children = osrf_settings_host_value_object("/apps/%s/unix_config/max_children", appname); + jsonObject* max_req = osrf_settings_host_value_object("/apps/%s/unix_config/max_requests", appname); + jsonObject* min_children = osrf_settings_host_value_object("/apps/%s/unix_config/min_children", appname); + jsonObject* max_children = osrf_settings_host_value_object("/apps/%s/unix_config/max_children", appname); if(!max_req) warning_handler("Max requests not defined, assuming 1000"); - else maxr = max_req->num_value; + else maxr = (int) jsonObjectGetNumber(max_req); if(!min_children) warning_handler("Min children not defined, assuming 3"); - else minc = min_children->num_value; + else minc = (int) jsonObjectGetNumber(min_children); if(!max_children) warning_handler("Max children not defined, assuming 10"); - else maxc = max_children->num_value; + else maxc = (int) jsonObjectGetNumber(max_children); - free_object(max_req); - free_object(min_children); - free_object(max_children); + jsonObjectFree(max_req); + jsonObjectFree(min_children); + jsonObjectFree(max_children); /* --------------------------------------------------- */ char* resc = va_list_to_string("%s_listener", appname); - if(!osrf_system_bootstrap_client_resc( - osrf_get_bootstrap_config(), osrf_get_config_context(), resc)) + if(!osrf_system_bootstrap_client_resc( NULL, NULL, resc )) fatal_handler("Unable to bootstrap client for osrf_prefork_run()"); free(resc); @@ -71,8 +70,7 @@ void prefork_child_init_hook(prefork_child* child) { if(!child) return; info_handler("Child init hook for child %d", child->pid); char* resc = va_list_to_string("%s_drone",child->appname); - if(!osrf_system_bootstrap_client_resc( - osrf_get_bootstrap_config(), osrf_get_config_context(), resc)) + if(!osrf_system_bootstrap_client_resc( NULL, NULL, resc)) fatal_handler("Unable to bootstrap client for osrf_prefork_run()"); free(resc); } diff --git a/src/libstack/osrf_prefork.h b/src/libstack/osrf_prefork.h index 8c1725f..c1c35de 100644 --- a/src/libstack/osrf_prefork.h +++ b/src/libstack/osrf_prefork.h @@ -11,6 +11,7 @@ #include "opensrf/transport_message.h" #include "osrf_stack.h" #include "osrf_settings.h" +#include "osrfConfig.h" #define READ_BUFSIZE 4096 #define MAX_BUFSIZE 10485760 /* 10M enough? ;) */ diff --git a/src/libstack/osrf_settings.c b/src/libstack/osrf_settings.c index 8cc5d41..286a1eb 100644 --- a/src/libstack/osrf_settings.c +++ b/src/libstack/osrf_settings.c @@ -3,55 +3,16 @@ osrf_host_config* config = NULL; char* osrf_settings_host_value(char* format, ...) { - - /* grab the format string ---------------- */ - long len = 0; - va_list args; - va_list a_copy; - - va_copy(a_copy, args); - - va_start(args, format); - len = va_list_size(format, args); - char buf[len]; - memset(buf, 0, len); - - va_start(a_copy, format); - vsnprintf(buf, len - 1, format, a_copy); - va_end(a_copy); - /* -------------------------------------- */ - - object* o = object_find_path(config->config, buf); - - char* val = NULL; - if(o && o->is_string && o->string_data) { - val = strdup(o->string_data); - free_object(o); - } - + VA_LIST_TO_STRING(format); + jsonObject* o = jsonObjectFindPath(config->config, VA_BUF); + char* val = jsonObjectToSimpleString(o); + jsonObjectFree(o); return val; } -object* osrf_settings_host_value_object(char* format, ...) { - - /* grab the format string ---------------- */ - long len = 0; - va_list args; - va_list a_copy; - - va_copy(a_copy, args); - - va_start(args, format); - len = va_list_size(format, args); - char buf[len]; - memset(buf, 0, len); - - va_start(a_copy, format); - vsnprintf(buf, len - 1, format, a_copy); - va_end(a_copy); - /* -------------------------------------- */ - - return object_find_path(config->config, buf); +jsonObject* osrf_settings_host_value_object(char* format, ...) { + VA_LIST_TO_STRING(format); + return jsonObjectFindPath(config->config, VA_BUF); } @@ -60,14 +21,15 @@ int osrf_settings_retrieve(char* hostname) { if(!config) { osrf_app_session* session = osrf_app_client_session_init("opensrf.settings"); - object* params = new_object(hostname); - int req_id = osrf_app_session_make_req( session, params, "opensrf.settings.host_config.get", 1, NULL ); + jsonObject* params = jsonNewObject(hostname); + int req_id = osrf_app_session_make_req( + session, params, "opensrf.settings.host_config.get", 1, NULL ); osrf_message* omsg = osrf_app_session_request_recv( session, req_id, 60 ); - free_object(params); + jsonObjectFree(params); if(omsg && omsg->_result_content) { config = osrf_settings_new_host_config(hostname); - config->config = object_clone(omsg->_result_content); + config->config = jsonObjectClone(omsg->_result_content); osrf_message_free(omsg); } @@ -92,6 +54,6 @@ void osrf_settings_free_host_config(osrf_host_config* c) { if(!c) c = config; if(!c) return; free(c->hostname); - free_object(c->config); + jsonObjectFree(c->config); free(c); } diff --git a/src/libstack/osrf_settings.h b/src/libstack/osrf_settings.h index 4666aa0..f8d5d31 100644 --- a/src/libstack/osrf_settings.h +++ b/src/libstack/osrf_settings.h @@ -1,3 +1,6 @@ +#ifndef OSRF_SETTINGS_H +#define OSRF_SETTINGS_H + #include #include #include @@ -11,19 +14,17 @@ #include "objson/json_parser.h" #include "osrf_app_session.h" -#ifndef OSRF_SETTINGS_H -#define OSRF_SETTINGS_H typedef struct { char* hostname; - object* config; + jsonObject* config; } osrf_host_config; osrf_host_config* osrf_settings_new_host_config(char* hostname); void osrf_settings_free_host_config(osrf_host_config*); char* osrf_settings_host_value(char* path, ...); -object* osrf_settings_host_value_object(char* format, ...); +jsonObject* osrf_settings_host_value_object(char* format, ...); int osrf_settings_retrieve(char* hostname); #endif diff --git a/src/libstack/osrf_stack.c b/src/libstack/osrf_stack.c index 23cbf4c..3f73dbf 100644 --- a/src/libstack/osrf_stack.c +++ b/src/libstack/osrf_stack.c @@ -36,13 +36,18 @@ int osrf_stack_transport_handler( transport_message* msg, char* my_service ) { debug_handler( "Transport handler received new message \nfrom %s " "to %s with body \n\n%s\n", msg->sender, msg->recipient, msg->body ); + if(! msg->thread && ! msg->is_error ) { + warning_handler("Received a non-error message with no thread trace... dropping"); + message_free( msg ); + } + osrf_app_session* session = osrf_app_session_find_session( msg->thread ); if( session == NULL ) { /* we must be a server, build a new session */ info_handler( "Received message for nonexistant session. Dropping..." ); - osrf_app_server_session_init( msg->thread, my_service, msg->sender); - //message_free( msg ); - //return 1; + //osrf_app_server_session_init( msg->thread, my_service, msg->sender); + message_free( msg ); + return 1; } //debug_handler("Session [%s] found, building message", msg->thread ); diff --git a/src/libstack/osrf_system.c b/src/libstack/osrf_system.c index 39cf7cf..f8cf8dd 100644 --- a/src/libstack/osrf_system.c +++ b/src/libstack/osrf_system.c @@ -1,21 +1,9 @@ #include "osrf_system.h" -transport_client* global_client; -char* system_config = NULL; -char* config_context = NULL; -char* bootstrap_config = NULL; +transport_client* __osrfGlobalTransportClient; transport_client* osrf_system_get_transport_client() { - return global_client; -} - - -char* osrf_get_config_context() { - return config_context; -} - -char* osrf_get_bootstrap_config() { - return bootstrap_config; + return __osrfGlobalTransportClient; } int osrf_system_bootstrap_client( char* config_file, char* contextnode ) { @@ -24,23 +12,28 @@ int osrf_system_bootstrap_client( char* config_file, char* contextnode ) { int osrf_system_bootstrap_client_resc( char* config_file, char* contextnode, char* resource ) { - if( !config_file || !contextnode ) + if( !( config_file && contextnode ) && ! osrfConfigHasDefaultConfig() ) fatal_handler("No Config File Specified\n" ); - config_context = strdup(contextnode); - bootstrap_config = strdup(config_file); + if( config_file ) { + osrfConfigCleanup(); + osrfConfig* cfg = osrfConfigInit( config_file, contextnode ); + osrfConfigSetDefaultConfig(cfg); + } + - debug_handler("Bootstrapping client with config %s and context node %s", config_file, contextnode); + char* log_file = osrfConfigGetValue( NULL, "/logfile"); + char* log_level = osrfConfigGetValue( NULL, "/loglevel" ); + osrfStringArray* arr = osrfNewStringArray(8); + osrfConfigGetValueList(NULL, arr, "/domains/domain"); + char* username = osrfConfigGetValue( NULL, "/username" ); + char* password = osrfConfigGetValue( NULL, "/passwd" ); + char* port = osrfConfigGetValue( NULL, "/port" ); + char* unixpath = osrfConfigGetValue( NULL, "/unixpath" ); - config_reader_init( "opensrf.bootstrap", config_file ); + char* domain = osrfStringArrayGetString( arr, 0 ); /* just the first for now */ + osrfStringArrayFree(arr); - char* log_file = config_value( "opensrf.bootstrap", "//%s/logfile", contextnode ); - char* log_level = config_value( "opensrf.bootstrap", "//%s/loglevel", contextnode ); - char* domain = config_value( "opensrf.bootstrap", "//%s/domains/domain1", contextnode ); /* just the first for now */ - char* username = config_value( "opensrf.bootstrap", "//%s/username", contextnode ); - char* password = config_value( "opensrf.bootstrap", "//%s/passwd", contextnode ); - char* port = config_value( "opensrf.bootstrap", "//%s/port", contextnode ); - char* unixpath = config_value( "opensrf.bootstrap", "//%s/unixpath", contextnode ); int llevel = 0; int iport = 0; @@ -64,35 +57,32 @@ int osrf_system_bootstrap_client_resc( char* config_file, char* contextnode, cha if(client_connect( client, username, password, buf, 10, AUTH_DIGEST )) { /* child nodes will leak the parents client... but we can't free it without disconnecting the parents client :( */ - global_client = client; + __osrfGlobalTransportClient = client; } free(log_level); free(log_file); - free(domain); free(username); free(password); free(port); free(unixpath); - if(global_client) + if(__osrfGlobalTransportClient) return 1; return 0; } int osrf_system_disconnect_client() { - client_disconnect( global_client ); - client_free( global_client ); - global_client = NULL; + client_disconnect( __osrfGlobalTransportClient ); + client_free( __osrfGlobalTransportClient ); + __osrfGlobalTransportClient = NULL; return 0; } int osrf_system_shutdown() { - config_reader_free(); + osrfConfigCleanup(); osrf_system_disconnect_client(); - //free(system_config); - //free(config_context); osrf_settings_free_host_config(NULL); log_free(); return 1; diff --git a/src/libstack/osrf_system.h b/src/libstack/osrf_system.h index 66e155d..0b9b262 100644 --- a/src/libstack/osrf_system.h +++ b/src/libstack/osrf_system.h @@ -1,11 +1,13 @@ +#ifndef OSRF_SYSTEM_H +#define OSRF_SYSTEM_H + #include "opensrf/transport_client.h" #include "utils.h" #include "logging.h" -#include "osrf_config.h" -//#include "osrf_settings.h" +//#include "osrf_config.h" +#include "osrf_settings.h" +#include "osrfConfig.h" -#ifndef OSRF_SYSTEM_H -#define OSRF_SYSTEM_H /** Connects to jabber. Returns 1 on success, 0 on failure contextnode is the location in the config file where we collect config info diff --git a/src/objson/Makefile b/src/objson/Makefile index d8ed0b6..f55f27e 100644 --- a/src/objson/Makefile +++ b/src/objson/Makefile @@ -31,6 +31,12 @@ UTIL_DIR = ../utils DEST_INCLUDE = objson CC_OPTS += -DSTRICT_JSON_WRITE #-DSTRICT_JSON_READ +# ------------- +#CC_OPTS += -I ../utils/ +#LD_OPTS += -L . +#TMPDIR = . +# ------------- + all: msg test msg: diff --git a/src/objson/json_parser.c b/src/objson/json_parser.c index 9f3221d..95e385a 100644 --- a/src/objson/json_parser.c +++ b/src/objson/json_parser.c @@ -21,7 +21,14 @@ GNU General Public License for more details. */ int current_strlen; /* XXX need to move this into the function params for thread support */ -object* json_parse_string(char* string) { + +jsonObject* jsonParseString( char* string ) { + return json_parse_string( string ); +} + +//jsonObject* (*jsonParseString) (char* str) = &_jsonParseString; + +jsonObject* json_parse_string(char* string) { if(string == NULL) return NULL; @@ -30,24 +37,27 @@ object* json_parse_string(char* string) { if(current_strlen == 0) return NULL; - object* obj = new_object(NULL); unsigned long index = 0; json_eat_ws(string, &index, 1); /* remove leading whitespace */ if(index == current_strlen) return NULL; + jsonObject* obj = jsonNewObject(NULL); + int status = _json_parse_string(string, &index, obj); if(!status) return obj; - if(status == -2) + if(status == -2) { + jsonObjectFree(obj); return NULL; + } return NULL; } -int _json_parse_string(char* string, unsigned long* index, object* obj) { - assert(string && index && *index < current_strlen); +int _json_parse_string(char* string, unsigned long* index, jsonObject* obj) { + if( !string || !index || *index >= current_strlen) return -2; int status = 0; /* return code from parsing routines */ char* classname = NULL; /* object class hint */ @@ -137,7 +147,7 @@ int _json_parse_string(char* string, unsigned long* index, object* obj) { } if(classname){ - obj->set_class(obj, classname); + jsonObjectSetClass(obj, classname); free(classname); } @@ -145,7 +155,7 @@ int _json_parse_string(char* string, unsigned long* index, object* obj) { } -int json_parse_json_null(char* string, unsigned long* index, object* obj) { +int json_parse_json_null(char* string, unsigned long* index, jsonObject* obj) { if(*index >= (current_strlen - 3)) { return json_handle_error(string, index, @@ -154,7 +164,7 @@ int json_parse_json_null(char* string, unsigned long* index, object* obj) { if(!strncasecmp(string + (*index), "null", 4)) { (*index) += 4; - obj->is_null = 1; + obj->type = JSON_NULL; return 0; } else { return json_handle_error(string, index, @@ -163,8 +173,8 @@ int json_parse_json_null(char* string, unsigned long* index, object* obj) { } /* should be at the first character of the bool at this point */ -int json_parse_json_bool(char* string, unsigned long* index, object* obj) { - assert(string && obj && *index < current_strlen); +int json_parse_json_bool(char* string, unsigned long* index, jsonObject* obj) { + if( ! string || ! obj || *index >= current_strlen ) return -1; char* ret = "json_parse_json_bool(): truncated bool"; @@ -173,9 +183,8 @@ int json_parse_json_bool(char* string, unsigned long* index, object* obj) { if(!strncasecmp( string + (*index), "false", 5)) { (*index) += 5; - obj->bool_value = 0; - obj->is_bool = 1; - obj->is_null = 0; + obj->value.b = 0; + obj->type = JSON_BOOL; return 0; } @@ -184,9 +193,8 @@ int json_parse_json_bool(char* string, unsigned long* index, object* obj) { if(!strncasecmp( string + (*index), "true", 4)) { (*index) += 4; - obj->bool_value = 1; - obj->is_bool = 1; - obj->is_null = 0; + obj->value.b = 1; + obj->type = JSON_BOOL; return 0; } @@ -195,8 +203,8 @@ int json_parse_json_bool(char* string, unsigned long* index, object* obj) { /* expecting the first character of the number */ -int json_parse_json_number(char* string, unsigned long* index, object* obj) { - assert(string && obj && *index < current_strlen); +int json_parse_json_number(char* string, unsigned long* index, jsonObject* obj) { + if( ! string || ! obj || *index >= current_strlen ) return -1; growing_buffer* buf = buffer_init(64); char c = string[*index]; @@ -217,6 +225,7 @@ int json_parse_json_number(char* string, unsigned long* index, object* obj) { else if( c == '.' ) { if(dot_seen) { + buffer_free(buf); return json_handle_error(string, index, "json_parse_json_number(): malformed json number"); } @@ -231,32 +240,22 @@ int json_parse_json_number(char* string, unsigned long* index, object* obj) { if(done) break; } - if(dot_seen) { - obj->is_double = 1; - obj->is_null = 0; - obj->double_value = strtod(buf->buf, NULL); - buffer_free(buf); - return 0; - - } else { - obj->is_number = 1; - obj->is_null = 0; - obj->num_value = atol(buf->buf); - buffer_free(buf); - return 0; - } + obj->type = JSON_NUMBER; + obj->value.n = strtod(buf->buf, NULL); + buffer_free(buf); + return 0; } /* index should point to the character directly following the '['. when done * index will point to the character directly following the ']' character */ -int json_parse_json_array(char* string, unsigned long* index, object* obj) { - assert(string && obj && index && *index < current_strlen); +int json_parse_json_array(char* string, unsigned long* index, jsonObject* obj) { + + if( ! string || ! obj || ! index || *index >= current_strlen ) return -1; int status = 0; int in_parse = 0; /* true if this array already contains one item */ - obj->is_array = 1; - obj->is_null = 0; + obj->type = JSON_ARRAY; int set = 0; int done = 0; @@ -280,24 +279,23 @@ int json_parse_json_array(char* string, unsigned long* index, object* obj) { json_eat_ws(string, index, 1); } - object* item = new_object(NULL); + jsonObject* item = jsonNewObject(NULL); -#ifndef STRICT_JSON_READ + #ifndef STRICT_JSON_READ if(*index < current_strlen) { if(string[*index] == ',' || string[*index] == ']') { status = 0; set = 1; } } - if(!set) - status = _json_parse_string(string, index, item); + if(!set) status = _json_parse_string(string, index, item); -#else - status = _json_parse_string(string, index, item); -#endif + #else + status = _json_parse_string(string, index, item); + #endif - if(status) return status; - obj->push(obj, item); + if(status) { jsonObjectFree(item); return status; } + jsonObjectPush(obj, item); in_parse = 1; set = 0; } @@ -313,11 +311,10 @@ int json_parse_json_array(char* string, unsigned long* index, object* obj) { /* index should point to the character directly following the '{'. when done * index will point to the character directly following the '}' */ -int json_parse_json_object(char* string, unsigned long* index, object* obj) { - assert(string && obj && index && *index < current_strlen); +int json_parse_json_object(char* string, unsigned long* index, jsonObject* obj) { + if( ! string || !obj || ! index || *index >= current_strlen ) return -1; - obj->is_hash = 1; - obj->is_null = 0; + obj->type = JSON_HASH; int status; int in_parse = 0; /* true if we've already added one item to this object */ int set = 0; @@ -343,16 +340,16 @@ int json_parse_json_object(char* string, unsigned long* index, object* obj) { } /* first we grab the hash key */ - object* key_obj = new_object(NULL); + jsonObject* key_obj = jsonNewObject(NULL); status = _json_parse_string(string, index, key_obj); if(status) return status; - if(!key_obj->is_string) { + if(key_obj->type != JSON_STRING) { return json_handle_error(string, index, "_json_parse_json_object(): hash key not a string"); } - char* key = key_obj->string_data; + char* key = key_obj->value.s; json_eat_ws(string, index, 1); @@ -365,7 +362,7 @@ int json_parse_json_object(char* string, unsigned long* index, object* obj) { /* now grab the value object */ json_eat_ws(string, index, 1); - object* value_obj = new_object(NULL); + jsonObject* value_obj = jsonNewObject(NULL); #ifndef STRICT_JSON_READ if(*index < current_strlen) { @@ -384,8 +381,8 @@ int json_parse_json_object(char* string, unsigned long* index, object* obj) { if(status) return status; /* put the data into the object and continue */ - obj->add_key(obj, key, value_obj); - free_object(key_obj); + jsonObjectSetKey(obj, key, value_obj); + jsonObjectFree(key_obj); in_parse = 1; set = 0; } @@ -400,8 +397,8 @@ int json_parse_json_object(char* string, unsigned long* index, object* obj) { /* when done, index will point to the character after the closing quote */ -int json_parse_json_string(char* string, unsigned long* index, object* obj) { - assert(string && index && *index < current_strlen); +int json_parse_json_string(char* string, unsigned long* index, jsonObject* obj) { + if( ! string || ! index || *index >= current_strlen ) return -1; int in_escape = 0; int done = 0; @@ -474,6 +471,7 @@ int json_parse_json_string(char* string, unsigned long* index, object* obj) { (*index)++; if(*index >= (current_strlen - 4)) { + buffer_free(buf); return json_handle_error(string, index, "json_parse_json_string(): truncated escaped unicode"); } @@ -533,14 +531,14 @@ int json_parse_json_string(char* string, unsigned long* index, object* obj) { if(done) break; } - obj->set_string(obj, buf->buf); + jsonObjectSetString(obj, buf->buf); buffer_free(buf); return 0; } void json_eat_ws(char* string, unsigned long* index, int eat_all) { - assert(string && index); + if( ! string || ! index ) return; if(*index >= current_strlen) return; @@ -560,7 +558,8 @@ void json_eat_ws(char* string, unsigned long* index, int eat_all) { * when done, index will point to the first character after the final / */ int json_eat_comment(char* string, unsigned long* index, char** buffer, int parse_class) { - assert(string && index && *index < current_strlen); + if( ! string || ! index || *index >= current_strlen ) return -1; + if(string[*index] != '*' && string[*index] != '/' ) return json_handle_error(string, index, @@ -722,10 +721,14 @@ int json_handle_error(char* string, unsigned long* index, char* err_msg) { } -object* json_parse_file(char* filename) { +jsonObject* jsonParseFile( const char* filename ) { + return json_parse_file( filename ); +} + +jsonObject* json_parse_file(const char* filename) { if(!filename) return NULL; char* data = file_to_string(filename); - object* o = json_parse_string(data); + jsonObject* o = json_parse_string(data); free(data); return o; } diff --git a/src/objson/json_parser.h b/src/objson/json_parser.h index a2a6ec6..e47a429 100644 --- a/src/objson/json_parser.h +++ b/src/objson/json_parser.h @@ -19,47 +19,52 @@ GNU General Public License for more details. /* --------------------------------------------------------------------------------------- JSON parser. * --------------------------------------------------------------------------------------- */ +#ifndef JSON_PARSER_H +#define JSON_PARSER_H + #include #include "object.h" #include "utils.h" -#ifndef JSON_PARSER_H -#define JSON_PARSER_H /* Parses the given JSON string and returns the built object. * returns NULL (and prints parser error to stderr) on error. - * if string is NULL, returns an object whose is_null flag is set to true. */ -object* json_parse_string(char* string); -object* json_parse_file(char* filename); +jsonObject* json_parse_string(char* string); + +jsonObject* jsonParseString( char* string ); + +jsonObject* json_parse_file( const char* filename ); + +jsonObject* jsonParseFile( const char* string ); /* does the actual parsing work. returns 0 on success. -1 on error and * -2 if there was no object to build (string was all comments) */ -int _json_parse_string(char* string, unsigned long* index, object* obj); +int _json_parse_string(char* string, unsigned long* index, jsonObject* obj); /* returns 0 on success and turns obj into a string object */ -int json_parse_json_string(char* string, unsigned long* index, object* obj); +int json_parse_json_string(char* string, unsigned long* index, jsonObject* obj); /* returns 0 on success and turns obj into a number or double object */ -int json_parse_json_number(char* string, unsigned long* index, object* obj); +int json_parse_json_number(char* string, unsigned long* index, jsonObject* obj); /* returns 0 on success and turns obj into an 'object' object */ -int json_parse_json_object(char* string, unsigned long* index, object* obj); +int json_parse_json_object(char* string, unsigned long* index, jsonObject* obj); /* returns 0 on success and turns object into an array object */ -int json_parse_json_array(char* string, unsigned long* index, object* obj); +int json_parse_json_array(char* string, unsigned long* index, jsonObject* obj); /* churns through whitespace and increments index as it goes. * eat_all == true means we should eat newlines, tabs */ void json_eat_ws(char* string, unsigned long* index, int eat_all); -int json_parse_json_bool(char* string, unsigned long* index, object* obj); +int json_parse_json_bool(char* string, unsigned long* index, jsonObject* obj); /* removes comments from a json string. if the comment contains a class hint * and class_hint isn't NULL, an allocated char* with the class name will be @@ -74,7 +79,7 @@ int json_handle_error(char* string, unsigned long* index, char* err_msg); /* returns true if c is 0-9 */ int is_number(char c); -int json_parse_json_null(char* string, unsigned long* index, object* obj); +int json_parse_json_null(char* string, unsigned long* index, jsonObject* obj); #endif diff --git a/src/objson/object.c b/src/objson/object.c index e04d6ad..ee3dbff 100644 --- a/src/objson/object.c +++ b/src/objson/object.c @@ -15,8 +15,6 @@ GNU General Public License for more details. #include "object.h" #include "json_parser.h" -#include - /* ---------------------------------------------------------------------- */ @@ -26,87 +24,59 @@ GNU General Public License for more details. char* __tabs(int count); -object* new_object(char* string_value) { - return _init_object(string_value); -} +jsonObject* jsonNewObject( const char* stringValue ) { + jsonObject* obj = (jsonObject*) safe_malloc(sizeof(jsonObject)); + obj->size = 0; + obj->type = JSON_NULL; -object* new_int_object(long num) { - object* o = new_object(NULL); - o->is_null = 0; - o->is_number = 1; - o->num_value = num; - return o; -} + if(stringValue) { + obj->type = JSON_STRING; + obj->value.s = strdup(stringValue); + } -object* new_double_object(double num) { - object* o = new_object(NULL); - o->is_null = 0; - o->is_double = 1; - o->double_value = num; - return o; + return obj; } -object* _init_object(char* string_value) { - object* obj = (object*) safe_malloc(sizeof(object)); - obj->size = 0; - obj->data = NULL; - - obj->push = &object_push; - obj->set_index = &object_set_index; - obj->add_key = &object_add_key; - obj->get_index = &object_get_index; - obj->get_key = &object_get_key; - obj->get_string = &object_get_string; - obj->set_string = &object_set_string; - obj->set_number = &object_set_number; - obj->set_class = &object_set_class; - obj->set_double = &object_set_double; - obj->remove_index = &object_remove_index; - obj->remove_key = &object_remove_key; - obj->to_json = &object_to_json; - obj->set_comment = &object_set_comment; - - if(string_value) { - obj->is_string = 1; - obj->string_data = strdup(string_value); - } else - obj->is_null = 1; - return obj; + +jsonObject* jsonNewNumberObject( double num ) { + jsonObject* o = jsonNewObject(NULL); + o->type = JSON_NUMBER; + o->value.n = num; + return o; + } -object_node* new_object_node(object* obj) { - object_node* node = (object_node*) safe_malloc(sizeof(object_node)); + +jsonObjectNode* jsonNewObjectNode( jsonObject* obj ) { + jsonObjectNode* node = (jsonObjectNode*) safe_malloc(sizeof(jsonObjectNode)); node->item = obj; node->next = NULL; node->index = -1; return node; } -unsigned long object_push(object* obj, object* new_obj) { - assert(obj != NULL); - object_clear_type(obj); - obj->is_array = 1; +unsigned long jsonObjectPush( jsonObject* obj, jsonObject* new_obj) { + if(!obj) return -1; + + obj->type = JSON_ARRAY; if(new_obj == NULL) { - new_obj = new_object(NULL); - new_obj->is_null = 1; + new_obj = jsonNewObject(NULL); + new_obj->type = JSON_NULL; } - object_node* node = new_object_node(new_obj); + jsonObjectNode* node = jsonNewObjectNode(new_obj); node->index = obj->size++; - if( obj->size > MAX_OBJECT_NODES ) - return -1; - - if(obj->data == NULL) { - obj->data = node; + if(obj->value.c == NULL) { + obj->value.c = node; } else { /* append the node onto the end */ - object_node* tmp = obj->data; + jsonObjectNode* tmp = obj->value.c; while(tmp) { if(tmp->next == NULL) break; tmp = tmp->next; @@ -116,45 +86,44 @@ unsigned long object_push(object* obj, object* new_obj) { return obj->size; } -unsigned long object_set_index(object* obj, unsigned long index, object* new_obj) { - assert(obj != NULL && index <= MAX_OBJECT_NODES); - object_clear_type(obj); - obj->is_array = 1; +unsigned long jsonObjectSetIndex( jsonObject* obj, unsigned long index, jsonObject* new_obj) { + if( obj == NULL ) return -1; + obj->type = JSON_ARRAY; if(obj->size <= index) obj->size = index + 1; if(new_obj == NULL) { - new_obj = new_object(NULL); - new_obj->is_null = 1; + new_obj = jsonNewObject(NULL); + new_obj->type = JSON_NULL; } - object_node* node = new_object_node(new_obj); + jsonObjectNode* node = jsonNewObjectNode(new_obj); node->index = index; - if( obj->data == NULL ) { - obj->data = node; + if( obj->value.c == NULL ) { + obj->value.c = node; } else { - if(obj->data->index == index) { - object_node* tmp = obj->data->next; - free_object_node(obj->data); - obj->data = node; + if(obj->value.c->index == index) { + jsonObjectNode* tmp = obj->value.c->next; + jsonObjectNodeFree(obj->value.c); + obj->value.c = node; node->next = tmp; } else { - object_node* prev = obj->data; - object_node* cur = prev->next; + jsonObjectNode* prev = obj->value.c; + jsonObjectNode* cur = prev->next; int inserted = 0; while(cur != NULL) { /* replace an existing node */ if( cur->index == index ) { - object_node* tmp = cur->next; - free_object_node(cur); + jsonObjectNode* tmp = cur->next; + jsonObjectNodeFree(cur); node->next = tmp; prev->next = node; inserted = 1; @@ -181,14 +150,15 @@ unsigned long object_set_index(object* obj, unsigned long index, object* new_ob } -void object_shift_index(object* obj, unsigned long index) { - assert(obj && index <= MAX_OBJECT_NODES); - if(obj->data == NULL) { +void _jsonObjectShifIndex( jsonObject* obj, unsigned long index) { + if( obj == NULL || index < 0 ) return; + + if(obj->value.c == NULL) { obj->size = 0; return; } - object_node* data = obj->data; + jsonObjectNode* data = obj->value.c; while(data) { if(data->index >= index) data->index--; @@ -197,29 +167,30 @@ void object_shift_index(object* obj, unsigned long index) { obj->size--; } -unsigned long object_remove_index(object* obj, unsigned long index) { - assert(obj != NULL && index <= MAX_OBJECT_NODES); - if(obj->data == NULL) return 0; +unsigned long jsonObjectRemoveIndex( jsonObject* obj, unsigned long index) { + if( obj == NULL || index < 0 ) return -1; + + if(obj->value.c == NULL) return 0; /* removing the first item in the list */ - if(obj->data->index == index) { - object_node* tmp = obj->data->next; - free_object_node(obj->data); - obj->data = tmp; - object_shift_index(obj,index); + if(obj->value.c->index == index) { + jsonObjectNode* tmp = obj->value.c->next; + jsonObjectNodeFree(obj->value.c); + obj->value.c = tmp; + _jsonObjectShiftIndex(obj,index); return obj->size; } - object_node* prev = obj->data; - object_node* cur = prev->next; + jsonObjectNode* prev = obj->value.c; + jsonObjectNode* cur = prev->next; while(cur) { if(cur->index == index) { - object_node* tmp = cur->next; - free_object_node(cur); + jsonObjectNode* tmp = cur->next; + jsonObjectNodeFree(cur); prev->next = tmp; - object_shift_index(obj,index); + _jsonObjectShiftIndex(obj, index); break; } prev = cur; @@ -230,28 +201,49 @@ unsigned long object_remove_index(object* obj, unsigned long index) { } -unsigned long object_remove_key(object* obj, char* key) { - assert(obj && key); - if(obj->data == NULL) return 0; +void _jsonObjectShiftIndex(jsonObject* obj, unsigned long index) { + + if( ! obj ) return; + + if(obj->value.c == NULL) { + obj->size = 0; + return; + } + + jsonObjectNode* data = obj->value.c; + while(data) { + if(data->index >= index) + data->index--; + data = data->next; + } + obj->size--; +} + + +unsigned long jsonObjectRemoveKey( jsonObject* obj, const char* key) { + if( obj == NULL || key == NULL ) return -1; + + if(obj->value.c == NULL) return 0; /* removing the first item in the list */ - if(!strcmp(obj->data->key, key)) { - object_node* tmp = obj->data->next; - free_object_node(obj->data); - obj->data = tmp; - if(!obj->data) - obj->size = 0; + if(!strcmp(obj->value.c->key, key)) { + + jsonObjectNode* tmp = obj->value.c->next; + jsonObjectNodeFree(obj->value.c); + obj->value.c = tmp; + if(!obj->value.c) obj->size = 0; return obj->size; } - object_node* prev = obj->data; - object_node* cur = prev->next; + jsonObjectNode* prev = obj->value.c; + jsonObjectNode* cur = prev->next; while(cur) { if(!strcmp(cur->key,key)) { - object_node* tmp = cur->next; - free_object_node(cur); + + jsonObjectNode* tmp = cur->next; + jsonObjectNodeFree(cur); prev->next = tmp; obj->size--; break; @@ -264,46 +256,43 @@ unsigned long object_remove_key(object* obj, char* key) { } -unsigned long object_add_key(object* obj, char* key, object* new_obj) { - - assert(obj != NULL && key != NULL); - object_clear_type(obj); - obj->is_hash = 1; - +unsigned long jsonObjectSetKey( jsonObject* obj, const char* key, jsonObject* new_obj ) { + if( obj == NULL || key == NULL ) return -1; + obj->type = JSON_HASH; if(new_obj == NULL) { - new_obj = new_object(NULL); - new_obj->is_null = 1; + new_obj = jsonNewObject(NULL); + new_obj->type = JSON_NULL; } - object_node* node = new_object_node(new_obj); + jsonObjectNode* node = jsonNewObjectNode(new_obj); node->key = strdup(key); - if( obj->data == NULL ) { - obj->data = node; + if( obj->value.c == NULL ) { + obj->value.c = node; obj->size++; } else { /* replace the first node */ - if(!strcmp(obj->data->key, key)) { - object_node* tmp = obj->data->next; - free_object_node(obj->data); - obj->data = node; + if(!strcmp(obj->value.c->key, key)) { + jsonObjectNode* tmp = obj->value.c->next; + jsonObjectNodeFree(obj->value.c); + obj->value.c = node; node->next = tmp; } else { - object_node* prev = obj->data; - object_node* cur = prev->next; + jsonObjectNode* prev = obj->value.c; + jsonObjectNode* cur = prev->next; int inserted = 0; while(cur != NULL) { /* replace an existing node */ if( !strcmp(cur->key, key) ) { - object_node* tmp = cur->next; - free_object_node(cur); + jsonObjectNode* tmp = cur->next; + jsonObjectNodeFree(cur); node->next = tmp; prev->next = node; inserted = 1; @@ -326,94 +315,101 @@ unsigned long object_add_key(object* obj, char* key, object* new_obj) { } -void free_object(object* obj) { - +void jsonObjectFree( jsonObject* obj) { if(obj == NULL) return; - if(obj->classname) free(obj->classname); - if(obj->comment) free(obj->comment); - while(obj->data) { - object_node* tmp = obj->data->next; - free_object_node(obj->data); - obj->data = tmp; + free(obj->classname); + free(obj->comment); + + if( obj->type == JSON_ARRAY || obj->type == JSON_HASH ) { + while(obj->value.c) { + jsonObjectNode* tmp = obj->value.c->next; + jsonObjectNodeFree(obj->value.c); + obj->value.c = tmp; + } } - if(obj->string_data) - free(obj->string_data); + if(obj->type == JSON_STRING) + free(obj->value.s); + free(obj); } -void free_object_node(object_node* node) { +void jsonObjectNodeFree( jsonObjectNode* node ) { if(node == NULL) return; - if(node->key) free(node->key); - free_object(node->item); + free(node->key); + jsonObjectFree(node->item); free(node); } -object* object_get_index( object* obj, unsigned long index ) { - assert(obj != NULL && index <= MAX_OBJECT_NODES); - object_node* node = obj->data; - while(node) { - if(node->index == index) - return node->item; - node = node->next; +jsonObject* jsonObjectGetIndex( const jsonObject* obj, unsigned long index ) { + + if( obj && index >= 0 && obj->type == JSON_ARRAY ) { + + jsonObjectNode* node = obj->value.c; + while(node) { + if(node->index == index) + return node->item; + node = node->next; + } } + return NULL; } -object* object_get_key( object* obj, char* key ) { - assert(obj && key); - object_node* node = obj->data; +jsonObject* jsonObjectGetKey( const jsonObject* obj, const char* key ) { - while(node) { - if(node->key && !strcmp(node->key, key)) - return node->item; - node = node->next; - } + if( obj && key && obj->type == JSON_HASH ) { + + jsonObjectNode* node = obj->value.c; + + while(node) { + if(node->key && !strcmp(node->key, key)) + return node->item; + node = node->next; + } + } return NULL; } -char* object_get_string(object* obj) { - assert(obj != NULL); - return obj->string_data; +char* jsonObjectGetString( const jsonObject* obj ) { + if( obj && obj->type == JSON_STRING ) return obj->value.s; + return NULL; } -void object_set_string(object* obj, char* string) { - assert(obj); - object_clear_type(obj); - obj->is_string = 1; - if(string) - obj->string_data = strdup(string); +double jsonObjectGetNumber( const jsonObject* obj ) { + if( obj && obj->type == JSON_NUMBER ) return obj->value.n; + return 0; } - -void object_set_number(object* obj, long num) { - assert(obj); - object_clear_type(obj); - obj->is_number = 1; - obj->num_value = num; +void jsonObjectSetString( jsonObject* obj, const char* string) { + if( obj ) { + obj->type = JSON_STRING; + if(string) obj->value.s = strdup(string); + else obj->value.s = NULL; + } } -void object_set_double(object* obj, double num) { - assert(obj); - object_clear_type(obj); - obj->is_double = 1; - obj->double_value = num; + +void jsonObjectSetNumber( jsonObject* obj, double num) { + if(obj) { + obj->type = JSON_NUMBER; + obj->value.n = num; + } } -void object_set_class(object* obj, char* classname) { - assert(obj && classname); +void jsonObjectSetClass( jsonObject* obj, const char* classname) { + if( obj == NULL || classname == NULL ) return; obj->classname = strdup(classname); } -char* object_to_json(object* obj) { +char* jsonObjectToJSON( const jsonObject* obj ) { - if(obj == NULL) - return strdup("null"); + if(obj == NULL) return strdup("null"); growing_buffer* buf = buffer_init(64); @@ -424,85 +420,98 @@ char* object_to_json(object* obj) { buffer_add(buf, "--*/"); } - if(obj->is_bool && obj->bool_value) - buffer_add(buf, "true"); - - else if(obj->is_bool && ! obj->bool_value) - buffer_add(buf, "false"); - - else if(obj->is_number) { - char b[128]; - memset(b, 0, 128); - sprintf(b, "%ld", obj->num_value); - buffer_add(buf, b); - } + switch( obj->type ) { - else if(obj->is_double) { - char b[128]; - memset(b, 0, 128); - sprintf(b, "%lf", obj->double_value); - buffer_add(buf, b); - } + case JSON_BOOL: + if(obj->value.b) buffer_add(buf, "true"); + else buffer_add(buf, "false"); + break; - else if(obj->is_null) - buffer_add(buf, "null"); + case JSON_NUMBER: { + double x = obj->value.n; - else if (obj->is_string) { + /* if the number does not need to be a double, + turn it into an int on the way out */ + if( x == (int) x ) { + INT_TO_STRING((int)x); + buffer_add(buf, INTSTR); - buffer_add(buf, "\""); - char* data = obj->string_data; - int len = strlen(data); - - char* output = uescape(data, len, 1); - buffer_add(buf, output); - free(output); - buffer_add(buf, "\""); + } else { + DOUBLE_TO_STRING(x); + buffer_add(buf, DOUBLESTR); + } + break; + } - } else if(obj->is_array) { + case JSON_NULL: + buffer_add(buf, "null"); + break; - buffer_add(buf, "["); - int i; - for( i = 0; i!= obj->size; i++ ) { - char* data = object_to_json(obj->get_index(obj,i)); + case JSON_STRING: + buffer_add(buf, "\""); + char* data = obj->value.s; + int len = strlen(data); + + char* output = uescape(data, len, 1); + buffer_add(buf, output); + free(output); + buffer_add(buf, "\""); + break; + case JSON_ARRAY: + buffer_add(buf, "["); + int i; + for( i = 0; i!= obj->size; i++ ) { + const jsonObject* x = jsonObjectGetIndex(obj,i); + char* data = jsonObjectToJSON(x); + #ifdef STRICT_JSON_WRITE - buffer_add(buf, data); -#else - if(strcmp(data,"null")) /* only add the string if it isn't null */ buffer_add(buf, data); +#else + if(strcmp(data,"null")) /* only add the string if it isn't null */ + buffer_add(buf, data); #endif + + free(data); + if(i != obj->size - 1) + buffer_add(buf, ","); + } + buffer_add(buf, "]"); + break; - free(data); - if(i != obj->size - 1) - buffer_add(buf, ","); - } - buffer_add(buf, "]"); - - } else if(obj->is_hash) { - - buffer_add(buf, "{"); - object_iterator* itr = new_iterator(obj); - object_node* tmp; + case JSON_HASH: + + buffer_add(buf, "{"); + jsonObjectIterator* itr = jsonNewObjectIterator(obj); + jsonObjectNode* tmp; + + while( (tmp = jsonObjectIteratorNext(itr)) ) { - while( (tmp = itr->next(itr)) ) { - buffer_add(buf, "\""); - buffer_add(buf, tmp->key); - buffer_add(buf, "\":"); - char* data = object_to_json(tmp->item); + buffer_add(buf, "\""); + buffer_add(buf, tmp->key); + buffer_add(buf, "\":"); + char* data = jsonObjectToJSON(tmp->item); #ifdef STRICT_JSON_WRITE - buffer_add(buf, data); -#else - if(strcmp(data,"null")) /* only add the string if it isn't null */ buffer_add(buf, data); +#else + if(strcmp(data,"null")) /* only add the string if it isn't null */ + buffer_add(buf, data); #endif - if(itr->has_next(itr)) - buffer_add(buf, ","); - free(data); - } - free_iterator(itr); - buffer_add(buf, "}"); + if(jsonObjectIteratorHasNext(itr)) + buffer_add(buf, ","); + free(data); + } + + jsonObjectIteratorFree(itr); + buffer_add(buf, "}"); + break; + + default: + fprintf(stderr, "Unknown object type %d\n", obj->type); + break; + } /* close out the object hint */ @@ -525,18 +534,8 @@ char* object_to_json(object* obj) { } -void object_clear_type(object* obj) { - if(obj == NULL) return; - obj->is_string = 0; - obj->is_hash = 0; - obj->is_array = 0; - obj->is_bool = 0; - obj->is_null = 0; -} - - -void object_set_comment(object* obj, char* com) { - assert(obj && com); +void jsonObjectSetComment( jsonObject* obj, const char* com) { + if( obj == NULL || com == NULL ) return; obj->comment = strdup(com); } @@ -550,25 +549,26 @@ char* __tabs(int count) { return final; } -char* json_string_format(char* string) { +char* jsonFormatString( const char* string ) { if(!string) return strdup(""); growing_buffer* buf = buffer_init(64); int i; int depth = 0; + char* tab = NULL; for(i=0; i!= strlen(string); i++) { if( string[i] == '{' || string[i] == '[' ) { - char* tab = __tabs(++depth); + tab = __tabs(++depth); buffer_fadd( buf, "%c\n%s", string[i], tab); free(tab); } else if( string[i] == '}' || string[i] == ']' ) { - char* tab = __tabs(--depth); + tab = __tabs(--depth); buffer_fadd( buf, "\n%s%c", tab, string[i]); free(tab); @@ -580,7 +580,7 @@ char* json_string_format(char* string) { } else if( string[i] == ',' ) { - char* tab = __tabs(depth); + tab = __tabs(depth); buffer_fadd(buf, ",\n%s", tab); free(tab); @@ -595,10 +595,10 @@ char* json_string_format(char* string) { } -object* object_clone(object* o) { +jsonObject* jsonObjectClone(const jsonObject* o) { if(!o) return NULL; - char* json = o->to_json(o); - object* newo = json_parse_string(json); + char* json = jsonObjectToJSON(o); + jsonObject* newo = jsonParseString(json); free(json); return newo; } @@ -608,56 +608,42 @@ object* object_clone(object* o) { /* ---------------------------------------------------------------------- */ /* Iterator */ -object_iterator* new_iterator(object* obj) { - object_iterator* iter = safe_malloc(sizeof(object_iterator)); +jsonObjectIterator* jsonNewObjectIterator(const jsonObject* obj) { + + if(!obj) return NULL; + jsonObjectIterator* iter = safe_malloc(sizeof(jsonObjectIterator)); iter->obj = obj; - iter->current = obj->data; - iter->next = &object_iterator_next; - iter->has_next = &object_iterator_has_next; + + if( obj->type == JSON_HASH || obj->type == JSON_ARRAY ) + iter->current = obj->value.c; + else iter->current = NULL; return iter; } -object_node* object_iterator_next(object_iterator* itr) { - assert( itr != NULL ); +jsonObjectNode* jsonObjectIteratorNext( jsonObjectIterator* itr ) { + if( itr == NULL ) return NULL; - object_node* tmp = itr->current; + jsonObjectNode* tmp = itr->current; if(tmp == NULL) return NULL; itr->current = itr->current->next; return tmp; } -void free_iterator(object_iterator* iter) { - if(iter == NULL) return; +void jsonObjectIteratorFree(jsonObjectIterator* iter) { free(iter); } -int object_iterator_has_next(object_iterator* itr) { - assert(itr); - if(itr->current) return 1; - return 0; +int jsonObjectIteratorHasNext(const jsonObjectIterator* itr) { + return (itr && itr->current); } -object* object_find_path(object* obj, char* format, ...) { +jsonObject* jsonObjectFindPath( const jsonObject* obj, char* format, ...) { if(!obj || !format || strlen(format) < 1) return NULL; - /* build the string from the variable args */ - long len = 0; - va_list args, a_copy; - - va_copy(a_copy, args); - - va_start(args, format); - len = va_list_size(format, args); - char buf[len]; - bzero(buf, len); - - va_start(a_copy, format); - vsnprintf(buf, len - 1, format, a_copy); - va_end(a_copy); - /* -------------------------------------------- */ - + VA_LIST_TO_STRING(format); + char* buf = VA_BUF; /* tmp storage for strtok_r */ char tokbuf[len]; @@ -676,7 +662,7 @@ object* object_find_path(object* obj, char* format, ...) { /* special case where path starts with // (start anywhere) */ if(strlen(pathcopy) > 2 && pathcopy[0] == '/' && pathcopy[1] == '/') { - object* it = _object_find_path_recurse(obj, token, pathcopy + 1); + jsonObject* it = _jsonObjectFindPathRecurse(obj, token, pathcopy + 1); free(pathcopy); return it; } @@ -685,23 +671,25 @@ object* object_find_path(object* obj, char* format, ...) { t = NULL; do { - obj = obj->get_key(obj, token); + obj = jsonObjectGetKey(obj, token); } while( (token = strtok_r(NULL, "/", &tt)) && obj); - return object_clone(obj); + return jsonObjectClone(obj); } +/* --------------------------------------------------------------- */ -object* _object_find_path_recurse(object* obj, char* root, char* path) { - if(!obj || ! root) return NULL; +jsonObject* _jsonObjectFindPathRecurse(const jsonObject* obj, char* root, char* path) { + + if(!obj || ! root || !path) return NULL; /* collect all of the potential objects */ - object* arr = __object_find_path_recurse(obj, root); + jsonObject* arr = __jsonObjectFindPathRecurse(obj, root); /* container for fully matching objects */ - object* newarr = json_parse_string("[]"); + jsonObject* newarr = jsonParseString("[]"); int i; /* path is just /root or /root/ */ @@ -712,45 +700,66 @@ object* _object_find_path_recurse(object* obj, char* root, char* path) { /* gather all of the sub-objects that match the full path */ for( i = 0; i < arr->size; i++ ) { - object* a = arr->get_index(arr, i); - object* thing = object_find_path(a , path + strlen(root) + 1); - if(thing) newarr->push(newarr, thing); + jsonObject* a = jsonObjectGetIndex(arr, i); + jsonObject* thing = jsonObjectFindPath(a , path + strlen(root) + 1); + if(thing) jsonObjectPush(newarr, thing); } } - free_object(arr); + jsonObjectFree(arr); return newarr; } -object* __object_find_path_recurse(object* obj, char* root) { +jsonObject* __jsonObjectFindPathRecurse(const jsonObject* obj, char* root) { - object* arr = json_parse_string("[]"); + jsonObject* arr = jsonParseString("[]"); if(!obj) return arr; int i; /* if the current object has a node that matches, add it */ - object* o = obj->get_key(obj, root); - if(o) arr->push(arr, object_clone(o)); - object_node* tmp = NULL; - object* childarr; - object_iterator* itr = new_iterator(obj); + jsonObject* o = jsonObjectGetKey(obj, root); + if(o) jsonObjectPush( arr, jsonObjectClone(o) ); + + jsonObjectNode* tmp = NULL; + jsonObject* childarr; + jsonObjectIterator* itr = jsonNewObjectIterator(obj); /* recurse through the children and find all potential nodes */ - while( (tmp = itr->next(itr)) ) { - childarr = __object_find_path_recurse(tmp->item, root); + while( (tmp = jsonObjectIteratorNext(itr)) ) { + childarr = __jsonObjectFindPathRecurse(tmp->item, root); if(childarr && childarr->size > 0) { for( i = 0; i!= childarr->size; i++ ) { - arr->push(arr, object_clone(childarr->get_index(childarr, i))); + jsonObjectPush( arr, jsonObjectClone(jsonObjectGetIndex(childarr, i)) ); } } - free_object(childarr); + jsonObjectFree(childarr); } - free_iterator(itr); + jsonObjectIteratorFree(itr); return arr; } +char* jsonObjectToSimpleString( const jsonObject* o ) { + char* value = NULL; + + if(o) { + switch( o->type ) { + + case JSON_NUMBER: { + DOUBLE_TO_STRING(o->value.n); + value = strdup(DOUBLESTR); + break; + } + + case JSON_STRING: + value = strdup(o->value.s); + } + } + return value; +} + + diff --git a/src/objson/object.h b/src/objson/object.h index bf8f4a5..64168b9 100644 --- a/src/objson/object.h +++ b/src/objson/object.h @@ -13,160 +13,188 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ + /* --------------------------------------------------------------------------------------- - Generic object framework for C. An object can be either a string, boolean, null, - number, array or hash (think Perl hash, dictionary, etc.). + libjson * --------------------------------------------------------------------------------------- */ +#ifndef _JSON_OBJECT_H +#define _JSON_OBJECT_H + #include #include #include #include -#include #include "utils.h" -#define MAX_OBJECT_NODES 1000000 +/* json object types */ +#define JSON_HASH 0 +#define JSON_ARRAY 1 +#define JSON_STRING 2 +#define JSON_NUMBER 3 +#define JSON_NULL 4 +#define JSON_BOOL 5 -#ifndef OBJECT_H -#define OBJECT_H /* top level generic object structure */ -struct object_struct { +struct _jsonObjectStruct { - /* how many sub-objects do we contain. Note that this includes null - * array elements in sparse arrays */ + /* how many sub-objects do we contain if we're an array or an object. + Note that this includes null array elements in sparse arrays */ unsigned long size; /* optional class hint */ char* classname; - /* these determine how we define a given object */ - int is_array; - int is_hash; - int is_string; - int is_null; - int is_bool; - int is_number; - int is_double; - - /* attached accessor/mutator methods for the OO inclined*/ - unsigned long (*push) (struct object_struct* src, struct object_struct*); - unsigned long (*set_index) (struct object_struct* src, unsigned long index, struct object_struct*); - unsigned long (*add_key) (struct object_struct* src, char* key, struct object_struct*); - struct object_struct* (*get_index) (struct object_struct*, unsigned long index); - struct object_struct* (*get_key) (struct object_struct*, char* key); - void (*set_string) (struct object_struct*, char*); - void (*set_number) (struct object_struct*, long number); - void (*set_double) (struct object_struct*, double number); - void (*set_class) (struct object_struct*, char* classname); - unsigned long (*remove_index) (struct object_struct*, unsigned long index); - unsigned long (*remove_key) (struct object_struct*, char* key); - char* (*get_string) (struct object_struct*); - char* (*to_json) (struct object_struct*); - void (*set_comment) (struct object_struct*, char* com); - - /* our list of sub-objects */ - struct object_node_struct* data; - - /* if we're a string, here's our data */ - char* string_data; - - /* if we're a boolean value, here's our value */ - int bool_value; - - /* if we're a number, here's our value */ - long num_value; - - /* if we're a double, here's our value */ - double double_value; + /* see JSON types above */ + int type; + + + /* our cargo */ + union _jsonObjectValue { + struct _jsonObjectNodeStruct* c; /* our list of sub-objects if we're an array or a hash */ + char* s; /* string */ + int b; /* bool */ + double n; /* number */ + } value; + /* client may provide a comment string which will be - * added serialized object when applicable - */ + * added to the object when stringified */ char* comment; }; -typedef struct object_struct object; +typedef struct _jsonObjectStruct jsonObject; + + +/** + String parsing function. This is assigned by the json_parser code. + to avoid circular dependency, declare the parse function here, + and have the json parse code set the variable to a real function +*/ +//jsonObject* (*jsonParseString) (char* str); /* this contains a single element of the object along with the elements * index (if this object is an array) and key (if this object is a hash) */ -struct object_node_struct { +struct _jsonObjectNodeStruct { + unsigned long index; /* our array position */ char* key; /* our hash key */ - object* item; /* our object */ - struct object_node_struct* next; /* pointer to the next object node */ + + jsonObject* item; /* our object */ + struct _jsonObjectNodeStruct* next; /* pointer to the next object node */ }; -typedef struct object_node_struct object_node; +typedef struct _jsonObjectNodeStruct jsonObjectNode; + + /* utility object for iterating over hash objects */ -struct object_iterator_struct { - object* obj; /* the topic object */ - object_node* current; /* the current node within the object */ - object_node* (*next) (struct object_iterator_struct*); - int (*has_next) (struct object_iterator_struct*); +struct _jsonObjectIteratorStruct { + const jsonObject* obj; /* the topic object */ + jsonObjectNode* current; /* the current node within the object */ }; -typedef struct object_iterator_struct object_iterator; +typedef struct _jsonObjectIteratorStruct jsonObjectIterator; -/* allocates a new iterator */ -object_iterator* new_iterator(object* obj); -/* de-allocates an iterator */ -void free_iterator(object_iterator*); +/** Allocates a new iterator + @param obj The object over which to iterate. +*/ +jsonObjectIterator* jsonNewObjectIterator(const jsonObject* obj); -/* returns the object_node currently pointed to by the iterator - * and increments the pointer to the next node +/** + De-allocates an iterator + @param iter The iterator object to free +*/ +void jsonObjectIteratorFree(jsonObjectIterator* iter); + +/** + Returns the object_node currently pointed to by the iterator + and increments the pointer to the next node + @param iter The iterator in question. */ -object_node* object_iterator_next(object_iterator*); +jsonObjectNode* jsonObjectIteratorNext(jsonObjectIterator* iter); -/* returns true if there is another node after the node - * currently pointed to +/** + @param iter The iterator. + @return True if there is another node after the current node. */ -int object_iterator_has_next(object_iterator*); +int jsonObjectIteratorHasNext(const jsonObjectIterator* iter); -/* allocates a new object. 'string' is the string data if this object - is to be a string. if not, string should be NULL */ -object* new_object(char* string); +/** + Allocates a new object. + @param string The string data if this object is to be a string. + if not, string should be NULL + @return The newly allocated object or NULL on memory error. +*/ +jsonObject* jsonNewObject(const char* string); -object* new_int_object(long num); +/** + Allocates a new JSON number object. + @param num The number this object is to hold + @return The newly allocated object. +*/ +jsonObject* jsonNewNumberObject( double num); -object* new_double_object(double num); -/* utility method for initing an object */ -object* _init_object(); +/** + Returns a pointer to the object at the given index. This call is + only valid if the object has a type of JSON_ARRAY. + @param obj The object + @param index The position within the object + @return The object at the given index. +*/ +jsonObject* jsonObjectGetIndex( const jsonObject* obj, unsigned long index ); -/* returns a pointer to the object at the given index */ -object* object_get_index( object* obj, unsigned long index ); +/** + Returns a pointer to the object with the given key + @param obj The object + @param key The key + @return The object with the given key. +*/ +jsonObject* jsonObjectGetKey( const jsonObject* obj, const char* key ); -/* returns a pointer to the object with the given key */ -object* object_get_key( object* obj, char* key ); +/** + De-allocates an object. Note that this function should only be called + on objects that are _not_ children of other objects or there will be + double-free's + @param obj The object to free. +*/ +void jsonObjectFree(jsonObject* obj); -/* de-allocates a object ( * should only be called on objects that are not - children of other objects ) */ -void free_object(object*); -/* allocates a new object node */ -object_node* new_object_node(object* obj); +/** + Allocates a new object node. + @param obj The object to which the node will be appended. + @return The new object node. +*/ +jsonObjectNode* jsonNewObjectNode(jsonObject* obj); -/* de-allocates a object node */ -void free_object_node(object_node*); +/** + De-allocates an object node + @param obj The object node to de-allocate. +*/ +void jsonObjectNodeFree(jsonObjectNode* obj); -/* pushes the given object onto the end of the list, - * returns the size on success, -1 on error - * If obj is NULL, inserts a new object into the list with is_null set to true +/** + Pushes the given object onto the end of the list. This coerces an object + into becoming an array. _Only_ use this function on objects that you + want to become an array. + If obj is NULL, inserts a new NULL object into the list. + @return array size on success, -1 on error */ -unsigned long object_push(object*, object* obj); +unsigned long jsonObjectPush(jsonObject* dest, jsonObject* newObj); /* removes (and deallocates) the object at the given index (if one exists) and inserts * the new one. returns the size on success, -1 on error * If obj is NULL, inserts a new object into the list with is_null set to true */ -unsigned long object_set_index(object*, unsigned long index, object* obj); +unsigned long jsonObjectSetIndex(jsonObject* dest, unsigned long index, jsonObject* newObj); /* inserts the new object, overwriting (removing, deallocating) any * previous object with the given key. @@ -174,72 +202,82 @@ unsigned long object_set_index(object*, unsigned long index, object* obj); * if 'obj' is NULL, a new object is inserted at key 'key' with 'is_null' * set to true */ -unsigned long object_add_key(object*, char* key, object* obj); +unsigned long jsonObjectSetKey(jsonObject* dest, const char* key, jsonObject* newObj); /* removes the object at the given index and, if more items exist, * re-indexes (shifts down by 1) the rest of the objects in the array */ -unsigned long object_remove_index(object*, unsigned long index); +unsigned long jsonObjectRemoveIndex(jsonObject* dest, unsigned long index); /* removes (and deallocates) the object with key 'key' if it exists */ -unsigned long object_remove_key(object*, char* key); +unsigned long jsonObjectRemoveKey( jsonObject* dest, const char* key); -/* returns a pointer to the string data held by this object */ -char* object_get_string(object*); +/* returns a pointer to the string data held by this object if this object + is a string. Otherwise returns NULL*/ +char* jsonObjectGetString(const jsonObject*); + +double jsonObjectGetNumber( const jsonObject* obj ); /* sets the string data */ -void object_set_string(object*, char* string); +void jsonObjectSetString(jsonObject* dest, const char* string); /* sets the number value for the object */ -void object_set_number(object*, long num); - -/* sets the double value for this object */ -void object_set_double(object*, double num); +void jsonObjectSetNumber(jsonObject* dest, double num); /* sets the class hint for this object */ -void object_set_class(object*, char* classname); +void jsonObjectSetClass(jsonObject* dest, const char* classname ); /* converts an object to a json string. client is responsible for freeing the return string */ -char* object_to_json(object*); - -/* utility function. clears all of the is_* flags */ -void object_clear_type(object*); +char* jsonObjectToJSON( const jsonObject* obj ); /* set this object's comment string */ -void object_set_comment(object*, char*); +void jsonObjectSetComment(jsonObject* dest, const char* classname); /* utility method. starting at index 'index', shifts all indices down by one and * decrements the objects size by 1 */ -void object_shift_index(object*, unsigned long index); +void _jsonObjectShiftIndex(jsonObject* dest, unsigned long index); /* formats a JSON string from printing. User must free returned string */ -char* json_string_format(char* json); +char* jsonFormatString( const char* jsonString ); + +jsonObject* jsonObjectClone( const jsonObject* o ); -object* object_clone(object* o); +/* tries to extract the string data from an object. + if object -> NULL (the C NULL) + if array -> NULL (the C NULL) + if null -> NULL (the C NULL) + if true/false -> true/false + if string/number/double the string version of either of those + The caller is responsible for freeing the returned string + */ +char* jsonObjectToSimpleString( const jsonObject* o ); /* ------------------------------------------------------------------------ */ /* XPATH */ -/* provide an XPATH style path (e.g. /some/node/here) and this will +/* provides an XPATH style search interface (e.g. /some/node/here) and return the object at that location if one exists. Naturally, every element in the path must be a proper object ("hash" / {}). Returns NULL if the specified node is not found Note also that the object returned is a clone and must be freed by the caller */ -object* object_find_path(object* obj, char* format, ...); +jsonObject* jsonObjectFindPath( const jsonObject* obj, char* path, ... ); /* Utility method. finds any object in the tree that matches the path. Use this for finding paths that start with '//' */ -object* _object_find_path_recurse(object* obj, char* root, char* path); +jsonObject* _jsonObjectFindPathRecurse( const jsonObject* o, char* root, char* path ); /* returns a list of object whose key is 'root'. These are used as potential objects when doing a // search */ -object* __object_find_path_recurse(object* obj, char* root); +jsonObject* __jsonObjectFindPathRecurse( const jsonObject* o, char* root ); /* ------------------------------------------------------------------------ */ + #endif + + diff --git a/src/objson/objson_test.c b/src/objson/objson_test.c index 89bd2d2..dc1d9d3 100644 --- a/src/objson/objson_test.c +++ b/src/objson/objson_test.c @@ -27,77 +27,85 @@ int main() { - object* o; + jsonObject* o; + + + o = jsonParseString("[ 1, 4, 6, 9 ]"); + jsonObjectIterator* itr = jsonNewObjectIterator(o); + jsonObjectNode* tmp = NULL; + while( (tmp = jsonObjectIteratorNext(itr)) ) { + char* q = jsonObjectToJSON(tmp->item); + printf("Iterator thing => %s\n", q); + free(q); + } + jsonObjectIteratorFree(itr); + jsonObjectFree(o); + printf("------------------------------------------------------------------\n"); - //o = json_parse_string("-1"); - o = json_parse_string("{\"key\":-1}"); - char* h = o->to_json(o); + o = jsonParseString("{\"key\":-1}"); + char* h = jsonObjectToJSON(o); printf("\nParsed number: %s\n", h); - free_object(o); + free(h); + jsonObjectFree(o); /* number, double, and 'null' parsing... */ printf("------------------------------------------------------------------\n"); - o = json_parse_string("1"); - printf("\nParsed number: %ld\n", o->num_value); - free_object(o); + o = jsonParseString("1"); + printf("\nParsed number: %lf\n", jsonObjectGetNumber(o)); + jsonObjectFree(o); printf("------------------------------------------------------------------\n"); - o = json_parse_string("1.1"); - printf("\nDouble number: %lf\n", o->double_value); - free_object(o); - - printf("------------------------------------------------------------------\n"); - o = json_parse_string("nUlL"); - char* s = o->to_json(o); - free_object(o); - + o = jsonParseString("nUlL"); + char* s = jsonObjectToJSON(o); printf("\nJSON Null: %s\n", s); free(s); + jsonObjectFree(o); printf("------------------------------------------------------------------\n"); - o = json_parse_string("[1, .5, null]"); - s = o->to_json(o); + o = jsonParseString("[1, .5, null]"); + s = jsonObjectToJSON(o); printf("\nJSON MIX: %s\n", s ); free(s); - free_object(o); + jsonObjectFree(o); printf("------------------------------------------------------------------\n"); /* simulate an error.. */ printf("\nShould print error msg: \n"); - o = json_parse_string("[1, .5. null]"); + o = jsonParseString("[1, .5. null]"); if( o == NULL ) printf("\n"); + jsonObjectFree(o); printf("------------------------------------------------------------------\n"); - o = json_parse_string("[ Null, trUe, falSE, 1, 12.9, \"true\" ]"); - s = o->to_json(o); + o = jsonParseString("[ Null, trUe, falSE, 1, 12.9, \"true\" ]"); + s = jsonObjectToJSON(o); printf("More JSON: %s\n", s); free(s); - free_object(o); + jsonObjectFree(o); printf("------------------------------------------------------------------\n"); - o = json_parse_string("[ Null, trUe, falSE, 1, 12.9, \"true\", " + o = jsonParseString("[ Null, trUe, falSE, 1, 12.9, \"true\", " "{\"key\":[0,0.0,1],\"key2\":null},NULL, { }, [] ]"); - s = o->to_json(o); + s = jsonObjectToJSON(o); printf("More JSON: %s\n", s); free(s); - free_object(o); + jsonObjectFree(o); printf("------------------------------------------------------------------\n"); - o = json_parse_string("{ Null: trUe }"); + o = jsonParseString("{ Null: trUe }"); printf("------------------------------------------------------------------\n"); - o = json_parse_string("\"Pin\\u0303ata\""); - s = o->to_json(o); - printf("UNICODE:: %s\n", o->string_data); + o = jsonParseString("\"Pin\\u0303ata\""); + s = jsonObjectToJSON(o); + printf("UNICODE:: %s\n", o->value.s); printf("Back to JSON: %s\n", s); - free_object(o); + jsonObjectFree(o); free(s); @@ -109,41 +117,41 @@ int main() { printf("\nOriginal JSON\n%s\n", jsons); /* parse the JSON string */ - object* yuk = json_parse_string(jsons); + jsonObject* yuk = jsonParseString(jsons); /* grab the class name from the object */ printf("------------------------------------------------------------------\n"); printf("\nParsed object with class %s\n", yuk->classname ); /* turn the resulting object back into JSON */ - char* ccc = yuk->to_json(yuk); + char* ccc = jsonObjectToJSON(yuk); /* extract a sub-object from the object and print its data*/ - o = yuk->get_index(yuk, 11); - printf("\nRandom unicode string => %s\n", o->string_data); + o = jsonObjectGetIndex(yuk, 11); + printf("\nRandom unicode string => %s\n", jsonObjectGetString(o)); /* parse the new JSON string to build yet another object */ - object* yuk2 = json_parse_string(ccc); + jsonObject* yuk2 = jsonParseString(ccc); printf("------------------------------------------------------------------\n"); /* turn that one back into JSON and print*/ - char* cccc = yuk2->to_json(yuk2); + char* cccc = jsonObjectToJSON(yuk2); printf("\nFinal JSON: \n%s\n", cccc); char* string2 = strdup(jsons); printf("------------------------------------------------------------------\n"); int x = 0; - int count = 3000; + int count = 30; printf("\nParsing %d round trips at %f...\n", count, get_timestamp_millis()); /* parse and stringify many times in a loop to check speed */ while(x++ < count) { - object* o = json_parse_string(string2); + jsonObject* o = jsonParseString(string2); free(string2); - string2 = o->to_json(o); - free_object(o); + string2 = jsonObjectToJSON(o); + jsonObjectFree(o); if(!(x % 500)) fprintf(stderr, "Round trip at %d\n", x); @@ -152,15 +160,14 @@ int main() { printf("After Loop: %f\n", get_timestamp_millis()); - /* to_json() generates a string that must be freed by the caller */ free(string2); free(ccc); free(cccc); /* only free the top level objects. objects that are 'children' of other objects should not be freed */ - free_object(yuk); - free_object(yuk2); + jsonObjectFree(yuk); + jsonObjectFree(yuk2); @@ -172,6 +179,7 @@ int main() { perror("unable to open test.json for testing"); exit(99); } + fclose(F); char buf[10240]; char smallbuf[512]; @@ -184,15 +192,15 @@ int main() { /* dig our way into the JSON object we parsed, see test.json to get an idea of the object structure */ printf("------------------------------------------------------------------\n"); - object* big = json_parse_string(buf); - object* k = big->get_key(big,"web-app"); - object* k2 = k->get_key(k,"servlet"); - object* k3 = k2->get_index(k2, 0); - object* k4 = k3->get_key(k3,"servlet-class"); - - printf("\nValue for object with key 'servlet-class' in the JSON file => %s\n", k4->get_string(k4)); + jsonObject* big = jsonParseString(buf); + jsonObject* k = jsonObjectGetKey(big,"web-app"); + jsonObject* k2 = jsonObjectGetKey(k,"servlet"); + jsonObject* k3 = jsonObjectGetIndex(k2, 0); + jsonObject* k4 = jsonObjectGetKey(k3,"servlet-class"); + jsonObjectFree(big); + printf("\nValue for object with key 'servlet-class' in the JSON file => %s\n", jsonObjectGetString(k4)); return 0; diff --git a/src/router/router.c b/src/router/router.c index bd91f68..810fbb6 100644 --- a/src/router/router.c +++ b/src/router/router.c @@ -10,7 +10,7 @@ void _build_trusted_sites( transport_router_registrar* router ); void sig_hup_handler( int a ) { router_registrar_free( routt ); - config_reader_free(); + osrfConfigCleanup(); log_free(); free( router_resource ); exit(0); @@ -24,27 +24,26 @@ int main( int argc, char* argv[] ) { exit(0); } - config_reader_init( "opensrf.router", argv[1] ); - if( conf_reader == NULL ) fatal_handler( "main(): Config is NULL" ); + osrfConfig* cfg = osrfConfigInit( argv[1], "router" ); + osrfConfigSetDefaultConfig(cfg); /* load the config options */ - char* server = config_value("opensrf.router", "//router/transport/server"); - char* port = config_value("opensrf.router", "//router/transport/port"); - char* unixpath = config_value("opensrf.router", "//router/transport/unixpath"); - char* username = config_value("opensrf.router", "//router/transport/username"); - char* password = config_value("opensrf.router", "//router/transport/password"); - router_resource = config_value("opensrf.router", "//router/transport/resource"); - char* con_timeout = config_value("opensrf.router", "//router/transport/connect_timeout" ); - char* max_retries = config_value("opensrf.router", "//router/transport/max_reconnect_attempts" ); - char* component = config_value("opensrf.router", "//router/component" ); + char* server = osrfConfigGetValue(NULL, "/transport/server"); + char* port = osrfConfigGetValue(NULL, "/transport/port"); + char* unixpath = osrfConfigGetValue(NULL, "/transport/unixpath"); + char* username = osrfConfigGetValue(NULL, "/transport/username"); + char* password = osrfConfigGetValue(NULL, "/transport/password"); + router_resource = osrfConfigGetValue(NULL, "/transport/resource"); + char* con_timeout = osrfConfigGetValue(NULL, "/transport/connect_timeout" ); + char* max_retries = osrfConfigGetValue(NULL, "/transport/max_reconnect_attempts" ); + char* component = osrfConfigGetValue(NULL, "/component" ); fprintf(stderr, "Router connecting with uname %s, server %s, port %s, unixpath %s", username, server, port, unixpath ); - /* set up the logger */ - char* level = config_value("opensrf.router","//router/loglevel"); - char* log_file = config_value("opensrf.router","//router/logfile"); + char* level = osrfConfigGetValue(NULL, "/loglevel"); + char* log_file = osrfConfigGetValue(NULL, "/logfile"); int llevel = atoi(level); fprintf(stderr, "Level %d; file %s\n", llevel, log_file ); @@ -110,7 +109,6 @@ int main( int argc, char* argv[] ) { router_registrar_free( router_registrar ); - config_reader_free(); return 1; } @@ -128,40 +126,19 @@ transport_router_registrar* router_registrar_init( char* server, router_registrar->client_timeout = client_timeout; router_registrar->jabber = jabber_connect_init( server, port, unixpath, username, password, resource, con_timeout, component ); _build_trusted_sites( router_registrar ); - info_handler( "Trusted stuff %s, %s, %s", router_registrar->trusted_servers[0], - router_registrar->trusted_clients[0], router_registrar->trusted_clients[1] ); - return router_registrar; + return router_registrar; } void _build_trusted_sites( transport_router_registrar* router ) { - router->trusted_servers = (char**) safe_malloc(sizeof(char**)); - router->trusted_clients = (char**) safe_malloc(sizeof(char**)); - - *(router->trusted_servers) = (char*) safe_malloc(ROUTER_MAX_TRUSTED); - *(router->trusted_clients) = (char*) safe_malloc(ROUTER_MAX_TRUSTED); - - int i = 0; - while( ++i ) { - char* server = config_value("opensrf.router","//router/trusted_domains/server%d", i ); - if(server == NULL) - break; - - router->trusted_servers[i-1] = server; - } - - i = 0; - while( ++i ) { - char* client = config_value( "opensrf.router","//router/trusted_domains/client%d", i ); - if(client == NULL) - break; - router->trusted_clients[i-1] = client; - } - - if( router->trusted_servers[0] == NULL || - router->trusted_clients[0] == NULL ) + router->trusted_servers = osrfNewStringArray(4); + router->trusted_clients = osrfNewStringArray(4); + osrfConfigGetValueList(NULL, router->trusted_servers, "/trusted_domains/server" ); + osrfConfigGetValueList(NULL, router->trusted_clients, "/trusted_domains/client" ); + if(router->trusted_servers->size < 1 || + router->trusted_clients->size < 1 ) fatal_handler( "You must specify at least one trusted server and client in the config file"); } @@ -270,7 +247,7 @@ void listen_loop( transport_router_registrar* router ) { message came from one of those servers */ if(cur_msg) { - if(router->trusted_servers && router->trusted_servers[0]) { + if( router->trusted_servers->size > 0 ) { int i = 0; int found = 0; @@ -284,11 +261,12 @@ void listen_loop( transport_router_registrar* router ) { info_handler("Received top level message from %s", server_buf ); while(1) { - if(router->trusted_servers[i] == NULL) - break; - if(!strcmp(router->trusted_servers[i], server_buf)) { - found = 1; - break; + char* domain = osrfStringArrayGetString(router->trusted_servers, i); + if(domain) { + if(!strcmp(domain, server_buf)) { + found = 1; + break; + } } i++; } @@ -998,7 +976,7 @@ osrf_message** router_registrar_process_app_request( if(!strcmp(omsg->method_name,"opensrf.router.info.class.list")) { - object* result_content = json_parse_string("[]"); + jsonObject* result_content = jsonParseString("[]"); debug_handler("Processing opensrf.router.info.class.list request"); @@ -1007,7 +985,7 @@ osrf_message** router_registrar_process_app_request( debug_handler("Adding %s to request list", cur_class->server_class); - result_content->push(result_content, new_object(cur_class->server_class)); + jsonObjectPush(result_content, jsonNewObject(cur_class->server_class)); cur_class = cur_class->next; } result_array = safe_malloc(sizeof(osrf_message*)); @@ -1016,8 +994,8 @@ osrf_message** router_registrar_process_app_request( result_array[0] = osrf_message_init( RESULT, omsg->thread_trace, omsg->protocol ); - osrf_message_set_result_content( result_array[0], object_to_json(result_content)); - free_object(result_content); + osrf_message_set_result_content( result_array[0], jsonObjectToJSON(result_content)); + jsonObjectFree(result_content); } else if(!strcmp(omsg->method_name,"opensrf.router.info.stats")) { @@ -1028,7 +1006,7 @@ osrf_message** router_registrar_process_app_request( debug_handler("Processing opensrf.router.info.stats request"); - object* result_content = json_parse_string("{}"); + jsonObject* result_content = jsonParseString("{}"); server_class_node* cur_class = router->server_class_list; @@ -1038,58 +1016,58 @@ osrf_message** router_registrar_process_app_request( server_node* cur_node = start_node; if( cur_node == NULL ) continue; - object* server_object = json_parse_string("{}"); + jsonObject* server_object = jsonParseString("{}"); do { - object* node_stats_array = json_parse_string("[]"); + jsonObject* node_stats_array = jsonParseString("[]"); - object* json_reg_time = json_parse_string("{}"); + jsonObject* json_reg_time = jsonParseString("{}"); - object_add_key( json_reg_time, "reg_time", - new_int_object((int) cur_node->reg_time)); + jsonObjectSetKey( json_reg_time, "reg_time", + jsonNewNumberObject((double) cur_node->reg_time)); - object_push( node_stats_array, json_reg_time ); + jsonObjectPush( node_stats_array, json_reg_time ); - object* json_upd_time = json_parse_string("{}"); + jsonObject* json_upd_time = jsonParseString("{}"); - object_add_key( json_upd_time, "upd_time", - new_int_object((int)cur_node->upd_time)); + jsonObjectSetKey( json_upd_time, "upd_time", + jsonNewNumberObject((int)cur_node->upd_time)); - object_push( node_stats_array, json_upd_time ); + jsonObjectPush( node_stats_array, json_upd_time ); - object* json_la_time = json_parse_string("{}"); + jsonObject* json_la_time = jsonParseString("{}"); - object_add_key( json_la_time, "la_time", - new_int_object((int)cur_node->la_time)); + jsonObjectSetKey( json_la_time, "la_time", + jsonNewNumberObject((int)cur_node->la_time)); - object_push( node_stats_array, json_la_time ); + jsonObjectPush( node_stats_array, json_la_time ); - object* json_serve_count = json_parse_string("{}"); + jsonObject* json_serve_count = jsonParseString("{}"); - object_add_key( json_serve_count, "serve_count", - new_int_object((int)cur_node->serve_count)); + jsonObjectSetKey( json_serve_count, "serve_count", + jsonNewNumberObject((int)cur_node->serve_count)); - object_push( node_stats_array, json_serve_count ); + jsonObjectPush( node_stats_array, json_serve_count ); - object_add_key( server_object, cur_node->remote_id, node_stats_array ); + jsonObjectSetKey( server_object, cur_node->remote_id, node_stats_array ); cur_node = cur_node->next; } while( cur_node != start_node ); - object_add_key( result_content, cur_class->server_class, server_object ); + jsonObjectSetKey( result_content, cur_class->server_class, server_object ); cur_class = cur_class->next; @@ -1102,30 +1080,30 @@ osrf_message** router_registrar_process_app_request( result_array[0] = osrf_message_init( RESULT, omsg->thread_trace, omsg->protocol ); - osrf_message_set_result_content(result_array[0], object_to_json(result_content)); + osrf_message_set_result_content(result_array[0], jsonObjectToJSON(result_content)); - free_object(result_content); + jsonObjectFree(result_content); } else if(!strcmp(omsg->method_name,"opensrf.system.method.all")) { - object* content = json_parse_string("{}"); - object_add_key(content, "api_level", new_object("1")); - object_add_key(content, "api_name", new_object("opensrf.router.info.class.list")); - object_add_key(content, "server_class", new_object("router")); - object_add_key(content, "stream", new_object("0")); + jsonObject* content = jsonParseString("{}"); + jsonObjectSetKey(content, "api_level", jsonNewObject("1")); + jsonObjectSetKey(content, "api_name", jsonNewObject("opensrf.router.info.class.list")); + jsonObjectSetKey(content, "server_class", jsonNewObject("router")); + jsonObjectSetKey(content, "stream", jsonNewObject("0")); - object* content2 = json_parse_string("{}"); - object_add_key(content2, "api_level", new_object("1")); - object_add_key(content2, "api_name", new_object("opensrf.router.info.stats")); - object_add_key(content2, "server_class", new_object("router")); - object_add_key(content2, "stream", new_object("0")); + jsonObject* content2 = jsonParseString("{}"); + jsonObjectSetKey(content2, "api_level", jsonNewObject("1")); + jsonObjectSetKey(content2, "api_name", jsonNewObject("opensrf.router.info.stats")); + jsonObjectSetKey(content2, "server_class", jsonNewObject("router")); + jsonObjectSetKey(content2, "stream", jsonNewObject("0")); - object* content3 = json_parse_string("{}"); - object_add_key(content3, "api_level", new_object("1")); - object_add_key(content3, "api_name", new_object("opensrf.system.method.all")); - object_add_key(content3, "server_class", new_object("router")); - object_add_key(content3, "stream", new_object("1")); + jsonObject* content3 = jsonParseString("{}"); + jsonObjectSetKey(content3, "api_level", jsonNewObject("1")); + jsonObjectSetKey(content3, "api_name", jsonNewObject("opensrf.system.method.all")); + jsonObjectSetKey(content3, "server_class", jsonNewObject("router")); + jsonObjectSetKey(content3, "stream", jsonNewObject("1")); result_array = safe_malloc(3*sizeof(osrf_message*)); *num_responses = 3; @@ -1133,18 +1111,18 @@ osrf_message** router_registrar_process_app_request( result_array[0] = osrf_message_init( RESULT, omsg->thread_trace, omsg->protocol ); - osrf_message_set_result_content( result_array[0], object_to_json(content)); - free_object(content); + osrf_message_set_result_content( result_array[0], jsonObjectToJSON(content)); + jsonObjectFree(content); result_array[1] = osrf_message_init( RESULT, omsg->thread_trace, omsg->protocol ); - osrf_message_set_result_content( result_array[1], object_to_json(content2) ); - free_object(content2); + osrf_message_set_result_content( result_array[1], jsonObjectToJSON(content2) ); + jsonObjectFree(content2); result_array[2] = osrf_message_init( RESULT, omsg->thread_trace, omsg->protocol ); - osrf_message_set_result_content( result_array[1], object_to_json(content3) ); - free_object(content3); + osrf_message_set_result_content( result_array[1], jsonObjectToJSON(content3) ); + jsonObjectFree(content3); } @@ -1169,23 +1147,8 @@ int router_registrar_free( transport_router_registrar* router_registrar ) { debug_handler( "Removed server classes in registrar free"); } - //transport_router_registrar* router = router_registrar; - - /* make this better - int i = 0; - while(1) { - - if( router->trusted_servers[i] == NULL && - router->trusted_clients[i] == NULL ) - break; - - if(router->trusted_servers[i] != NULL) - free(router->trusted_servers[i]); - if(router->trusted_clients[i] != NULL) - free(router->trusted_clients[i]); - i++; - } - */ + osrfStringArrayFree(router_registrar->trusted_servers); + osrfStringArrayFree(router_registrar->trusted_clients); free( router_registrar ); return 1; diff --git a/src/router/router.h b/src/router/router.h index 04b1557..f123396 100644 --- a/src/router/router.h +++ b/src/router/router.h @@ -4,7 +4,7 @@ #include "utils.h" #include "logging.h" -#include "osrf_config.h" +#include "osrfConfig.h" #include #include @@ -121,8 +121,11 @@ struct transport_router_registrar_struct { /* true if we connect to jabber as a jabber component */ int component; - char** trusted_servers; - char** trusted_clients; + osrfStringArray* trusted_servers; + osrfStringArray* trusted_clients; + + //char** trusted_servers; + //char** trusted_clients; }; diff --git a/src/srfsh/srfsh.c b/src/srfsh/srfsh.c index 47ff5a1..ebc9a61 100644 --- a/src/srfsh/srfsh.c +++ b/src/srfsh/srfsh.c @@ -6,8 +6,6 @@ FILE* shell_reader = NULL; int main( int argc, char* argv[] ) { - - /* --------------------------------------------- */ /* see if they have a .srfsh.xml in their home directory */ char* home = getenv("HOME"); @@ -71,12 +69,10 @@ int main( int argc, char* argv[] ) { if(history_file != NULL ) write_history(history_file); + free(request); - client_disconnect( client ); - client_free( client ); - config_reader_free(); - log_free(); - + + osrf_system_shutdown(); return 0; } @@ -248,8 +244,8 @@ int handle_login( char* words[]) { char* hash; if(last_result && last_result->_result_content) { - object* r = last_result->_result_content; - hash = r->string_data; + jsonObject* r = last_result->_result_content; + hash = jsonObjectGetString(r); } else return 0; @@ -270,7 +266,9 @@ int handle_login( char* words[]) { parse_request( buf2 ); - login_session = strdup(last_result->_result_content->string_data); + char* x = jsonObjectGetString(last_result->_result_content); + if(x) login_session = strdup(x); + else login_session = NULL; printf("Login Session: %s\n", login_session ); @@ -504,7 +502,7 @@ int send_request( char* server, if( server == NULL || method == NULL ) return 0; - object* params = NULL; + jsonObject* params = NULL; if( !relay ) { if( buffer != NULL && buffer->n_used > 0 ) params = json_parse_string(buffer->buf); @@ -514,8 +512,8 @@ int send_request( char* server, return 1; } else { - object* o = new_object(NULL); - o->push(o, last_result->_result_content ); + jsonObject* o = jsonNewObject(NULL); + jsonObjectPush(o, last_result->_result_content ); params = o; } } @@ -566,12 +564,12 @@ int send_request( char* server, char* content; if( pretty_print && omsg->_result_content ) { - char* j = object_to_json(omsg->_result_content); + char* j = jsonObjectToJSON(omsg->_result_content); //content = json_printer(j); - content = json_string_format(j); + content = jsonFormatString(j); free(j); } else - content = object_get_string(omsg->_result_content); + content = jsonObjectGetString(omsg->_result_content); printf( "\nReceived Data: %s\n", content ); free(content); @@ -599,12 +597,12 @@ int send_request( char* server, char* content; if( pretty_print && omsg->_result_content ) { - char* j = object_to_json(omsg->_result_content); + char* j = jsonObjectToJSON(omsg->_result_content); //content = json_printer(j); - content = json_string_format(j); + content = jsonFormatString(j); free(j); } else - content = object_get_string(omsg->_result_content); + content = jsonObjectGetString(omsg->_result_content); buffer_add( resp_buffer, "\nReceived Data: " ); buffer_add( resp_buffer, content ); @@ -792,9 +790,9 @@ int do_math( int count, int style ) { osrf_app_session* session = osrf_app_client_session_init( "opensrf.math" ); - object* params = json_parse_string("[]"); - params->push(params,new_object("1")); - params->push(params,new_object("2")); + jsonObject* params = json_parse_string("[]"); + jsonObjectPush(params,jsonNewObject("1")); + jsonObjectPush(params,jsonNewObject("2")); char* methods[] = { "add", "sub", "mult", "div" }; char* answers[] = { "3", "-1", "2", "0.500000" }; @@ -840,7 +838,7 @@ int do_math( int count, int style ) { if(omsg) { if(omsg->_result_content) { - char* jsn = object_to_json(omsg->_result_content); + char* jsn = jsonObjectToJSON(omsg->_result_content); if(!strcmp(jsn, answers[j])) fprintf(stderr, "+"); else @@ -867,7 +865,7 @@ int do_math( int count, int style ) { } osrf_app_session_destroy( session ); - free_object(params); + jsonObjectFree(params); int c; float total = 0; diff --git a/src/srfsh/srfsh.h b/src/srfsh/srfsh.h index 5f2d94f..b3719fd 100644 --- a/src/srfsh/srfsh.h +++ b/src/srfsh/srfsh.h @@ -1,7 +1,6 @@ #include "opensrf/transport_client.h" #include "opensrf/osrf_message.h" #include "opensrf/osrf_app_session.h" -#include "opensrf/osrf_config.h" #include #include #include diff --git a/src/utils/Makefile b/src/utils/Makefile index 2221ae2..f0e4c28 100644 --- a/src/utils/Makefile +++ b/src/utils/Makefile @@ -17,6 +17,7 @@ msg: install: echo installing libc_utils.so cp $(UTIL_HEADERS) $(INCLUDEDIR)/ + cp xml_utils.h $(INCLUDEDIR)/ cp $(TMPDIR)/libc_utils.so $(LIBDIR)/ libc_utils.so: $(UTIL_OBJECTS) diff --git a/src/utils/string_array.c b/src/utils/string_array.c index 8290a43..1428a22 100644 --- a/src/utils/string_array.c +++ b/src/utils/string_array.c @@ -1,17 +1,8 @@ #include "string_array.h" -/* -int main() { - string_array* arr = init_string_array(1); - string_array_add(arr, "1"); - fprintf(stderr,"adding 3\n"); - string_array_add(arr, "3"); - string_array_destroy(arr); - return 0; +osrfStringArray* osrfNewStringArray(int size) { + return init_string_array(size); } -*/ - - string_array* init_string_array(int size) { if(size > STRING_ARRAY_MAX_SIZE) @@ -26,16 +17,15 @@ string_array* init_string_array(int size) { } -void string_array_add(string_array* arr, char* str) { - if(arr == NULL || str == NULL ) { - warning_handler("Invalid params to string_array_add"); - return; - } +void osrfStringArrayAdd(osrfStringArray* arr, char* string) { + string_array_add(arr, string); +} +void string_array_add(string_array* arr, char* str) { + if(arr == NULL || str == NULL ) return; if( strlen(str) < 1 ) return; arr->size++; - //fprintf(stderr,"size is %d\n", arr->size); if( arr->size > STRING_ARRAY_MAX_SIZE ) fatal_handler("string_array_add size is too large"); @@ -43,7 +33,6 @@ void string_array_add(string_array* arr, char* str) { /* if necessary, double capacity */ if(arr->size >= arr->arr_size) { arr->arr_size *= 2; - debug_handler("string_array: Doubling array size to %d", arr->arr_size); char** tmp = (char**) safe_malloc(arr->arr_size * sizeof(char*)); int i; @@ -55,35 +44,28 @@ void string_array_add(string_array* arr, char* str) { arr->array = tmp; } - //fprintf(stderr, "String is %s", str); - //debug_handler("string_array_add: Adding string %s", str); - //arr->array[arr->size - 1] = (char*) safe_malloc(strlen(str)); arr->array[arr->size - 1] = strdup(str); - //fprintf(stderr,"we have %s\n", arr->array[arr->size - 1]); +} + +char* osrfStringArrayGetString(osrfStringArray* arr, int index) { + return string_array_get_string(arr, index); } char* string_array_get_string(string_array* arr, int index) { - if(!arr || index < 0 || index >= arr->size ) - return NULL; - char* str = arr->array[index]; + if(!arr || index < 0 || index >= arr->size ) return NULL; + return arr->array[index]; +} - if(str == NULL) - warning_handler("Somehow we have a NULL string in the string array"); - //debug_handler("string_array_get_string: getting string %s", str); - return str; +void osrfStringArrayFree(osrfStringArray* arr) { + string_array_destroy(arr); } - void string_array_destroy(string_array* arr) { - if(!arr) return; - int i; - for( i = 0; i!= arr->size; i++ ) { - if( arr->array[i] != NULL ) { - //debug_handler("Freeing string from string array %s", arr->array[i]); - free(arr->array[i]); - } + if(arr) { + int i = 0; + while( i++ < arr->size ) free(arr->array[i]); + free(arr->array); + free(arr); } - free(arr->array); - free(arr); } diff --git a/src/utils/string_array.h b/src/utils/string_array.h index 0a20eab..d0867aa 100644 --- a/src/utils/string_array.h +++ b/src/utils/string_array.h @@ -15,15 +15,23 @@ struct string_array_struct { int total_string_size; }; typedef struct string_array_struct string_array; +typedef struct string_array_struct osrfStringArray; -string_array* init_string_array(int size); -void string_array_add(string_array*, char* string); +osrfStringArray* init_string_array(int size); +osrfStringArray* osrfNewStringArray(int size); -char* string_array_get_string(string_array* arr, int index); -void string_array_destroy(string_array*); +void string_array_add(osrfStringArray*, char* string); +void osrfStringArrayAdd(osrfStringArray*, char* string); + +char* string_array_get_string(osrfStringArray* arr, int index); +char* osrfStringArrayGetString(osrfStringArray* arr, int index); + + +void string_array_destroy(osrfStringArray*); +void osrfStringArrayFree(osrfStringArray*); /* total size of all included strings */ -int string_array_get_total_size(string_array* arr); +int string_array_get_total_size(osrfStringArray* arr); #endif diff --git a/src/utils/utils.c b/src/utils/utils.c index c1019da..e60925d 100644 --- a/src/utils/utils.c +++ b/src/utils/utils.c @@ -348,7 +348,7 @@ int stringisnum(char* s) { -char* file_to_string(char* filename) { +char* file_to_string(const char* filename) { if(!filename) return NULL; @@ -368,6 +368,8 @@ char* file_to_string(char* filename) { bzero(buf, len); } + fclose(file); + char* data = buffer_data(gb); buffer_free(gb); return data; diff --git a/src/utils/utils.h b/src/utils/utils.h index 1dc004d..8da7002 100644 --- a/src/utils/utils.h +++ b/src/utils/utils.h @@ -30,6 +30,49 @@ GNU General Public License for more details. //#include +/* turns a va_list into a string */ +#define VA_LIST_TO_STRING(x) \ + unsigned long len = 0;\ + va_list args; \ + va_list a_copy;\ + va_copy(a_copy, args); \ + va_start(args, x); \ + len = vsnprintf(NULL, 0, x, args); \ + va_end(args); \ + len += 2; \ + char _b[len]; \ + bzero(_b, len); \ + va_start(a_copy, x); \ + vsnprintf(_b, len - 1, x, a_copy); \ + va_end(a_copy); \ + char* VA_BUF = _b; \ + +/* turns a long into a string */ +#define LONG_TO_STRING(l) \ + unsigned int __len = snprintf(NULL, 0, "%ld", l) + 2;\ + char __b[__len]; \ + bzero(__b, __len); \ + snprintf(__b, __len - 1, "%ld", l); \ + char* LONGSTR = __b; + +#define DOUBLE_TO_STRING(l) \ + unsigned int __len = snprintf(NULL, 0, "%lf", l) + 2; \ + char __b[__len]; \ + bzero(__b, __len); \ + snprintf(__b, __len - 1, "%lf", l); \ + char* DOUBLESTR = __b; + +#define INT_TO_STRING(l) \ + unsigned int __len = snprintf(NULL, 0, "%d", l) + 2; \ + char __b[__len]; \ + bzero(__b, __len); \ + snprintf(__b, __len - 1, "%d", l); \ + char* INTSTR = __b; + + + + + #define BUFFER_MAX_SIZE 10485760 int daemonize(); @@ -97,7 +140,7 @@ int stringisnum(char* s); /* reads a file and returns the string version of the file user is responsible for freeing the returned char* */ -char* file_to_string(char* filename); +char* file_to_string(const char* filename); -- 2.43.2