Replaced listenCallback PTree with cereal
authorErich Keane <erich.keane@intel.com>
Sat, 11 Oct 2014 20:02:33 +0000 (13:02 -0700)
committerErich Keane <erich.keane@intel.com>
Sat, 11 Oct 2014 20:02:33 +0000 (13:02 -0700)
Change-Id: I3ded4d42c495c73d5f2fb1d564722758ba8e5879

examples/makefile
include/IClientWrapper.h
include/InProcClientWrapper.h
include/OCResource.h
include/OutOfProcClientWrapper.h
makefile
src/InProcClientWrapper.cpp

index d703be3..5047d63 100644 (file)
@@ -37,6 +37,7 @@ CXX_INC         += -I../csdk/ocsocket/include
 CXX_INC          += -I../csdk/ocrandom/include
 CXX_INC          += -I../csdk/logger/include
 CXX_INC          += -I../csdk/libcoap
+CXX_INC   += -I../../oic-utilities/tb/cereal-1.0.0/include
 
 LIB_OC_LOGGER := ../oc_logger/lib/oc_logger.a
 
index dc3f545..0400343 100644 (file)
@@ -75,11 +75,6 @@ namespace OC
 
         virtual ~IClientWrapper(){}
 
-
-        // Note: this should never be called by anyone but the handler for the listen command.
-        // It is public becuase that needs to be a non-instance callback
-        virtual std::shared_ptr<OCResource> parseOCResource(IClientWrapper::Ptr clientWrapper,
-                        const std::string& host, const boost::property_tree::ptree resourceNode)=0;
     private:
     };
 }
index 431ba1d..598078d 100644 (file)
@@ -73,10 +73,6 @@ namespace OC
             SubscribeCallback& presenceHandler);
 
         virtual OCStackResult UnsubscribePresence(OCDoHandle handle);
-        // Note: this should never be called by anyone but the handler for the listen command.
-        // It is public becuase that needs to be a non-instance callback
-        virtual std::shared_ptr<OCResource> parseOCResource(IClientWrapper::Ptr clientWrapper,
-            const std::string& host, const boost::property_tree::ptree resourceNode);
     private:
         void listeningFunc();
         std::string assembleSetResourceUri(std::string uri, const QueryParamsMap& queryParams);
index 8e98693..4eb8158 100644 (file)
@@ -30,9 +30,6 @@
 #include <random>
 #include <algorithm>
 
-#include <boost/property_tree/ptree.hpp>
-#include <boost/property_tree/json_parser.hpp>
-
 #include <OCApi.h>
 #include <ResourceInitException.h>
 #include <IClientWrapper.h>
