replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / service / resource-encapsulation / include / RCSResourceAttributes.h
index 9f4c98d..99d29bf 100644 (file)
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
+/**
+ * @file
+ *
+ * This file contains the declaration of classes and its members related to RCSResourceAttributes
+ */
 #ifndef RES_ENCAPSULATION_RESOURCEATTRIBUTES_H
 #define RES_ENCAPSULATION_RESOURCEATTRIBUTES_H
 
 
 #include <functional>
 #include <unordered_map>
+#include <vector>
 
-#include <boost/variant.hpp>
-#include <boost/mpl/contains.hpp>
-#include <boost/mpl/find.hpp>
-#include <boost/mpl/distance.hpp>
-#include <boost/mpl/begin_end.hpp>
-#include <boost/scoped_ptr.hpp>
+#include "boost/variant.hpp"
+#include "boost/mpl/contains.hpp"
+#include "boost/mpl/find.hpp"
+#include "boost/mpl/distance.hpp"
+#include "boost/mpl/begin_end.hpp"
+#include "boost/scoped_ptr.hpp"
+
+#include "RCSException.h"
 
-#include <RCSException.h>
-/**
- * @file
- *
- * This file contains the "RCSResourceAttributes" class & its helper classes
- */
 namespace OIC
 {
     namespace Service
     {
         /**
-         * Thrown when getting value with wrong template parameter.
-         */
-        class BadGetException: public RCSException
-        {
-        public:
-            BadGetException(const std::string& what) : RCSException{ what } {}
-            BadGetException(std::string&& what) : RCSException{ std::move(what) } {}
-        };
-
-        /**
-        * Thrown when a key is invalid.
+        * This RCSByteString the one of RCSResourceAttributes value for Byte String (Binary).
+        *
+        * It provides similar usage to c++ standard vector.<br/>
+        * An RCSByteString can be one of various attribute value type.
+        *
+        * @see Value
+        * @see Type
+        * @see RCSRemoteResourceObject
+        * @see RCSResourceObject
+        * @see RCSResourceAttributes
         */
-        class InvalidKeyException: public RCSException
+        class RCSByteString
         {
         public:
-            InvalidKeyException(const std::string& what) : RCSException{ what } {}
-            InvalidKeyException(std::string&& what) : RCSException{ std::move(what) } {}
+            typedef std::vector<uint8_t> DataType;
+
+            /**
+             * Returns a vector<uint8_t> type of byte string.
+             *
+             * @return A stored byte string with std::vector<uint8_t>
+             */
+            DataType getByteString() const
+            {
+                return {m_data};
+            }
+
+            /**
+             * Returns a size of stored vector<uint8_t>.
+             *
+             * @return A size of stored byte string.
+             */
+            size_t size() const
+            {
+                return m_data.size();
+            }
+
+            /**
+              * @relates RCSByteString
+              *
+              * Checks if the byte string is same contents, or not.
+              *
+              * @return true if the byte string are equal, false otherwise.
+              */
+            inline bool operator==(const RCSByteString& rhs) const
+            {
+                return this->m_data == rhs.getByteString();
+            }
+
+            /**
+             * @relates RCSByteString
+             *
+             * Checks if the byte string is not same contents, or is same.
+             *
+             * @return true if the byte string are not equal, false otherwise.
+             */
+            inline bool operator!=(const RCSByteString& rhs) const
+            {
+                return this->m_data != rhs.getByteString();
+            }
+
+            /**
+             * Return a value of indexed byte string.
+             *
+             * @param it location of the element.
+             *
+             * @return A copied value of indexed byte string.
+             */
+            inline uint8_t operator[](size_t it) const
+            {
+                return this->m_data[it];
+            }
+
+            RCSByteString()
+            {
+            }
+            RCSByteString(DataType && rhs)
+            : m_data {std::move(rhs)}
+            {
+            }
+            RCSByteString(const DataType & rhs)
+            : m_data {rhs}
+            {
+            }
+            RCSByteString(RCSByteString && rhs)
+            : m_data {DataType{rhs.getByteString()}}
+            {
+            }
+            RCSByteString(const RCSByteString & rhs)
+            : m_data {DataType{rhs.getByteString()}}
+            {
+            }
+
+            RCSByteString(::OCByteString && rhs)
+            : m_data {DataType{rhs.bytes, rhs.bytes + rhs.len}}
+            {
+            }
+            RCSByteString(const ::OCByteString & rhs)
+            : m_data {DataType{rhs.bytes, rhs.bytes + rhs.len}}
+            {
+            }
+
+            RCSByteString(uint8_t* bytes, size_t size)
+            : m_data {DataType{bytes, bytes + size}}
+            {
+            }
+            inline RCSByteString& operator=(RCSByteString&& rhs)
+            {
+                return operator =(rhs);
+            }
+            inline RCSByteString& operator=(const RCSByteString& rhs)
+            {
+                if (!m_data.empty())
+                {
+                    m_data.clear();
+                }
+                m_data = DataType{rhs.getByteString()};
+                return *this;
+            }
+        private:
+            DataType m_data;
         };
 
+#ifdef __APPLE__
+    class RCSResourceAttributes;
+    typedef boost::variant<
+                    std::nullptr_t,
+                    int,
+                    double,
+                    bool,
+                    std::string,
+                    RCSByteString,
+                    RCSResourceAttributes,
+
+                    std::vector< int >,
+                    std::vector< double >,
+                    std::vector< bool >,
+                    std::vector< std::string >,
+                    std::vector< RCSByteString >,
+                    std::vector< RCSResourceAttributes >,
+
+                    std::vector< std::vector< int > >,
+                    std::vector< std::vector< std::vector< int > > >,
+
+                    std::vector< std::vector< double > >,
+                    std::vector< std::vector< std::vector< double > > >,
+
+                    std::vector< std::vector< bool > >,
+                    std::vector< std::vector< std::vector< bool > > >,
+
+                    std::vector< std::vector< std::string > >,
+                    std::vector< std::vector< std::vector< std::string > > >,
+
+                    std::vector< std::vector< RCSByteString > >,
+                    std::vector< std::vector< std::vector< RCSByteString > > >,
+
+                    std::vector< std::vector< RCSResourceAttributes > >,
+                    std::vector< std::vector< std::vector< RCSResourceAttributes > > >
+                > ValueVariant;
+#endif
+
         /**
-        * RCSResourceAttributes represents the attributes for a resource.
+        * This represents the attributes for a resource.
         *
         * It provides similar usage to c++ standard containers. (iterator,
         * operators and accessors)<br/>
         * An attribute value can be one of various types. <br/>
         *
-        * @note If client developer wants to get the RCSResourceAttributes for the resource of
-        *            interest following are the steps:
-        *            - first call the discover API of DiscoveryManager class.
-        *            - After getting the RemoteResourceObject, call getRemoteAttributes() API
-        *               of RemoteResourceObject class
         *
         * @see Value
         * @see Type
@@ -87,21 +225,48 @@ namespace OIC
         * @see RCSDiscoveryManager
         * @see RCSRemoteResourceObject
         * @see RCSResourceObject
+        * @see RCSByteString
         */
         class RCSResourceAttributes
         {
         private:
             template< typename T > struct IsSupportedTypeHelper;
-
+#ifndef __APPLE__
             typedef boost::variant<
                 std::nullptr_t,
                 int,
                 double,
                 bool,
                 std::string,
-                RCSResourceAttributes
-            > ValueVariant;
+                RCSByteString,
+                RCSResourceAttributes,
+
+                std::vector< int >,
+                std::vector< double >,
+                std::vector< bool >,
+                std::vector< std::string >,
+                std::vector< RCSByteString >,
+                std::vector< RCSResourceAttributes >,
+
+                std::vector< std::vector< int > >,
+                std::vector< std::vector< std::vector< int > > >,
+
+                std::vector< std::vector< double > >,
+                std::vector< std::vector< std::vector< double > > >,
+
+                std::vector< std::vector< bool > >,
+                std::vector< std::vector< std::vector< bool > > >,
 
+                std::vector< std::vector< std::string > >,
+                std::vector< std::vector< std::vector< std::string > > >,
+
+                std::vector< std::vector< RCSByteString > >,
+                std::vector< std::vector< std::vector< RCSByteString > > >,
+
+                std::vector< std::vector< RCSResourceAttributes > >,
+                std::vector< std::vector< std::vector< RCSResourceAttributes > > >
+            > ValueVariant;
+#endif
             template< typename T, typename V = void,
                     typename = typename std::enable_if<
                         IsSupportedTypeHelper< T >::type::value, V >::type >
@@ -110,21 +275,29 @@ namespace OIC
                 typedef V type;
             };
 
-            template< typename VISITOR >
+            template< typename VISITOR, typename MOVE = std::false_type >
             class KeyValueVisitorHelper: public boost::static_visitor< >
             {
             public:
-                KeyValueVisitorHelper(VISITOR& visitor) :
+                KeyValueVisitorHelper(VISITOR& visitor) BOOST_NOEXCEPT :
                         m_visitor( visitor )
                 {
                 }
 
-                template< typename T >
-                void operator()(const std::string& key, const T& value) const
+                template< typename T, typename M = MOVE >
+                typename std::enable_if< std::is_same< M, std::false_type >::value >::type
+                operator()(const std::string& key, const T& value) const
                 {
                     m_visitor(key, value);
                 }
 
+                template< typename T, typename M = MOVE >
+                typename std::enable_if< std::is_same< M, std::true_type >::value >::type
+                operator()(const std::string& key, T& value)
+                {
+                    m_visitor(key, std::move(value));
+                }
+
             private:
                 VISITOR& m_visitor;
             };
@@ -141,7 +314,7 @@ namespace OIC
                 IsSupportedTypeHelper< T >::type::value, std::true_type, std::false_type>::type { };
 
             /**
-             * Identifier for types of Value.
+             * Identifiers for types of Value.
              *
              * @see Type
              */
@@ -152,6 +325,7 @@ namespace OIC
                 DOUBLE, /**< double */
                 BOOL, /**< bool */
                 STRING, /**< std::string */
+                BYTESTRING, /**< RCSByteString */
                 ATTRIBUTES, /**< RCSResourceAttributes */
                 VECTOR /**< std::vector */
             };
@@ -176,32 +350,69 @@ namespace OIC
                  * Returns type identifier.
                  *
                  * @return Identifier of type.
+                 *
+                 * @see getBaseTypeId
+                 */
+                TypeId getId() const BOOST_NOEXCEPT;
+
+                /**
+                 * Returns the type identifier of a base type of sequence.
+                 *
+                 * For non sequence types, it is equivalent to calling getId.
+                 *
+                 * @return Identifier of type.
+                 *
+                 * @see getDepth
+                 * @see getId
+                 */
+                static TypeId getBaseTypeId(const Type& t) BOOST_NOEXCEPT;
+
+                /**
+                 * Returns the depth of a type.
+                 *
+                 * The return will be zero for non sequence types.
+                 *
+                 * @see getBaseTypeId
                  */
-                TypeId getId() const;
+                static size_t getDepth(const Type& t) BOOST_NOEXCEPT;
 
                 /**
                  * Factory method to create Type instance from T.
                  *
                  * @return An instance that has TypeId for T.
                  *
-                 * @note T must be supported by Value. Otherwise, it won't be compiled.
+                 * @note T must be supported by Value. Otherwise, it won't compile.
                  *
                  * @see is_supported_type
                  */
                 template < typename T >
-                static Type typeOf(const T& value)
+                constexpr static Type typeOf(const T&) BOOST_NOEXCEPT
                 {
-                    return Type(value);
+                    return Type{ IndexOfType< T >::value };
+                }
+
+                /**
+                 * Factory method to create Type instance from T.
+                 *
+                 * @return An instance that has TypeId for T.
+                 *
+                 * @note T must be supported by Value. Otherwise, it won't compile.
+                 *
+                 * @see is_supported_type
+                 */
+                template < typename T >
+                constexpr static Type typeOf() BOOST_NOEXCEPT
+                {
+                    return Type{ IndexOfType< T >::value };
                 }
 
                 //! @cond
-                friend bool operator==(const Type&, const Type&);
+                friend bool operator==(const Type&, const Type&) BOOST_NOEXCEPT;
                 //! @endcond
 
             private:
-                template < typename T >
-                explicit Type(const T&) :
-                    m_which{ IndexOfType< T >::value }
+                constexpr explicit Type(int which) BOOST_NOEXCEPT :
+                    m_which{ which }
                 {
                 }
 
@@ -214,6 +425,41 @@ namespace OIC
              *
              * Type helps identify type information of Value.
              *
+             * Supported types are below
+             * @code
+                int
+                double
+                bool
+                std::string
+                RCSByteString
+                RCSResourceAttributes
+
+                std::vector< int >
+                std::vector< double >
+                std::vector< bool >
+                std::vector< std::string >
+                std::vector< RCSByteString >
+                std::vector< RCSResourceAttributes >
+
+                std::vector< std::vector< int > >
+                std::vector< std::vector< std::vector< int > > >
+
+                std::vector< std::vector< double > >
+                std::vector< std::vector< std::vector< double > > >
+
+                std::vector< std::vector< bool > >
+                std::vector< std::vector< std::vector< bool > > >
+
+                std::vector< std::vector< std::string > >
+                std::vector< std::vector< std::vector< std::string > > >
+
+                std::vector< std::vector< RCSByteString > >
+                std::vector< std::vector< std::vector< RCSByteString > > >
+
+                std::vector< std::vector< RCSResourceAttributes > >
+                std::vector< std::vector< std::vector< RCSResourceAttributes > > >
+             * @endcode
+             *
              * @see RCSResourceAttributes
              * @see Type
              * @see is_supported_type
@@ -225,11 +471,11 @@ namespace OIC
 
                 Value();
                 Value(const Value&);
-                Value(Value&&);
+                Value(Value&&) BOOST_NOEXCEPT;
 
                 /**
                  * Constructs a Value if T is a supported type.<br/>
-                 *       Otherwise it won't be compiled.
+                 *       Otherwise it won't compile.
                  */
                 template< typename T, typename = typename enable_if_supported< T >::type >
                 Value(T&& value) :
@@ -237,7 +483,7 @@ namespace OIC
                 {
                 }
 
-                Value(const char* value);
+                Value(const char*);
 
                 Value& operator=(const Value&);
                 Value& operator=(Value&&);
@@ -294,7 +540,7 @@ namespace OIC
                 /**
                  * Exchanges the content of the object by the content of the parameter.
                  */
-                void swap(Value&);
+                void swap(Value&) BOOST_NOEXCEPT;
 
                 //! @cond
                 friend class RCSResourceAttributes;
@@ -306,11 +552,18 @@ namespace OIC
                 {
                     try
                     {
-                        return boost::get< T >(*m_data);
+                        if ((*m_data).type() == typeid(T))
+                        {
+                            return boost::get< T >(*m_data);
+                        }
+                        else
+                        {
+                            throw RCSBadGetException{ "Wrong type" };
+                        }
                     }
                     catch (const boost::bad_get&)
                     {
-                        throw BadGetException{ "Wrong type" };
+                        throw RCSBadGetException{ "Wrong type" };
                     }
                 }
 
@@ -321,13 +574,17 @@ namespace OIC
                     {
                         return get< T >() == rhs;
                     }
-                    catch (const BadGetException&)
+                    catch (const RCSBadGetException&)
                     {
                         return false;
                     }
                 }
 
