]> granicus.if.org Git - icinga2/commitdiff
Cleaned up the Variant class.
authorGunnar Beutner <gunnar.beutner@netways.de>
Wed, 11 Jul 2012 18:55:46 +0000 (20:55 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Wed, 11 Jul 2012 18:55:46 +0000 (20:55 +0200)
13 files changed:
base/application.cpp
base/dictionary.h
base/i2-base.h
base/utility.cpp
base/utility.h
base/variant.cpp
base/variant.h
components/convenience/conveniencecomponent.cpp
components/discovery/discoverycomponent.cpp
dyn/config_parser.cc
dyn/config_parser.yy
dyn/expression.cpp
jsonrpc/messagepart.cpp

index c373b0c25b6c252431a4226aa290c8a9857cf3f6..b2730d91c0db45ece4b2c2dbc20630f9a7a30f44 100644 (file)
@@ -400,7 +400,7 @@ int Application::Run(int argc, char **argv)
                        Application::m_Instance.reset();
 
                        Logger::Write(LogCritical, "base", "---");
-                       Logger::Write(LogCritical, "base", "Exception: " + Utility::GetTypeName(ex));
+                       Logger::Write(LogCritical, "base", "Exception: " + Utility::GetTypeName(typeid(ex)));
                        Logger::Write(LogCritical, "base", "Message: " + string(ex.what()));
 
                        return EXIT_FAILURE;
index 4aa17f9872d04c1ba05b603737c74665614e9ebe..d6c7f490f36eb6a3b42f068be636f3f5c21fccac 100644 (file)
@@ -57,27 +57,6 @@ public:
                return true;
        }
 
-       /**
-        * Retrieves a value from the dictionary.
-        *
-        * @param key The key.
-        * @param[out] value Pointer to the value.
-        * @returns true if the value was retrieved, false otherwise.
-        */
-       bool Get(const string& key, Dictionary::Ptr *value)
-       {
-               Object::Ptr object;
-
-               if (!Get(key, &object))
-                       return false;
-
-               *value = dynamic_pointer_cast<Dictionary>(object);
-               if (!*value)
-                       throw runtime_error("Object is not a dictionary.");
-
-               return true;
-       }
-
        /**
         * Sets a value in the dictionary.
         *
index eddb501d851da7e25a0d8f876844e20be2566c0c..29ee50d59c258b1c27e2bcc230c119a4c7379706 100644 (file)
@@ -108,11 +108,14 @@ using std::ostream;
 using std::ofstream;
 
 using std::exception;
+using std::bad_cast;
 using std::runtime_error;
 using std::logic_error;
 using std::invalid_argument;
 using std::domain_error;
 
+using std::type_info;
+
 #include <boost/smart_ptr.hpp>
 #include <boost/make_shared.hpp>
 #include <boost/bind.hpp>
@@ -121,6 +124,8 @@ using std::domain_error;
 #include <boost/algorithm/string/trim.hpp>
 #include <boost/algorithm/string/split.hpp>
 #include <boost/thread.hpp>
+#include <boost/variant.hpp>
+#include <boost/lexical_cast.hpp>
 
 using boost::shared_ptr;
 using boost::weak_ptr;
index 2a078d77fd57bc967316029d49dc50ff724198a5..4c63066eec40154cbe034251b217777fed68d9b5 100644 (file)
@@ -24,6 +24,30 @@ using namespace icinga;
 
 bool I2_EXPORT Utility::m_SSLInitialized = false;
 
+/**
+ * Returns a human-readable type name of a type_info object.
+ *
+ * @param ti A type_info object.
+ * @returns The type name of the object.
+ */
+string Utility::GetTypeName(const type_info& ti)
+{
+       string klass = ti.name();
+
+#ifdef HAVE_GCC_ABI_DEMANGLE
+       int status;
+       char *realname = abi::__cxa_demangle(klass.c_str(), 0, 0, &status);
+
+       if (realname != NULL) {
+               klass = string(realname);
+               free(realname);
+       }
+#endif /* HAVE_GCC_ABI_DEMANGLE */
+
+       return klass;
+}
+
+
 /**
  * Detaches from the controlling terminal.
  */
