[AMBClient] - fixed json stream handling
authorKevron Rees <kevron.m.rees@intel.com>
Tue, 3 Feb 2015 01:36:32 +0000 (17:36 -0800)
committerKevron Rees <kevron.m.rees@intel.com>
Tue, 3 Feb 2015 01:36:32 +0000 (17:36 -0800)
15 files changed:
CMakeLists.txt
README.md
lib/abstractpropertytype.h
lib/debugout.h
lib/jsonhelper.cpp
lib/jsonhelper.h
lib/listplusplus.cpp
lib/listplusplus.h
plugins/common/abstractio.hpp
plugins/common/jsonprotocol.cpp
plugins/common/jsonprotocol.h
plugins/common/serialport.hpp
plugins/testplugin/testplugin.cpp
tests/testProtocolClient.cpp
tests/testProtocolCommon.h

index 57360b8..429d1fd 100644 (file)
@@ -10,10 +10,10 @@ set(PROJECT_NAME "automotive-message-broker")
 set(PROJECT_PRETTY_NAME "Automotive Message Broker")
 set(PROJECT_SERIES "0.14")
 set(PROJECT_MAJOR_VERSION "0.13")
-set(PROJECT_MINOR_VERSION "803")
+set(PROJECT_MINOR_VERSION "900")
 set(PROJECT_VERSION "${PROJECT_MAJOR_VERSION}.${PROJECT_MINOR_VERSION}")
 set(PROJECT_CODENAME "74A")
-set(PROJECT_QUALITY "alpha")
+set(PROJECT_QUALITY "beta")
 
 add_definitions(-DPROJECT_VERSION="${PROJECT_VERSION}")
 add_definitions(-DPROJECT_NAME="${PROJECT_PRETTY_NAME}")
index 7ed3e02..7f07113 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 # Automotive Message Broker Daemon {#ambd}
 
-Version 0.13.803
+Version 0.13.900
 
 ## Introduction
 
index e0a2f00..b5c59f6 100644 (file)
@@ -270,9 +270,6 @@ public:
                if(!var) return "";
 
                const string s = g_variant_get_type_string(var.get());
-
-               DebugOut() << "returning signature: " << s << " for "<< name << endl;
-
                return s;
        }
 
@@ -963,7 +960,8 @@ public:
 
                for(auto itr : mList)
                {
-                       GVariant *newvar = g_variant_new(GVS<T>::signature(), GVS<T>::gvalue(itr));
+                       DebugOut(0) << "toVariant value: " << GVS<T>::gvalue(itr) << endl;
+                       GVariant *newvar = g_variant_new("v", g_variant_new(GVS<T>::signature(), GVS<T>::gvalue(itr)));
                        g_variant_builder_add_value(&params, newvar);
                }
 
index c63b183..1f6116e 100644 (file)
@@ -100,6 +100,13 @@ public:
                                out<<"WARNING ";
                }
        }
