Committing massive pile of new-json code. This includes:
authorerickson <erickson@9efc2488-bf62-4759-914b-345cdb29e865>
Mon, 14 May 2007 22:58:03 +0000 (22:58 +0000)
committererickson <erickson@9efc2488-bf62-4759-914b-345cdb29e865>
Mon, 14 May 2007 22:58:03 +0000 (22:58 +0000)
the new-json object encoding protocol
a new C JSON parser which uses osrfHash and osrfList and is built into libopensrf (but has a standalone makefile)
altered osrfHashIterator API
some more work on the Python opensrf bindings
Lots of small updates to extract objson from header files and makefiles, etc.
support for new and legacy JSON encodings in the opensrf JSON gateway

git-svn-id: svn://svn.open-ils.org/OpenSRF/branches/new-json@889 9efc2488-bf62-4759-914b-345cdb29e865

32 files changed:
src/Makefile
src/c-apps/Makefile
src/c-apps/osrf_dbmath.c
src/c-apps/osrf_math.c
src/c-apps/osrf_version.c
src/gateway/Makefile
src/gateway/fieldmapper-c-xml-out.pl
src/gateway/osrf_json_gateway.c
src/jserver/Makefile
src/libstack/Makefile
src/libstack/osrfConfig.c
src/libstack/osrfConfig.h
src/libstack/osrf_app_session.h
src/libstack/osrf_application.c
src/libstack/osrf_application.h
src/libstack/osrf_cache.h
src/libstack/osrf_message.c
src/libstack/osrf_message.h
src/libstack/osrf_settings.h
src/libtransport/Makefile
src/libtransport/transport_message.c
src/libtransport/transport_session.c
src/perlmods/JSON.pm
src/python/osrf/json.py
src/python/osrf/net.py
src/python/srfsh.py
src/router/Makefile
src/srfsh/Makefile
src/srfsh/srfsh.c
src/utils/fieldmapper-c.pl
src/utils/utils.h
src/utils/xml_utils.c

index 008679e..0ad9171 100644 (file)
@@ -32,6 +32,10 @@ OPENSRF_TARGETS =    libtransport/transport_session.o \
                        libstack/osrf_transgroup.o \
                        libstack/osrf_list.o \
                        libstack/osrf_hash.o \
+                       libstack/osrf_json_parser.o \
+                       libstack/osrf_json_object.o \
+                       libstack/osrf_json_tools.o \
+                       libstack/legacy_json.o \
                        utils/socket_bundle.o \
                        utils/string_array.o \
                        utils/utils.o \
@@ -55,6 +59,7 @@ OPENSRF_HEADERS =     libtransport/transport_session.h \
                        libstack/osrf_transgroup.h \
                        libstack/osrf_list.h \
                        libstack/osrf_hash.h \
+                       libstack/osrf_json.h \
                        utils/socket_bundle.h \
                        utils/string_array.h \
                        utils/utils.h \
@@ -67,22 +72,19 @@ all:        prep \
        libstack/opensrf \
        router \
        srfsh \
-       jserver \
        gateway
 
-install:       install-prep \
+install:       install-prep \
                opensrf-install \
                gateway-install \
                router-install \
                srfsh-install \
-               jserver-install \
-               perl-install \
-               objson-install
+               perl-install 
 
 prep:
        mkdir -p $(TMPDIR)
 
-libopensrf.so: objson/libobjson.so
+libopensrf.so:
        @echo utils
        make -C utils
        @echo transport
@@ -90,30 +92,19 @@ libopensrf.so:      objson/libobjson.so
        @echo stack
        make -C libstack
        @echo $@
-       $(CC) -shared -W1 $(LDFLAGS) -lxml2 -lmemcache -lobjson $(OPENSRF_TARGETS) -o $(TMPDIR)/$(LIBOPENSRF)
+       $(CC) -shared -W1 $(LDFLAGS) -lxml2 -lmemcache $(OPENSRF_TARGETS) -o $(TMPDIR)/$(LIBOPENSRF)
        @echo apps
        make -C  c-apps
 
 
-opensrf-install:       objson-install
-       @echo $@
-       cp $(TMPDIR)/$(LIBOPENSRF) $(LIBDIR)/$(LIBOPENSRF)
-       cp $(OPENSRF_HEADERS) $(INCLUDEDIR)/opensrf/
-       cp libstack/opensrf $(BINDIR)/opensrf-c
-       make -C c-apps install
-
-
-objson/libobjson.so:   prep
-       @echo $@
-       make -C objson
-
+#
 # --------------------------------------------------------------------------------
 # BINARIES
 # --------------------------------------------------------------------------------
 libstack/opensrf.o:    libstack/opensrf.c libopensrf.so
 libstack/opensrf:      libstack/opensrf.o
        @echo $@
-       $(CC) $(CFLAGS) $(LDFLAGS) -lxml2 -lopensrf -lobjson libstack/opensrf.o -o $@
+       $(CC) $(CFLAGS) $(LDFLAGS) -lxml2 -lopensrf libstack/opensrf.o -o $@
        
 
 router: libopensrf.so
@@ -146,14 +137,17 @@ install-prep:
        mkdir -p $(ETCDIR)
        mkdir -p $(TEMPLATEDIR)
 
-objson-install:        install-prep 
-       @echo $@
-       make -C objson install
-
 libopensrf-install:    install-prep
        @echo $@
        cp $(TMPDIR)/$(LIBOPENSRF) $(LIBDIR)
 
+opensrf-install:
+       @echo $@
+       cp $(TMPDIR)/$(LIBOPENSRF) $(LIBDIR)/$(LIBOPENSRF)
+       cp $(OPENSRF_HEADERS) $(INCLUDEDIR)/opensrf/
+       cp libstack/opensrf $(BINDIR)/opensrf-c
+       make -C c-apps install
+
 gateway-install:       install-prep opensrf-install    
        @echo $@
        make -C gateway install
@@ -191,7 +185,6 @@ clean:
        make -C gateway clean
        make -C jserver clean
        make -C utils clean
-       make -C objson clean
        make -C srfsh clean
        make -C c-apps clean
        echo "Removing directory [$(TMPDIR)]"
index ceda792..14b884e 100644 (file)
@@ -1,4 +1,4 @@
-LDLIBS += -lobjson -lopensrf
+LDLIBS +=  -lopensrf
 CFLAGS += -DOSRF_LOG_PARAMS
 
 all:   osrf_math.so osrf_dbmath.so osrf_version.so
index 0b930cd..ace60a1 100644 (file)
@@ -1,6 +1,6 @@
 #include "opensrf/osrf_app_session.h"
 #include "opensrf/osrf_application.h"
-#include "objson/object.h"
+#include "opensrf/osrf_json.h"
 #include "opensrf/log.h"
 
 #define MODULENAME "opensrf.dbmath"
index 63d168a..05d9a1f 100644 (file)
@@ -1,6 +1,6 @@
 #include "opensrf/osrf_app_session.h"
 #include "opensrf/osrf_application.h"
-#include "objson/object.h"
+#include "opensrf/osrf_json.h"
 #include "opensrf/log.h"
 
 #define MODULENAME "opensrf.math"
index 1affb70..9d07874 100644 (file)
@@ -1,6 +1,6 @@
 #include "opensrf/osrf_app_session.h"
 #include "opensrf/osrf_application.h"
-#include "objson/object.h"
+#include "opensrf/osrf_json.h"
 #include "opensrf/utils.h"
 #include "opensrf/log.h"
 
index 2120b23..8da80b1 100644 (file)
@@ -1,6 +1,6 @@
 #CFLAGS        += -DASSUME_STATELESS -DOSRF_GATEWAY_NASTY_DEBUG
 CFLAGS += -DASSUME_STATELESS 
-LDLIBS += -lobjson -lopensrf
+LDLIBS +=  -lopensrf 
 
 all: osrf_json_gateway.so copy
 
index 8f28c91..5d5555b 100755 (executable)
@@ -42,8 +42,7 @@ print SOURCE <<C;
 /* and the JSON parser, so we can read the response we're XMLizing */
 #include <string.h>
 #include <stdio.h>
