Imported Upstream version 1.1.0
[platform/upstream/iotivity.git] / service / resource-encapsulation / src / common / primitiveResource / src / RCSResourceAttributes.cpp
index 99de4a6..e96e7cc 100644 (file)
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
-#include <RCSResourceAttributes.h>
+#include "RCSResourceAttributes.h"
 
-#include <ResourceAttributesUtils.h>
-#include <ResourceAttributesConverter.h>
+#include <sstream>
 
-#include <boost/lexical_cast.hpp>
-#include <boost/mpl/advance.hpp>
-#include <boost/mpl/size.hpp>
-#include <boost/mpl/deref.hpp>
+#include "ResourceAttributesUtils.h"
+#include "ResourceAttributesConverter.h"
+
+#include "boost/lexical_cast.hpp"
+#include "boost/mpl/advance.hpp"
+#include "boost/mpl/size.hpp"
+#include "boost/mpl/deref.hpp"
 
 namespace
 {
 
     using namespace OIC::Service;
 
-    class ToStringVisitor: public boost::static_visitor< std::string >
+    class ToStringVisitor: public boost::static_visitor<>
     {
     public:
         ToStringVisitor() = default;
@@ -43,31 +45,56 @@ namespace
         ToStringVisitor& operator=(const ToStringVisitor&) = delete;
         ToStringVisitor& operator=(ToStringVisitor&&) = delete;
 
-        template < typename T >
-        std::string operator()(const T& value) const
+        template< typename T >
+        void operator()(const T& value)
         {
-            return boost::lexical_cast<std::string>(value);
+            m_stream << boost::lexical_cast< std::string >(value);
+        }
+
+        template< typename T >
+        void operator()(const std::vector< T >& v)
+        {
+            m_stream << "[";
+            for (auto it = v.begin(); it != v.end(); ++it)
+            {
+                if (it != v.begin()) m_stream << ", ";
+                (*this)(*it);
+            }
+            m_stream << "]";
         }
 
-        std::string operator()(std::nullptr_t) const
+        void operator()(std::nullptr_t)
         {
-            return "";
+            m_stream << "";
         }
 
-        std::string operator()(bool value) const
+        void operator()(bool value)
         {
-            return value ? "true" : "false";
+            m_stream << (value ? "true" : "false");
         }
 
-        std::string operator()(const std::string& value) const
+        void operator()(const std::string& value)
         {
-            return value;
+            m_stream << "\"" + value + "\"";
         }
 
-        std::string operator()(const OIC::Service::RCSResourceAttributes&) const
+        void operator()(const RCSResourceAttributes& attrs)
         {
-            return "Attributes";
+            m_stream << "{";
+            for (auto it = attrs.begin(); it != attrs.end(); ++it)
+            {
+                if (it != attrs.begin()) m_stream << ", ";
+                m_stream << "\"" << it->key() << "\" : " << it->value().toString();
+            }
+            m_stream << "}";
         }
+
+        std::string get() const {
+            return m_stream.str();
+        }
+
+    private:
+        std::ostringstream m_stream;
     };
 
     class TypeVisitor: public boost::static_visitor< RCSResourceAttributes::Type >
@@ -103,13 +130,15 @@ namespace
     template< >
     struct TypeInfoConverter< std::nullptr_t >
     {
-        static constexpr RCSResourceAttributes::TypeId typeId = RCSResourceAttributes::TypeId::NULL_T;
+        static constexpr RCSResourceAttributes::TypeId typeId =
+                RCSResourceAttributes::TypeId::NULL_T;
     };
 
     template< >
     struct TypeInfoConverter< double >
     {
-        static constexpr RCSResourceAttributes::TypeId typeId = RCSResourceAttributes::TypeId::DOUBLE;
+        static constexpr RCSResourceAttributes::TypeId typeId =
+                RCSResourceAttributes::TypeId::DOUBLE;
     };
 
     template< >
@@ -121,59 +150,85 @@ namespace
     template< >
     struct TypeInfoConverter< std::string >
     {
-        static constexpr RCSResourceAttributes::TypeId typeId = RCSResourceAttributes::TypeId::STRING;
+        static constexpr RCSResourceAttributes::TypeId typeId =
+                RCSResourceAttributes::TypeId::STRING;
     };
 
     template< >
     struct TypeInfoConverter< RCSResourceAttributes >
     {
-        static constexpr RCSResourceAttributes::TypeId typeId = RCSResourceAttributes::TypeId::ATTRIBUTES;
+        static constexpr RCSResourceAttributes::TypeId typeId =
+                RCSResourceAttributes::TypeId::ATTRIBUTES;
+    };
+
+    template< typename T >
+    struct TypeInfoConverter< std::vector< T > >
+    {
+        static constexpr RCSResourceAttributes::TypeId typeId =
+                RCSResourceAttributes::TypeId::VECTOR;
+    };
+
+    template< typename T >
+    struct SequenceTraits
+    {
+        static constexpr size_t depth = 0;
+        typedef T base_type;
+    };
+
+    template< typename T >
+    struct SequenceTraits< std::vector< T > >
+    {
+        static constexpr size_t depth = SequenceTraits< T >::depth + 1;
+        typedef typename SequenceTraits< T >::base_type base_type;
     };
 
     struct TypeInfo
     {
-        RCSResourceAttributes::TypeId typeId;
+        RCSResourceAttributes::TypeId m_typeId;
+        RCSResourceAttributes::Type m_baseType;
+        size_t m_depth;
 
-        template< typename TRAIT >
-        constexpr TypeInfo(TRAIT) :
-                typeId{ TRAIT::typeId }
+        template< typename T, typename ST = SequenceTraits < T > >
+        constexpr static TypeInfo get()
         {
+            return { TypeInfoConverter< T >::typeId ,
+                    RCSResourceAttributes::Type::typeOf< typename ST::base_type >(), ST::depth };
         }
 
         template< typename VARIANT, int POS >
-        static constexpr TypeInfo get()
+        constexpr static TypeInfo get()
         {
-            return TypeInfo(TypeInfoConverter<
-                        typename boost::mpl::deref<
-                            typename boost::mpl::advance<
-                                typename boost::mpl::begin< typename VARIANT::types>::type,
-                                boost::mpl::int_< POS >
-                            >::type
-                        >::type >{ });
+            typedef typename boost::mpl::begin< typename VARIANT::types >::type mpl_begin;
+            typedef typename boost::mpl::advance< mpl_begin, boost::mpl::int_< POS > >::type iter;
+
+            return get< typename boost::mpl::deref< iter >::type >();
         }
     };
 
     template< typename VARIANT, int POS >
-    constexpr inline std::vector< TypeInfo > getTypeInfo(Int2Type< POS >)
+    constexpr inline std::vector< TypeInfo > getTypeInfo(Int2Type< POS >) noexcept
     {
-        auto&& vec = getTypeInfo< VARIANT >(Int2Type< POS - 1 >{ });
+        auto vec = getTypeInfo< VARIANT >(Int2Type< POS - 1 >{ });
         vec.push_back(TypeInfo::get< VARIANT, POS >());
         return vec;
     }
 
     template< typename VARIANT >
-    constexpr inline std::vector< TypeInfo > getTypeInfo(Int2Type< 0 >)
+    constexpr inline std::vector< TypeInfo > getTypeInfo(Int2Type< 0 >) noexcept
     {
         return { TypeInfo::get< VARIANT, 0 >() };
     }
 
     template< typename VARIANT >
-    inline TypeInfo getTypeInfo(int which)
+    inline TypeInfo getTypeInfo(int which) noexcept
     {
-        static constexpr int variantEnd = boost::mpl::size< typename VARIANT::types >::value - 1;
+        static constexpr size_t variantSize = boost::mpl::size< typename VARIANT::types >::value;
+        static constexpr size_t variantEnd = variantSize - 1;
         static const std::vector< TypeInfo > typeInfos = getTypeInfo< VARIANT >(
                 Int2Type< variantEnd >{ });
 
+        static_assert(variantSize > 0, "Variant has no type!");
+
         return typeInfos[which];
     }
 
@@ -196,12 +251,14 @@ namespace OIC
             return *m_valueRef.m_data == *rhs.m_valueRef.m_data;
         }
 
