Make exception and error handling more consistent through the top-level API.
authorErich Keane <erich.keane@intel.com>
Mon, 6 Oct 2014 17:50:47 +0000 (10:50 -0700)
committerErich Keane <erich.keane@intel.com>
Mon, 6 Oct 2014 17:50:47 +0000 (10:50 -0700)
Following up on Sudarshan's comments.

Change-Id: I8e19a89952f5235abbab43f1eb266604b5a4f1ac

README [deleted file]
examples/ocicuc/Makefile
include/OCException.h
include/OCResource.h
include/OCUtilities.h
makefile
src/OCException.cpp [new file with mode: 0644]
src/OCPlatform.cpp
src/OCResource.cpp
src/OCUtilities.cpp

diff --git a/README b/README
deleted file mode 100644 (file)
index 22129e5..0000000
--- a/README
+++ /dev/null
@@ -1,113 +0,0 @@
-******************************************************************
-
- Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
-
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-===============================================================================
-==                      UB Stack & TB Stack                                  ==
-===============================================================================
-
-The OIC-RESOURCE repository contains two SDKs with underlying code
-(i.e. "stack"). The two SDKs are referred to as "UB SDK" (or "C++ SDK") and "TB
-SDK" (or "C SDK"). The associated stacks are referred to as "UB Stack" (or "C++
-Stack") and "TB Stack" (or "C Stack").  The UB Stack requires that the TB Stack
-is built under it.
-
-For a list of artifact locations for all possible build processes in the
-OIC-RESOURCE repository, please refer to:
-<oic-resource>/artifact_output_locations.txt.
-
-===============================================================================
-
-The UB Stack is intended ONLY for Linux Ubuntu 12.04 operating system.
-To build UB Stack, please follow these requirements:
-- GCC compiler version is 4.6.1
-- Pre-install the "gnu-libc" libraries package.
-- The OIC-UTILITIES repository must be a sibling directory to the OIC-RESOURCE
-  repository.
-
-The TB Stack is intended ONLY for Linux Ubuntu 12.04, Arduino ATMega 2560 with
-Arduino Framework 1.0.5, and Arduino Due with Arduino Framework 1.5.7.
-Tip: Use Cutecom in Ubuntu 12.04 to view logs from Arduino ATMega 2560 and
-Arduino Due.
-
-To build TB Stack, please follow these requirements for Linux Ubuntu 12.04:
-- GCC compiler version is 4.6.1
-- Pre-install the "gnu-libc" libraries package.
-- The OIC-UTILITIES repository must be a cousin directory to the OIC-RESOURCE
-  repository.
-To build TB Stack, please follow these requirements for Arduino ATMega 2560:
-- AVR-GCC compiler version is 4.5.3
-- Unzip the Time Library from here to your Arduino Directory Structure:
-  http://playground.arduino.cc/code/time
-- The OIC-UTILITIES repository must be a cousin directory to the OIC-RESOURCE
-  repository.
-- Apply 2 patches from OIC-UTILITIES/tb/ to your Arduino Directory Structure.
-
-At this time, build instructions have not been written for the Arduino ATMega
-2560 with WiFi Shield, Arduino Due with Ethernet Shield, and Arduino Due with
-WiFi Shield. These instructions will be included very soon (as the build
-server(s) verifies and utilizes the new build script "buildScript.mk").
-
-===============================================================================
-
-Instructions for Common Build Processes:
-
-NOTE: 'GNU Make' is required to utilize the build script at location:
-<oic-resource>/buildScript.mk.
-
-- All Modules (TB Stack, TB Unit Tests, TB Examples, UB Stack, UB Examples) for
-Linux & Arduino Mega 2560:
-
-       make -f buildScript.mk all
-
-- All UB Stack Modules in Release & Debug (TB Stack, UB Stack, UB Examples) for
-Linux:
-
-       make -f buildScript.mk linux_ub
-
-- All Modules, without OCICUC, in Release & Debug (TB Stack, TB Unit Tests,
-TB Examples, UB Stack, UB Examples) for linux:
-
-       make -f buildScript.mk linux
-
-- All Modules, Including OCICUC, in Release & Debug (TB Stack, TB Unit Tests,
-TB Examples, UB Stack, UB Examples, UB OCICUC) for linux:
-(This will be what is used on the Build Server(s) to limit regression.)
-
-       make -f buildScript.mk all_dev
-
-- All UB Stack Modules, Including OCICUC, in Release & Debug (TB Stack,
-UB Stack, UB Examples, UB OCICUC) for linux:
-
-       make -f buildScript.mk linux_ub_dev
-
-- All TB Stack Modules in Release & Debug (TB Stack, TB Unit Tests,
-TB Examples) for Linux:
-
-       make -f buildScript.mk linux_tb
-
-- All TB Stack Modules in Release & Debug (TB Stack, TB Unit Tests,
-TB Examples) for Arduino ATMega 2560:
-
-       make -f buildScript.mk arduinomega
-
-- Clean All:
-
-       make -f buildScript.mk clean
-
index 88bce11..cc83bd0 100644 (file)
@@ -24,6 +24,10 @@ PLATFORM:=linux
 OCLIB=../..
 OCLIB_LIB=../../$(BUILD)/obj/liboc.a
 
+BOOST_BASE=/usr/local/boost
+BOOST_INC=$(BOOST_BASE)/include
+BOOST_LIB=$(BOOST_BASE)/lib
+
 CXX_FLAGS.debug     := -g3 -O0
 CXX_FLAGS.release   := -O3
 
@@ -31,6 +35,7 @@ CXX_FLAGS:=-Werror -Wall -std=c++0x -ggdb $(CXX_FLAGS.$(BUILD)) -pthread
 
 # There's probably nicer Makefile magic for this, but hopefully it will suffice:
 CXX_INC=-I$(OCLIB)/include \