-#include "objson/object.h"
-#include "objson/json_parser.h"
+#include "opensrf/osrf_json.h"
 #include "opensrf/utils.h"
 
 char* json_string_to_xml(char*);
index a575bd9..27ce454 100644 (file)
@@ -2,8 +2,8 @@
 #include "opensrf/osrf_app_session.h"
 #include "opensrf/osrf_system.h"
 #include "opensrf/osrfConfig.h"
-#include "objson/object.h"
-#include "objson/json2xml.h"
+#include "opensrf/osrf_json.h"
+#include "../libstack/legacy_json.h"
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <unistd.h>
 
 #define MODULE_NAME "osrf_json_gateway_module"
 #define GATEWAY_CONFIG "OSRFGatewayConfig"
+#define JSON_PROTOCOL "OSRFGatewayJSONProtocol"
 #define CONFIG_CONTEXT "gateway"
 
 #define GATEWAY_DEFAULT_CONFIG "/openils/conf/opensrf_core.xml"
+#define GATEWAY_DEFAULT_PROTOCOL "wrapper"  // other option is "classy"
 
 
 /* our config structure */
@@ -21,6 +23,11 @@ typedef struct {
        char* configfile;  /* our bootstrap config file */
 } osrf_json_gateway_config;
 
+
+typedef struct { 
+       char* JSONProtocol;
+} osrf_json_gateway_dir_config;
+
 module AP_MODULE_DECLARE_DATA osrf_json_gateway_module;
 
 char* osrf_json_gateway_config_file = NULL;
@@ -36,10 +43,18 @@ static const char* osrf_json_gateway_set_config(cmd_parms *parms, void *config,
        return NULL;
 }
 
+static const char* osrf_json_gateway_set_json_proto(cmd_parms *parms, void *config, const char *arg) {
+       osrf_json_gateway_dir_config* cfg = (osrf_json_gateway_dir_config*) config;
+       cfg->JSONProtocol = (char*) arg;
+       return NULL;
+}
+
 /* tell apache about our commands */
 static const command_rec osrf_json_gateway_cmds[] = {
        AP_INIT_TAKE1( GATEWAY_CONFIG, osrf_json_gateway_set_config, 
                        NULL, RSRC_CONF, "osrf json gateway config file"),
+       AP_INIT_TAKE1( JSON_PROTOCOL, osrf_json_gateway_set_json_proto,
+                       NULL, ACCESS_CONF, "osrf json gateway config file"),
        {NULL}
 };
 
@@ -51,6 +66,13 @@ static void* osrf_json_gateway_create_config( apr_pool_t* p, server_rec* s) {
        return (void*) cfg;
 }
 