+#ifdef __APPLE__
+            public:
+#else
             private:
+#endif
                 boost::scoped_ptr< ValueVariant > m_data;
             };
 
@@ -346,32 +603,32 @@ namespace OIC
             /**
              * Returns an {@link iterator} referring to the first element.
              */
-            iterator begin();
+            iterator begin() BOOST_NOEXCEPT;
 
             /**
              * Returns an {@link iterator} referring to the <i>past-the-end element</i>.
              */
-            iterator end();
+            iterator end() BOOST_NOEXCEPT;
 
             /**
              * @copydoc cbegin()
              */
-            const_iterator begin() const;
+            const_iterator begin() const BOOST_NOEXCEPT;
 
             /**
              * @copydoc cend()
              */
-            const_iterator end() const;
+            const_iterator end() const BOOST_NOEXCEPT;
 
             /**
              * Returns a const_iterator referring to the first element.
              */
-            const_iterator cbegin() const;
+            const_iterator cbegin() const BOOST_NOEXCEPT;
 
             /**
              * Returns a const_iterator referring to the <i>past-the-end element</i>.
              */
-            const_iterator cend() const;
+            const_iterator cend() const BOOST_NOEXCEPT;
 
             /**
              * Accesses a value.
@@ -445,7 +702,7 @@ namespace OIC
             /**
              * Removes all elements.
              */