+
+       DebugOut(const std::string & toLog, int debugLevel = 4)
+               :DebugOut(debugLevel)
+       {
+               (*this) << toLog << endl;
+       }
+
        DebugOut const& operator << (const string &message) const
        {
                if(mDebugLevel <= debugThreshhold || mDebugLevel == Error || mDebugLevel == Warning)
index ff1d879..98654c9 100644 (file)
@@ -146,3 +146,26 @@ GVariant *amb::jsonToGVariant(const picojson::value & value, const std::string&
 
        return v;
 }
+
+
+void amb::findJson(const string &buffer, std::string::size_type beg, std::string::size_type &end)
+{
+       if(end == 0)
+       {
+               beg = buffer.find("{", beg);
+       }
+       else
+       {
+               beg = buffer.find("{", beg+1);
+       }
+
+       if(beg != std::string::npos)
+               findJson(buffer, beg+1, end);
+
+       std::string::size_type tempEnd;
+       if((tempEnd = buffer.find("}", end)) != string::npos)
+       {
+               end = tempEnd;
+               return;
+       }
+}
index 70eb286..f573749 100644 (file)
@@ -46,6 +46,8 @@ std::shared_ptr<AbstractPropertyType> jsonToProperty(const picojson::value& json
 
 picojson::value propertyToJson(std::shared_ptr<AbstractPropertyType> property);
 
+void findJson(const std::string & buffer, std::string::size_type beg, std::string::size_type & end);
+
 }
 
 #endif
index 1351491..86cb212 100644 (file)
@@ -1,21 +1,56 @@
 /*
-    Copyright (C) 2012  Intel Corporation
+       Copyright (C) 2012  Intel Corporation
 
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
+       This library is free software; you can redistribute it and/or
+       modify it under the terms of the GNU Lesser General Public
+       License as published by the Free Software Foundation; either
+       version 2.1 of the License, or (at your option) any later version.
 
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
+       This library is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+       Lesser General Public License for more details.
 
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+       You should have received a copy of the GNU Lesser General Public
+       License along with this library; if not, write to the Free Software
+       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
 
 
 #include "listplusplus.h"
+#include "debugout.h"
+
+std::string::size_type amb::count(const std::string & t, const std::string & toFind, const std::string &before)
+{
+       int count = 0;
+       int pos = -1;
+
+       std::string::size_type beforePos = t.find(before);
+
+       while((pos = t.find(toFind, pos+1)) != std::string::npos && (before.empty() || pos < beforePos))
+       {
+               count++;
+       }
+
+       return count;
+}
+
+int amb::findNth(const std::string & t, const std::string & toFind, std::string::size_type n)
+{
+       int count = 0;
+       auto itr = t.begin();
+       for(itr; count < n; itr++, count++)
+       {
+               if(itr == t.end())
+                       break;
+
+               itr = std::search(itr, t.end(), toFind.begin(), toFind.end());
+       }
+
+       if(count != n)
+               return -1;
+
+
+       return std::distance(t.begin(), itr) - 1;
+}
 
index 25e2039..433d34c 100644 (file)
 #include <algorithm>
 #include <functional>
 
-template <class T, class V>
-bool contains(const T & iteratable, V value)
+template <class T, class V, class Predicate>
+bool contains(const T & iteratable, V value, Predicate comparator )
 {
-       return iteratable.size() > 0 && (std::find(iteratable.begin(), iteratable.end(), value) != iteratable.end());
+       return std::any_of(iteratable.begin(), iteratable.end(), [value, &comparator](auto i) { return comparator(value, i); });
 }
 
 template <class T, class V>
-bool contains(const T & iteratable, V value, std::function<bool(V,V)> comparator)
+bool contains(const T & iteratable, V value)
 {
-       for(auto i : iteratable)
-       {
-               if(comparator(value, i))
-                       return true;
-       }
-
-       return false;
+       return contains(iteratable, value, [](auto a, auto b) { return a == b; });
 }
 
+
 template <class T, class V>
 void removeOne(T * iteratable, V value)
 {
@@ -60,6 +55,11 @@ bool containsKey(const T & map, const Key & key)
 {
        return map.find(key) != map.end();
 }
+
+std::string::size_type count(const std::string & t, const std::string & toFind, const std::string & before = "");
+
+int findNth(const std::string & t, const std::string &toFind, std::string::size_type n);
+
 }
 
 #endif // LISTPLUSPLUS_H
index 3e0aa67..912f6b6 100644 (file)
@@ -11,7 +11,7 @@ public:
        virtual bool close() = 0;
        virtual bool isOpen() =0;
        virtual std::string read() = 0;
-       virtual void write(std::string data) = 0;
+       virtual void write(const std::string & data) = 0;
 
        virtual int fileDescriptor() = 0;
 };
index 2374931..1d7eda2 100644 (file)
@@ -38,7 +38,7 @@ void amb::AmbRemoteClient::list(amb::AmbRemoteClient::ListCallback cb)
 
        mListCalls[methodCall.messageId] = cb;
 
-       mIo->write(methodCall.toJson().serialize());
+       send(methodCall);
 }
 
 void amb::AmbRemoteClient::get(const string &objectName, amb::AmbRemoteClient::ObjectCallback cb)
@@ -61,6 +61,7 @@ void amb::AmbRemoteClient::get(const string &objectName, const string &sourceUui
        GetMethodCall getCall;
        getCall.sourceUuid = sourceUuid;
        getCall.zone = zone;
+       getCall.value = Object(objectName);
 
        mGetMethodCalls[getCall.messageId] = cb;
 
@@ -250,13 +251,14 @@ void amb::BaseJsonMessageReader::canHasData()
        std::string d = mIo->read();
        incompleteMessage += d;
 
-       while(hasJson(incompleteMessage));
+       while(hasJson());
 }
 
-bool amb::BaseJsonMessageReader::hasJson(string & d)
-{
 
-       std::string::size_type start = d.find("{");
+
+bool amb::BaseJsonMessageReader::hasJson()
+{
+       std::string::size_type start = incompleteMessage.find("{");
 
        if(start == std::string::npos && incompleteMessage.empty())
        {
@@ -265,19 +267,19 @@ bool amb::BaseJsonMessageReader::hasJson(string & d)
 
        if(start > 0)
        {
-               DebugOut(7) << "We have an incomplete message at the beginning.  Toss it away." << endl;
-               d = d.substr(start-1);
+               DebugOut(7) << "We have an incomplete message at the beginning.  Toss it away:" << endl;
+               DebugOut(7) << incompleteMessage << endl;
+               incompleteMessage = incompleteMessage.substr(start-1);
        }
 
-
-       std::string::size_type end = d.find_last_of("}");
+       int end = incompleteMessage.find("\n");
 
        if(end == std::string::npos)
        {
                return false;
        }
 
-       std::string tryMessage = d.substr(0, end+1);
+       std::string tryMessage = incompleteMessage.substr(0, end+1);
 
        DebugOut(6) << "Trying to parse message: " << tryMessage << endl;
 
@@ -294,13 +296,12 @@ bool amb::BaseJsonMessageReader::hasJson(string & d)
                return false;
        }
 
-       incompleteMessage = end == d.length()-1 ? "" : d.substr(end);
+       incompleteMessage = end == incompleteMessage.length()-1 ? "" : incompleteMessage.substr(end+1);
 
        hasJsonMessage(doc);
        return true;
 }
 
-
 picojson::value amb::MethodCall::toJson()
 {
        picojson::value value = BaseMessage::toJson();
@@ -457,7 +458,7 @@ bool amb::GetMethodCall::fromJson(const picojson::value &json)
 {
        MethodCall::fromJson(json);
 
-       value = Object::fromJson(json.get<picojson::object>());
+       value = Object::fromJson(json.get("data").get<picojson::object>());
 }
 
 
index ccc3752..e851929 100644 (file)
@@ -243,14 +243,16 @@ protected:
        template <class T>
        void send(T & msg)
        {
-               mIo->write(msg.toJson().serialize());
+               std::string buff = msg.toJson().serialize()+"\n";
+               DebugOut() << "writing: " << buff << endl;
+               mIo->write(buff);
        }
 
        std::shared_ptr<AbstractIo> mIo;
 
 private:
 
-       bool hasJson(string &d);
+       bool hasJson();
 
        std::string incompleteMessage;
 
index 238a4a4..1d5038e 100644 (file)
@@ -106,9 +106,9 @@ public:
                return result;
        }
 
-       void write(std::string data)
+       void write(const std::string & data)
        {
-               int written = ::write(fd,data.c_str(),data.length());
+               int written = ::write(fd, data.c_str(), data.length());
                if(written == -1)
                {
                        DebugOut(DebugOut::Warning)<<"Unable to write ("<<fd<<")"<<endl;
index a1120bc..05097b0 100644 (file)
 #include "debugout.h"
 #include "timestamp.h"
 #include "testplugin.h"
+#include <jsonhelper.h>
+
 #define __SMALLFILE__ std::string(__FILE__).substr(std::string(__FILE__).rfind("/")+1)
 AbstractRoutingEngine *m_re;
 
-#define TEST(success)  g_assert((success));
+#define TEST(success)  DebugOut(0) << "Testing " << ""#success"" << endl; g_assert((success));
 const std::string TestProptertyName1 = "TestPropertyName1";
 const std::string TestProptertyName2 = "TestPropertyName2";
 
@@ -232,6 +234,56 @@ bool TestPlugin::testSubscription()
        return true;
 }
 
+bool testListPlusPlus()
+{
+       std::map<std::string, int> theMap;
+       theMap["1"] = 1;
+       theMap["2"] = 2;
+
+       TEST(amb::containsKey(theMap, "1"));
+       TEST(!amb::containsKey(theMap, "bar"));
+
+       std::vector<int> list;
+       list.push_back(1);
+       list.push_back(2);
+       list.push_back(3);
+
+       TEST(contains(list, 2));
+       removeOne(&list, 2);
+       TEST(!contains(list, 2));
+
+       class Complex
+       {
+       public:
+               Complex(int a, int b): foo(a), bar(b) {}
+               int foo;
+               int bar;
+       };
+
+       Complex complex1(1, 2);
+
+       Complex complex2(2, 2);
+
+       std::vector<Complex> complexList;
+       complexList.push_back(complex1);
+       complexList.push_back(complex2);
+
+       TEST(contains(complexList, complex1, [](auto a, auto b) { return a.foo == b.foo && a.bar == b.bar; }));
+
+       return true;
+}
+
+void testJsonHelper()
+{
+       std::string json = "{{}{}}{}";
+
+       std::string::size_type end = 0;
+       amb::findJson(json, 0, end);
+
+       DebugOut(0) << "Found complete Json message at " << end << endl;
+       TEST(end == 7);
+}
+
 bool TestPlugin::testSetAndGet()
 {
        bool replySuccess(false);
@@ -279,7 +331,7 @@ bool TestPlugin::testCoreUpdateSupported()
        PropertyList toAdd;
        toAdd.push_back(VehicleProperty::ClutchStatus);
 
-       routingEngine->updateSupported(toAdd,PropertyList(), this);
+       routingEngine->updateSupported(toAdd, PropertyList(), this);
 
        PropertyList supported = routingEngine->supported();
 
@@ -360,6 +412,10 @@ TestPlugin::TestPlugin(AbstractRoutingEngine *re, map<string, string> config)
        testSubscription();
 
        testSetAndGet();
+
+       TEST(testListPlusPlus());
+
+       testJsonHelper();
 }
 
 TestPlugin::~TestPlugin()
index 24ea5b8..e962a7d 100644 (file)
@@ -23,7 +23,7 @@ void runTest(amb::AmbRemoteClient *c)
        c->get("interface1", [](amb::Object &obj)
        {
                DebugOut(0) << "get call reply" << endl;
-               g_assert(obj.size() == 3);
+               g_assert(obj.size() == 2);
        });
 }
 
index 7e8feef..a8c63ce 100644 (file)
@@ -39,7 +39,7 @@ public:
                return socket->readAll().data();
        }
 
-       void write(string data)
+       void write(const string & data)
        {
                socket->write(data.c_str(), data.length());
        }