+static void* osrf_json_gateway_create_dir_config( apr_pool_t* p, char* dir) {
+       osrf_json_gateway_dir_config* cfg = (osrf_json_gateway_dir_config*) 
+                       apr_palloc(p, sizeof(osrf_json_gateway_dir_config));
+       cfg->JSONProtocol = GATEWAY_DEFAULT_PROTOCOL;
+       return (void*) cfg;
+}
+
 
 static void osrf_json_gateway_child_init(apr_pool_t *p, server_rec *s) {
 
@@ -83,6 +105,25 @@ static int osrf_json_gateway_method_handler (request_rec *r) {
        /* make sure we're needed first thing*/
        if (strcmp(r->handler, MODULE_NAME )) return DECLINED;
 
+    /* XXX */
+       osrf_json_gateway_dir_config* dir_conf =  
+               ap_get_module_config(r->per_dir_config, &osrf_json_gateway_module);
+
+       ap_log_rerror( APLOG_MARK, APLOG_INFO, 0, r, "JSON protocol = %s", dir_conf->JSONProtocol);
+
+       /* provide 2 different JSON parsers and serializers to support legacy JSON */
+       jsonObject* (*parseJSONFunc) (char*) = legacy_jsonParseString;
+       char* (*jsonToStringFunc) (const jsonObject*) = legacy_jsonObjectToJSON;
+
+       if(dir_conf->JSONProtocol && !strcmp(dir_conf->JSONProtocol,"wrapper") ) {
+               /* if protocol is wrapper, use the new wrapper JSON code */
+               ap_log_rerror( APLOG_MARK, APLOG_INFO, 0, r, "Using wrapper JSON");
+               parseJSONFunc = jsonParseString;
+               jsonToStringFunc = jsonObjectToJSON;
+       }
+    /* XXX */
+
+
        osrfLogDebug(OSRF_LOG_MARK, "osrf gateway: entered request handler");
 
        /* verify we are connected */
@@ -179,7 +220,7 @@ static int osrf_json_gateway_method_handler (request_rec *r) {
                char* str; int i = 0;
                while( (str = osrfStringArrayGetString(mparams, i++)) ) {
                        if( i == 1 ) {
-            OSRF_BUFFER_ADD(act, " ");
+                OSRF_BUFFER_ADD(act, " ");
                                OSRF_BUFFER_ADD(act, str);
                        } else {
                                OSRF_BUFFER_ADD(act, ", ");
@@ -217,7 +258,8 @@ static int osrf_json_gateway_method_handler (request_rec *r) {
                                if (isXML) {
                                        output = jsonObjectToXML( res );
                                } else {
-                                       output = jsonObjectToJSON( res );
+                                       //output = jsonObjectToJSON( res );
+                    output = jsonToStringFunc( res );
                                        if( morethan1 ) ap_rputs(",", r); /* comma between JSON array items */
                                }
                                ap_rputs(output, r);
@@ -263,7 +305,8 @@ static int osrf_json_gateway_method_handler (request_rec *r) {
                                bzero(bb, l);
                                snprintf(bb, l,  "%s : %s", statusname, statustext);
                                jsonObject* tmp = jsonNewObject(bb);
-                               char* j = jsonObjectToJSON(tmp);
+                               //char* j = jsonObjectToJSON(tmp);
+                char* j = jsonToStringFunc(tmp);
                                snprintf( buf, l, ",\"debug\": %s", j);
                                free(j);
                                jsonObjectFree(tmp);
@@ -314,7 +357,8 @@ static void osrf_json_gateway_register_hooks (apr_pool_t *p) {
 
 module AP_MODULE_DECLARE_DATA osrf_json_gateway_module = {
        STANDARD20_MODULE_STUFF,
-       NULL,
+       osrf_json_gateway_create_dir_config,
+       /*NULL,*/
        NULL,
        osrf_json_gateway_create_config,
        NULL,
index e21cfe1..28a6147 100644 (file)
@@ -1,4 +1,4 @@
-LDLIBS += -lopensrf -lobjson -lxml2
+LDLIBS += -lopensrf -lxml2
 CFLAGS += -D_GNU_SOURCE
 
 all: chopchop
index 82fae9a..3dc5dd2 100644 (file)
@@ -2,8 +2,8 @@
 # OSRF_STRICT_PARAMS instructs the app handler to return an error if the number of method arguments
 #      provided to any method is not at least as large as the 'argc' setting for the method
 
-CFLAGS +=  -DASSUME_STATELESS  -DOSRF_LOG_PARAMS -DOSRF_STRICT_PARAMS -rdynamic -fno-strict-aliasing
-LDLIBS += -lxml2 -lobjson -ldl -lmemcache 
+CFLAGS +=  -DASSUME_STATELESS  -DOSRF_LOG_PARAMS -DOSRF_STRICT_PARAMS -rdynamic -fno-strict-aliasing -I.
+LDLIBS += -lxml2  -ldl -lmemcache
 
 TARGETS = osrf_message.o \
                         osrf_app_session.o \
@@ -17,7 +17,13 @@ TARGETS = osrf_message.o \
                         osrf_transgroup.o \
                         osrf_list.o \
                         osrf_hash.o \
-                        xml_utils.o 
+                        xml_utils.o \
+                        osrf_hash.o \
+                        osrf_json_object.o \
+                        osrf_json_parser.o \
+                        osrf_json_tools.o \
+                        legacy_json.o \
+                        xml_utils.o
 
 HEADERS = osrf_message.h \
                         osrf_app_session.h \
@@ -31,6 +37,7 @@ HEADERS = osrf_message.h \
                         osrf_transgroup.h \
                         osrf_list.h \
                         osrf_hash.h \
+                        osrf_json.h \
                         xml_utils.h
 
 all: xml_utils.o $(TARGETS) copy 
@@ -53,10 +60,11 @@ osrfConfig.o:       osrfConfig.c osrfConfig.h xml_utils.o
 osrf_application.o: osrf_application.c osrf_application.h
 osrf_cache.o:  osrf_cache.c osrf_cache.h
 osrf_list.o:   osrf_list.c osrf_list.h
-#osrf_big_list.o:      osrf_big_list.c osrf_big_list.h
 osrf_hash.o:   osrf_hash.c osrf_hash.h
-#osrf_big_hash.o:      osrf_big_hash.c osrf_big_hash.h
-
+osrf_json_object.o:    osrf_json_object.c osrf_json.h osrf_json_utils.h
+osrf_json_parser.o:    osrf_json_parser.c osrf_json.h osrf_json_utils.h
+osrf_json_tools.o:     osrf_json_tools.c osrf_json.h osrf_json_utils.h
+legacy_json.o: legacy_json.c osrf_json.h osrf_json_utils.h
 
 clean:
        /bin/rm -f *.o libopensrf_stack.so xml_utils.h xml_utils.c opensrf
index a172a2b..c195a19 100644 (file)
@@ -50,6 +50,13 @@ osrfConfig* osrfConfigInit(char* configFile, char* configContext) {
        }
 
        cfg->config = xmlDocToJSON(doc);
+
+       /*
+       char* j = jsonObjectToJSON(cfg->config);
+       fprintf(stderr, "JSON:\n%s\n", j);
+       free(j);
+       */
+
        xmlFreeDoc(doc);
 
        if(!cfg->config) {
index c0a6459..ff1cbbd 100644 (file)
@@ -19,7 +19,7 @@ GNU General Public License for more details.
 #include "xml_utils.h"
 #include "opensrf/utils.h"
 #include "opensrf/string_array.h"
-#include "objson/object.h"
+#include "osrf_json.h"
 
 typedef struct {
        jsonObject* config;
@@ -45,11 +45,11 @@ osrfConfig* osrfConfigInit(char* configFile, char* configContext);
 int osrfConfigHasDefaultConfig();
 
 /**
-       Replaces the config object's objson object.  This is useful
+       Replaces the config object's json object.  This is useful
        if you have an ojbson object already and not an XML config
        file to parse.
        @param cfg The config object to alter
-       @param obj The objson objet to use when searching values
+       @param obj The json objet to use when searching values
 */
 void osrfConfigReplaceConfig(osrfConfig* cfg, const jsonObject* obj);
 
index af35af5..733cb28 100644 (file)
@@ -2,7 +2,7 @@
 #define _OSRF_APP_SESSION
 
 #include "opensrf/transport_client.h"
-#include "objson/object.h"
+#include "osrf_json.h"
 #include "osrf_message.h"
 #include "osrf_system.h"
 #include "opensrf/string_array.h"
@@ -10,9 +10,6 @@
 #include "osrf_hash.h"
 #include "osrf_list.h"
 
-#include "objson/object.h"
-#include "objson/json_parser.h"
-
 
 
 #define        DEF_RECV_TIMEOUT 6 /* receive timeout */
index 1d62642..4110783 100644 (file)
@@ -1,11 +1,7 @@
 #include "osrf_application.h"
-#include "objson/object.h"
-
-//osrfApplication* __osrfAppList = NULL; 
 
 osrfHash* __osrfAppHash = NULL;
 
-
 int osrfAppRegisterApplication( char* appName, char* soFile ) {
        if(!appName || ! soFile) return -1;
        char* error;
index 0980a81..de6a167 100644 (file)
@@ -2,7 +2,7 @@
 #include <dlfcn.h>
 #include "opensrf/utils.h"
 #include "opensrf/log.h"
-#include "objson/object.h"
+#include "osrf_json.h"
 #include "osrf_app_session.h"
 #include "osrf_hash.h"
 
index 317cdd0..d110b47 100644 (file)
@@ -14,8 +14,7 @@ GNU General Public License for more details.
 */
 
 
-#include "objson/object.h"
-#include "objson/json_parser.h"
+#include "osrf_json.h"
 #include "memcache.h"
 #include "log.h"
 
index beb52d0..c650139 100644 (file)
@@ -119,8 +119,10 @@ char* osrfMessageSerializeBatch( osrfMessage* msgs [], int count ) {
        while( ((msg = msgs[i]) && (i++ < count)) ) 
                jsonObjectPush(wrapper, osrfMessageToJSON( msg ));
 
+       //jsonObject* enc = jsonObjectEncodeClass(wrapper);
        j = jsonObjectToJSON(wrapper);
        jsonObjectFree(wrapper);
+       //jsonObjectFree(enc);
 
        return j;       
 }
@@ -133,12 +135,14 @@ char* osrf_message_serialize(osrf_message* msg) {
 
        jsonObject* json = osrfMessageToJSON( msg );
 
-       if(json) {
-               jsonObject* wrapper = jsonNewObject(NULL);
-               jsonObjectPush(wrapper, json);
-               j = jsonObjectToJSON(wrapper);
-               jsonObjectFree(wrapper);
-       }
+       if(!json) return NULL;
+
+       jsonObject* wrapper = jsonNewObject(NULL);
+       jsonObjectPush(wrapper, json);
+       //jsonObject* enc = jsonObjectEncodeClass(wrapper);
+       j = jsonObjectToJSON(wrapper);
+       jsonObjectFree(wrapper);
+       //jsonObjectFree(enc);
 
        return j;
 }
@@ -211,7 +215,11 @@ int osrf_message_deserialize(char* string, osrf_message* msgs[], int count) {
        if(!string || !msgs || count <= 0) return 0;
        int numparsed = 0;
 
+       /** XXX **/
        jsonObject* json = jsonParseString(string);
+       //jsonObject* json2 = jsonObjectDecodeClass(json);
+       //jsonObjectFree(json);
+       //json = json2;
 
        if(!json) {
                osrfLogWarning( OSRF_LOG_MARK, 
index b87a97e..e99a604 100644 (file)
@@ -1,8 +1,7 @@
 #include "opensrf/string_array.h"
 #include "opensrf/utils.h"
 #include "opensrf/log.h"
-#include "objson/object.h"
-#include "objson/json_parser.h"
+#include "osrf_json.h"
 
 
 /* libxml stuff for the config reader */
index fecfc32..6313490 100644 (file)
@@ -10,8 +10,7 @@
 
 #include "opensrf/log.h"
 #include "opensrf/utils.h"
-#include "objson/object.h"
-#include "objson/json_parser.h"
+#include "osrf_json.h"
 #include "osrf_app_session.h"
 
 
index 643e81c..103ecc9 100644 (file)
@@ -1,6 +1,7 @@
 
 TARGETS        = transport_message.o transport_session.o transport_client.o 
 HEADERS        = transport_message.h transport_session.h transport_client.h 
+CFLAGS += -I ../libstack -I ../utils
 
 TARGET = libopensrf_transport.so
 
index f0e63af..44eaa98 100644 (file)
@@ -95,7 +95,7 @@ transport_message* new_message_from_xml( const char* msg_xml ) {
                xmlFree(router_class);
        }
        if(broadcast) {
-               if(strcmp(broadcast,"0") )
+               if(strcmp( (char*)broadcast,"0") )
                        new_msg->broadcast      = 1;
                xmlFree(broadcast);
        }
@@ -211,9 +211,9 @@ int message_free( transport_message* msg ){
 // ---------------------------------------------------------------------------------
 char* message_to_xml( const transport_message* msg ) {
 
-       int                     bufsize;
+       //int                   bufsize;
        //xmlChar*              xmlbuf;
-       char*                   encoded_body;
+       //char*                 encoded_body;
 
        xmlNodePtr      message_node;
        xmlNodePtr      body_node;
index 43bdcbc..1db881a 100644 (file)
@@ -322,13 +322,14 @@ void grab_incoming(void* blob, socket_manager* mgr, int sockid, char* data, int
 
 
 void startElementHandler(
-       void *session, const xmlChar *name, const xmlChar **atts) {
+       void *session, const xmlChar *ename, const xmlChar **atts) {
 
        transport_session* ses = (transport_session*) session;
        if( ! ses ) { return; }
 
-       
-       if( strcmp( name, "message" ) == 0 ) {
+   char* name = (char*) ename;
+
+       if( strcmp(  name, "message" ) == 0 ) {
                ses->state_machine->in_message = 1;
                buffer_add( ses->from_buffer, get_xml_attr( atts, "from" ) );
                buffer_add( ses->recipient_buffer, get_xml_attr( atts, "to" ) );
@@ -429,7 +430,7 @@ char* get_xml_attr( const xmlChar** atts, char* attr_name ) {
        int i;
        if (atts != NULL) {
                for(i = 0;(atts[i] != NULL);i++) {
-                       if( strcmp( atts[i++], attr_name ) == 0 ) {
+                       if( strcmp( (char*)atts[i++], attr_name ) == 0 ) {
                                if( atts[i] != NULL ) {
                                        return (char*) atts[i];
                                }
@@ -443,10 +444,11 @@ char* get_xml_attr( const xmlChar** atts, char* attr_name ) {
 // ------------------------------------------------------------------
 // See which tags are ending
 // ------------------------------------------------------------------
-void endElementHandler( void *session, const xmlChar *name) {
+void endElementHandler( void *session, const xmlChar *ename) {
        transport_session* ses = (transport_session*) session;
        if( ! ses ) { return; }
 
+   char* name = (char*) ename;
        if( strcmp( name, "message" ) == 0 ) {
 
 
index 2128f96..13f75e8 100644 (file)
@@ -85,7 +85,78 @@ sub _json_hint_to_class {
        return $hint;
 }
 
+
+my $JSON_CLASS_KEY = '__c';
+my $JSON_PAYLOAD_KEY = '__p';
+
 sub JSON2perl {
+       my( $class, $string ) = @_;
+       my $perl = $class->rawJSON2perl($string);
+       use Data::Dumper;
+       return $class->JSONObject2Perl($perl);
+}
+
+sub perl2JSON {
+       my( $class, $obj ) = @_;
+       my $json = $class->perl2JSONObject($obj);
+       return $class->rawPerl2JSON($json);
+}
+
+sub JSONObject2Perl {
+       my $class = shift;
+       my $obj = shift;
+       my $ref = ref($obj);
+       if( $ref eq 'HASH' ) {
+               if( defined($obj->{$JSON_CLASS_KEY})) {
+                       my $cls = $obj->{$JSON_CLASS_KEY};
+                       if( $obj = $class->JSONObject2Perl($obj->{$JSON_PAYLOAD_KEY}) ) {
+                               $cls = $class->lookup_class($cls) || $cls;
+                               return bless(\$obj, $cls) unless ref($obj); 
+                               return bless($obj, $cls);
+                       }
+                       return undef;
+               }
+               $obj->{$_} = $class->JSONObject2Perl($obj->{$_}) for (keys %$obj);
+       } elsif( $ref eq 'ARRAY' ) {
+               $obj->[$_] = $class->JSONObject2Perl($obj->[$_]) for(0..scalar(@$obj) - 1);
+       }
+       return $obj;
+}
+
+sub perl2JSONObject {
+       my $class = shift;
+       my $obj = shift;
+       my $ref = ref($obj);
+
+       return $obj unless $ref;
+       my $newobj;
+
+       if( $ref eq 'HASH' ) {
+               $newobj = {};
+               $newobj->{$_} = $class->perl2JSONObject( $obj->{$_} ) for (keys %$obj);
+       } elsif( $ref eq 'ARRAY' ) {
+               $newobj = [];
+               $newobj->[$_] = $class->perl2JSONObject( $obj->[$_] ) for(0..scalar(@$obj) - 1 );
+       } elsif( $ref ) {
+               if(UNIVERSAL::isa($obj, 'HASH')) {
+                       $newobj = {};
+                       $newobj->{$_} = $class->perl2JSONObject( $obj->{$_} ) for (keys %$obj);
+                       bless( $newobj, ref($obj) );
+                       #bless($obj, 'HASH'); # so our parser won't add the hints
+               } elsif(UNIVERSAL::isa($obj, 'ARRAY')) {
+                       $newobj = [];
+                       $newobj->[$_] = $class->perl2JSONObject( $obj->[$_] ) for(0..scalar(@$obj) - 1);
+                       bless( $newobj, ref($obj) );
+                       #bless($obj, 'ARRAY'); # so our parser won't add the hints
+               }
+               $ref = $class->lookup_hint($ref) || $ref;
+               $newobj = { $JSON_CLASS_KEY => $ref, $JSON_PAYLOAD_KEY => $newobj };
+       } 
+       return $newobj; 
+}
+
+
+sub rawJSON2perl {
        my $class = shift;
        local $_ = shift;
 
@@ -97,8 +168,8 @@ sub JSON2perl {
        s/\\u([0-9a-fA-F]{4})/chr(hex($1))/esog;
 
        # handle class blessings
-       s/\/\*--\s*S\w*?\s+\S+\s*--\*\// bless(/sog;
-       s/(\]|\}|")\s*\/\*--\s*E\w*?\s+(\S+)\s*--\*\//$1 => _json_hint_to_class("$1", "$2")) /sog;
+#      s/\/\*--\s*S\w*?\s+\S+\s*--\*\// bless(/sog;
+#      s/(\]|\}|")\s*\/\*--\s*E\w*?\s+(\S+)\s*--\*\//$1 => _json_hint_to_class("$1", "$2")) /sog;
 
        my $re = qr/((?<!\\)"(?>(?<=\\)"|[^"])*(?<!\\)")/;
        # Grab strings...
@@ -123,6 +194,7 @@ sub JSON2perl {
        return eval '$ret = '.$_;
 }
 
+
 my $_json_index;
 sub ___JSON2perl {
        my $class = shift;
@@ -667,7 +739,8 @@ sub old_JSON2perl {
        return eval $output;
 }
 
-sub perl2JSON {
+
+sub rawPerl2JSON {
        my ($class, $perl, $strict) = @_;
 
        my $output = '';
@@ -676,17 +749,18 @@ sub perl2JSON {
                $output = 'null' unless $strict;
        } elsif (ref($perl) and ref($perl) =~ /^JSON/) {
                $output .= $perl;
-       } elsif ( ref($perl) && exists($_class_map{classes}{ref($perl)}) ) {
-               $output .= '/*--S '.$_class_map{classes}{ref($perl)}{hint}.'--*/';
-               if (lc($_class_map{classes}{ref($perl)}{type}) eq 'hash') {
-                       my %hash =  %$perl;
-                       $output .= perl2JSON(undef,\%hash, $strict);
-               } elsif (lc($_class_map{classes}{ref($perl)}{type}) eq 'array') {
-                       my @array =  @$perl;
-                       $output .= perl2JSON(undef,\@array, $strict);
-               }
-               $output .= '/*--E '.$_class_map{classes}{ref($perl)}{hint}.'--*/';
-       } elsif (ref($perl) and ref($perl) =~ /HASH/) {
+#      } elsif ( ref($perl) && exists($_class_map{classes}{ref($perl)}) ) {
+#              $output .= '/*--S '.$_class_map{classes}{ref($perl)}{hint}.'--*/';
+#              if (lc($_class_map{classes}{ref($perl)}{type}) eq 'hash') {
+#                      my %hash =  %$perl;
+#                      $output .= rawPerl2JSON(undef,\%hash, $strict);
+#              } elsif (lc($_class_map{classes}{ref($perl)}{type}) eq 'array') {
+#                      my @array =  @$perl;
+#                      $output .= rawPerl2JSON(undef,\@array, $strict);
+#              }
+#              $output .= '/*--E '.$_class_map{classes}{ref($perl)}{hint}.'--*/';
+#      } elsif (ref($perl) and ref($perl) =~ /HASH/) {
+       } elsif (UNIVERSAL::isa($perl, 'HASH')) {
                $output .= '{';
                my $c = 0;
                for my $key (sort keys %$perl) {
@@ -701,27 +775,28 @@ sub perl2JSON {
                        $outkey =~ s/\n/\\n/sgo;
                        $outkey =~ s/([\x{0080}-\x{fffd}])/sprintf('\u%0.4x',ord($1))/sgoe;
 
-                       $output .= '"'.$outkey.'":'. perl2JSON(undef,$$perl{$key}, $strict);
+                       $output .= '"'.$outkey.'":'. rawPerl2JSON(undef,$$perl{$key}, $strict);
                        $c++;
                }
                $output .= '}';
-       } elsif (ref($perl) and ref($perl) =~ /ARRAY/) {
+#      } elsif (ref($perl) and ref($perl) =~ /ARRAY/) {
+       } elsif (UNIVERSAL::isa($perl, 'ARRAY')) {
                $output .= '[';
                my $c = 0;
                for my $part (@$perl) {
                        $output .= ',' if ($c); 
                        
-                       $output .= perl2JSON(undef,$part, $strict);
+                       $output .= rawPerl2JSON(undef,$part, $strict);
                        $c++;
                }
                $output .= ']';
        } elsif (ref($perl) and ref($perl) =~ /CODE/) {
-               $output .= perl2JSON(undef,$perl->(), $strict);
+               $output .= rawPerl2JSON(undef,$perl->(), $strict);
        } elsif (ref($perl) and ("$perl" =~ /^([^=]+)=(\w+)/o)) {
                my $type = $2;
                my $name = $1;
                JSON->register_class_hint(name => $name, hint => $name, type => lc($type));
-               $output .= perl2JSON(undef,$perl, $strict);
+               $output .= rawPerl2JSON(undef,$perl, $strict);
        } else {
                $perl = NFC($perl);
                $perl =~ s{\\}{\\\\}sgo;
index 615b0fd..826e6b9 100644 (file)
 # -----------------------------------------------------------------------
 
 
-import simplejson, types
+import simplejson, types, cjson
 
 JSON_PAYLOAD_KEY = '__p'
 JSON_CLASS_KEY = '__c'
 
 class osrfNetworkObject(object):
-       """Base class for serializable network objects."""
-       def getData(self):
-               """Returns a dict of data contained by this object"""
-               return self.data
+    """Base class for serializable network objects."""
+    def getData(self):
+        """Returns a dict of data contained by this object"""
+        return self.data
 
 
 class __unknown(osrfNetworkObject):
-       """Default class for un-registered network objects."""
-       def __init__(self, data=None):
-               self.data = data
+    """Default class for un-registered network objects."""
+    def __init__(self, data=None):
+        self.data = data
 
 setattr(__unknown,'__keys', [])
 setattr(osrfNetworkObject,'__unknown', __unknown)
 
 
 def osrfNetworkRegisterHint(hint, keys, type='hash'):
-       """Register a network hint.  
-       
-               This creates a new class at osrfNetworkObject.<hint> with 
-               methods for accessing/mutating the object's data.  
-               Method names will match the names found in the keys array
-
-               hint - The hint name to encode with the object
-               type - The data container type.  
-               keys - An array of data keys.  If type is an 'array', the order of
-               the keys will determine how the data is accessed
-       """
-
-       estr = "class %s(osrfNetworkObject):\n" % hint
-       estr += "\tdef __init__(self, data=None):\n"
-       estr += "\t\tself.data = data\n"
-       estr += "\t\tif data:\n"
-
-       if type == 'hash': 
-               estr += "\t\t\tpass\n"
-       else:
-               # we have to make sure the array is large enough        
-               estr += "\t\t\twhile len(data) < %d:\n" % len(keys)
-               estr += "\t\t\t\tdata.append(None)\n"
-
-       estr += "\t\telse:\n"
-
-       if type == 'array':
-               estr += "\t\t\tself.data = []\n"
-               estr += "\t\t\tfor i in range(%s):\n" % len(keys)
-               estr += "\t\t\t\tself.data.append(None)\n"
-               for i in range(len(keys)):
-                       estr += "\tdef %s(self, *args):\n"\
-                                               "\t\tif len(args) != 0:\n"\
-                                               "\t\t\tself.data[%s] = args[0]\n"\
-                                               "\t\treturn self.data[%s]\n" % (keys[i], i, i)
-
-       if type == 'hash':
-               estr += "\t\t\tself.data = {}\n"
-               estr += "\t\t\tfor i in %s:\n" % str(keys)
-               estr += "\t\t\t\tself.data[i] = None\n"
-               for i in keys:
-                       estr += "\tdef %s(self, *args):\n"\
-                                               "\t\tif len(args) != 0:\n"\
-                                               "\t\t\tself.data['%s'] = args[0]\n"\
-                                               "\t\tval = None\n"\
-                                               "\t\ttry: val = self.data['%s']\n"\
-                                               "\t\texcept: return None\n"\
-                                               "\t\treturn val\n" % (i, i, i)
-
-       estr += "setattr(osrfNetworkObject, '%s', %s)\n" % (hint,hint)
-       estr += "setattr(osrfNetworkObject.%s, '__keys', keys)" % hint
-       exec(estr)
-       
-               
+    """Register a network hint.  
+    
+        This creates a new class at osrfNetworkObject.<hint> with 
+        methods for accessing/mutating the object's data.  
+        Method names will match the names found in the keys array
+
+        hint - The hint name to encode with the object
+        type - The data container type.  
+        keys - An array of data keys.  If type is an 'array', the order of
+        the keys will determine how the data is accessed
+    """
+
+    # XXX there must be a cleaner way to do this via the python API
+
+    estr = "class %s(osrfNetworkObject):\n" % hint
+    estr += "\tdef __init__(self, data=None):\n"
+    estr += "\t\tself.data = data\n"
+    estr += "\t\tif data:\n"
+
+    if type == 'hash': 
+        estr += "\t\t\tpass\n"
+    else:
+        # we have to make sure the array is large enough    
+        estr += "\t\t\twhile len(data) < %d:\n" % len(keys)
+        estr += "\t\t\t\tdata.append(None)\n"
+
+    estr += "\t\telse:\n"
+
+    if type == 'array':
+        estr += "\t\t\tself.data = []\n"
+        estr += "\t\t\tfor i in range(%s):\n" % len(keys)
+        estr += "\t\t\t\tself.data.append(None)\n"
+        for i in range(len(keys)):
+            estr += "\tdef %s(self, *args):\n"\
+                        "\t\tif len(args) != 0:\n"\
+                        "\t\t\tself.data[%s] = args[0]\n"\
+                        "\t\treturn self.data[%s]\n" % (keys[i], i, i)
+
+    if type == 'hash':
+        estr += "\t\t\tself.data = {}\n"
+        estr += "\t\t\tfor i in %s:\n" % str(keys)
+        estr += "\t\t\t\tself.data[i] = None\n"
+        for i in keys:
+            estr += "\tdef %s(self, *args):\n"\
+                        "\t\tif len(args) != 0:\n"\
+                        "\t\t\tself.data['%s'] = args[0]\n"\
+                        "\t\tval = None\n"\
+                        "\t\ttry: val = self.data['%s']\n"\
+                        "\t\texcept: return None\n"\
+                        "\t\treturn val\n" % (i, i, i)
+
+    estr += "setattr(osrfNetworkObject, '%s', %s)\n" % (hint,hint)
+    estr += "setattr(osrfNetworkObject.%s, '__keys', keys)" % hint
+    exec(estr)
+    
+        
 
 # -------------------------------------------------------------------
 # Define the custom object parsing behavior 
 # -------------------------------------------------------------------
 def __parseNetObject(obj):
-       hint = None
-       islist = False
-       try:
-               hint = obj[JSON_CLASS_KEY]
-               obj = obj[JSON_PAYLOAD_KEY]
-       except: pass
-       if isinstance(obj,list):
-               islist = True
-               for i in range(len(obj)):
-                       obj[i] = __parseNetObject(obj[i])
-       else: 
-               if isinstance(obj,dict):
-                       for k,v in obj.iteritems():
-                               obj[k] = __parseNetObject(v)
-
-       if hint: # Now, "bless" the object into an osrfNetworkObject
-               estr = 'obj = osrfNetworkObject.%s(obj)' % hint
-               try:
-                       exec(estr)
-               except AttributeError:
-                       # this object has not been registered, shove it into the default container
-                       obj = osrfNetworkObject.__unknown(obj)
-
-       return obj;
+    hint = None
+    #islist = False
+    try:
+        hint = obj[JSON_CLASS_KEY]
+        obj = obj[JSON_PAYLOAD_KEY]
+    except: pass
+    if isinstance(obj,list):
+        #islist = True
+        for i in range(len(obj)):
+            obj[i] = __parseNetObject(obj[i])
+    else: 
+        if isinstance(obj,dict):
+            for k,v in obj.iteritems():
+                obj[k] = __parseNetObject(v)
+
+    if hint: # Now, "bless" the object into an osrfNetworkObject
+        estr = 'obj = osrfNetworkObject.%s(obj)' % hint
+        try:
+            exec(estr)
+        except AttributeError:
+            # this object has not been registered, shove it into the default container
+            obj = osrfNetworkObject.__unknown(obj)
+
+    return obj;
 
 
 # -------------------------------------------------------------------
 # Define the custom object encoding behavior 
 # -------------------------------------------------------------------
 class osrfJSONNetworkEncoder(simplejson.JSONEncoder):
-       def default(self, obj):
-               if isinstance(obj, osrfNetworkObject):
-                       return { 
-                               JSON_CLASS_KEY: obj.__class__.__name__,
-                               JSON_PAYLOAD_KEY: self.default(obj.getData())
-                       }       
-               return obj
+    def default(self, obj):
+        if isinstance(obj, osrfNetworkObject):
+            return { 
+                JSON_CLASS_KEY: obj.__class__.__name__,
+                JSON_PAYLOAD_KEY: self.default(obj.getData())
+            }   
+        return obj
 
 
 def osrfObjectToJSON(obj):
-       """Turns a python object into a wrapped JSON object"""
-       return simplejson.dumps(obj, cls=osrfJSONNetworkEncoder)
+    """Turns a python object into a wrapped JSON object"""
+    return simplejson.dumps(obj, cls=osrfJSONNetworkEncoder)
 
 
 def osrfJSONToObject(json):
-       """Turns a JSON string into python objects"""
-       obj = simplejson.loads(json)
-       return __parseNetObject(obj)
+    """Turns a JSON string into python objects"""
+    #obj = simplejson.loads(json)
+    obj = None
+    try:
+        obj = cjson.decode(json)
+    except Exception:
+        # cjson is more finicky, if it dies, try simplejson
+        obj = simplejson.loads(json)
+    return __parseNetObject(obj)
 
 def osrfParseJSONRaw(json):
-       """Parses JSON the old fashioned way."""
-       return simplejson.loads(json)
+    """Parses JSON the old fashioned way."""
+    return simplejson.loads(json)
 
 def osrfToJSONRaw(obj):
-       """Stringifies an object as JSON with no additional logic."""
-       return simplejson.dumps(obj)
+    """Stringifies an object as JSON with no additional logic."""
+    return simplejson.dumps(obj)
 
 def __tabs(t):
-       r=''
-       for i in range(t): r += '   '
-       return r
+    r=''
+    for i in range(t): r += '   '
+    return r
 
-def osrfDebugNetworkObject(obj, t=1):
-       """Returns a debug string for a given object.
+def osrfDebugNetworkObject(obj, t=0):
+    """Returns a debug string for a given object.
 
-       If it's an osrfNetworkObject and has registered keys, key/value p
-       pairs are returned.  Otherwise formatted JSON is returned"""
+    If it's an osrfNetworkObject and has registered keys, key/value p
+    pairs are returned.  Otherwise formatted JSON is returned"""
 
-       s = ''
-       if isinstance(obj, osrfNetworkObject) and len(obj.__keys):
-               obj.__keys.sort()
+    s = ''
+    if isinstance(obj, osrfNetworkObject) and len(obj.__keys):
+        obj.__keys.sort()
 
-               for k in obj.__keys:
+        for k in obj.__keys:
 
-                       key = k
-                       while len(key) < 24: key += '.' # pad the names to make the values line up somewhat
-                       val = getattr(obj, k)()
+            key = k
+            while len(key) < 24: key += '.' # pad the names to make the values line up somewhat
+            val = getattr(obj, k)()
 
-                       subobj = val and not (isinstance(val,unicode) or \
-                                       isinstance(val, int) or isinstance(val, float) or isinstance(val, long))
+            subobj = val and not (isinstance(val,unicode) or isinstance(val,str) or\
+                    isinstance(val, int) or isinstance(val, float) or isinstance(val, long))
 
 
-                       s += __tabs(t) + key + ' = '
+            s += __tabs(t) + key + ' '
 
-                       if subobj:
-                               s += '\n'
-                               val = osrfDebugNetworkObject(val, t+1)
+            if subobj:
+                s += '\n'
+                val = osrfDebugNetworkObject(val, t+1)
 
-                       s += str(val)
+            s += str(val)
 
-                       if not subobj: s += '\n'
+            if not subobj: s += '\n'
 
-       else:
-               s = osrfFormatJSON(osrfObjectToJSON(obj))
-       return s
+    else:
+        s = osrfFormatJSON(osrfObjectToJSON(obj))
+    return s
 
 def osrfFormatJSON(json):
-       """JSON pretty-printer"""
-       r = ''
-       t = 0
-       instring = False
-       inescape = False
-       done = False
+    """JSON pretty-printer"""
+    r = ''
+    t = 0
+    instring = False
+    inescape = False
+    done = False
 
-       for c in json:
+    for c in json:
 
-               done = False
-               if (c == '{' or c == '[') and not instring:
-                       t += 1
-                       r += c + '\n' + __tabs(t)
-                       done = True
+        done = False
+        if (c == '{' or c == '[') and not instring:
+            t += 1
+            r += c + '\n' + __tabs(t)
+            done = True
 
-               if (c == '}' or c == ']') and not instring:
-                       t -= 1
-                       r += '\n' + __tabs(t) + c
-                       done = True
+        if (c == '}' or c == ']') and not instring:
+            t -= 1
+            r += '\n' + __tabs(t) + c
+            done = True
 
-               if c == ',' and not instring:
-                       r += c + '\n' + __tabs(t)
-                       done = True
+        if c == ',' and not instring:
+            r += c + '\n' + __tabs(t)
+            done = True
 
-               if c == '"' and not inescape:
-                       instring = not instring
+        if c == '"' and not inescape:
+            instring = not instring
 
-               if inescape: 
-                       inescape = False
+        if inescape: 
+            inescape = False
 
-               if c == '\\':
-                       inescape = True
+        if c == '\\':
+            inescape = True
 
-               if not done:
-                       r += c
+        if not done:
+            r += c
 
-       return r
+    return r
 
-       
+    
index db0b131..5664761 100644 (file)
@@ -22,7 +22,7 @@ from osrf.log import *
 import os, time
 import logging
 
-# - log jabber activity (for future reference)
+# - if you need raw jabber logs
 #logger=logging.getLogger()
 #logger.addHandler(logging.StreamHandler())
 #logger.addHandler(logging.FileHandler('j.log'))
index 4742246..e3e63c4 100755 (executable)
@@ -5,79 +5,94 @@ from osrf.system import osrfConnect
 from osrf.json import *
 from osrf.ses import osrfClientSession
 from osrf.conf import osrfConfigValue
+import osrf.ex
 
+prompt = "\033[01;32msrfsh\033[01;34m% \033[00m"
+last_response = None
+commands = {}
+
+
+def register_command(name, callback):
+    commands[name] = callback
+    
 
 # -------------------------------------------------------------------
 # main listen loop
 # -------------------------------------------------------------------
+"""
 def do_loop():
-       while True:
+    while True:
+
+        try:
+            line = raw_input(prompt+'')
+            if not len(line): 
+                continue
+            if lower(line) == 'exit' or lower(line) == 'quit': 
+                break
+            parts = split(line)
 
-               try:
-                       #line = raw_input("srfsh% ")
-                       line = raw_input("\033[01;32msrfsh\033[01;34m% \033[00m")
-                       if not len(line): 
-                               continue
-                       if lower(line) == 'exit' or lower(line) == 'quit': 
-                               break
-                       parts = split(line)
+            command = parts.pop(0)
+        
+            if command == 'request':
+                handle_request(parts)
+                continue
 
-                       command = parts[0]
-               
-                       if command == 'request':
-                               parts.pop(0)
-                               handle_request(parts)
-                               continue
+            if command == 'math_bench':
+                handle_math_bench(parts)
+                continue
 
-                       if command == 'math_bench':
-                               parts.pop(0)
-                               handle_math_bench(parts)
-                               continue
+            if command == 'help':
+                handle_help()
+                continue
 
-                       if command == 'help':
-                               handle_help()
-                               continue
+            if command == 'set':
+                handle_set(parts)
 
-                       if command == 'set':
-                               parts.pop(0)
-                               handle_set(parts)
+            if command == 'get':
+                handle_get(parts)
 
-                       if command == 'get':
-                               parts.pop(0)
-                               handle_get(parts)
+            if command == 'eval':
+                handle_eval(parts)
 
 
 
-               except KeyboardInterrupt:
-                       print ""
+        except KeyboardInterrupt:
+            print ""
 
-               except EOFError:
-                       print "exiting..."
-                       sys.exit(0)
+        except EOFError:
+            print "exiting..."
+            sys.exit(0)
+"""
 
 
 # -------------------------------------------------------------------
 # Set env variables to control behavior
 # -------------------------------------------------------------------
 def handle_set(parts):
-       m = re.compile('(.*)=(.*)').match(parts[0])
-       key = m.group(1)
-       val = m.group(2)
-       set_var(key, val)
-       print "%s = %s" % (key, val)
+    m = re.compile('(.*)=(.*)').match(parts[0])
+    key = m.group(1)
+    val = m.group(2)
+    set_var(key, val)
+    print "%s = %s" % (key, val)
 
 def handle_get(parts):
-       try:
-               print get_var(parts[0])
-       except:
-               print ""
-
+    try:
+        print get_var(parts[0])
+    except:
+        print ""
+
+def handle_eval(parts):
+    com = ' '.join(parts)
+    try:
+        print eval(com)
+    except Exception, e:
+        print "EVAL failed: " + str(e)
 
 # -------------------------------------------------------------------
 # Prints help info
 # -------------------------------------------------------------------
 def handle_help():
-       print """
+    print """
   help
     - show this menu
 
@@ -87,94 +102,109 @@ def handle_help():
   request <service> <method> [<param1>, <param2>, ...]
     - performs an opensrf request
 
+  eval <command>
+    - evals the requested command within the srfsh environment
+    - special variables:
+      - last_response - last item received from a network call
+
   set VAR=<value>
     - sets an environment variable
 
   Environment variables:
     SRFSH_OUTPUT = pretty - print pretty JSON and key/value pairs for network objects
                  = raw - print formatted JSON 
-       """
+    """
 
-               
+        
 
 
 # -------------------------------------------------------------------
 # performs an opesnrf request
 # -------------------------------------------------------------------
 def handle_request(parts):
-       service = parts.pop(0)
-       method = parts.pop(0)
-       jstr = '[%s]' % join(parts)
-       params = None
+    service = parts.pop(0)
+    method = parts.pop(0)
+    jstr = '[%s]' % join(parts)
+    params = None
+    global last_response
 
-       try:
-               params = osrfJSONToObject(jstr)
-       except:
-               print "Error parsing JSON: %s" % jstr
-               return
+    try:
+        params = osrfJSONToObject(jstr)
+    except:
+        print "Error parsing JSON: %s" % jstr
+        return
 
-       ses = osrfClientSession(service)
+    otp = get_var('SRFSH_OUTPUT')
 
-       end = None
-       start = time.time()
+    ses = osrfClientSession(service)
 
-       req = ses.request2(method, tuple(params))
+    end = None
+    start = time.time()
+    req = ses.request2(method, tuple(params))
 
 
-       while True:
-               resp = req.recv(timeout=120)
-               if not end:
-                       total = time.time() - start
-               if not resp: break
+    while True:
 
-               otp = get_var('SRFSH_OUTPUT')
-               if otp == 'pretty':
-                       print osrfDebugNetworkObject(resp.content())
-               else:
-                       print osrfFormatJSON(osrfObjectToJSON(resp.content()))
+        resp = None
 
-       req.cleanup()
-       ses.cleanup()
+        try:
+            resp = req.recv(timeout=120)
+        except Exception, e:
+            print "\nThere was a problem running your request:\n\n%s\n" % str(e)
+            return
 
-       print '-'*60
-       print "Total request time: %f" % total
-       print '-'*60
+        if not end:
+            total = time.time() - start
+        if not resp: break
+
+        if otp == 'pretty':
+            print osrfDebugNetworkObject(resp.content())
+        else:
+            print osrfFormatJSON(osrfObjectToJSON(resp.content()))
+        last_response = resp.content()
+
+    req.cleanup()
+    ses.cleanup()
+
+    print '-'*60
+    print "Total request time: %f" % total
+    print '-'*60
 
 
 def handle_math_bench(parts):
 
-       count = int(parts.pop(0))
-       ses = osrfClientSession('opensrf.math')
-       times = []
-
-       for i in range(100):
-               if i % 10: sys.stdout.write('.')
-               else: sys.stdout.write( str( i / 10 ) )
-       print "";
-
-
-       for i in range(count):
-       
-               starttime = time.time()
-               req = ses.request('add', 1, 2)
-               resp = req.recv(timeout=2)
-               endtime = time.time()
-       
-               if resp.content() == 3:
-                       sys.stdout.write("+")
-                       sys.stdout.flush()
-                       times.append( endtime - starttime )
-               else:
-                       print "What happened? %s" % str(resp.content())
-       
-               req.cleanup()
-               if not ( (i+1) % 100):
-                       print ' [%d]' % (i+1)
-       
-       ses.cleanup()
-       total = 0
-       for i in times: total += i
-       print "\naverage time %f" % (total / len(times))
+    count = int(parts.pop(0))
+    ses = osrfClientSession('opensrf.math')
+    times = []
+
+    for i in range(100):
+        if i % 10: sys.stdout.write('.')
+        else: sys.stdout.write( str( i / 10 ) )
+    print "";
+
+
+    for i in range(count):
+    
+        starttime = time.time()
+        req = ses.request('add', 1, 2)
+        resp = req.recv(timeout=2)
+        endtime = time.time()
+    
+        if resp.content() == 3:
+            sys.stdout.write("+")
+            sys.stdout.flush()
+            times.append( endtime - starttime )
+        else:
+            print "What happened? %s" % str(resp.content())
+    
+        req.cleanup()
+        if not ( (i+1) % 100):
+            print ' [%d]' % (i+1)
+    
+    ses.cleanup()
+    total = 0
+    for i in times: total += i
+    print "\naverage time %f" % (total / len(times))
 
 
 
@@ -183,88 +213,151 @@ def handle_math_bench(parts):
 # Defines the tab-completion handling and sets up the readline history 
 # -------------------------------------------------------------------
 def setup_readline():
-       class SrfshCompleter(object):
-               def __init__(self, words):
-                       self.words = words
-                       self.prefix = None
-       
-               def complete(self, prefix, index):
-                       if prefix != self.prefix:
-                               # find all words that start with this prefix
-                               self.matching_words = [
-                                       w for w in self.words if w.startswith(prefix)
-                               ]
-                               self.prefix = prefix
-                               try:
-                                       return self.matching_words[index]
-                               except IndexError:
-                                       return None
-       
-       words = 'request', 'help', 'exit', 'quit', 'opensrf.settings', 'opensrf.math', 'set'
-       completer = SrfshCompleter(words)
-       readline.parse_and_bind("tab: complete")
-       readline.set_completer(completer.complete)
-
-       histfile = os.path.join(get_var('HOME'), ".srfsh_history")
-       try:
-           readline.read_history_file(histfile)
-       except IOError:
-               pass
-       atexit.register(readline.write_history_file, histfile)
+    class SrfshCompleter(object):
+        def __init__(self, words):
+            self.words = words
+            self.prefix = None
+    
+        def complete(self, prefix, index):
+            if prefix != self.prefix:
+                # find all words that start with this prefix
+                self.matching_words = [
+                    w for w in self.words if w.startswith(prefix)
+                ]
+                self.prefix = prefix
+                try:
+                    return self.matching_words[index]
+                except IndexError:
+                    return None
+    
+    words = 'request', 'help', 'exit', 'quit', 'opensrf.settings', 'opensrf.math', 'set'
+    completer = SrfshCompleter(words)
+    readline.parse_and_bind("tab: complete")
+    readline.set_completer(completer.complete)
+
+    histfile = os.path.join(get_var('HOME'), ".srfsh_history")
+    try:
+        readline.read_history_file(histfile)
+    except IOError:
+        pass
+    atexit.register(readline.write_history_file, histfile)
 
 def do_connect():
-       file = os.path.join(get_var('HOME'), ".srfsh.xml")
+    file = os.path.join(get_var('HOME'), ".srfsh.xml")
 
-       print_green("Connecting to opensrf...")
-       osrfConnect(file)
-       print_red('OK\n')
+    print_green("Connecting to opensrf...")
+    osrfConnect(file)
+    print_red('OK')
+    print ''
 
 def load_plugins():
-       # Load the user defined external plugins
-       # XXX Make this a real module interface, with tab-complete words, commands, etc.
-       plugins = osrfConfigValue('plugins')
-       plugins = osrfConfigValue('plugins.plugin')
-       if not isinstance(plugins, list):
-               plugins = [plugins]
-
-       for module in plugins:
-               name = module['module']
-               init = module['init']
-               print_green("Loading module %s..." % name)
-
-               try:
-                       str = 'from %s import %s\n%s()' % (name, init, init)
-                       exec(str)
-                       print_red('OK\n')
-
-               except Exception, e:
-                       sys.stderr.write("\nError importing plugin %s, with init symbol %s: \n%s\n" % (name, init, e))
+    # Load the user defined external plugins
+    # XXX Make this a real module interface, with tab-complete words, commands, etc.
+    plugins = osrfConfigValue('plugins')
+    plugins = osrfConfigValue('plugins.plugin')
+    if not isinstance(plugins, list):
+        plugins = [plugins]
+
+    for module in plugins:
+        name = module['module']
+        init = module['init']
+        print_green("Loading module %s..." % name)
+
+        try:
+            str = 'from %s import %s\n%s()' % (name, init, init)
+            exec(str)
+            print_red('OK')
+            print ''
+
+        except Exception, e:
+            sys.stderr.write("\nError importing plugin %s, with init symbol %s: \n%s\n" % (name, init, e))
 
 def set_vars():
-       if not get_var('SRFSH_OUTPUT'):
-               set_var('SRFSH_OUTPUT', 'pretty')
+    if not get_var('SRFSH_OUTPUT'):
+        set_var('SRFSH_OUTPUT', 'pretty')
 
 
 def set_var(key, val):
-       os.environ[key] = val
+    os.environ[key] = val
 
 
 def get_var(key):
-       try: return os.environ[key]
-       except: return ''
-       
-       
+    try: return os.environ[key]
+    except: return ''
+    
+    
 def print_green(str):
-       sys.stdout.write("\033[01;32m")
-       sys.stdout.write(str)
-       sys.stdout.write("\033[00m")
-       sys.stdout.flush()
+    sys.stdout.write("\033[01;32m")
+    sys.stdout.write(str)
+    sys.stdout.write("\033[00m")
+    #sys.stdout.flush()
 
 def print_red(str):
-       sys.stdout.write("\033[01;31m")
-       sys.stdout.write(str)
-       sys.stdout.write("\033[00m")
-       sys.stdout.flush()
+    sys.stdout.write("\033[01;31m")
+    sys.stdout.write(str)
+    sys.stdout.write("\033[00m")
+    #sys.stdout.flush()
+
+def print_purple(str):
+    sys.stdout.write("\033[01;34m")
+    sys.stdout.write(str)
+    sys.stdout.write("\033[00m")
+    #sys.stdout.flush()
+
+
+
+
+
+
+
+# -------------------------------------------------------------------
+# main listen loop
+# -------------------------------------------------------------------
+def do_loop():
+    while True:
+
+        try:
+            line = raw_input(prompt+'')
+            if not len(line): 
+                continue
+            if lower(line) == 'exit' or lower(line) == 'quit': 
+                break
+            parts = split(line)
+
+            command = parts.pop(0)
+        
+            if command == 'request':
+                handle_request(parts)
+                continue
+
+            if command == 'math_bench':
+                handle_math_bench(parts)
+                continue
+
+            if command == 'help':
+                handle_help()
+                continue
+
+            if command == 'set':
+                handle_set(parts)
+
+            if command == 'get':
+                handle_get(parts)
+
+            if command == 'eval':
+                handle_eval(parts)
+
+
+
+        except KeyboardInterrupt:
+            print ""
+
+        except EOFError:
+            print "exiting..."
+            sys.exit(0)
+
+
+
 
 
 
index e156743..f545b66 100644 (file)
@@ -1,6 +1,6 @@
 #MALLOC_CHECK_=1 # XXX debug only
 
-LDLIBS += -lxml2 -lopensrf -lobjson
+LDLIBS += -lxml2 -lopensrf 
 CFLAGS += -D_ROUTER
 
 all: opensrf_router 
index 163818e..17526a0 100644 (file)
@@ -1,6 +1,6 @@
 # if EXEC_DEFAULT is defined, then srfsh will send all unknown commands to the shell for execution
 
-LDLIBS += -lobjson -lreadline -lxml2 -lopensrf -lncurses 
+LDLIBS +=  -lreadline -lxml2 -lopensrf -lncurses 
 LDFLAGS        += -DEXEC_DEFAULT
 
 all: srfsh
index 9887038..a5e1f82 100644 (file)
@@ -514,7 +514,7 @@ int send_request( char* server,
        jsonObject* params = NULL;
        if( !relay ) {
                if( buffer != NULL && buffer->n_used > 0 ) 
-                       params = json_parse_string(buffer->buf);
+                       params = jsonParseString(buffer->buf);
        } else {
                if(!last_result || ! last_result->_result_content) { 
                        printf("We're not going to call 'relay' with no result params\n");
@@ -802,7 +802,7 @@ int do_math( int count, int style ) {
        osrf_app_session* session = osrf_app_client_session_init(  "opensrf.math" );
        osrf_app_session_connect(session);
 
-       jsonObject* params = json_parse_string("[]");
+       jsonObject* params = jsonParseString("[]");
        jsonObjectPush(params,jsonNewObject("1"));
        jsonObjectPush(params,jsonNewObject("2"));
 
index 80a59e5..063e614 100755 (executable)
@@ -24,8 +24,7 @@ my $map = $Fieldmapper::fieldmap;
 
 print HEADER <<C;
 
-#include "objson/object.h"
-#include "objson/json_parser.h"
+#include "opensrf/osrf_json.h"
 #include "utils.h"
 
 /* Fieldmapper-C.  Autogenerated from fieldmapper-c.pl.\n\nNote that object*'s passed in as
index 308e3b7..671650f 100644 (file)
@@ -27,10 +27,12 @@ GNU General Public License for more details.
 #include <sys/types.h>
 #include <stdlib.h>
 #include <string.h>
-//#include <sys/timeb.h>
-
 #include "md5.h"
 
+
+//#define MKCHAR(__c) (char*) __c
+
+
 #define OSRF_MALLOC(ptr, size) \
        ptr = (void*) malloc( size ); \
        if( ptr == NULL ) { \
index 15a350b..a33c36c 100644 (file)
@@ -91,7 +91,7 @@ char* xmlSaxAttr( const xmlChar** atts, char* name ) {
        if( atts && name ) {
                int i;
                for(i = 0; (atts[i] != NULL); i++) {
-                       if(!strcmp(atts[i], name)) {
+                       if(!strcmp( (char*)atts[i], name)) {
                                if(atts[++i]) return (char*) atts[i];
                        }
                }