-        bool operator==(const RCSResourceAttributes::Type& lhs, const RCSResourceAttributes::Type& rhs)
+        bool operator==(const RCSResourceAttributes::Type& lhs,
+                const RCSResourceAttributes::Type& rhs) noexcept
         {
             return lhs.m_which == rhs.m_which;
         }
 
-        bool operator!=(const RCSResourceAttributes::Type& lhs, const RCSResourceAttributes::Type& rhs)
+        bool operator!=(const RCSResourceAttributes::Type& lhs,
+                const RCSResourceAttributes::Type& rhs) noexcept
         {
             return !(lhs == rhs);
         }
@@ -228,11 +285,22 @@ namespace OIC
             return !(lhs == rhs);
         }
 
-        auto RCSResourceAttributes::Type::getId() const -> TypeId
+        auto RCSResourceAttributes::Type::getId() const noexcept -> TypeId
+        {
+            return ::getTypeInfo< ValueVariant >(m_which).m_typeId;
+        }
+
+        auto RCSResourceAttributes::Type::getBaseTypeId(const Type& t) noexcept -> TypeId
         {
-            return ::getTypeInfo< ValueVariant >(m_which).typeId;
+            return ::getTypeInfo< ValueVariant >(t.m_which).m_baseType.getId();
         }
 