+       -I$(BOOST_INC) \
        -I../../include/ \
        -I../../oc_logger/include/ \
        -I../../csdk/stack/include \
@@ -39,7 +44,6 @@ CXX_INC=-I$(OCLIB)/include \
        -I../../csdk/logger/include
 
 BOOST_LIBS=-lboost_program_options
-#BOOST_LIBS=/usr/local/boost/lib/libboost_program_options.a    # for boost_1_55 lib
 
 LIB_OC_LOGGER:=../../oc_logger/lib/oc_logger.a
 
@@ -74,8 +78,7 @@ small_example: small_example.o driver.o utility.o
 
 clean:
        rm -f *.o $(APPS)
-       cd ../../ && $(MAKE) clean_cpp_sdk
 
 clean_apps:
-       rm -f *.o $(APPS)
+       rm -f server client monoprocess
 
index 5aad87c..459f2d8 100644 (file)
 #include <ocstack.h>
 namespace OC {
 
-typedef std::runtime_error reflection_exception;
-
 class OCException : public std::runtime_error
 {
     public:
-        OCException(const std::string& msg, OCStackResult reason = OC_STACK_ERROR): std::runtime_error(msg),  m_reason(reason) {}
-        std::string reason()
+        OCException(const std::string& msg, OCStackResult reason = OC_STACK_ERROR)
+         : std::runtime_error(msg),  
+           m_reason(reason) 
+        {}
+
+        static std::string reason(const OCStackResult sr);
+
+        std::string reason() const
+        {
+            return reason(m_reason);
+        }
+
+        std::string reason(const OC::OCException& e) const
         {
-            switch(m_reason)
-            {
-                case OC_STACK_OK:
-                    return "No Error";
-                case OC_STACK_INVALID_URI:
-                    return "Invalid URI";
-                case OC_STACK_INVALID_IP:
-                    return "Invalid IP";
-                case OC_STACK_INVALID_PORT:
-                    return "Invalid Port";
-                case OC_STACK_INVALID_CALLBACK:
-                    return "Invalid Callback";
-                case OC_STACK_INVALID_METHOD:
-                    return "Invalid Method";
-                case OC_STACK_INVALID_QUERY:
-                    return "Invalid Query";
-                case OC_STACK_INVALID_PARAM:
-                    return "Invalid Param";
-                case OC_STACK_INVALID_OBSERVE_PARAM:
-                    return "Invalid Observe Param";
-                case OC_STACK_NO_MEMORY:
-                    return "No Memory";
-                case OC_STACK_COMM_ERROR:
-                    return "Communication Error";
-                case OC_STACK_NOTIMPL:
-                    return "Not Implemented";
-                case OC_STACK_NO_RESOURCE:
-                    return "Resource Not Found";
-                case OC_STACK_RESOURCE_ERROR:
-                    return "Resource Error";
-                case OC_STACK_SLOW_RESOURCE:
-                    return "Slow Resource";
-                case OC_STACK_NO_OBSERVERS:
-                    return "No Observers";
-                case OC_STACK_ERROR:
-                    return "General Fault";
-                default:
-                    return "Unknown Error";
-            }
+            return e.reason();
         }
 
     private:
index a399825..3cc765f 100644 (file)
@@ -53,6 +53,7 @@ namespace OC
     {
     friend class OCPlatform;
     friend class InProcClientWrapper;
+
     public:
         typedef std::shared_ptr<OCResource> Ptr;
         /**
index 6d4f6b1..35a6383 100644 (file)
 
 #ifndef _INTEL_OCUTILITIES_H_
 #define _INTEL_OCUTILITIES_H_
-#endif
 
 #include <map>
 #include <vector>
 #include <memory>
+#include <utility>
 #include <exception>
 
+#include "OCException.h"
+
 namespace OC {
     namespace Utilities {
 
@@ -48,3 +50,52 @@ namespace OC {
 
     }
 }
+
+/* The C++11 standard unfortunately forgot to provide make_unique<>! However, if we're
+using C++14 or later, we want to take the standard library's implementation: */
+#if defined(__cplusplus) && __cplusplus < 201300
+namespace OC {
+
+    template<typename T, typename ...XS>
+    std::unique_ptr<T> make_unique(XS&& ...xs)
+    {
+        return std::unique_ptr<T>(new T(std::forward<XS>(xs)...));
+    }
+
+} // namespace OC
+#else
+    using std::make_unique;
+#endif
+
+namespace OC {
+
+    using OC::make_unique;
+
+    /* Examine an OCStackResult, and either forward its value or raise an exception: */
+    OCStackResult result_guard(const OCStackResult r);
+
+    /* Check for a nullptr, and throw an exception if we see one; otherwise, return the
+    result of the function call: */
+    template <typename PtrT, typename FnT, typename ...ParamTs>
+    auto nil_guard(PtrT&& p, FnT&& fn, ParamTs&& ...params) -> OCStackResult
+    {
+        if(nullptr == p)
+        {
+            throw OCException("nullptr at nil_guard()", OC_STACK_INVALID_PARAM);
+        }
+
+        // Note that although parameters are being forwarded, std::bind() will make a single copy:
+        return std::bind(fn, p, std::forward<ParamTs>(params)...)();
+    }
+
+    /* Check for nullptr and forward the result of an OC function call on success; raise
+    an exception on failure or exceptional result: */
+    template <typename PtrT, typename FnT, typename ...ParamTs>
+    auto checked_guard(PtrT&& p, FnT&& fn, ParamTs&& ...params) -> OCStackResult
+    {
+        return result_guard(nil_guard(p, fn, std::forward<ParamTs>(params)...));
+    }
+
+} // namespace OC
+
+#endif
index e3098d9..f93c3c8 100644 (file)
--- a/makefile
+++ b/makefile
@@ -70,8 +70,8 @@ cpp_sdk: prep_dirs c_sdk liboc.a
 examples: liboc.a
        cd examples && $(MAKE) apps "BUILD=$(BUILD)"
 
-liboc.a: OCPlatform.o OCResource.o OCUtilities.o InProcServerWrapper.o InProcClientWrapper.o
-       ar -cvq $(OBJ_DIR)/liboc.a $(OBJ_DIR)/OCPlatform.o $(OBJ_DIR)/OCResource.o $(OBJ_DIR)/OCUtilities.o $(OBJ_DIR)/InProcServerWrapper.o $(OBJ_DIR)/InProcClientWrapper.o
+liboc.a: OCPlatform.o OCResource.o OCException.o OCUtilities.o InProcServerWrapper.o InProcClientWrapper.o
+       ar -cvq $(OBJ_DIR)/liboc.a $(OBJ_DIR)/OCPlatform.o $(OBJ_DIR)/OCResource.o $(OBJ_DIR)/OCException.o $(OBJ_DIR)/OCUtilities.o $(OBJ_DIR)/InProcServerWrapper.o $(OBJ_DIR)/InProcClientWrapper.o
 
 OCPlatform.o: src/OCPlatform.cpp
        $(CXX) $(CXX_FLAGS.$(BUILD)) -o $(OBJ_DIR)/$@ -c src/OCPlatform.cpp $(CXX_INC)
@@ -79,6 +79,9 @@ OCPlatform.o: src/OCPlatform.cpp
 OCResource.o: src/OCResource.cpp
        $(CXX) $(CXX_FLAGS.$(BUILD)) -o $(OBJ_DIR)/$@ -c src/OCResource.cpp $(CXX_INC)
 
+OCException.o: src/OCException.cpp
+       $(CXX) $(CXX_FLAGS.$(BUILD)) -o $(OBJ_DIR)/$@ -c src/OCException.cpp $(CXX_INC)
+
 OCUtilities.o: src/OCUtilities.cpp
        $(CXX) $(CXX_FLAGS.$(BUILD)) -o $(OBJ_DIR)/$@ -c src/OCUtilities.cpp $(CXX_INC)
 
diff --git a/src/OCException.cpp b/src/OCException.cpp
new file mode 100644 (file)
index 0000000..39010f8
--- /dev/null
@@ -0,0 +1,80 @@
+//******************************************************************
+//
+// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "OCException.h"
+
+std::string OC::OCException::reason(const OCStackResult sr)
+{
+    switch(sr)
+    {
+        case OC_STACK_OK:
+               return "No Error";
+        case OC_STACK_INVALID_URI:
+            return "Invalid URI";
+        case OC_STACK_INVALID_IP:
+            return "Invalid IP";
+        case OC_STACK_INVALID_PORT:
+            return "Invalid Port";
+        case OC_STACK_INVALID_CALLBACK:
+            return "Invalid Callback";
+        case OC_STACK_INVALID_METHOD:
+            return "Invalid Method";
+        case OC_STACK_INVALID_QUERY:
+            return "Invalid Query";
+        case OC_STACK_INVALID_PARAM:
+            return "Invalid Parameter";
+        case OC_STACK_INVALID_OBSERVE_PARAM:
+            return "Invalid Observe Parameter";
+        case OC_STACK_NO_MEMORY:
+            return "No Memory";
+        case OC_STACK_COMM_ERROR:
+            return "Communication Error";
+        case OC_STACK_NOTIMPL:
+            return "Not Implemented";
+        case OC_STACK_NO_RESOURCE:
+            return "Resource Not Found";
+        case OC_STACK_RESOURCE_ERROR:
+            return "Resource Error";
+        case OC_STACK_SLOW_RESOURCE:
+            return "Slow Resource";
+        case OC_STACK_NO_OBSERVERS:
+            return "No Observers";
+       case OC_STACK_OBSERVER_NOT_FOUND:
+            return "Stack observer not found";
+       case OC_STACK_OBSERVER_NOT_ADDED:
+            return "Stack observer not added";
+       case OC_STACK_OBSERVER_NOT_REMOVED:
+            return "Stack observer not removed";
+#ifdef WITH_PRESENCE
+       case OC_STACK_PRESENCE_STOPPED:
+            return "Stack presence stopped";
+       case OC_STACK_PRESENCE_DO_NOT_HANDLE:
+            return "Stack presence should not be handled";
+#endif
+       case OC_STACK_INVALID_OPTION:
+            return "Invalid option";
+
+       case OC_STACK_ERROR:
+            return "General Fault";
+    }
+
+    return "Unknown Error";
+}
+
index dd8d877..16e4dce 100644 (file)
 //*********************************************************************
 
 #include <random>
+#include <utility>
+#include <functional>
+
+#include "ocstack.h"
 
 #include "OCPlatform.h"
 #include "OCApi.h"
 #include "OCException.h"
+#include "OCUtilities.h"
 
 #include "oc_logger.hpp"
 
 namespace OC
 {
-    OCPlatform::OCPlatform(const PlatformConfig& config)
-     : m_log_stream(std::move(oc_log_stream {oc_make_ostream_logger})),
-       m_cfg(config)
-    {
-        init(m_cfg);
-    }
+void OCPlatform::init(const PlatformConfig& config)
+{
+    switch(config.mode)
+     {
+       case ModeType::Server:
+                       m_server = m_WrapperInstance->CreateServerWrapper(*this, m_csdkLock, config);
+                       break;
+
+       case ModeType::Client:
+                      m_client = m_WrapperInstance->CreateClientWrapper(*this, m_csdkLock, config);
+                      break;
+
+       case ModeType::Both:
+                       m_server = m_WrapperInstance->CreateServerWrapper(*this, m_csdkLock, config);
+                       m_client = m_WrapperInstance->CreateClientWrapper(*this, m_csdkLock, config);
+                       break;
+     }
+}
+
+OCPlatform::OCPlatform(const PlatformConfig& config)
+ : m_log_stream      { std::move(oc_log_stream {oc_make_ostream_logger}) },
+   m_cfg             { config },
+   m_WrapperInstance { make_unique<WrapperFactory>() },
+   m_csdkLock        { make_shared<std::mutex>() }
+{
+    init(m_cfg);
+}
+
+OCPlatform::OCPlatform(const PlatformConfig& config, OC::oc_log_stream& log_target)
+ :  m_log_stream      { log_target },
+    m_cfg             { config },
+    m_WrapperInstance { make_unique<WrapperFactory>() },
+    m_csdkLock        { make_shared<std::mutex>() }
+{
+    init(m_cfg);
+}
 
-    OCPlatform::OCPlatform(const PlatformConfig& config, OC::oc_log_stream& log_target)
-     :  m_log_stream(log_target),
-        m_cfg(config)
-    {
-        init(m_cfg);
-    }
+OCPlatform::~OCPlatform(void)
+{
+}
 
-    OCPlatform::~OCPlatform(void)
-    {
-    }
+OCStackResult OCPlatform::setDefaultDeviceEntityHandler(EntityHandler entityHandler)
+{
+    return checked_guard(m_server, &IServerWrapper::setDefaultDeviceEntityHandler,
+                         entityHandler);
+}
 
-    OCStackResult OCPlatform::notifyAllObservers(OCResourceHandle resourceHandle)
-    {
-        return OCNotifyAllObservers(resourceHandle);
-    }
+OCStackResult OCPlatform::notifyAllObservers(OCResourceHandle resourceHandle)
+{
+    return result_guard(OCNotifyAllObservers(resourceHandle));
+}
 
-    OCStackResult OCPlatform::notifyListOfObservers(
-                                          OCResourceHandle resourceHandle,
-                                          ObservationIds& observationIds,
-                                          const std::shared_ptr<OCResourceResponse> pResponse)
+OCStackResult OCPlatform::notifyListOfObservers(OCResourceHandle resourceHandle,
+                                            ObservationIds& observationIds,
+                                            const std::shared_ptr<OCResourceResponse> pResponse)
+{
+    if(!pResponse)
     {
-        OCStackResult result = OC_STACK_ERROR;
-
-        if(pResponse)
-        {
-            try
-            {
-                std::string payload = pResponse->getPayload();
-                unsigned char *pBuffer = new unsigned char[payload.length()+1];
-                strncpy((char*)pBuffer, payload.c_str(), payload.length() + 1);
-
-                // TODO Logging
-                printf("\tGoing from stack for List of Observers: Payload: %s\n", (char*)pBuffer);
-
-                result = OCNotifyListOfObservers(resourceHandle, &observationIds[0],
-                                                 observationIds.size(), pBuffer);
-
-                delete(pBuffer);
-            }
-            catch(std::exception e) // TODO : define our own exception
-            {
-                throw e;
-            }
-        }
-        return result;
+     return result_guard(OC_STACK_ERROR);
     }
 
-    void OCPlatform::init(const PlatformConfig& config)
-    {
-        m_csdkLock = make_shared<std::mutex>();
-        std::unique_ptr<WrapperFactory> wrapperInstance(new WrapperFactory());
-        m_WrapperInstance = std::move(wrapperInstance);
-
-        if(config.mode == ModeType::Server)
-        {
-            // Call server wrapper init
-            m_server = m_WrapperInstance->CreateServerWrapper(*this, m_csdkLock, config);
-        }
-        else if(config.mode == ModeType::Client)
-        {
-            // Call client wrapper init
-            m_client = m_WrapperInstance->CreateClientWrapper(*this, m_csdkLock, config);
-        }
-        else
-        {
-            // This must be both server and client
-            m_server = m_WrapperInstance->CreateServerWrapper(*this, m_csdkLock, config);
-            m_client = m_WrapperInstance->CreateClientWrapper(*this, m_csdkLock, config);
-        }
-    }
+    std::string payload(pResponse->getPayload());
 
-    OCResource::Ptr OCPlatform::constructResourceObject(const std::string& host, const std::string& uri,
-        bool isObservable, const std::vector<std::string>& resourceTypes,
-        const std::vector<std::string>& interfaces)
-    {
-        if(m_client)
-        {
-            return std::shared_ptr<OCResource>(new OCResource(m_client, host, uri, isObservable, resourceTypes, interfaces));
-        }
-
-        else
-        {
-            return std::shared_ptr<OCResource>();
-        }
-    }
+    return result_guard(
+               OCNotifyListOfObservers(resourceHandle,
+                                       &observationIds[0], observationIds.size(),
+                                       reinterpret_cast<unsigned char *>(const_cast<char *>(payload.c_str()))));
+}
 
-    OCStackResult OCPlatform::findResource(const std::string& host, const std::string& resourceName,
-        FindCallback resourceHandler)
+OCResource::Ptr OCPlatform::constructResourceObject(const std::string& host, const std::string& uri,
+                                                    bool isObservable, const std::vector<std::string>& resourceTypes,
+                                                    const std::vector<std::string>& interfaces)
+{
+    if(!m_client)
     {
-        if(m_client)
-        {
-            return m_client->ListenForResource(host, resourceName, resourceHandler);
-        }
-        return OC_STACK_ERROR;
+        return std::shared_ptr<OCResource>();
     }
 
+    return std::shared_ptr<OCResource>(new OCResource(m_client, host, uri, isObservable, resourceTypes, interfaces));
+}
 
-    OCStackResult OCPlatform::registerResource(OCResourceHandle& resourceHandle,
-        std::string& resourceURI,
-        const std::string& resourceTypeName,
-        const std::string& resourceInterface,
-        EntityHandler entityHandler,
-        uint8_t resourceProperty)
-    {
-        OCStackResult result = OC_STACK_ERROR;
-
-        if(m_server)
-        {
-            try{
-                result = m_server->registerResource(resourceHandle, resourceURI, resourceTypeName, resourceInterface, entityHandler, resourceProperty);
-            }
-            catch(std::exception e) // TODO: define our own expception.
-            {
-                throw e;
-            }
-        }
-
-        return result;
-    }
-
-    OCStackResult OCPlatform::setDefaultDeviceEntityHandler(EntityHandler entityHandler)
-    {
-        OCStackResult result = OC_STACK_ERROR;
-
-        if(m_server)
-        {
-            try{
-                result = m_server->setDefaultDeviceEntityHandler(entityHandler);
-            }
-            catch(std::exception e) // TODO: define our own expception.
-            {
-                throw e;
-            }
-        }
-        return result;
-    }
+OCStackResult OCPlatform::findResource(const std::string& host, const std::string& resourceName,
+                                       FindCallback resourceHandler)
+{
+    return checked_guard(m_client, &IClientWrapper::ListenForResource,
+                         host, resourceName, resourceHandler);
+}
 
-    OCStackResult OCPlatform::unregisterResource(const OCResourceHandle& resourceHandle) const
-    {
-        OCStackResult result = OC_STACK_ERROR;
 
-        if(m_server)
-        {
-            result = m_server->unregisterResource(resourceHandle);
-        }
-        return result;
-    }
+OCStackResult OCPlatform::registerResource(OCResourceHandle& resourceHandle,
+                                           std::string& resourceURI,
+                                           const std::string& resourceTypeName,
+                                           const std::string& resourceInterface,
+                                           EntityHandler entityHandler,
+                                           uint8_t resourceProperty)
+{
+    return checked_guard(m_server, &IServerWrapper::registerResource,
+                         ref(resourceHandle), resourceURI, resourceTypeName, resourceInterface, entityHandler, resourceProperty);
+}
 
+OCStackResult OCPlatform::unregisterResource(const OCResourceHandle& resourceHandle) const
+{
+    return checked_guard(m_server, &IServerWrapper::unregisterResource,
+                         resourceHandle);
+}
 
+OCStackResult OCPlatform::unbindResource(OCResourceHandle collectionHandle, OCResourceHandle resourceHandle)
+{
+    return result_guard(OCUnBindResource(ref(collectionHandle), ref(resourceHandle)));
+}
 
-    OCStackResult OCPlatform::unbindResource(OCResourceHandle collectionHandle, OCResourceHandle resourceHandle)
+OCStackResult OCPlatform::unbindResources(const OCResourceHandle collectionHandle, const std::vector<OCResourceHandle>& resourceHandles)
+{
+    for(const auto& h : resourceHandles)
     {
-        OCStackResult result = OC_STACK_ERROR;
-
-        try {
-            result = OCUnBindResource(collectionHandle, resourceHandle);
-        }
-        catch(std::exception e) // TODO: define our own expception.
-        {
-            throw e;
-        }
-
-        return result;
-    }
+       OCStackResult r;
 
-    OCStackResult OCPlatform::unbindResources(const OCResourceHandle collectionHandle, const std::vector<OCResourceHandle>& resourceHandles)
-    {
-        OCStackResult result = OC_STACK_ERROR;
-
-        try {
-
-            for(const OCResourceHandle& handle : resourceHandles)
-            {
-                result = OCUnBindResource(collectionHandle, handle);
-
-                if(result != OC_STACK_OK)
-                {
-                    // TODO Should we unbind the previous successful ones?
-                    // TODO should we return which are succesful
-                    // Currently just returns with any failure
-                    return result;
-                }
-            }
-        }
-        catch(std::exception e) // TODO : define our own exception
-        {
-            throw e;
-        }
-
-        return result;
+       if(OC_STACK_OK != (r = result_guard(OCUnBindResource(collectionHandle, h))))
+       {
+           return r;
+       }
     }
 
-    OCStackResult OCPlatform::bindResource(const OCResourceHandle collectionHandle, const OCResourceHandle resourceHandle)
-    {
-        OCStackResult result = OC_STACK_ERROR;
-
-        try {
-            result = OCBindResource(collectionHandle, resourceHandle);
-        }
-        catch(std::exception e) // TODO : define our own exception
-        {
-            throw e;
-        }
+    return OC_STACK_OK;
+}
 
-        return result;
-    }
+OCStackResult OCPlatform::bindResource(const OCResourceHandle collectionHandle, const OCResourceHandle resourceHandle)
+{
+    return result_guard(OCBindResource(collectionHandle, resourceHandle));
+}
 
-    OCStackResult OCPlatform::bindResources(const OCResourceHandle collectionHandle, const std::vector<OCResourceHandle>& resourceHandles)
+OCStackResult OCPlatform::bindResources(const OCResourceHandle collectionHandle, const std::vector<OCResourceHandle>& resourceHandles)
+{
+    for(const auto& h : resourceHandles)
     {
-        OCStackResult result = OC_STACK_ERROR;
-
-        try {
-
-            for(const OCResourceHandle& handle : resourceHandles)
-            {
-                result = OCBindResource(collectionHandle, handle);
-
-                if(result != OC_STACK_OK)
-                {
-                    // TODO Should we unbind the previous successful ones?
-                    // TODO should we return which are succesful
-                    // Currently just returns with any failure
-                    return result;
-                }
-            }
-        }
-        catch(std::exception e) // TODO : define our own exception
-        {
-            throw e;
-        }
-
-        return result;
-    }
+       OCStackResult r;
 
-    OCStackResult OCPlatform::bindTypeToResource(const OCResourceHandle& resourceHandle,
-        const std::string& resourceTypeName) const
-    {
-        OCStackResult result = OC_STACK_ERROR;
-        if(m_server)
-        {
-            try
-            {
-                result = m_server->bindTypeToResource(resourceHandle, resourceTypeName);
-            }
-            catch (OCException& e)
-            {
-                log() << "Caught an exception..." << endl;
-                log() << "\tMessage: " << e.what()  << endl;
-                log() << "\t Reason: " << e.reason() << endl;
-            }
-        }
-        return result;
+       if(OC_STACK_OK != (r = result_guard(OCBindResource(collectionHandle, h))))
+       {
+           return r;
+       }
     }
 
-    OCStackResult OCPlatform::bindInterfaceToResource(const OCResourceHandle& resourceHandle,
-        const std::string& resourceInterfaceName) const
-    {
-        OCStackResult result = OC_STACK_ERROR;
-        if(m_server)
-        {
-            try
-            {
-                result = m_server->bindInterfaceToResource(resourceHandle, resourceInterfaceName);
-            }
-            catch (OCException& e)
-            {
-                log() << "Caught an exception..." << endl;
-                log() << "\tMessage: " << e.what()  << endl;
-                log() << "\t Reason: " << e.reason() << endl;
-            }
-        }
-        return result;
+    return OC_STACK_OK;
+}
 
-    }
+OCStackResult OCPlatform::bindTypeToResource(const OCResourceHandle& resourceHandle,
+                                             const std::string& resourceTypeName) const
+{
+    return checked_guard(m_server, &IServerWrapper::bindTypeToResource,
+                         resourceHandle, resourceTypeName);
+}
 
-    OCStackResult OCPlatform::startPresence(const unsigned int announceDurationSeconds)
-    {
-        if(m_server)
-        {
-            return m_server->startPresence(announceDurationSeconds);
-        }
-        else
-        {
-            return OC_STACK_ERROR;
-        }
-    }
+OCStackResult OCPlatform::bindInterfaceToResource(const OCResourceHandle& resourceHandle,
+                                                  const std::string& resourceInterfaceName) const
+{
+    return checked_guard(m_server, &IServerWrapper::bindInterfaceToResource,
+                         resourceHandle, resourceInterfaceName);
+}
 
-    OCStackResult OCPlatform::stopPresence()
-    {
-        if(m_server)
-        {
-            return m_server->stopPresence();
-        }
-        else
-        {
-            return OC_STACK_ERROR;
-        }
-    }
+OCStackResult OCPlatform::startPresence(const unsigned int announceDurationSeconds)
+{
+    return checked_guard(m_server, &IServerWrapper::startPresence,
+                         announceDurationSeconds);
+}
 
-    OCStackResult OCPlatform::subscribePresence(OCPresenceHandle& presenceHandle, const std::string& host,
-        SubscribeCallback presenceHandler)
-    {
-        if(m_client)
-        {
-            return m_client->SubscribePresence(&presenceHandle, host, presenceHandler);
-        }
-        else
-        {
-            return OC_STACK_ERROR;
-        }
-    }
+OCStackResult OCPlatform::stopPresence()
+{
+    return checked_guard(m_server, &IServerWrapper::stopPresence);
+}
 
-    OCStackResult OCPlatform::unsubscribePresence(OCPresenceHandle presenceHandle)
-    {
-        if(m_client)
-        {
-            return m_client->UnsubscribePresence(presenceHandle);
-        }
-        else
-        {
-            return OC_STACK_ERROR;
-        }
-    }
+OCStackResult OCPlatform::subscribePresence(OCPresenceHandle& presenceHandle, const std::string& host,
+                                            SubscribeCallback presenceHandler)
+{
+    return checked_guard(m_client, &IClientWrapper::SubscribePresence,
+                         &presenceHandle, host, presenceHandler);
+}
+
+OCStackResult OCPlatform::unsubscribePresence(OCPresenceHandle presenceHandle)
+{
+    return checked_guard(m_client, &IClientWrapper::UnsubscribePresence,
+                         ref(presenceHandle));
+}
 
 } //namespace OC
index a1f6353..e9b2730 100644 (file)
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
 #include "OCResource.h"
+#include "OCUtilities.h"
 
 namespace OC {
-    OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper, const std::string& host,
-        const std::string& uri, bool observable, const std::vector<std::string>& resourceTypes,
-        const std::vector<std::string>& interfaces) :
-        m_clientWrapper(clientWrapper), m_uri(uri), m_host(host), m_isObservable(observable),
-        m_isCollection(false), m_resourceTypes(resourceTypes), m_interfaces(interfaces),
-        m_observeHandle(nullptr)
+
+using OC::nil_guard;
+using OC::result_guard;
+using OC::checked_guard;
+
+OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper, const std::string& host,
+                       const std::string& uri, bool observable, const std::vector<std::string>& resourceTypes,
+                       const std::vector<std::string>& interfaces) 
+ :  m_clientWrapper(clientWrapper), m_uri(uri), m_host(host), m_isObservable(observable),
+    m_isCollection(false), m_resourceTypes(resourceTypes), m_interfaces(interfaces),
+    m_observeHandle(nullptr)
+{
+    m_isCollection = std::find(m_interfaces.begin(), m_interfaces.end(), LINK_INTERFACE)
+                        != m_interfaces.end();
+
+    if (m_uri.empty() ||
+        resourceTypes.empty() ||
+        interfaces.empty()||
+        m_clientWrapper.expired())
     {
-        m_isCollection = std::find(m_interfaces.begin(), m_interfaces.end(), LINK_INTERFACE)
-                            != m_interfaces.end();
-
-        if (m_uri.empty() || resourceTypes.empty()
-            || interfaces.empty()|| m_clientWrapper.expired())
-        {
-            throw ResourceInitException(m_uri.empty(), resourceTypes.empty(),
-                    interfaces.empty(), m_clientWrapper.expired());
-        }
+        throw ResourceInitException(m_uri.empty(), resourceTypes.empty(),
+                interfaces.empty(), m_clientWrapper.expired());
     }
-
-    OCResource::~OCResource()
+}
+
+OCResource::~OCResource()
+{
+}
+
+OCStackResult OCResource::get(const QueryParamsMap& queryParametersMap,
+                              GetCallback attributeHandler)
+{
+    return checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetResourceRepresentation,
+                         m_host, m_uri, queryParametersMap, attributeHandler);
+}
+
+OCStackResult OCResource::get(const std::string& resourceType,
+                              const std::string& resourceInterface, const QueryParamsMap& queryParametersMap,
+                              GetCallback attributeHandler)
+{
+    QueryParamsMap mapCpy(queryParametersMap);
+
+    if(!resourceType.empty())
     {
+        mapCpy["rt"]=resourceType;
     }
 
-    OCStackResult OCResource::get(const QueryParamsMap& queryParametersMap,
-        GetCallback attributeHandler)
+    if(!resourceInterface.empty())
     {
-        auto cw = m_clientWrapper.lock();
-
-        if(cw)
-        {
-            return cw->GetResourceRepresentation(m_host, m_uri, queryParametersMap, attributeHandler);
-        }
-        else
-        {
-            return OC_STACK_ERROR;
-        }
+        mapCpy["if"]= resourceInterface;
     }
 
-    OCStackResult OCResource::get(const std::string& resourceType,
-        const std::string& resourceInterface, const QueryParamsMap& queryParametersMap,
-        GetCallback attributeHandler)
+    return result_guard(get(mapCpy, attributeHandler));
+}
+
+OCStackResult OCResource::put(const OCRepresentation& rep,
+                              const QueryParamsMap& queryParametersMap, PutCallback attributeHandler)
+{
+    return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PutResourceRepresentation,
+                         m_host, m_uri, rep, queryParametersMap, attributeHandler);
+}
+
+OCStackResult OCResource::put(const std::string& resourceType,
+                              const std::string& resourceInterface, const OCRepresentation& rep,
+                              const QueryParamsMap& queryParametersMap,
+                              PutCallback attributeHandler)
+{
+    QueryParamsMap mapCpy(queryParametersMap);
+
+    if(!resourceType.empty())
+     {
+            mapCpy["rt"]=resourceType;
+     }
+
+    if(!resourceInterface.empty())
+     {
+            mapCpy["if"]=resourceInterface;
+     }
+
+    return result_guard(put(rep, mapCpy, attributeHandler));
+}
+
+OCStackResult OCResource::post(const OCRepresentation& rep,
+                               const QueryParamsMap& queryParametersMap, PostCallback attributeHandler)
+{
+    return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PostResourceRepresentation,
+                         m_host, m_uri, rep, queryParametersMap, attributeHandler);
+}
+
+OCStackResult OCResource::post(const std::string& resourceType,
+                               const std::string& resourceInterface, const OCRepresentation& rep,
+                               const QueryParamsMap& queryParametersMap,
+                               PostCallback attributeHandler)
+{
+    QueryParamsMap mapCpy(queryParametersMap);
+
+    if(!resourceType.empty())
     {
-        auto cw = m_clientWrapper.lock();
-
-        if(cw)
-        {
-            QueryParamsMap mapCpy(queryParametersMap);
-
-            if(!resourceType.empty())
-            {
-                mapCpy["rt"]=resourceType;
-            }
-            if(!resourceInterface.empty())
-            {
-                mapCpy["if"]= resourceInterface;
-            }
-
-            return get(mapCpy, attributeHandler);
-        }
-        else
-        {
-            return OC_STACK_ERROR;
-        }
+        mapCpy["rt"]=resourceType;
     }
 
-    OCStackResult OCResource::put(const OCRepresentation& rep,
-        const QueryParamsMap& queryParametersMap, PutCallback attributeHandler)
+    if(!resourceInterface.empty())
     {
-        auto cw = m_clientWrapper.lock();
-
-        if(cw)
-        {
-            return cw->PutResourceRepresentation(m_host, m_uri, rep, queryParametersMap,
-                    attributeHandler);
-        }
-        else
-        {
-            return OC_STACK_ERROR;
-        }
+        mapCpy["if"]=resourceInterface;
     }
 
+    return result_guard(post(rep, mapCpy, attributeHandler));
+}
 
