BuildRequires: cmake
BuildRequires: pkgconfig(sqlite3)
+BuildRequires: pkgconfig(glib-2.0)
%description
The package provides libConfig library.
%post -p /sbin/ldconfig
-%postun -p /sbin/ldconfig
\ No newline at end of file
+%postun -p /sbin/ldconfig
SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY VERSION ${_LIB_VERSION_})
## Link libraries #############################################################
-PKG_CHECK_MODULES(CONFIG_DEPS REQUIRED sqlite3)
+PKG_CHECK_MODULES(CONFIG_DEPS REQUIRED sqlite3 glib-2.0)
INCLUDE_DIRECTORIES(${SRC_FOLDER})
INCLUDE_DIRECTORIES(SYSTEM ${CONFIG_DEPS_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} ${CONFIG_DEPS_LIBRARIES})
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Mateusz Malicki (m.malicki2@samsung.com)
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * @author Mateusz Malicki (m.malicki2@samsung.com)
+ * @brief GVariant visitor
+ */
+
+#ifndef CONFIG_FROM_GVARIANT_VISITOR_HPP
+#define CONFIG_FROM_GVARIANT_VISITOR_HPP
+
+#include "config/is-visitable.hpp"
+#include "config/exception.hpp"
+#include "config/is-union.hpp"
+
+#include <string>
+#include <vector>
+#include <cassert>
+#include <glib.h>
+
+namespace config {
+
+class FromGVariantVisitor {
+public:
+ explicit FromGVariantVisitor(GVariant* variant)
+ {
+ //Assume that the visited object is not a union
+ checkType(variant, G_VARIANT_TYPE_TUPLE);
+ mIter = g_variant_iter_new(variant);
+ }
+
+ FromGVariantVisitor(const FromGVariantVisitor& visitor)
+ : mIter(g_variant_iter_copy(visitor.mIter))
+ {
+ }
+
+ ~FromGVariantVisitor()
+ {
+ g_variant_iter_free(mIter);
+ }
+
+ FromGVariantVisitor& operator=(const FromGVariantVisitor&) = delete;
+
+ template<typename T>
+ void visit(const std::string& name, T& value)
+ {
+ GVariant* child = g_variant_iter_next_value(mIter);
+ if (child == NULL) {
+ throw config::ConfigException(
+ "GVariant doesn't match with config. Can't set '" + name + "'");
+ }
+ fromGVariant(child, value);
+ g_variant_unref(child);
+ }
+
+private:
+ GVariantIter* mIter;
+
+ explicit FromGVariantVisitor(GVariant* variant, bool isUnion)
+ {
+ if (isUnion) {
+ checkType(variant, G_VARIANT_TYPE_VARIANT);
+ variant = g_variant_get_variant(variant);
+ }
+ checkType(variant, G_VARIANT_TYPE_TUPLE);
+ mIter = g_variant_iter_new(variant);
+ }
+
+ static void checkType(GVariant* object, const GVariantType* type)
+ {
+ if (!g_variant_is_of_type(object, type)) {
+ throw ConfigException("Invalid field type");
+ }
+ }
+
+ static void fromGVariant(GVariant* object, int& value)
+ {
+ checkType(object, G_VARIANT_TYPE_INT32);
+ value = g_variant_get_int32(object);
+ }
+
+ static void fromGVariant(GVariant* object, std::int64_t& value)
+ {
+ checkType(object, G_VARIANT_TYPE_INT64);
+ value = g_variant_get_int64(object);
+ }
+
+ static void fromGVariant(GVariant* object, bool& value)
+ {
+ checkType(object, G_VARIANT_TYPE_BOOLEAN);
+ value = g_variant_get_boolean(object);
+ }
+
+ static void fromGVariant(GVariant* object, double& value)
+ {
+ checkType(object, G_VARIANT_TYPE_DOUBLE);
+ value = g_variant_get_double(object);
+ }
+
+ static void fromGVariant(GVariant* object, std::string& value)
+ {
+ checkType(object, G_VARIANT_TYPE_STRING);
+ value = g_variant_get_string(object, NULL);
+ }
+
+ template<typename T>
+ static void fromGVariant(GVariant* object, std::vector<T>& value)
+ {
+ checkType(object, G_VARIANT_TYPE_ARRAY);
+ GVariantIter iter;
+ g_variant_iter_init(&iter, object);
+ int length = g_variant_iter_n_children(&iter);
+ value.resize(static_cast<size_t>(length));
+ for (int i = 0; i < length; ++i) {
+ GVariant* child = g_variant_iter_next_value(&iter);
+ assert(child != NULL);
+ fromGVariant(child, value[static_cast<size_t>(i)]);
+ g_variant_unref(child);
+ }
+ }
+
+ template<typename T>
+ static typename std::enable_if<isVisitable<T>::value>::type
+ fromGVariant(GVariant* object, T& value)
+ {
+ FromGVariantVisitor visitor(object, isUnion<T>::value);
+ value.accept(visitor);
+ }
+
+};
+
+} // namespace config
+
+#endif // CONFIG_FROM_GVARIANT_VISITOR_HPP
#ifndef CONFIG_MANAGER_HPP
#define CONFIG_MANAGER_HPP
+#include "config/to-gvariant-visitor.hpp"
#include "config/to-json-visitor.hpp"
#include "config/to-kvstore-visitor.hpp"
#include "config/to-fdstore-visitor.hpp"
+#include "config/from-gvariant-visitor.hpp"
#include "config/from-json-visitor.hpp"
#include "config/from-kvstore-visitor.hpp"
#include "config/from-fdstore-visitor.hpp"
#include "config/from-kvjson-visitor.hpp"
#include "config/fs-utils.hpp"
-
+#include "config/is-union.hpp"
namespace config {
/**
+ * Fills the configuration with data stored in the GVariant
+ *
+ * @param gvariant configuration in GVariant type
+ * @param config visitable structure to fill
+ */
+template <class Config>
+void loadFromGVariant(GVariant* gvariant, Config& config)
+{
+ static_assert(isVisitable<Config>::value, "Use CONFIG_REGISTER macro");
+ static_assert(!isUnion<Config>::value, "Don't use CONFIG_DECLARE_UNION in top level config");
+
+ FromGVariantVisitor visitor(gvariant);
+ config.accept(visitor);
+}
+
+/**
+ * Saves the config in a GVariant
+ *
+ * @param config visitable structure to convert
+ */
+template <class Config>
+GVariant* saveToGVariant(const Config& config)
+{
+ static_assert(isVisitable<Config>::value, "Use CONFIG_REGISTER macro");
+ static_assert(!isUnion<Config>::value, "Don't use CONFIG_DECLARE_UNION in top level config");
+
+ ToGVariantVisitor visitor;
+ config.accept(visitor);
+ return visitor.toVariant();
+}
+
+/**
* Fills the configuration with data stored in the json string
*
* @param jsonString configuration in a json format
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Mateusz Malicki (m.malicki2@samsung.com)
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * @author Mateusz Malicki (m.malicki2@samsung.com)
+ * @brief GVariant visitor
+ */
+
+#ifndef CONFIG_TO_GVARIANT_VISITOR_HPP
+#define CONFIG_TO_GVARIANT_VISITOR_HPP
+
+#include "config/is-visitable.hpp"
+#include "config/is-union.hpp"
+
+#include <string>
+#include <vector>
+#include <glib.h>
+
+namespace config {
+
+class ToGVariantVisitor {
+
+public:
+ ToGVariantVisitor()
+ : mBuilder(g_variant_builder_new(G_VARIANT_TYPE_TUPLE))
+ {
+ }
+
+ ToGVariantVisitor(const ToGVariantVisitor& visitor)
+ : mBuilder(visitor.mBuilder ? g_variant_builder_ref(visitor.mBuilder) : nullptr)
+ {
+ }
+
+ ~ToGVariantVisitor()
+ {
+ if (mBuilder) {
+ g_variant_builder_unref(mBuilder);
+ }
+ }
+
+ ToGVariantVisitor& operator=(const ToGVariantVisitor&) = delete;
+
+ GVariant* toVariant()
+ {
+ if (mBuilder) {
+ GVariant* ret = g_variant_builder_end(mBuilder);
+ g_variant_builder_unref(mBuilder);
+ mBuilder = nullptr;
+ return ret;
+ }
+ return nullptr;
+ }
+
+ template<typename T>
+ void visit(const std::string& /* name */, const T& value)
+ {
+ writeInternal(value);
+ }
+private:
+ GVariantBuilder* mBuilder;
+
+ void writeInternal(std::int32_t value) { add("i", value); };
+ void writeInternal(std::int64_t value) { add("x", value); };
+ void writeInternal(bool value) { add("b", value); };
+ void writeInternal(double value) { add("d", value); };
+ void writeInternal(const std::string& value) { add("s", value.c_str()); };
+
+ template<typename T>
+ void writeInternal(const std::vector<T>& value)
+ {
+ if (!value.empty()) {
+ g_variant_builder_open(mBuilder, G_VARIANT_TYPE_ARRAY);
+ for (const T& v : value) {
+ writeInternal(v);
+ }
+ g_variant_builder_close(mBuilder);
+ } else {
+ g_variant_builder_add(mBuilder, "as", NULL);
+ }
+ }
+
+ template<typename T>
+ typename std::enable_if<isVisitable<T>::value && !isUnion<T>::value>::type
+ writeInternal(const T& value)
+ {
+ ToGVariantVisitor visitor;
+ value.accept(visitor);
+ g_variant_builder_add_value(mBuilder, visitor.toVariant());
+ }
+
+ template<typename T>
+ typename std::enable_if<isVisitable<T>::value && isUnion<T>::value>::type
+ writeInternal(const T& value)
+ {
+ ToGVariantVisitor visitor;
+ value.accept(visitor);
+ add("v", visitor.toVariant());
+ }
+
+ template<typename Value>
+ void add(const char* type, Value value) {
+ g_variant_builder_add(mBuilder, type, value);
+ }
+};
+
+} // namespace config
+
+#endif // CONFIG_TO_GVARIANT_VISITOR_HPP