@@ -52,8 +49,7 @@ namespace OC
     class OCResource
     {
     friend class OCPlatform;
-    friend class InProcClientWrapper;
-
+    friend class ListenOCContainer;
     public:
         typedef std::shared_ptr<OCResource> Ptr;
         /**
index df8e1cb..ef12e02 100644 (file)
@@ -62,12 +62,6 @@ namespace OC
             const std::string& uri,
             const HeaderOptions& headerOptions){return OC_STACK_NOTIMPL;}
 
-        virtual std::shared_ptr<OCResource> parseOCResource(IClientWrapper::Ptr clientWrapper,
-            const std::string& host, const boost::property_tree::ptree resourceNode)
-        {
-            return nullptr;
-        }
-
         virtual OCStackResult SubscribePresence(OCDoHandle* handle, const std::string& host,
             SubscribeCallback& presenceHandler){return OC_STACK_NOTIMPL;}
 
index f93c3c8..d6c44ff 100644 (file)
--- a/makefile
+++ b/makefile
@@ -45,7 +45,7 @@ CXX_INC         += -I./csdk/ocsocket/include
 CXX_INC          += -I./csdk/ocrandom/include
 CXX_INC          += -I./csdk/logger/include
 CXX_INC          += -I./csdk/libcoap
-
+CXX_INC   += -I./../oic-utilities/tb/cereal-1.0.0/include
 # Force metatargets to build:
 all.PHONY: prep_dirs c_sdk oc_logger_target liboc.a examples
 
index 7f05d57..6e3c78c 100644 (file)
 #include "OCPlatform.h"
 #include "OCResource.h"
 
+#include <cereal/cereal.hpp>
+#include <cereal/types/memory.hpp>
+#include <cereal/types/vector.hpp>
+#include <cereal/archives/json.hpp>
+
 using namespace std;
 
 namespace OC
@@ -126,35 +131,122 @@ namespace OC
     const std::string PROPERTYKEY = "prop";
     const std::string REPKEY = "rep";
 
-    std::shared_ptr<OCResource> InProcClientWrapper::parseOCResource(
-        IClientWrapper::Ptr clientWrapper, const std::string& host,
-        const boost::property_tree::ptree resourceNode)
+    class ListenOCContainer
     {
-        std::string uri = resourceNode.get<std::string>(URIKEY, "");
-        bool obs = resourceNode.get<int>(OBSERVABLEKEY,0) == 1;
-        std::vector<std::string> rTs;
-        std::vector<std::string> ifaces;
+        class ListenResourceContainer
+        {
+            class ListenResourcePropertiesContainer
+            {
+                friend class cereal::access;
+                friend class ListenResourceContainer;
 
-        boost::property_tree::ptree properties =
-            resourceNode.get_child(PROPERTYKEY, boost::property_tree::ptree());
+                template<class Archive>
+                void serialize(Archive& ar)
+                {
+                    try
+                    {
+                        ar(cereal::make_nvp(OBSERVABLEKEY, m_observable));
+                    }
+                    catch(cereal::Exception&)
+                    {
+                        // we swallow this exception, since it means the key
+                        // doesn't exist, allowing these to be optional
+                    }
 
-        boost::property_tree::ptree rT =
-            properties.get_child(RESOURCETYPESKEY, boost::property_tree::ptree());
-        for(auto itr : rT)
-        {
-            rTs.push_back(itr.second.data());
-        }
+                    try
+                    {
+                        ar(cereal::make_nvp(RESOURCETYPESKEY,m_resourceTypes));
+                    }
+                    catch(cereal::Exception&)
+                    {}
+                    try
+                    {
+                        ar(cereal::make_nvp(INTERFACESKEY, m_interfaces));
+                    }
+                    catch(cereal::Exception&)
+                    {}
+                }
 
-        boost::property_tree::ptree iF =
-            properties.get_child(INTERFACESKEY, boost::property_tree::ptree());
-        for(auto itr : iF)
-        {
-            ifaces.push_back(itr.second.data());
-        }
+                bool m_observable;
+                std::vector<std::string> m_resourceTypes;
+                std::vector<std::string> m_interfaces;
+            };
+
+            friend class cereal::access;
+            friend class ListenOCContainer;
+            template <class Archive>
+            void serialize(Archive& ar)
+            {
+                ar(cereal::make_nvp(URIKEY, m_uri));
+                ar(cereal::make_nvp(PROPERTYKEY, m_props));
+                // todo
+            }
+
+
+            std::string m_uri;
+            ListenResourcePropertiesContainer m_props;
+            bool observable()
+            {
+                return m_props.m_observable;
+            }
+            std::vector<std::string> resourceTypes()
+            {
+                return m_props.m_resourceTypes;
+            }
+            std::vector<std::string> interfaces()
+            {
+                return m_props.m_interfaces;
+            }
+        };
+
+        private:
+            friend class cereal::access;
+            template <class Archive>
+            void serialize(Archive& ar)
+            {
+                std::vector<ListenResourceContainer> resources;
+                ar(resources);
+            }
+        public:
+            ListenOCContainer(std::weak_ptr<IClientWrapper> cw, const std::string& host):
+                m_clientWrapper(cw), m_host(host)
+            {
+            }
+            void LoadFromJson(std::stringstream& json)
+            {
+                m_resources.clear();
+                cereal::JSONInputArchive archive(json);
+
+                std::vector<ListenResourceContainer> resources;
+                archive(cereal::make_nvp("oc", resources));
+
+                for(auto& res : resources)
+                {
+                    try
+                    {
+                        m_resources.push_back(std::shared_ptr<OCResource>(
+                            new OCResource(m_clientWrapper, m_host,
+                            res.m_uri, res.observable(), res.resourceTypes(),
+                            res.interfaces())));
+
+                    }
+                    catch(ResourceInitException& e)
+                    {
+                        oclog() << "listenCallback(): failed to create resource: " << e.what()
+                                << std::flush;
+                    }
+                }
+            }
+            const std::vector<std::shared_ptr<OCResource>>& Resources() const
+            {
+                return m_resources;
+            }
+        private:
+            std::vector<std::shared_ptr<OC::OCResource>> m_resources;
+            std::weak_ptr<IClientWrapper> m_clientWrapper;
+            std::string m_host;
+    };
 
-        return std::shared_ptr<OCResource>(
-            new OCResource(clientWrapper, host, uri, obs, rTs, ifaces));
-    }
 
     OCStackApplicationResult listenCallback(void* ctx, OCDoHandle handle,
         OCClientResponse* clientResponse)
@@ -172,48 +264,18 @@ namespace OC
 
         std::stringstream requestStream;
         requestStream << clientResponse->resJSONPayload;
+std::cout<<"ERICH::::"<<clientResponse->resJSONPayload<<std::endl;
+        std::string host = convertOCAddrToString(*clientResponse->addr);
+        ListenOCContainer container(context->clientWrapper,host);
+        container.LoadFromJson(requestStream);
 
-        boost::property_tree::ptree root;
 
-        try
-        {
-                boost::property_tree::read_json(requestStream, root);
-        }
-        catch(boost::property_tree::json_parser::json_parser_error &e)
+        // loop to ensure valid construction of all resources
+        for(auto resource : container.Resources())
         {
-                oclog() << "listenCallback(): read_json() failed: " << e.what()
-                        << std::flush;
-
-                return OC_STACK_KEEP_TRANSACTION;
+            std::thread exec(context->callback, resource);
+            exec.detach();
         }
-
-        boost::property_tree::ptree payload =
-                root.get_child("oc", boost::property_tree::ptree());
-
-        for(auto payloadItr : payload)
-        {
-                try
-                {
-                    std::string host = convertOCAddrToString(*clientResponse->addr);
-                    std::shared_ptr<OCResource> resource =
-                        context->clientWrapper->parseOCResource(context->clientWrapper, host,
-                        payloadItr.second);
-
-                    // Note: the call to detach allows the underlying thread to continue until
-                    // completion and allows us to destroy the exec object. This is apparently NOT
-                    // a memory leak, as the thread will apparently take care of itself.
-                    // Additionally, the only parameter here is a shared ptr, so OCResource will be
-                    // disposed of properly upon completion of the callback handler.
-                    std::thread exec(context->callback,resource);
-                    exec.detach();
-                }
-                catch(ResourceInitException& e)
-                {
-                    oclog() << "listenCallback(): failed to create resource: " << e.what()
-                            << std::flush;
-                }
-        }
-
         return OC_STACK_KEEP_TRANSACTION;
     }