-#ifndef CONFIG_FROM_KVJSON_VISITOR_HPP
-#define CONFIG_FROM_KVJSON_VISITOR_HPP
-
/*
* Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
*
* @brief KVStore visitor with defaults values from json
*/
-#include "config/manager.hpp"
+#ifndef CONFIG_FROM_KVJSON_VISITOR_HPP
+#define CONFIG_FROM_KVJSON_VISITOR_HPP
+#include "config/from-kvstore-visitor.hpp"
+#include "config/is-union.hpp"
+#include <json/json.h>
namespace config {
FromKVJsonVisitor(const std::string& db, const std::string& json, const std::string& prefix)
: mStorePtr(new KVStore(db))
, mKeyPrefix(prefix)
+ , mIsUnion(false)
{
mObject = json_tokener_parse(json.c_str());
if (mObject == nullptr) {
}
}
+
~FromKVJsonVisitor() {
json_object_put(mObject);
}
FromKVJsonVisitor(const FromKVJsonVisitor& v) :
- mObject(json_object_get(v.mObject)),
+ mObject(v.mObject ? json_object_get(v.mObject) : nullptr),
mStorePtr(v.mStorePtr),
- mKeyPrefix(v.mKeyPrefix)
+ mKeyPrefix(v.mKeyPrefix),
+ mIsUnion(v.mIsUnion)
{
}
FromKVJsonVisitor& operator=(const FromKVJsonVisitor&) = delete;
std::shared_ptr<KVStore> mStorePtr;
std::string mKeyPrefix;
json_object* mObject;
+ bool mIsUnion;
// create visitor for field object (visitable object)
- FromKVJsonVisitor(const FromKVJsonVisitor& v, const std::string& name) :
- mStorePtr(v.mStorePtr)
+ FromKVJsonVisitor(const FromKVJsonVisitor& v, const std::string& name, const bool isUnion) :
+ mStorePtr(v.mStorePtr), mIsUnion(isUnion || v.mIsUnion)
{
- json_object* object;
- if (!json_object_object_get_ex(v.mObject, name.c_str(), &object)) {
- throw ConfigException("Missing json field " + key(mKeyPrefix, name));
- }
- mObject = json_object_get(object);
mKeyPrefix = key(v.mKeyPrefix, name);
+ json_object* object = nullptr;
+ if (v.mObject && !json_object_object_get_ex(v.mObject, name.c_str(), &object)) {
+ if (!mIsUnion)
+ throw ConfigException("Missing json field " + mKeyPrefix);
+ }
+ mObject = object ? json_object_get(object) : nullptr;
}
// create visitor for vector i-th element (visitable object)
- FromKVJsonVisitor(const FromKVJsonVisitor& v, int i) :
- mStorePtr(v.mStorePtr)
+ FromKVJsonVisitor(const FromKVJsonVisitor& v, int i, const bool isUnion) :
+ mStorePtr(v.mStorePtr), mIsUnion(isUnion || v.mIsUnion)
{
- json_object* object = json_object_array_get_idx(v.mObject, i);
- checkType(object, json_type_object);
- mObject = json_object_get(object);
mKeyPrefix = key(v.mKeyPrefix, std::to_string(i));
+ json_object* object = nullptr;
+ if (v.mObject) {
+ object = json_object_array_get_idx(v.mObject, i);
+ checkType(object, json_type_object);
+ }
+ mObject = object ? json_object_get(object) : nullptr;
}
template<typename T, typename std::enable_if<!isVisitable<T>::value, int>::type = 0>
void getValue(const std::string& name, T& t)
{
- json_object* object;
- if (!json_object_object_get_ex(mObject, name.c_str(), &object)) {
- throw ConfigException("Missing json field " + key(mKeyPrefix, name));
- }
std::string k = key(mKeyPrefix, name);
if (mStorePtr->exists(k)) {
t = mStorePtr->get<T>(k);
}
else {
+ json_object* object = nullptr;
+ if (mObject) {
+ json_object_object_get_ex(mObject, name.c_str(), &object);
+ }
+ if (!object) {
+ throw ConfigException("Missing json field " + key(mKeyPrefix, name));
+ }
fromJsonObject(object, t);
}
}
- template<typename T, typename std::enable_if<isVisitable<T>::value, int>::type = 0>
+ template<typename T, typename std::enable_if<isUnion<T>::value, int>::type = 0>
+ void getValue(const std::string& name, T& t)
+ {
+ FromKVJsonVisitor visitor(*this, name, true);
+ t.accept(visitor);
+ }
+
+ template<typename T, typename std::enable_if<isVisitable<T>::value && !isUnion<T>::value, int>::type = 0>
void getValue(const std::string& name, T& t)
{
- FromKVJsonVisitor visitor(*this, name);
+ FromKVJsonVisitor visitor(*this, name, false);
t.accept(visitor);
}
if (mStorePtr->exists(name)) {
return mStorePtr->get<int>(name);
}
- return json_object_array_length(object);
+ if (object) {
+ return json_object_array_length(object);
+ }
+ return -1;
}
template<typename T>
void getValue(const std::string& name, std::vector<T>& value)
{
- json_object* object;
- if (!json_object_object_get_ex(mObject, name.c_str(), &object)) {
- throw ConfigException("Missing json field " + key(mKeyPrefix, name));
+ json_object* object = nullptr;
+ if (mObject && json_object_object_get_ex(mObject, name.c_str(), &object)) {
+ checkType(object, json_type_array);
}
- checkType(object, json_type_array);
std::string k = key(mKeyPrefix, name);
int length = getArraySize(k, object);
+ if (length < 0) {
+ throw ConfigException("Missing json field " + key(mKeyPrefix, name));
+ }
value.resize(static_cast<size_t>(length));
- FromKVJsonVisitor visitor(*this, name);
+ FromKVJsonVisitor visitor(*this, name, false);
for (int i = 0; i < length; ++i) {
visitor.getValue(i, value[i]);
}
template<typename T, typename std::enable_if<!isVisitable<T>::value, int>::type = 0>
void getValue(int i, T& t)
{
- json_object* object = json_object_array_get_idx(mObject, i);
std::string k = key(mKeyPrefix, std::to_string(i));
if (mStorePtr->exists(k)) {
t = mStorePtr->get<T>(k);
}
else {
+ json_object* object = mObject ? json_object_array_get_idx(mObject, i) : nullptr;
+ if (!object) {
+ throw ConfigException("Missing json array elem " + k);
+ }
fromJsonObject(object, t);
}
}
- template<typename T, typename std::enable_if<isVisitable<T>::value, int>::type = 0>
+ template<typename T, typename std::enable_if<isUnion<T>::value, int>::type = 0>
+ void getValue(int i, T& t)
+ {
+ FromKVJsonVisitor visitor(*this, i, true);
+ t.accept(visitor);
+ }
+
+ template<typename T, typename std::enable_if<isVisitable<T>::value && !isUnion<T>::value, int>::type = 0>
void getValue(int i, T& t)
{
- FromKVJsonVisitor visitor(*this, i);
+ FromKVJsonVisitor visitor(*this, i, false);
t.accept(visitor);
}
std::string k = key(mKeyPrefix, std::to_string(i));
int length = getArraySize(k, mObject);
value.resize(static_cast<size_t>(length));
- FromKVJsonVisitor visitor(*this, i);
+ FromKVJsonVisitor visitor(*this, i, false);
for (int i = 0; i < length; ++i) {
visitor.getValue(i, value[i]);
}
--- /dev/null
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Piotr Bartosiewicz (p.bartosiewi@partner.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 Krzysztof Dynowski (k.dynowski@samsumg.com)
+ * @brief Internal configuration helper
+ */
+
+#ifndef CONFIG_IS_UNION_HPP
+#define CONFIG_IS_UNION_HPP
+
+#include "config/is-visitable.hpp"
+
+namespace config {
+
+// generic member checker, start
+template <typename T, typename F>
+struct has_member_impl {
+ template <typename C>
+ static std::true_type check(typename F::template checker__<C>* =0);
+
+ template <typename C>
+ static std::false_type check(...);
+
+ static const bool value = std::is_same<decltype(check<T>(0)), std::true_type>::value;
+};
+
+template <typename T, typename F>
+struct has_member : public std::integral_constant<bool, has_member_impl<T, F>::value> {};
+// generic member checker, end
+
+
+template <typename X>
+struct check_union : isVisitable<X> {
+ template <typename T,
+ //list of function union must implement
+ const X& (T::*)() const = &T::as,
+ X& (T::*)(const X& src) = &T::set,
+ bool (T::*)() = &T::isSet
+ >
+ struct checker__ {};
+};
+template<typename T>
+struct isUnion : has_member<T, check_union<T>> {};
+
+//Note:
+// unfortunately, above generic has_member can't be used for isVisitable
+// because Vistable need 'accept' OR 'accept const', while has_member make exect match
+// e.g accept AND accept const
+
+} // namespace config
+
+#endif // CONFIG_FROM_KVJSON_VISITOR_HPP
+