+        size_t RCSResourceAttributes::Type::getDepth(const Type& t) noexcept
+        {
+            return ::getTypeInfo< ValueVariant >(t.m_which).m_depth;
+        }
+
+
         RCSResourceAttributes::Value::Value() :
                 m_data{ new ValueVariant{} }
         {
@@ -243,10 +311,10 @@ namespace OIC
         {
         }
 
-        RCSResourceAttributes::Value::Value(Value&& from) :
+        RCSResourceAttributes::Value::Value(Value&& from) noexcept :
                 m_data{ new ValueVariant{} }
         {
-            m_data->swap(*from.m_data);
+            m_data.swap(from.m_data);
         }
 
         RCSResourceAttributes::Value::Value(const char* value) :
@@ -286,27 +354,29 @@ namespace OIC
 
         std::string RCSResourceAttributes::Value::toString() const
         {
-            return boost::apply_visitor(ToStringVisitor(), *m_data);
+            ToStringVisitor visitor;
+            boost::apply_visitor(visitor, *m_data);
+            return visitor.get();
         }
 
-        void RCSResourceAttributes::Value::swap(Value& rhs)
+        void RCSResourceAttributes::Value::swap(Value& rhs) noexcept
         {
             m_data.swap(rhs.m_data);
         }
 
         auto RCSResourceAttributes::KeyValuePair::KeyVisitor::operator()(
-                iterator* iter) const -> result_type
+                iterator* iter) const noexcept -> result_type
         {
             return iter->m_cur->first;
         }
 
         auto RCSResourceAttributes::KeyValuePair::KeyVisitor::operator()(
-                const_iterator* iter) const -> result_type
+                const_iterator* iter) const noexcept -> result_type
         {
             return iter->m_cur->first;
         }
 
-        auto RCSResourceAttributes::KeyValuePair::ValueVisitor::operator() (iterator* iter)
+        auto RCSResourceAttributes::KeyValuePair::ValueVisitor::operator() (iterator* iter) noexcept
                 -> result_type
         {
             return iter->m_cur->second;
@@ -316,27 +386,27 @@ namespace OIC
                 -> result_type
         {
             // should not reach here.
-            throw BadGetException("");
+            throw RCSBadGetException("");
         }
 
         auto RCSResourceAttributes::KeyValuePair::ConstValueVisitor::operator()(
-                iterator*iter) const -> result_type
+                iterator*iter) const noexcept -> result_type
         {
             return iter->m_cur->second;
         }
 
         auto RCSResourceAttributes::KeyValuePair::ConstValueVisitor::operator()(
-                const_iterator* iter) const -> result_type
+                const_iterator* iter) const noexcept -> result_type
         {
             return iter->m_cur->second;
         }
 
-        auto RCSResourceAttributes::KeyValuePair::key() const -> const std::string&
+        auto RCSResourceAttributes::KeyValuePair::key() const noexcept -> const std::string&
         {
             return boost::apply_visitor(m_keyVisitor, m_iterRef);
         }
 
-        auto RCSResourceAttributes::KeyValuePair::value() const -> const Value&
+        auto RCSResourceAttributes::KeyValuePair::value() const noexcept -> const Value&
         {
             return boost::apply_visitor(m_constValueVisitor, m_iterRef);
         }
@@ -347,7 +417,7 @@ namespace OIC
         }
 
         RCSResourceAttributes::KeyValuePair::KeyValuePair(boost::variant<iterator*,
-                const_iterator*>&& ref) :
+                const_iterator*>&& ref) noexcept :
                 m_iterRef{ ref }
         {
         }
@@ -359,6 +429,18 @@ namespace OIC
         {
         }
 
