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;
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.
*
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>
#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;
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.
*/
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);
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.
*
*/
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));
}
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.
*
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;
};
}
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))
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();
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();
}
}
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;
}
}
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);
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
/* 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);
case 12:
/* Line 1806 of yacc.c */
-#line 137 "config_parser.yy"
+#line 136 "config_parser.yy"
{
m_Abstract = true;
}
case 13:
/* Line 1806 of yacc.c */
-#line 141 "config_parser.yy"
+#line 140 "config_parser.yy"
{
m_Local = true;
}
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));
case 19:
/* Line 1806 of yacc.c */
-#line 162 "config_parser.yy"
+#line 161 "config_parser.yy"
{
m_ExpressionLists.push(boost::make_shared<ExpressionList>());
}
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();
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));
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));
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));
case 33:
/* Line 1806 of yacc.c */
-#line 217 "config_parser.yy"
+#line 216 "config_parser.yy"
{
(yyval.op) = (yyvsp[(1) - (1)].op);
}
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));
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));
}
case 36:
/* Line 1806 of yacc.c */
-#line 232 "config_parser.yy"
+#line 231 "config_parser.yy"
{
(yyval.variant) = new Variant();
}
case 38:
/* Line 1806 of yacc.c */
-#line 239 "config_parser.yy"
+#line 238 "config_parser.yy"
{
(yyval.variant) = (yyvsp[(1) - (1)].variant);
}
/* 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
/* Line 2067 of yacc.c */
-#line 243 "config_parser.yy"
+#line 242 "config_parser.yy"
}
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);
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;
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()) {
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());
}
}
*/
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;
}