-    OCStackResult OCResource::put(const std::string& resourceType,
-        const std::string& resourceInterface, const OCRepresentation& rep,
-        const QueryParamsMap& queryParametersMap,
-        PutCallback attributeHandler)
+OCStackResult OCResource::observe(ObserveType observeType,
+                                  const QueryParamsMap& queryParametersMap, ObserveCallback observeHandler)
+{
+    if(m_observeHandle != nullptr)
     {
-        auto cw = m_clientWrapper.lock();
-
-        if(cw)
-        {
-            QueryParamsMap mapCpy(queryParametersMap);
-
-            if(!resourceType.empty())
-            {
-                mapCpy["rt"]=resourceType;
-            }
-            if(!resourceInterface.empty())
-            {
-                mapCpy["if"]=resourceInterface;
-            }
-
-            return put(rep, mapCpy, attributeHandler);
-        }
-        else
-        {
-            return OC_STACK_ERROR;
-        }
+        return result_guard(OC_STACK_INVALID_PARAM);
     }
 
-    OCStackResult OCResource::post(const OCRepresentation& rep,
-        const QueryParamsMap& queryParametersMap, PostCallback attributeHandler)
-    {
-        auto cw = m_clientWrapper.lock();
-
-        if(cw)
-        {
-            return cw->PostResourceRepresentation(m_host, m_uri, rep, queryParametersMap,
-                    attributeHandler);
-        }
-        else
-        {
-            return OC_STACK_ERROR;
-        }
-    }
+    return checked_guard(m_clientWrapper.lock(), &IClientWrapper::ObserveResource,
+                         observeType, &m_observeHandle, m_host,
+                         m_uri, queryParametersMap, observeHandler);
+}
 