index bf9b082336ada9653c23fe4e292641ecb99ebeb1..4370be683d68fca330431f4151017ce375a2d47d 100644 (file)
@@ -31,29 +31,7 @@ namespace icinga
 class I2_BASE_API Utility
 {
 public:
-       /**
-        * Returns a human-readable type name of an object (using RTTI).
-        *
-        * @param value An object.
-        * @returns The type name of the object.
-        */
-       template<class T>
-       static string GetTypeName(const T& value)
-       {
-               string klass = typeid(value).name();
-
-#ifdef HAVE_GCC_ABI_DEMANGLE
-               int status;
-               char *realname = abi::__cxa_demangle(klass.c_str(), 0, 0, &status);
-
-               if (realname != NULL) {
-                       klass = string(realname);
-                       free(realname);
-               }
-#endif /* HAVE_GCC_ABI_DEMANGLE */
-
-               return klass;
-       }
+       static string GetTypeName(const type_info& ti);
 
        static void Daemonize(void);
 
index f1956d416b51078630b6a16aa972547640afe3c3..330989a7455377db24eb41db4486156ec88a39ea 100644 (file)
 
 using namespace icinga;
 
-/**
- * Converts the variant's value to a new type.
- *
- * @param newType The new type of the variant.
- */
-void Variant::Convert(VariantType newType) const
-{
-       if (newType == m_Type)
-               return;
-
-       if (m_Type == VariantString && newType == VariantInteger) {
-               m_IntegerValue = strtol(m_StringValue.c_str(), NULL, 10);
-               m_Type = VariantInteger;
-
-               return;
-       }
-
-       if (m_Type == VariantInteger && newType == VariantString) {
-               stringstream sbuf;
-               sbuf << m_IntegerValue;
-               m_StringValue = sbuf.str();
-               m_Type = VariantString;
-
-               return;
-       }
-
-       // TODO: convert variant data
-       throw runtime_error("Invalid variant conversion.");
-}
-
-/**
- * Retrieves the variant value's type.
- *
- * @returns The variant's type.
- */
-VariantType Variant::GetType(void) const
-{
-       return m_Type;
-}
-
-/**
- * Retrieves the variant's value as an integer.
- *
- * @returns The variant's value as an integer.
- */
-long Variant::GetInteger(void) const
-{
-       Convert(VariantInteger);
-
-       return m_IntegerValue;
-}
-
-/**
- * Retrieves the variant's value as a bool.
- *
- * @returns The variant's value as a bool.
- */
-bool Variant::GetBool(void) const
-{
-       Convert(VariantInteger);
-
-       return (m_IntegerValue != 0);
-}
-
-/**
- * Retrieves the variant's value as a string.
- *
- * @returns The variant's value as a string.
- */
-string Variant::GetString(void) const
-{
-       Convert(VariantString);
-
-       return m_StringValue;
-}
-
-/**
- * Retrieves the variant's value as an object.
- *
- * @returns The variant's value as an object.
- */
-Object::Ptr Variant::GetObject(void) const
-{
-       Convert(VariantObject);
-
-       return m_ObjectValue;
-}
-
 /**
  * Checks whether the variant is empty.
  *
@@ -116,45 +28,15 @@ Object::Ptr Variant::GetObject(void) const
  */
 bool Variant::IsEmpty(void) const
 {
-       return (m_Type == VariantEmpty);
+       return (m_Value.empty());
 }
 
-/**
- * Retrieves the variant's value as an integer.
- *
- * @returns The variant's value as an integer.
- */
-Variant::operator long(void) const
+bool Variant::IsScalar(void) const
 {
-       return GetInteger();
+       return !IsEmpty() && !IsObject();
 }
 
-/**
- * Retrieves the variant's value as a bool.
- *
- * @returns The variant's value as a bool.
- */
-Variant::operator bool(void) const
-{
-       return GetBool();
-}
-
-/**
- * Retrieves the variant's value as a string.
- *
- * @returns The variant's value as a string.
- */
-Variant::operator string(void) const
-{
-       return GetString();
-}
-
-/**
- * Retrieves the variant's value as an object.
- *
- * @returns The variant's value as an object.
- */
-Variant::operator Object::Ptr(void) const
+bool Variant::IsObject(void) const
 {
-       return GetObject();
+       return !IsEmpty() && (m_Value.type() == typeid(Object::Ptr));
 }
index 19db37a76508fe02775e4ec425d898bc4d917bfb..4889518a57011db98cf197d9eec99e511eb404b4 100644 (file)
 namespace icinga
 {
 
-/**
- * The type of a Variant object.
- *
- * @ingroup base
- */
-enum VariantType
-{
-       VariantEmpty, /**< Denotes that the Variant is empty. */
-       VariantInteger, /**< Denotes that the Variant is holding an integer. */
-       VariantString, /**< Denotes that the Variant is holding a string. */
-       VariantObject /**< Denotes that the Variant is holding an object
-                          that inherits from the Object class. */
-};
-
 /**
  * A type that can hold an arbitrary value.
  *
@@ -45,52 +31,81 @@ enum VariantType
 class I2_BASE_API Variant
 {
 public:
-       inline Variant(void) : m_Type(VariantEmpty) { }
+       inline Variant(void)
+               : m_Value()
+       { }
 
-       inline Variant(int value)
-           : m_Type(VariantInteger), m_IntegerValue(value) { }
+       inline Variant(double value)
+               : m_Value(value)
+       { }
 
-       inline Variant(bool value)
-           : m_Type(VariantInteger), m_IntegerValue(value ? 1 : 0) { }
-
-       inline Variant(long value)
-           : m_Type(VariantInteger), m_IntegerValue(value) { }
+       inline Variant(const string& value)
+               : m_Value(value)
+       { }
 
        inline Variant(const char *value)
-           : m_Type(VariantString), m_StringValue(string(value)) { }
+               : m_Value(string(value))
+       { }
 
-       inline Variant(string value)
-           : m_Type(VariantString), m_StringValue(value) { }
+       template<typename T>
+       inline Variant(const shared_ptr<T>& value)
+       {
+               Object::Ptr object = dynamic_pointer_cast<Object>(value);
+
+               if (!object)
+                       throw invalid_argument("shared_ptr value type must inherit from Object class.");
+
+               m_Value = object;
+       }
+
+       operator double(void) const
+       {
+               if (m_Value.type() != typeid(double)) {
+                       double result = boost::lexical_cast<double>(m_Value);
+                       m_Value = result;
+                       return result;
+               } else {
+                       return boost::get<double>(m_Value);
+               }
+       }
+
+       operator string(void) const
+       {
+               if (m_Value.type() != typeid(string)) {
+                       string result = boost::lexical_cast<string>(m_Value);
+                       m_Value = result;
+                       return result;
+               } else {
+                       return boost::get<string>(m_Value);
+               }
+       }
 
        template<typename T>
-       Variant(const shared_ptr<T>& value)
-           : m_Type(VariantObject), m_ObjectValue(value) { }
+       operator shared_ptr<T>(void) const
+       {
+               shared_ptr<T> object = dynamic_pointer_cast<T>(boost::get<Object::Ptr>(m_Value));
 
-       VariantType GetType(void) const;
+               if (!object)
+                       throw bad_cast();
 
-       long GetInteger(void) const;
-       bool GetBool(void) const;
-       string GetString(void) const;
-       Object::Ptr GetObject(void) const;
+               return object;
+       }
 
        bool IsEmpty(void) const;
+       bool IsScalar(void) const;
+       bool IsObject(void) const;
 
-       operator long(void) const;
-       operator bool(void) const;
-       operator string(void) const;
-       operator Object::Ptr(void) const;
-
-private:
-       mutable VariantType m_Type; /**< The type of the Variant. */
+       template<typename T>
+       bool IsObjectType(void) const
+       {
+               if (!IsObject())
+                       return false;
 
-       mutable long m_IntegerValue; /**< The value of the Variant
-                                         if m_Type == VariantInteger */
-       mutable string m_StringValue; /**< The value of the Variant
-                                          if m_Type == VariantString */
-       mutable Object::Ptr m_ObjectValue; /**< The value of the Variant
-                                               if m_Type == VariantObject */
+               return (dynamic_pointer_cast<T>(boost::get<Object::Ptr>(m_Value)));
+       }
 
-       void Convert(VariantType newType) const;
+private:
+       mutable boost::variant<double, string, Object::Ptr> m_Value;
 };
 
 }
