[cangen][cansim] - revert using picojson. continue using json-c
authorKevron Rees <kevron.m.rees@intel.com>
Thu, 22 Jan 2015 00:18:08 +0000 (16:18 -0800)
committerKevron Rees <kevron.m.rees@intel.com>
Thu, 22 Jan 2015 00:18:08 +0000 (16:18 -0800)
RELEASE.md
plugins/cangenplugin/CMakeLists.txt
plugins/cangenplugin/cangenplugin.cpp
plugins/cangenplugin/cangenplugin.h
plugins/cansimplugin/CMakeLists.txt
plugins/cansimplugin/cansimplugin.cpp

index 892b96c..350b4c1 100644 (file)
@@ -1,5 +1,5 @@
 # AMB Release Notes {#release_notes}
-Version: 0.13.802
+Version: 0.14
 
 ## New features:
 - [DBus] some classes for exporting custom interfaces moved to plugins-common
@@ -18,3 +18,5 @@ Version: 0.13.802
   obtained through the Properties interface.
 
 ## Fixes:
+- [XWalk] Fixed misspelled 'diagnostics' interface
+- [DBus] Fixed misspelled 'Diagnostics' interface
index cb50538..a954a00 100644 (file)
@@ -2,15 +2,16 @@ if(cangen_plugin)
 ############################################################################################################################################
 
 pkg_check_modules(websockets REQUIRED libwebsockets)
+pkg_check_modules(json REQUIRED json)
 
