Changes for json-c instead of json-glib
authorMichael Carpenter <malcom2073@gmail.com>
Sat, 16 Mar 2013 17:23:48 +0000 (13:23 -0400)
committerMichael Carpenter <malcom2073@gmail.com>
Sat, 16 Mar 2013 17:23:48 +0000 (13:23 -0400)
ambd/pluginloader.cpp
plugins/obd2plugin/obd2source.cpp
plugins/websocketsourceplugin/websocketsource.cpp

index c06d60b..11487e0 100644 (file)
@@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
 #include <iostream>
 #include <stdexcept>
+#include <boost/concept_check.hpp>
 //#include <json-glib/json-glib.h>
 
 
@@ -36,16 +37,31 @@ using namespace std;
  * 
 **********************************************/
 
+std::string get_file_contents(const char *filename)
+{
+  //FILE *in = fopen(filename,"r");
+  
+  std::ifstream in(filename, std::ios::in);
+  std::string output;
+  std::string line;
+  while(in.good())
+  {
+    getline(in,line);
+    output.append(line);
+  }
+  return output;
+}
 PluginLoader::PluginLoader(string configFile, AbstractRoutingEngine* re, int argc, char** argv): f_create(NULL), routingEngine(re), mMainLoop(nullptr)
 {
   
        DebugOut()<<"Loading config file: "<<configFile<<endl;
        json_object *rootobject;
        json_tokener *tokener = json_tokener_new();
+       std::string configBuffer = get_file_contents(configFile.c_str());
        enum json_tokener_error err;
        do
        {
-               rootobject = json_tokener_parse_ex(tokener, configFile.c_str(),configFile.length());
+               rootobject = json_tokener_parse_ex(tokener, configBuffer.c_str(),configBuffer.length());
        } while ((err = json_tokener_get_error(tokener)) == json_tokener_continue);
        if (err != json_tokener_success)
        {
@@ -93,6 +109,11 @@ PluginLoader::PluginLoader(string configFile, AbstractRoutingEngine* re, int arg
        
        
        array_list *sourceslist = json_object_get_array(sourcesobject);
+       if (!sourceslist)
+       {
+         DebugOut() << "Error getting source list" << endl;
+         throw std::runtime_error("Error getting sources list");
+       }
        
        for(int i=0; i < array_list_length(sourceslist); i++)
        {
@@ -116,14 +137,33 @@ PluginLoader::PluginLoader(string configFile, AbstractRoutingEngine* re, int arg
                }
                json_object_put(pathobject);
        }
+       DebugOut() << "Trying to free list" << endl;
        array_list_free(sourceslist);
-       json_object_put(sourcesobject);
-
+       DebugOut() << "Trying to free obj" << endl;
+       //json_object_put(sourcesobject);
+       DebugOut() << "Done first" << endl;
        ///read the sinks:
        
        json_object *sinksobject = json_object_object_get(rootobject,"sinks");
+       
+       if (!sinksobject)
+       {
+         DebugOut() << "Error getting sink object" << endl;
+         throw std::runtime_error("Error getting sink object");
+       }
+       
+       
+       
        array_list *sinkslist = json_object_get_array(sinksobject);
        
+       
+       if (!sinkslist)
+       {
+         DebugOut() << "Error getting sink list" << endl;
+         throw std::runtime_error("Error getting sink list");
+       }
+       
+       
        for(int i=0; i < array_list_length(sinkslist); i++)
        {
                json_object *obj = (json_object*)array_list_get_idx(sinkslist,i);
@@ -148,10 +188,14 @@ PluginLoader::PluginLoader(string configFile, AbstractRoutingEngine* re, int arg
                        throw std::runtime_error("plugin is not a SinkManager");
                }
                json_object_put(pathobject);
+               //json_object_put(obj);
 
        }
+       DebugOut() << "Trying to free list" << endl;
        array_list_free(sinkslist);
-       json_object_put(sinksobject);
+       DebugOut() << "Trying to free obj" << endl;
+       //json_object_put(sinksobject);
+       DebugOut() << "Done" << endl;
                
        
        ///TODO: this will probably explode:
index 582c944..4b8c2eb 100644 (file)
@@ -23,7 +23,7 @@
 #include <boost/lexical_cast.hpp>
 #include <glib.h>
 #include <sstream>
-#include <json-glib/json-glib.h>
+//#include <json-glib/json-glib.h>
 #include <listplusplus.h>
 #include "debugout.h"
 #include "bluetooth.hpp"
index a755061..c335f2f 100644 (file)
@@ -23,7 +23,7 @@
 #include <boost/lexical_cast.hpp>
 #include <glib.h>
 #include <sstream>
-#include <json-glib/json-glib.h>
+//#include <json-glib/json-glib.h>
 #include <listplusplus.h>
 #include <timestamp.h>
 #include "uuidhelper.h"
@@ -235,266 +235,223 @@ static int callback_http_only(libwebsocket_context *context,struct libwebsocket
 
                        DebugOut(2)<<"websocket source pre-json parse time: "<<prejsonparsetime<<endl;
 
-                       for(int i=0;i<1000;i++)
+                       json_object *rootobject;
+                       json_tokener *tokener = json_tokener_new();
+                       enum json_tokener_error err;
+                       do
                        {
-
-                       //Incoming JSON reqest.
-                       GError* error = nullptr;
-                       JsonParser* parser = json_parser_new();
-                       if (!json_parser_load_from_data(parser,(char*)in,len,&error))
+                               rootobject = json_tokener_parse_ex(tokener, (char*)in,len);
+                       } while ((err = json_tokener_get_error(tokener)) == json_tokener_continue);
+                       if (err != json_tokener_success)
                        {
-                               DebugOut(0) << __SMALLFILE__ <<":"<< __LINE__ << "Error loading JSON"<<endl;
-                               DebugOut(0) << (char*)in <<endl;
-                               DebugOut(0) <<error->message<<endl;
-                               return 0;
+                               fprintf(stderr, "Error: %s\n", json_tokener_error_desc(err));
+                               // Handle errors, as appropriate for your application.
                        }
-
-                       JsonNode* node = json_parser_get_root(parser);
-                       if(node == nullptr)
+                       if (tokener->char_offset < len) // XXX shouldn't access internal fields
                        {
-                               DebugOut(0) << __SMALLFILE__ <<":"<< __LINE__ << "Error getting root node of json"<<endl;
-                               //throw std::runtime_error("Unable to get JSON root object");
-                               return 0;
-                       }
-
-                       JsonReader* reader = json_reader_new(node);
-                       if(reader == nullptr)
-                       {
-                               DebugOut(0) << __SMALLFILE__ <<":"<< __LINE__ << "json_reader is null!"<<endl;
-                               //throw std::runtime_error("Unable to create JSON reader");
-                               return 0;
+                               // Handle extra characters after parsed object as desired.
+                               // e.g. issue an error, parse another object from that point, etc...
                        }
-
+                       //Incoming JSON reqest.
+                       
 
                        DebugOut(5)<<"source received: "<<string((char*)in)<<endl;
+                       
+                       json_object *typeobject= json_object_object_get(rootobject,"type");
+                       json_object *nameobject= json_object_object_get(rootobject,"name");
+                       json_object *transidobject= json_object_object_get(rootobject,"transactionid");
 
 
-                       string type;
-                       json_reader_read_member(reader,"type");
-                       type = json_reader_get_string_value(reader);
-                       json_reader_end_member(reader);
-
-                       string  name;
-                       json_reader_read_member(reader,"name");
-                       name = json_reader_get_string_value(reader);
-                       json_reader_end_member(reader);
-                       
+                       string type = string(json_object_get_string(typeobject));
+                       string  name = string(json_object_get_string(nameobject));
                        
                        string id;
-                       json_reader_read_member(reader,"transactionid");
-                       if (strcmp("gchararray",g_type_name(json_node_get_value_type(json_reader_get_value(reader)))) == 0)
+                       
+                       if (json_object_get_type(transidobject) == json_type_string)
                        {
-                               //Type is a string
-                               id = json_reader_get_string_value(reader);
+                               id = json_object_get_string(transidobject);
                        }
                        else
                        {
-                               //Type is an integer
                                stringstream strstr;
-                               strstr << json_reader_get_int_value(reader);
+                               strstr << json_object_get_int(transidobject);
                                id = strstr.str();
                        }
-                       json_reader_end_member(reader);
                        
                        list<pair<string,string> > pairdata;
                        if (type == "valuechanged")
                        {
-                               json_reader_read_member(reader,"data");
-                               if (json_reader_is_object(reader))
+                               json_object *dataobject = json_object_object_get(rootobject,"data");
+                               
+                               json_object *valueobject = json_object_object_get(rootobject,"value");
+                               json_object *timestampobject = json_object_object_get(rootobject,"timestamp");
+                               json_object *sequenceobject= json_object_object_get(rootobject,"sequence");
+                               
+                               string value = string(json_object_get_string(valueobject));
+                               string timestamp = string(json_object_get_string(timestampobject));
+                               string sequence = string(json_object_get_string(sequenceobject));
+                               //printf("Value changed: %s, %s\n",name.c_str(),data.front().c_str());
+                               DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Value changed:" << name << value << endl;
+                               //Name should be a valid property
+                               //      routingEngine->updateProperty(VehicleProperty::VehicleSpeed, velocity);
+                               //data.front()
+                               try
                                {
-                                       //Proper object.
-                                       json_reader_read_member(reader,"value");
-                                       std::string value = json_reader_get_string_value(reader);
-                                       json_reader_end_member(reader);
+                                       AbstractPropertyType* type = VehicleProperty::getPropertyTypeForPropertyNameValue(name,value);
+                                       type->timestamp = boost::lexical_cast<double,std::string>(timestamp);
+                                       type->sequence = boost::lexical_cast<double,std::string>(sequence);
+                                       m_re->updateProperty(name, type, source->uuid());
+                                       double currenttime = amb::currentTime();
+
+                                       /** This is now the latency between when something is available to read on the socket, until
+                                        *  a property is about to be updated in AMB.  This includes libwebsockets parsing and the
+                                        *  JSON parsing in this section.
+                                        */
                                        
-                                       json_reader_read_member(reader,"timestamp");
-                                       std::string timestamp = json_reader_get_string_value(reader);
-                                       json_reader_end_member(reader);
-                                       
-                                       json_reader_read_member(reader,"sequence");
-                                       std::string sequence= json_reader_get_string_value(reader);
-                                       json_reader_end_member(reader);
-                                       //printf("Value changed: %s, %s\n",name.c_str(),data.front().c_str());
-                                       DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Value changed:" << name << value << endl;
-                                       //Name should be a valid property
-                                       //      routingEngine->updateProperty(VehicleProperty::VehicleSpeed, velocity);
-                                       //data.front()
-                                       try
-                                       {
-                                               AbstractPropertyType* type = VehicleProperty::getPropertyTypeForPropertyNameValue(name,value);
-                                               type->timestamp = boost::lexical_cast<double,std::string>(timestamp);
-                                               type->sequence = boost::lexical_cast<double,std::string>(sequence);
-                                               m_re->updateProperty(name, type, source->uuid());
+                                       DebugOut(2)<<"websocket parse latency: "<<(currenttime - oldTimestamp)*1000<<"ms"<<endl;
+                                       DebugOut(2)<<"websocket network + parse latency: "<<(currenttime - type->timestamp)*1000<<"ms"<<endl;
+                                       totalTime += (currenttime - oldTimestamp)*1000;
+                                       numUpdates ++;
+                                       averageLatency = totalTime / numUpdates;
 
-                                               double currenttime = amb::currentTime();
+                                       DebugOut(2)<<"Average parse latency: "<<averageLatency<<endl;
 
-                                               /** This is now the latency between when something is available to read on the socket, until
-                                                *  a property is about to be updated in AMB.  This includes libwebsockets parsing and the
-                                                *  JSON parsing in this section.
-                                                */
-
-                                               DebugOut(2)<<"websocket parse latency: "<<(currenttime - oldTimestamp)*1000<<"ms"<<endl;
-                                               DebugOut(2)<<"websocket network + parse latency: "<<(currenttime - type->timestamp)*1000<<"ms"<<endl;
-
-                                               totalTime += (currenttime - oldTimestamp)*1000;
-                                               numUpdates ++;
-
-                                               averageLatency = totalTime / numUpdates;
-
-                                               DebugOut(2)<<"Average parse latency: "<<averageLatency<<endl;
-
-                                               delete type;
-                                       }
-                                       catch (exception ex)
+                                       delete type;
+                               }
+                               catch (exception ex)
+                               {
+                                       //printf("Exception %s\n",ex.what());
+                                       DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Exception:" << ex.what() << "\n";
+                               }
+                               json_object_put(valueobject);
+                               json_object_put(timestampobject);
+                               json_object_put(sequenceobject);
+                               json_object_put(dataobject);
+                               //printf("Done\n");
+                               /*if (name == "get")
+                               {
+                                       if (data.size() > 0)
                                        {
-                                               //printf("Exception %s\n",ex.what());
-                                               DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Exception:" << ex.what() << "\n";
                                        }
-                                       //printf("Done\n");
-                                       /*if (name == "get")
-                                       {
-                                               if (data.size() > 0)
-                                               {
-                                               }
-                                       }*/
-                               }
+                               }*/
                        }
                        else if (type == "methodReply")
                        {
+                               json_object *dataobject = json_object_object_get(rootobject,"data");
                                if (name == "getSupportedEventTypes")
                                {
-                                       json_reader_read_member(reader,"data");
                                        //printf("Got supported events!\n");
                                        DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Got getSupportedEventTypes request"<<endl;
                                        PropertyList props;
-                                       if (json_reader_is_array(reader))
+                                       if (json_object_get_type(dataobject) == json_type_array)
                                        {
-                                               for(int i=0; i < json_reader_count_elements(reader); i++)
+                                               array_list *dataarray = json_object_get_array(dataobject);
+                                               for (int i=0;i<array_list_length(dataarray);i++)
                                                {
-                                                       json_reader_read_element(reader,i);
-                                                       string path = json_reader_get_string_value(reader);
-                                                       props.push_back(path);
-                                                       json_reader_end_element(reader);
+                                                       json_object *arrayobj = (json_object*)array_list_get_idx(dataarray,i);
+                                                       props.push_back(string(json_object_get_string(arrayobj)));
                                                }
+                                               array_list_free(dataarray);
                                        }
                                        else
                                        {
-                                               string path = json_reader_get_string_value(reader);
-                                               if (path != "")
-                                               {
-                                                       props.push_back(path);;
-                                               }
+                                               props.push_back(string(json_object_get_string(dataobject)));
                                        }
-                                       json_reader_end_member(reader);
                                        source->setSupported(props);
                                        //m_re->updateSupported(m_supportedProperties,PropertyList());
                                }
                                else if (name == "getRanged")
                                {
-                                       json_reader_read_member(reader,"data");
-                                       if (json_reader_is_array(reader))
+                                       std::list<AbstractPropertyType*> propertylist;
+                                       array_list *dataarray = json_object_get_array(dataobject);
+                                       for (int i=0;i<array_list_length(dataarray);i++)
                                        {
-                                               std::list<AbstractPropertyType*> propertylist;
-                                               for(int i=0; i < json_reader_count_elements(reader); i++)
-                                               {
-                                                       json_reader_read_member(reader,"value");
-                                                       std::string value = json_reader_get_string_value(reader);
-                                                       json_reader_end_member(reader);
-                                               
-                                                       json_reader_read_member(reader,"timestamp");
-                                                       std::string timestamp = json_reader_get_string_value(reader);
-                                                       json_reader_end_member(reader);
-                                                       
-                                                       json_reader_read_member(reader,"sequence");
-                                                       std::string sequence = json_reader_get_string_value(reader);
-                                                       json_reader_end_member(reader);
-                                                       
-                                                       AbstractPropertyType* type = VehicleProperty::getPropertyTypeForPropertyNameValue(source->uuidRangedReplyMap[id]->property,value);
-                                                       propertylist.push_back(type);
-                                                       
-                                               }
-                                               if (source->uuidRangedReplyMap.find(id) != source->uuidRangedReplyMap.end())
-                                               {
-                                                       source->uuidRangedReplyMap[id]->values = propertylist;
-                                                       source->uuidRangedReplyMap[id]->success = true;
-                                                       source->uuidRangedReplyMap[id]->completed(source->uuidRangedReplyMap[id]);
-                                                       source->uuidRangedReplyMap.erase(id);
-                                               }
-                                               else
-                                               {
-                                                       DebugOut() << "getRanged methodReply has been recieved, without a request being in!. This is likely due to a request coming in after the timeout has elapsed.\n";
-                                               }
-                                               while (propertylist.size() > 0)
-                                               {
+                                               json_object *arrayobj = (json_object*)array_list_get_idx(dataarray,i);
+                                               json_object *valueobject = json_object_object_get(arrayobj,"value");
+                                               json_object *timestampobject = json_object_object_get(arrayobj,"timestamp");
+                                               json_object *sequenceobject = json_object_object_get(arrayobj,"sequence");
+                                               std::string value = json_object_get_string(valueobject);
+                                               std::string timestamp = json_object_get_string(timestampobject);
+                                               std::string sequence = json_object_get_string(sequenceobject);
+                                               json_object_put(valueobject);
+                                               json_object_put(timestampobject);
+                                               json_object_put(sequenceobject);
                                                        
-                                                       AbstractPropertyType *type = propertylist.front();
-                                                       delete type;
-                                                       propertylist.pop_front();
-                                               }
+                                               AbstractPropertyType* type = VehicleProperty::getPropertyTypeForPropertyNameValue(source->uuidRangedReplyMap[id]->property,value);
+                                               propertylist.push_back(type);
+                                               //props.push_back(string(json_object_get_string(arrayobj)));
+                                       }
+                                       array_list_free(dataarray);
+                                       if (source->uuidRangedReplyMap.find(id) != source->uuidRangedReplyMap.end())
+                                       {
+                                               source->uuidRangedReplyMap[id]->values = propertylist;
+                                               source->uuidRangedReplyMap[id]->success = true;
+                                               source->uuidRangedReplyMap[id]->completed(source->uuidRangedReplyMap[id]);
+                                               source->uuidRangedReplyMap.erase(id);
+                                       }
+                                       else
+                                       {
+                                               DebugOut() << "getRanged methodReply has been recieved, without a request being in!. This is likely due to a request coming in after the timeout has elapsed.\n";
+                                       }
+                                       while (propertylist.size() > 0)
+                                       {
+                                               
+                                               AbstractPropertyType *type = propertylist.front();
+                                               delete type;
+                                               propertylist.pop_front();
                                        }
-                                       json_reader_end_member(reader);
                                }
                                else if (name == "get")
                                {
-                                       json_reader_read_member(reader,"data");
-                                       if (json_reader_is_object(reader))
+                                       
+                                       DebugOut() << __SMALLFILE__ << ":" << __LINE__ << "Got \"GET\" event:" << pairdata.size()<<endl;
+                                       if (source->uuidReplyMap.find(id) != source->uuidReplyMap.end())
                                        {
-                                               DebugOut() << __SMALLFILE__ << ":" << __LINE__ << "Got \"GET\" event:" << pairdata.size()<<endl;
+                                               json_object *propertyobject = json_object_object_get(dataobject,"property");
+                                               json_object *valueobject = json_object_object_get(dataobject,"value");
+                                               json_object *timestampobject = json_object_object_get(dataobject,"timestamp");
+                                               json_object *sequenceobject = json_object_object_get(dataobject,"sequence");
+                                               std::string property = json_object_get_string(propertyobject);
+                                               std::string value = json_object_get_string(valueobject);
+                                               std::string timestamp = json_object_get_string(timestampobject);
+                                               std::string sequence = json_object_get_string(sequenceobject);
+                                               json_object_put(propertyobject);
+                                               json_object_put(valueobject);
+                                               json_object_put(timestampobject);
+                                               json_object_put(sequenceobject);
+                                             
+                                               AbstractPropertyType* v = VehicleProperty::getPropertyTypeForPropertyNameValue(property,value);
+                                               v->timestamp = boost::lexical_cast<double,std::string>(timestamp);
+                                               v->sequence = boost::lexical_cast<double,std::string>(sequence);
                                                if (source->uuidReplyMap.find(id) != source->uuidReplyMap.end())
                                                {
-                                                       json_reader_read_member(reader,"property");
-                                                       std::string property = json_reader_get_string_value(reader);
-                                                       json_reader_end_member(reader);
-                                                             
-                                                       json_reader_read_member(reader,"value");
-                                                       std::string value = json_reader_get_string_value(reader);
-                                                       json_reader_end_member(reader);
-                                                       
-                                                       json_reader_read_member(reader,"timestamp");
-                                                       std::string timestamp = json_reader_get_string_value(reader);
-                                                       json_reader_end_member(reader);
-                                                       
-                                                       
-                                                       json_reader_read_member(reader,"sequence");
-                                                       std::string sequence = json_reader_get_string_value(reader);
-                                                       json_reader_end_member(reader);
-                                                     
-                                                       AbstractPropertyType* v = VehicleProperty::getPropertyTypeForPropertyNameValue(property,value);
-                                                       v->timestamp = boost::lexical_cast<double,std::string>(timestamp);
-                                                       v->sequence = boost::lexical_cast<double,std::string>(sequence);
-                                                       if (source->uuidReplyMap.find(id) != source->uuidReplyMap.end())
-                                                       {
-                                                               source->uuidReplyMap[id]->value = v;
-                                                               source->uuidReplyMap[id]->success = true;
-                                                               source->uuidReplyMap[id]->completed(source->uuidReplyMap[id]);
-                                                               source->uuidReplyMap.erase(id);
-                                                       }
-                                                       else
-                                                       {
-                                                               DebugOut() << "get methodReply has been recieved, without a request being in!. This is likely due to a request coming in after the timeout has elapsed.\n";
-                                                       }
-
-                                                       delete v;
+                                                       source->uuidReplyMap[id]->value = v;
+                                                       source->uuidReplyMap[id]->success = true;
+                                                       source->uuidReplyMap[id]->completed(source->uuidReplyMap[id]);
+                                                       source->uuidReplyMap.erase(id);
                                                }
+                                               else
+                                               {
+                                                       DebugOut() << "get methodReply has been recieved, without a request being in!. This is likely due to a request coming in after the timeout has elapsed.\n";
+                                               }
+                                                       delete v;
                                        }
                                        else
                                        {
                                                DebugOut() << __SMALLFILE__ << ":" << __LINE__ << "GET Method Reply INVALID! Multiple properties detected, only single are supported!!!" << "\n";
                                        }
-                                       json_reader_end_member(reader);
+                                       
                                        //data will contain a property/value map.
                                }
+                               json_object_put(dataobject);
                        }
-
+                       json_object_put(rootobject);
                        ///TODO: this will probably explode:
                        //mlc: I agree with Kevron here, it does explode.
                        //if(error) g_error_free(error);
 
-                       g_object_unref(reader);
-                       g_object_unref(parser);
-
+                       
                        break;
-                       }
                }
                case LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED:
                {