+        RCSResourceAttributes::iterator::iterator(const iterator& rhs) :
+                m_cur{ rhs.m_cur },
+                m_keyValuePair{ this }
+        {
+        }
+
+        auto RCSResourceAttributes::iterator::operator=(const iterator& rhs) -> iterator&
+        {
+            m_cur = rhs.m_cur;
+            return *this;
+        }
+
         RCSResourceAttributes::iterator::iterator(base_iterator&& iter) :
                 m_cur{ std::move(iter) },
                 m_keyValuePair{ this }
@@ -409,14 +491,27 @@ namespace OIC
         {
         }
 
+        RCSResourceAttributes::const_iterator::const_iterator(const const_iterator& rhs) :
+                m_cur{ rhs.m_cur }, m_keyValuePair{ this }
+        {
+        }
+
         RCSResourceAttributes::const_iterator::const_iterator(
                 const RCSResourceAttributes::iterator& iter) :
                 m_cur{ iter.m_cur }, m_keyValuePair{ this }
         {
         }
 
-        auto RCSResourceAttributes::const_iterator::operator=(const RCSResourceAttributes::iterator& iter)
-            -> const_iterator& {
+        auto RCSResourceAttributes::const_iterator::operator=(
+                const const_iterator& rhs) -> const_iterator&
+        {
+            m_cur = rhs.m_cur;
+            return *this;
+        }
+
+        auto RCSResourceAttributes::const_iterator::operator=(
+                const RCSResourceAttributes::iterator& iter) -> const_iterator&
+        {
             m_cur = iter.m_cur;
             return *this;
         }
@@ -425,6 +520,7 @@ namespace OIC
         {
             return m_keyValuePair;
         }
+
         auto RCSResourceAttributes::const_iterator::operator->() const -> pointer
         {
             return &m_keyValuePair;
@@ -453,32 +549,33 @@ namespace OIC
             return !(*this == rhs);
         }
 
-        auto RCSResourceAttributes::begin() -> iterator
+
+        auto RCSResourceAttributes::begin() noexcept -> iterator
         {
             return iterator{ m_values.begin() };
         }
 
-        auto RCSResourceAttributes::end() -> iterator
+        auto RCSResourceAttributes::end() noexcept -> iterator
         {
             return iterator{ m_values.end() };
         }
 
-        auto RCSResourceAttributes::begin() const -> const_iterator
+        auto RCSResourceAttributes::begin() const noexcept -> const_iterator
         {
             return const_iterator{ m_values.begin() };
         }
 
-        auto RCSResourceAttributes::end() const -> const_iterator
+        auto RCSResourceAttributes::end() const noexcept -> const_iterator
         {
             return const_iterator{ m_values.end() };
         }
 
-        auto RCSResourceAttributes::cbegin() const -> const_iterator
+        auto RCSResourceAttributes::cbegin() const noexcept -> const_iterator
         {
             return const_iterator{ m_values.begin() };
         }
 
-        auto RCSResourceAttributes::cend() const -> const_iterator
+        auto RCSResourceAttributes::cend() const noexcept -> const_iterator
         {
             return const_iterator{ m_values.end() };
         }
@@ -501,7 +598,7 @@ namespace OIC
             }
             catch (const std::out_of_range&)
             {
-                throw InvalidKeyException{ "No attribute named '" + key + "'" };
+                throw RCSInvalidKeyException{ "No attribute named '" + key + "'" };
             }
         }
 
@@ -513,11 +610,11 @@ namespace OIC
             }
             catch (const std::out_of_range&)
             {
-                throw InvalidKeyException{ "No attribute named '" + key + "'" };
+                throw RCSInvalidKeyException{ "No attribute named '" + key + "'" };
             }
         }
 
-        void RCSResourceAttributes::clear()
+        void RCSResourceAttributes::clear() noexcept
         {
             return m_values.clear();
         }
@@ -527,17 +624,22 @@ namespace OIC
             return m_values.erase(key) == 1U;
         }
 
+        auto RCSResourceAttributes::erase(const_iterator pos) -> iterator
+        {
+            return iterator{ m_values.erase(pos.m_cur) };
+        }
+
         bool RCSResourceAttributes::contains(const std::string& key) const
         {
             return m_values.find(key) != m_values.end();
         }
 
-        bool RCSResourceAttributes::empty() const
+        bool RCSResourceAttributes::empty() const noexcept
         {
             return m_values.empty();
         }
 
-        size_t RCSResourceAttributes::size() const
+        size_t RCSResourceAttributes::size() const noexcept
         {
             return m_values.size();
         }
@@ -600,5 +702,6 @@ namespace OIC
 
             return replacedList;
         }
+
     }
 }