-            void clear();
+            void clear() BOOST_NOEXCEPT;
 
             /**
              * Removes a single element.
@@ -457,7 +714,16 @@ namespace OIC
             bool erase(const std::string& key);
 
             /**
-             * Checks the container has an element with a Key equivalent to key.
+             * Removes a single element.
+             *
+             * @param pos Iterator to the element to remove.
+             *
+             * @return Iterator following the last removed element.
+             */
+            iterator erase(const_iterator pos);
+
+            /**
+             * Checks this contains an element for the specified key.
              *
              * @param key Key to check.
              *
@@ -470,14 +736,14 @@ namespace OIC
              *
              * @see size
              */
-            bool empty() const;
+            bool empty() const BOOST_NOEXCEPT;
 
             /**
              * Returns the number of elements.
              *
              * @see empty
              */
-            size_t size() const;
+            size_t size() const BOOST_NOEXCEPT;
 
         private:
             template< typename VISITOR >
@@ -492,7 +758,22 @@ namespace OIC
                 }
             }
 
+            template< typename VISITOR >
+            void visitToMove(VISITOR& visitor)
+            {
+                KeyValueVisitorHelper< VISITOR, std::true_type > helper{ visitor };
+
+                for (auto& i : m_values)
+                {
+                    boost::variant< const std::string& > key{ i.first };
+                    boost::apply_visitor(helper, key, *i.second.m_data);
+                }
+            }
+#ifdef __APPLE__
+        public:
+#else
         private:
+#endif
             std::unordered_map< std::string, Value > m_values;
 
             //! @cond
@@ -516,6 +797,9 @@ namespace OIC
         public:
             ComparisonHelper(const Value&);
 
+            ComparisonHelper(const ComparisonHelper&) = delete;
+            ComparisonHelper& operator=(const ComparisonHelper&) = delete;
+
             template< typename T >
             typename std::enable_if< is_supported_type< T >::value, bool >::type equals(
                     const T& v) const
@@ -534,21 +818,28 @@ namespace OIC
             const Value& m_valueRef;
         };
 
+        //! @cond
         template< typename T >
         struct RCSResourceAttributes::IsSupportedTypeHelper
         {
-            typedef boost::mpl::contains<ValueVariant::types, typename std::decay< T >::type> type;
+            typedef boost::mpl::contains< ValueVariant::types, typename std::decay< T >::type > type;
         };
 
-        template <typename T>
+        template < typename T >
         struct RCSResourceAttributes::IndexOfType
         {
+            static_assert(RCSResourceAttributes::is_supported_type< T >::value,
+                "The type is not supported!");
+
             typedef typename boost::mpl::find< ValueVariant::types, T >::type iter;
             typedef typename boost::mpl::begin< ValueVariant::types >::type mpl_begin;
 
             static constexpr int value = boost::mpl::distance< mpl_begin, iter >::value;
         };
 