-    OCStackResult OCResource::post(const std::string& resourceType,
-        const std::string& resourceInterface, const OCRepresentation& rep,
-        const QueryParamsMap& queryParametersMap,
-        PostCallback attributeHandler)
+OCStackResult OCResource::cancelObserve()
+{
+    if(m_observeHandle == nullptr)
     {
-        auto cw = m_clientWrapper.lock();
-
-        if(cw)
-        {
-            QueryParamsMap mapCpy(queryParametersMap);
-
-            if(!resourceType.empty())
-            {
-                mapCpy["rt"]=resourceType;
-            }
-            if(!resourceInterface.empty())
-            {
-                mapCpy["if"]=resourceInterface;
-            }
-
-            return post(rep, mapCpy, attributeHandler);
-        }
-        else
-        {
-            return OC_STACK_ERROR;
-        }
+        return result_guard(OC_STACK_INVALID_PARAM);
     }
 
+    return checked_guard(m_clientWrapper.lock(), &IClientWrapper::CancelObserveResource,
+                         m_observeHandle, m_host, m_uri);
+}
 
-    OCStackResult OCResource::observe(ObserveType observeType,
-        const QueryParamsMap& queryParametersMap, ObserveCallback observeHandler)
-    {
-        if(m_observeHandle != nullptr)
-        {
-            return OC_STACK_INVALID_PARAM;
-        }
-        else
-        {
-            auto cw = m_clientWrapper.lock();
-
-            if(cw)
-            {
-                return cw->ObserveResource(observeType, &m_observeHandle, m_host,
-                        m_uri, queryParametersMap, observeHandler);
-            }
-            else
-            {
-                return OC_STACK_ERROR;
-            }
-        }
-    }
+std::string OCResource::host() const
+{
+    return m_host;
+}
 