-include_directories(${CMAKE_SOURCE_DIR}/lib ${include_dirs} ${gio_INCLUDE_DIRS} ${gio-unix_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/plugins/common ${Boost_INCLUDE_DIRS} )
+include_directories(${CMAKE_SOURCE_DIR}/lib ${include_dirs} ${gio_INCLUDE_DIRS} ${gio-unix_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/plugins/common ${Boost_INCLUDE_DIRS} ${json_INCLUDE_DIRS})
 
 set(cangenplugin_headers cangenplugin.h websockets.h)
 set(cangenplugin_sources cangenplugin.cpp websockets.cpp)
 
 add_library(cangenplugin MODULE ${cangenplugin_sources} ${cangenplugin_headers})
 set_target_properties(cangenplugin PROPERTIES PREFIX "")
-target_link_libraries(cangenplugin amb amb-plugins-common -L${CMAKE_CURRENT_BINARY_DIR}/plugins/common ${link_libraries} ${websockets_LIBRARIES} -lrt)
+target_link_libraries(cangenplugin amb amb-plugins-common -L${CMAKE_CURRENT_BINARY_DIR}/plugins/common ${link_libraries} ${websockets_LIBRARIES} -lrt ${json_LIBRARIES})
 
 install(TARGETS cangenplugin LIBRARY DESTINATION ${PLUGIN_INSTALL_PATH})
 
index 11d1987..73d3253 100644 (file)
@@ -99,11 +99,8 @@ void CANGenPlugin::parseMappingTable(const std::string& table)
 
        std::string json(table);
        std::replace(json.begin(), json.end(), '\'', '"');// replace all ' to "
-       picojson::value rootobject;
-
-       picojson::parse(rootobject, json);
-
-       if(!rootobject.is<picojson::object>())
+       std::unique_ptr<json_object, decltype(&json_object_put)> rootobject(json_tokener_parse(json.c_str()), &json_object_put);
+       if(!rootobject)
        {
                LOG_ERROR("Failed to parse json: " << json);
                return;
@@ -111,18 +108,31 @@ void CANGenPlugin::parseMappingTable(const std::string& table)
 
        // Success, use json_obj here.
        mappingTable.clear();
-       picojson::array sources = rootobject.get("sources").get<picojson::array>();
-       if(!sources.size())
+       json_object *sources = json_object_object_get(rootobject.get(),"sources");
+       if(!sources)
+               return;
+       array_list* arraySources = json_object_get_array(sources);
+       if(!arraySources)
                return;
-       for(auto rootsource : sources)
+       for(int i=0; i < array_list_length(arraySources); ++i)
        {
-               picojson::value source = rootsource.get("source");
-               const std::string guidstr = source.get("guid").to_str();
-               picojson::array signals = rootsource.get("signals").get<picojson::array>();
-               if(!signals.size())
+               json_object *rootsource = static_cast<json_object*>(array_list_get_idx(arraySources,i));
+               if(!rootsource)
                        continue;
-               for(auto signal : signals)
+               json_object* source = json_object_object_get(rootsource, "source");
+               if(!source)
+                       continue;
+               json_object* guid = json_object_object_get(source, "guid");
+               const std::string guidstr(guid ? json_object_get_string(guid) : "");
+               json_object* signals = json_object_object_get(rootsource, "signals");
+               if(!signals)
+                       continue;
+               array_list* arraySignals = json_object_get_array(signals);
+               for(int j = 0; j < array_list_length(arraySignals); ++j)
                {
+                       json_object *signal = static_cast<json_object*>(array_list_get_idx(arraySignals,j));
+                       if(!signal)
+                               continue;
                        mappingTable.addProperty(guidstr, signal);
                }// signals array loop
        }// sources array loop
@@ -280,36 +290,66 @@ void CANGenPlugin::dataReceived(libwebsocket* socket, const char* data, size_t l
        if(!data || len == 0)
                return;
 
-       picojson::value rootobject;
-
-       picojson::parse(rootobject, data);
-
-       if(!rootobject.is<picojson::object>())
+       //TODO: refactor ? copied from websocketsink
+       std::unique_ptr<json_object, decltype(&json_object_put)> rootobject(nullptr, &json_object_put);
+       std::unique_ptr<json_tokener, decltype(&json_tokener_free)> tokener(json_tokener_new(), &json_tokener_free);
+       enum json_tokener_error err;
+       do
+       {   std::unique_ptr<json_object, decltype(&json_object_put)> tmpobject(json_tokener_parse_ex(tokener.get(), data, len), &json_object_put);
+               rootobject.swap(tmpobject);
+       } while ((err = json_tokener_get_error(tokener.get())) == json_tokener_continue);
+       if (err != json_tokener_success)
+       {
+               LOG_ERROR("Error: " << json_tokener_error_desc(err) << std::endl);
+               return;
+       }
+       if(!rootobject)
        {
                LOG_ERROR("Failed to parse json: " << data << std::endl);
                return;
        }
 
-       std::string type = rootobject.get("type").to_str();
-       std::string name = rootobject.get("name").to_str();
-       std::string id = rootobject.get("transactionid").to_str();
+       if (tokener->char_offset < len) // XXX shouldn't access internal fields
+       {
+               // Handle extra characters after parsed object as desired.
+               // e.g. issue an error, parse another object from that point, etc...
+       }
+       // Success, use jobj here.
+       json_object *typeobject = json_object_object_get(rootobject.get(),"type");
+       json_object *nameobject = json_object_object_get(rootobject.get(),"name");
+       json_object *transidobject = json_object_object_get(rootobject.get(),"transactionid");
 
-       if(typeobject.empty() || nameobject.empty() || transidobject.empty())
+       if(!typeobject || !nameobject || !transidobject)
        {
                DebugOut(DebugOut::Warning)<<"Malformed json. aborting"<<endl;
                return;
        }
 
+       string type = string(json_object_get_string(typeobject));
+       string name = string(json_object_get_string(nameobject));
+       string id;
+       if (json_object_get_type(transidobject) == json_type_string)
+       {
+               id = string(json_object_get_string(transidobject));
+       }
+       else
+       {
+               stringstream strstr;
+               strstr << json_object_get_int(transidobject);
+               id = strstr.str();
+       }
        if (type == "method") {
 
                vector<string> propertyNames;
                list< std::tuple<string, string, string, Zone::Type, string> > propertyData;
 
-               picojson::value dataobject = rootobject.get("data");
-               if(dataobject.is<picojson::array)
+               json_object *dataobject = json_object_object_get(rootobject.get(),"data");
+               if (json_object_get_type(dataobject) == json_type_array)
                {
-                       for (auto arrayobject : dataobject)
+                       array_list *arraylist = json_object_get_array(dataobject);
+                       for (int i=0;i<array_list_length(arraylist);i++)
                        {
+                               json_object *arrayobject = (json_object*)array_list_get_idx(arraylist,i);
                                if (json_object_get_type(arrayobject) == json_type_object)
                                {
                                        json_object *interfaceobject = json_object_object_get(arrayobject,"interface");
@@ -335,85 +375,92 @@ void CANGenPlugin::dataReceived(libwebsocket* socket, const char* data, size_t l
                                        propertyNames.push_back(propertyName);
                                }
                        }
+                       //array_list_free(arraylist);
                }
                else
                {
-                       propertyNames.push_back();
-               }
-
-               if (name == "get")
-               {
-                       if (!propertyNames.empty())
+                       string path = json_object_get_string(dataobject);
+                       if (path != "")
                        {
-                               //GetProperty is going to be a singleshot sink.
-                               getValue(socket,propertyNames.front(), Zone::None,id);
-                       }
-                       else if (!propertyData.empty())
-                       {
-                               //GetProperty is going to be a singleshot sink.
-                               auto prop = propertyData.front();
-                               getValue(socket,std::get<1>(prop),std::get<3>(prop),id);
-                       }
-                       else
-                       {
-                               LOG_WARNING(" \"get\" method called with no data! Transaction ID:" << id);
+                               propertyNames.push_back(path);
                        }
                }
-               else if (name == "set")
+               if (type == "method")
                {
-                       LOG_MESSAGE("set called");
-                       if (!propertyNames.empty())
+                       if (name == "get")
                        {
-                               //Should not happen
+                               if (!propertyNames.empty())
+                               {
+                                       //GetProperty is going to be a singleshot sink.
+                                       getValue(socket,propertyNames.front(),Zone::None,id);
+                               }
+                               else if (!propertyData.empty())
+                               {
+                                       //GetProperty is going to be a singleshot sink.
+                                       auto prop = propertyData.front();
+                                       getValue(socket,std::get<1>(prop),std::get<3>(prop),id);
+                               }
+                               else
+                               {
+                                       LOG_WARNING(" \"get\" method called with no data! Transaction ID:" << id);
+                               }
                        }
-                       else if (!propertyData.empty())
+                       else if (name == "set")
                        {
-                               for (auto prop = propertyData.begin(); prop != propertyData.end(); ++prop)
+                               LOG_MESSAGE("set called");
+                               if (!propertyNames.empty())
                                {
-                                       LOG_MESSAGE("websocketsinkmanager setting " << std::get<1>(*prop) << " to " << std::get<2>(*prop) << " in zone " << std::get<3>(*prop));
-                                       setValue(socket,std::get<1>(*prop),std::get<2>(*prop),std::get<3>(*prop),std::get<0>(*prop), id);
+                                       //Should not happen
+                               }
+                               else if (!propertyData.empty())
+                               {
+                                       for (auto prop = propertyData.begin(); prop != propertyData.end(); ++prop)
+                                       {
+                                               LOG_MESSAGE("websocketsinkmanager setting " << std::get<1>(*prop) << " to " << std::get<2>(*prop) << " in zone " << std::get<3>(*prop));
+                                               setValue(socket,std::get<1>(*prop),std::get<2>(*prop),std::get<3>(*prop),std::get<0>(*prop), id);
+                                       }
                                }
                        }
-               }
-               else if (name == "getSupportedEventTypes")
-               {
-                       //If data.front() dosen't contain a property name, return a list of properties supported.
-                       //if it does, then return the event types that particular property supports.
-                       string typessupported = "";
-                       if (propertyNames.empty())
+                       else if (name == "getSupportedEventTypes")
                        {
-                               //Send what properties we support
-                               PropertyList foo(routingEngine->supported());
-                               PropertyList::const_iterator i=foo.cbegin();
-                               while (i != foo.cend())
+                               //If data.front() dosen't contain a property name, return a list of properties supported.
+                               //if it does, then return the event types that particular property supports.
+                               string typessupported = "";
+                               if (propertyNames.empty())
+                               {
+                                       //Send what properties we support
+                                       PropertyList foo(routingEngine->supported());
+                                       PropertyList::const_iterator i=foo.cbegin();
+                                       while (i != foo.cend())
+                                       {
+                                               if(i==foo.cbegin())
+                                                       typessupported.append("\"").append((*i)).append("\"");
+                                               else
+                                                       typessupported.append(",\"").append((*i)).append("\"");
+                                               ++i;
+                                       }
+                               }
+                               else
                                {
-                                       if(i==foo.cbegin())
-                                               typessupported.append("\"").append((*i)).append("\"");
-                                       else
-                                               typessupported.append(",\"").append((*i)).append("\"");
-                                       ++i;
+                                       //Send what events a particular property supports
+                                       PropertyList foo(routingEngine->supported());
+                                       if (contains(foo,propertyNames.front()))
+                                       {
+                                               //sinkManager->addSingleShotSink(wsi,data.front(),id);
+                                               typessupported = "\"get\",\"getSupportedEventTypes\"";
+                                       }
                                }
+                               stringstream s;
+                               string s2;
+                               s << "{\"type\":\"methodReply\",\"name\":\"getSupportedEventTypes\",\"data\":[" << typessupported << "],\"transactionid\":\"" << id << "\"}";
+                               string replystr = s.str();
+                               LOG_INFO(" JSON Reply: " << replystr);
+                               WebSockets::Write(socket, replystr);
                        }
                        else
                        {
-                               //Send what events a particular property supports
-                               PropertyList foo(routingEngine->supported());
-                               if (contains(foo,propertyNames.front()))
-                               {
-                                       //sinkManager->addSingleShotSink(wsi,data.front(),id);
-                                       typessupported = "\"get\",\"getSupportedEventTypes\"";
-                               }
+                               DebugOut(0)<<"Unknown method called."<<endl;
                        }
-                       stringstream s;
-                       string s2;
-                       s << "{\"type\":\"methodReply\",\"name\":\"getSupportedEventTypes\",\"data\":[" << typessupported << "],\"transactionid\":\"" << id << "\"}";
-                       string replystr = s.str();
-                       LOG_INFO(" JSON Reply: " << replystr);
-                       WebSockets::Write(socket, replystr);
-               }
-               else
-               {
-                       DebugOut(0)<<"Unknown method called."<<endl;
                }
        }
 }
index ac13687..09e9c4e 100644 (file)
@@ -23,12 +23,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 #include <memory>
 #include <tgmath.h>
 #include <libwebsockets.h>
+#include <json.h>
 
 #include <canbus.h>
 #include <canobserver.h>
 
 #include <ambpluginimpl.h>
-#include <picojson.h>
 #include "websockets.h"
 
 /*!
@@ -229,24 +229,21 @@ private:
                MappingTable(MappingTable&& other) = default;
                MappingTable& operator=(MappingTable&& other) = default;
 
-               void addProperty(const std::string& source, picojson::value signal)
+               void addProperty(const std::string& source, json_object* signal)
                {
-
-                       if(!signal.contains("can_id") || !signal.contains("name")) // mandatory
+                       json_object* canIdObj = json_object_object_get(signal, "can_id");
+                       json_object* nameObj = json_object_object_get(signal, "name");
+                       if(!canIdObj || !nameObj) // mandatory
                                return;
-                       picojson::value canIdObj = signal.get("can_id");
-                       picojson::value nameObj = signal.get("name");
                        Zone::Type zone(Zone::None);
-
-                       if(signal.contains("zone"))
-                       {
-                               zone = signal.get("zone").get<double>();
-                       }
+                       json_object* zoneObj = json_object_object_get(signal, "zone");
+                       if(zoneObj)
+                               zone = json_object_get_int(zoneObj);
 
                        auto& zp = mapping[source];
                        auto& prop = zp[Zone::Type(zone)];
-                       std::string name(nameObj.to_str());
-                       int can_id = canIdObj.get<double>();
+                       std::string name(json_object_get_string(nameObj));
+                       int can_id = json_object_get_int(canIdObj);
                        prop[name] = can_id; // update an existing value
                }
 
index 1374c61..e29c0de 100644 (file)
@@ -1,6 +1,8 @@
 if(cansim_plugin)
 ############################################################################################################################################
 
+pkg_check_modules(json REQUIRED json)
+
 include_directories(${CMAKE_SOURCE_DIR}/lib ${include_dirs} ${gio_INCLUDE_DIRS} ${gio-unix_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/plugins/common ${Boost_INCLUDE_DIRS} ${json_INCLUDE_DIRS})
 
 set(cansimplugin_headers cansimplugin.h)
@@ -8,7 +10,7 @@ set(cansimplugin_sources cansimplugin.cpp)
 
 add_library(cansimplugin MODULE ${cansimplugin_sources} ${cansimplugin_headers})
 set_target_properties(cansimplugin PROPERTIES PREFIX "")
-target_link_libraries(cansimplugin amb amb-plugins-common -L${CMAKE_CURRENT_BINARY_DIR}/plugins/common ${link_libraries} -lrt)
+target_link_libraries(cansimplugin amb amb-plugins-common -L${CMAKE_CURRENT_BINARY_DIR}/plugins/common ${link_libraries} -lrt ${json_LIBRARIES})
 
 install(TARGETS cansimplugin LIBRARY DESTINATION ${PLUGIN_INSTALL_PATH})
 
index 44bfa3d..b609b3f 100644 (file)
@@ -19,12 +19,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 #include <boost/assert.hpp>
 #include <glib.h>
 #include <deque>
+#include <json.h>
 
 #include <vehicleproperty.h>
 #include <listplusplus.h>
+#include <ambplugin.h>
 
 #include <logger.h>
-#include <ambplugin.h>
 
 #include "cansimplugin.h"