index 733fe29aa8f8abf94f1eb4d7efea5b2d689f6588..0f32a63fc2c7e2917828abcf6ab50a8c22779ef1 100644 (file)
@@ -125,13 +125,10 @@ void ConvenienceComponent::HostCommittedHandler(const ConfigItem::Ptr& item)
 
                        CopyServiceAttributes(host, host->GetProperties(), builder);
 
-                       if (svcdesc.GetType() == VariantString) {
+                       if (svcdesc.IsScalar()) {
                                builder->AddParent(svcdesc);
-                       } else if (svcdesc.GetType() == VariantObject) {
-                               Dictionary::Ptr service = dynamic_pointer_cast<Dictionary>(svcdesc.GetObject());
-
-                               if (!service)
-                                       throw invalid_argument("Service description invalid.");
+                       } else if (svcdesc.IsObjectType<Dictionary>()) {
+                               Dictionary::Ptr service = svcdesc;
 
                                string parent;
                                if (!service->Get("service", &parent))
@@ -154,7 +151,7 @@ void ConvenienceComponent::HostCommittedHandler(const ConfigItem::Ptr& item)
        if (oldServices) {
                Dictionary::Iterator it;
                for (it = oldServices->Begin(); it != oldServices->End(); it++) {
-                       ConfigItem::Ptr service = static_pointer_cast<ConfigItem>(it->second.GetObject());
+                       ConfigItem::Ptr service = it->second;
 
                        if (!newServices->Contains(service->GetName()))
                                service->Unregister();
@@ -182,7 +179,7 @@ void ConvenienceComponent::HostRemovedHandler(const ConfigItem::Ptr& item)
 
        Dictionary::Iterator it;
        for (it = services->Begin(); it != services->End(); it++) {
-               ConfigItem::Ptr service = static_pointer_cast<ConfigItem>(it->second.GetObject());
+               ConfigItem::Ptr service = it->second;
                service->Unregister();
        }
 }
index f240d28bc445497f99de07308e9e1298867eef3e..2b7102e3b95d78b6e699f0a32c15ee933cd1b867 100644 (file)
@@ -327,16 +327,12 @@ bool DiscoveryComponent::HasMessagePermission(const Dictionary::Ptr& roles, cons
        for (ConfigObject::TMap::Iterator ip = range.first; ip != range.second; ip++) {
                ConfigObject::Ptr role = ip->second;
 
-               Object::Ptr object;
-               if (!role->GetProperty(messageType, &object))
+               Dictionary::Ptr permissions;
+               if (!role->GetProperty(messageType, &permissions))
                        continue;
 
-               Dictionary::Ptr permissions = dynamic_pointer_cast<Dictionary>(object);
-               if (!permissions)
-                       throw runtime_error("Object is not a dictionary.");
-
                for (Dictionary::Iterator is = permissions->Begin(); is != permissions->End(); is++) {
-                       if (Utility::Match(is->second.GetString(), message))
+                       if (Utility::Match(is->second, message))
                                return true;
                }
        }
@@ -372,14 +368,8 @@ void DiscoveryComponent::ProcessDiscoveryMessage(const string& identity, const D
 
        ConfigObject::Ptr endpointConfig = ConfigObject::GetObject("endpoint", identity);
        Dictionary::Ptr roles;
-       if (endpointConfig) {
-               Object::Ptr object;
-               if (endpointConfig->GetProperty("roles", &object)) {
-                       roles = dynamic_pointer_cast<Dictionary>(object);
-                       if (!roles)
-                               throw runtime_error("Object is not a dictionary.");
-               }
-       }
+       if (endpointConfig)
+               endpointConfig->GetProperty("roles", &roles);
 
        Endpoint::Ptr endpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(identity);
 
index 55e9c5b900befd8429306dc3380b860a933831c7..4676d4203d61a8b0ee5b8b79765ad6265474de40 100644 (file)
@@ -535,9 +535,9 @@ static const yytype_int8 yyrhs[] =
 static const yytype_uint8 yyrline[] =
 {
        0,    94,    94,    95,    98,    98,   101,   107,   112,   107,
-     132,   133,   136,   140,   146,   147,   150,   157,   158,   162,
-     161,   173,   174,   176,   177,   178,   181,   189,   203,   212,
-     213,   214,   215,   216,   222,   227,   231,   237,   238
+     131,   132,   135,   139,   145,   146,   149,   156,   157,   161,
+     160,   172,   173,   175,   176,   177,   180,   188,   202,   211,
+     212,   213,   214,   215,   221,   226,   230,   236,   237
 };
 #endif
 
@@ -1582,9 +1582,8 @@ yyreduce:
 /* Line 1806 of yacc.c  */
 #line 118 "config_parser.yy"
     {
-               Object::Ptr exprl_object = *(yyvsp[(8) - (8)].variant);
+               ExpressionList::Ptr exprl = *(yyvsp[(8) - (8)].variant);
                delete (yyvsp[(8) - (8)].variant);
-               ExpressionList::Ptr exprl = dynamic_pointer_cast<ExpressionList>(exprl_object);
 
                m_Item->AddExpressionList(exprl);
                m_Item->SetLocal(m_Local);
@@ -1598,7 +1597,7 @@ yyreduce:
   case 12:
 
 /* Line 1806 of yacc.c  */
-#line 137 "config_parser.yy"
+#line 136 "config_parser.yy"
     {
                m_Abstract = true;
        }
@@ -1607,7 +1606,7 @@ yyreduce:
   case 13:
 
 /* Line 1806 of yacc.c  */
-#line 141 "config_parser.yy"
+#line 140 "config_parser.yy"
     {
                m_Local = true;
        }
@@ -1616,7 +1615,7 @@ yyreduce:
   case 16:
 
 /* Line 1806 of yacc.c  */
-#line 151 "config_parser.yy"
+#line 150 "config_parser.yy"
     {
                m_Item->AddParent((yyvsp[(1) - (1)].text));
                free((yyvsp[(1) - (1)].text));
@@ -1626,7 +1625,7 @@ yyreduce:
   case 19:
 
 /* Line 1806 of yacc.c  */
-#line 162 "config_parser.yy"
+#line 161 "config_parser.yy"
     {
                m_ExpressionLists.push(boost::make_shared<ExpressionList>());
        }
@@ -1635,7 +1634,7 @@ yyreduce:
   case 20:
 
 /* Line 1806 of yacc.c  */
-#line 167 "config_parser.yy"
+#line 166 "config_parser.yy"
     {
                (yyval.variant) = new Variant(m_ExpressionLists.top());
                m_ExpressionLists.pop();
@@ -1645,7 +1644,7 @@ yyreduce:
   case 26:
 
 /* Line 1806 of yacc.c  */
-#line 182 "config_parser.yy"
+#line 181 "config_parser.yy"
     {
                Expression expr((yyvsp[(1) - (3)].text), (yyvsp[(2) - (3)].op), *(yyvsp[(3) - (3)].variant), yylloc);
                free((yyvsp[(1) - (3)].text));
@@ -1658,7 +1657,7 @@ yyreduce:
   case 27:
 
 /* Line 1806 of yacc.c  */
-#line 190 "config_parser.yy"
+#line 189 "config_parser.yy"
     {
                Expression subexpr((yyvsp[(3) - (6)].text), (yyvsp[(5) - (6)].op), *(yyvsp[(6) - (6)].variant), yylloc);
                free((yyvsp[(3) - (6)].text));
@@ -1677,7 +1676,7 @@ yyreduce:
   case 28:
 
 /* Line 1806 of yacc.c  */
-#line 204 "config_parser.yy"
+#line 203 "config_parser.yy"
     {
                Expression expr((yyvsp[(1) - (1)].text), OperatorSet, (yyvsp[(1) - (1)].text), yylloc);
                free((yyvsp[(1) - (1)].text));
@@ -1689,7 +1688,7 @@ yyreduce:
   case 33:
 
 /* Line 1806 of yacc.c  */
-#line 217 "config_parser.yy"
+#line 216 "config_parser.yy"
     {
                (yyval.op) = (yyvsp[(1) - (1)].op);
        }
@@ -1698,7 +1697,7 @@ yyreduce:
   case 34:
 
 /* Line 1806 of yacc.c  */
-#line 223 "config_parser.yy"
+#line 222 "config_parser.yy"
     {
                (yyval.variant) = new Variant((yyvsp[(1) - (1)].text));
                free((yyvsp[(1) - (1)].text));
@@ -1708,7 +1707,7 @@ yyreduce:
   case 35:
 
 /* Line 1806 of yacc.c  */
-#line 228 "config_parser.yy"
+#line 227 "config_parser.yy"
     {
                (yyval.variant) = new Variant((yyvsp[(1) - (1)].num));
        }
@@ -1717,7 +1716,7 @@ yyreduce:
   case 36:
 
 /* Line 1806 of yacc.c  */
-#line 232 "config_parser.yy"
+#line 231 "config_parser.yy"
     {
                (yyval.variant) = new Variant();
        }
@@ -1726,7 +1725,7 @@ yyreduce:
   case 38:
 
 /* Line 1806 of yacc.c  */
-#line 239 "config_parser.yy"
+#line 238 "config_parser.yy"
     {
                (yyval.variant) = (yyvsp[(1) - (1)].variant);
        }
@@ -1735,7 +1734,7 @@ yyreduce:
 
 
 /* Line 1806 of yacc.c  */
-#line 1739 "config_parser.cc"
+#line 1738 "config_parser.cc"
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -1973,6 +1972,6 @@ yyreturn:
 
 
 /* Line 2067 of yacc.c  */
-#line 243 "config_parser.yy"
+#line 242 "config_parser.yy"
 
 
index ec0312624569e847a8591f4ccd8237f4f4405502..98f2817f2c31cf0a48889195e5956d14f5ea7996 100644 (file)
@@ -116,9 +116,8 @@ attributes T_OBJECT T_IDENTIFIER T_STRING
        }
 inherits_specifier expressionlist
        {
-               Object::Ptr exprl_object = *$8;
+               ExpressionList::Ptr exprl = *$8;
                delete $8;
-               ExpressionList::Ptr exprl = dynamic_pointer_cast<ExpressionList>(exprl_object);
 
                m_Item->AddExpressionList(exprl);
                m_Item->SetLocal(m_Local);
index cbca7eb428e47b803e1f6473e5663b459dfaa95f..9dc5676465ab9a2191abefa6f72eb10c74e610a1 100644 (file)
@@ -32,10 +32,11 @@ void Expression::Execute(const Dictionary::Ptr& dictionary) const
 
        ExpressionList::Ptr valueExprl;
        Dictionary::Ptr valueDict;
-       if (m_Value.GetType() == VariantObject) {
-               valueExprl = dynamic_pointer_cast<ExpressionList>(m_Value.GetObject());
-               valueDict = dynamic_pointer_cast<Dictionary>(m_Value.GetObject());
-       }
+       if (m_Value.IsObjectType<ExpressionList>())
+               valueExprl = m_Value;
+
+       if (m_Value.IsObjectType<Dictionary>())
+               valueDict = m_Value;
 
        newValue = m_Value;
 
@@ -62,8 +63,8 @@ void Expression::Execute(const Dictionary::Ptr& dictionary) const
                case OperatorPlus:
                        dictionary->Get(m_Key, &oldValue);
 
-                       if (oldValue.GetType() == VariantObject)
-                               dict = dynamic_pointer_cast<Dictionary>(oldValue.GetObject());
+                       if (oldValue.IsObjectType<Dictionary>())
+                               dict = oldValue;
 
                        if (!dict) {
                                if (!oldValue.IsEmpty()) {
index 7b3a2ef7ed48236a8a0eb4eb35da4d1c0906efd7..994753a738b5f8ccb4b02e29535abc33f78e1c2d 100644 (file)
@@ -113,21 +113,15 @@ json_t *MessagePart::GetJsonFromDictionary(const Dictionary::Ptr& dictionary)
        json = cJSON_CreateObject();
 
        for (Dictionary::Iterator i = dictionary->Begin(); i != dictionary->End(); i++) {
-               switch (i->second.GetType()) {
-                       case VariantInteger:
-                               cJSON_AddNumberToObject(json, i->first.c_str(), i->second.GetInteger());
-                               break;
-                       case VariantString:
-                               valueString = i->second.GetString();
-                               cJSON_AddStringToObject(json, i->first.c_str(), valueString.c_str());
-                               break;
-                       case VariantObject:
-                               valueDictionary = dynamic_pointer_cast<Dictionary>(i->second.GetObject());
-
-                               if (valueDictionary)
-                                       cJSON_AddItemToObject(json, i->first.c_str(), GetJsonFromDictionary(valueDictionary));
-                       default:
-                               break;
+               if (i->second.IsScalar()) {
+                       valueString = static_cast<string>(i->second);
+                       cJSON_AddStringToObject(json, i->first.c_str(), valueString.c_str());
+               } else if (i->second.IsObjectType<Dictionary>()) {
+                       cJSON_AddItemToObject(json, i->first.c_str(), GetJsonFromDictionary(i->second));
+               } else {
+                       stringstream msgbuf;
+                       msgbuf << "Dictionary serialization: Ignored property '" << i->first << "' (unknown type)";
+                       Logger::Write(LogDebug, "jsonrpc", msgbuf.str());
                }
        }
 
@@ -178,14 +172,10 @@ Dictionary::Ptr MessagePart::GetDictionary(void) const
  */
 bool MessagePart::Get(string key, MessagePart *value) const
 {
-       Object::Ptr object;
-       if (!GetDictionary()->Get(key, &object))
+       Dictionary::Ptr dictionary;
+       if (!GetDictionary()->Get(key, &dictionary))
                return false;
 
-       Dictionary::Ptr dictionary = dynamic_pointer_cast<Dictionary>(object);
-       if (!dictionary)
-               throw runtime_error("Object is not a dictionary.");
-
        *value = MessagePart(dictionary);
        return true;
 }