-    OCStackResult OCResource::cancelObserve()
-    {
-        if(m_observeHandle == nullptr)
-        {
-            return OC_STACK_INVALID_PARAM;
-        }
-        else
-        {
-            auto cw = m_clientWrapper.lock();
-
-            if(cw)
-            {
-                OCStackResult ret = cw->CancelObserveResource(m_observeHandle, m_host, m_uri);
-                m_observeHandle = nullptr;
-                return ret;
-            }
-            else
-            {
-                return OC_STACK_ERROR;
-            }
-        }
-    }
+std::string OCResource::uri() const
+{
+    return m_uri;
+}
+
+bool OCResource::isObservable() const
+{
+    return m_isObservable;
+}
 
-    std::string OCResource::host() const
-    {
-        return m_host;
-    }
-    std::string OCResource::uri() const
-    {
-        return m_uri;
-    }
-    bool OCResource::isObservable() const
-    {
-        return m_isObservable;
-    }
 } // namespace OC
index 0e98ae5..1162522 100644 (file)
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
+#include <OCApi.h>
+
 #include "OCUtilities.h"
-#include <algorithm>
-#include <iterator>
+
 #include <boost/algorithm/string.hpp>
+
 #include <sstream>
+#include <iterator>
+#include <algorithm>
+
 extern "C" {
 #include <uri.h>    // libcoap
 #include <option.h> // libcoap
 }
 