+        template < typename T > constexpr int RCSResourceAttributes::IndexOfType< T >::value;
+        //! @endcond
+
         /**
          * @relates RCSResourceAttributes::Type
          *
@@ -556,7 +847,8 @@ namespace OIC
          *
          * @return true if the objects are equal, false otherwise.
          */
-        bool operator==(const RCSResourceAttributes::Type&, const RCSResourceAttributes::Type&);
+        bool operator==(const RCSResourceAttributes::Type&, const RCSResourceAttributes::Type&)
+                BOOST_NOEXCEPT;
 
         /**
          * @relates RCSResourceAttributes::Type
@@ -565,7 +857,8 @@ namespace OIC
          *
          * @return true if the objects are not equal, false otherwise.
          */
-        bool operator!=(const RCSResourceAttributes::Type&, const RCSResourceAttributes::Type&);
+        bool operator!=(const RCSResourceAttributes::Type&, const RCSResourceAttributes::Type&)
+                BOOST_NOEXCEPT;
 
         /**
          * @relates RCSResourceAttributes::Value
@@ -656,32 +949,32 @@ namespace OIC
             class KeyVisitor: public boost::static_visitor< const std::string& >
             {
             public:
-                result_type operator()(iterator*) const;
-                result_type operator()(const_iterator*) const;
+                result_type operator()(iterator*) const BOOST_NOEXCEPT;
+                result_type operator()(const_iterator*) const BOOST_NOEXCEPT;
             };
 
             class ValueVisitor: public boost::static_visitor< Value& >
             {
             public:
-                result_type operator()(iterator*);
+                result_type operator()(iterator*) BOOST_NOEXCEPT;
                 result_type operator()(const_iterator*);
             };
 
             class ConstValueVisitor: public boost::static_visitor< const Value& >
             {
             public:
-                result_type operator()(iterator*) const;
-                result_type operator()(const_iterator*) const;
+                result_type operator()(iterator*) const BOOST_NOEXCEPT;
+                result_type operator()(const_iterator*) const BOOST_NOEXCEPT;
             };
 
         public:
-            const std::string& key() const;
-            const RCSResourceAttributes::Value& value() const;
+            const std::string& key() const BOOST_NOEXCEPT;
+            const RCSResourceAttributes::Value& value() const BOOST_NOEXCEPT;
             RCSResourceAttributes::Value& value();
 
         private:
             KeyValuePair(const KeyValuePair&) = default;
-            KeyValuePair(boost::variant< iterator*, const_iterator* >&&);
+            KeyValuePair(boost::variant< iterator*, const_iterator* >&&) BOOST_NOEXCEPT;
 
             KeyValuePair& operator=(const KeyValuePair&) = default;
 
@@ -713,9 +1006,9 @@ namespace OIC
 
         public:
             iterator();
-            iterator(const iterator&) = default;
+            iterator(const iterator&);
 
-            iterator& operator=(const iterator&) = default;
+            iterator& operator=(const iterator&);
 
             reference operator*();
             pointer operator->();
@@ -747,7 +1040,7 @@ namespace OIC
          * @see iterator
          */
         class RCSResourceAttributes::const_iterator:
-                public std::iterator < std::forward_iterator_tag,
+                public std::iterator< std::forward_iterator_tag,
                                        const RCSResourceAttributes::KeyValuePair >
         {
         private:
@@ -755,10 +1048,10 @@ namespace OIC
 
         public:
             const_iterator();
-            const_iterator(const const_iterator&) = default;
+            const_iterator(const const_iterator&);
             const_iterator(const RCSResourceAttributes::iterator&);
 
-            const_iterator& operator=(const const_iterator&) = default;
+            const_iterator& operator=(const const_iterator&);
             const_iterator& operator=(const RCSResourceAttributes::iterator&);
 
             reference operator*() const;