-#include <OCApi.h>
-
-namespace OC{
+namespace OC {
 
     // Helper function to escape special character.
     std::string escapeString(const std::string& value)
@@ -164,3 +167,51 @@ OC::Utilities::QueryParamsKeyVal OC::Utilities::getQueryParams(const std::string
     }
     return qp;
 }
+
+namespace OC {
+
+OCStackResult result_guard(const OCStackResult r)
+{
+ std::ostringstream os;
+
+ switch(r)
+ {
+    default:
+        os << "result_guard(): unhandled exception: " << OCException::reason(r);
+        throw OCException(os.str(), r);
+
+    /* Exceptional conditions: */
+    case OC_STACK_NO_MEMORY:
+    case OC_STACK_COMM_ERROR:
+    case OC_STACK_NOTIMPL:
+    case OC_STACK_INVALID_URI:
+    case OC_STACK_INVALID_QUERY:
+    case OC_STACK_INVALID_IP:
+    case OC_STACK_INVALID_PORT:
+    case OC_STACK_INVALID_CALLBACK:
+    case OC_STACK_INVALID_METHOD:
+    case OC_STACK_INVALID_PARAM:
+    case OC_STACK_INVALID_OBSERVE_PARAM:
+        throw OCException(os.str(), r);
+
+    /* Non-exceptional failures or success: */
+    case OC_STACK_OK:
+    case OC_STACK_NO_RESOURCE:
+    case OC_STACK_RESOURCE_ERROR:
+    case OC_STACK_SLOW_RESOURCE:
+    case OC_STACK_NO_OBSERVERS:
+    case OC_STACK_OBSERVER_NOT_FOUND:
+    case OC_STACK_OBSERVER_NOT_ADDED:
+    case OC_STACK_OBSERVER_NOT_REMOVED:
+#ifdef WITH_PRESENCE
+    case OC_STACK_PRESENCE_STOPPED:
+    case OC_STACK_PRESENCE_DO_NOT_HANDLE:
+#endif
+
+    break;
+ }
+
+ return r;
+}
+
+} // namespace OC