From 189ffc6af272535a79c811f02d3fe5d1378925da Mon Sep 17 00:00:00 2001 From: Jacek Pielaszkiewicz Date: Fri, 13 Jun 2014 11:09:38 +0200 Subject: [PATCH 2/4] Initial repository spec file. Change-Id: I4adf7ae50df656a822ccf5ecec7e298a493ea5e9 Signed-off-by: Jacek Pielaszkiewicz --- packaging/libConfig.manifest | 5 +++++ packaging/libConfig.spec | 50 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 packaging/libConfig.manifest create mode 100644 packaging/libConfig.spec diff --git a/packaging/libConfig.manifest b/packaging/libConfig.manifest new file mode 100644 index 0000000..2a0cec5 --- /dev/null +++ b/packaging/libConfig.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/libConfig.spec b/packaging/libConfig.spec new file mode 100644 index 0000000..45a604f --- /dev/null +++ b/packaging/libConfig.spec @@ -0,0 +1,50 @@ +Name: libConfig +Version: 0.0.1 +Release: 0 +Source0: %{name}-%{version}.tar.gz +License: Apache-2.0 +Group: Security/Other +Summary: libConfig library. + +%description +The package provides libConfig library. + +%files +%manifest packaging/libConfig.manifest +%defattr(644,root,root,755) + +%package devel +Summary: libConfig development +Group: Development/Libraries + +%description devel +The package provides libConfig development tools and libs. + +%files devel +%defattr(644,root,root,755) + +%package tests +Summary: libConfig tests +Group: Development/Libraries + +%description tests +The package provides libConfig test tools. + +%files tests +%defattr(644,root,root,755) + +%prep +%setup -q + +%build + +%install + +%clean +rm -rf %{buildroot} + +%post + +%preun + +%postun -- 2.7.4 From 788dcdef0c508e820882f30ca23025efac5b9a68 Mon Sep 17 00:00:00 2001 From: Jacek Pielaszkiewicz Date: Tue, 17 Jun 2014 10:28:19 +0200 Subject: [PATCH 3/4] Initial library content. [Bug/Feature] Initial library content. [Cause] N/A [Solution] N/A [Verification] Build, install, run tests Change-Id: I0de77757b11c87099b5b0d915e30aeeff1becf61 Signed-off-by: Jacek Pielaszkiewicz --- CMakeLists.txt | 66 ++++++++++++++++++ packaging/libConfig.spec | 49 +++++++------- src/CMakeLists.txt | 35 ++++++++++ src/config/config.hpp | 59 ++++++++++++++++ src/config/exception.hpp | 44 ++++++++++++ src/config/fields.hpp | 76 +++++++++++++++++++++ src/config/from-json-visitor.hpp | 141 +++++++++++++++++++++++++++++++++++++++ src/config/is-visitable.hpp | 53 +++++++++++++++ src/config/manager.hpp | 127 +++++++++++++++++++++++++++++++++++ src/config/to-json-visitor.hpp | 122 +++++++++++++++++++++++++++++++++ src/libConfig.pc.in | 8 +++ 11 files changed, 757 insertions(+), 23 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 src/CMakeLists.txt create mode 100644 src/config/config.hpp create mode 100644 src/config/exception.hpp create mode 100644 src/config/fields.hpp create mode 100644 src/config/from-json-visitor.hpp create mode 100644 src/config/is-visitable.hpp create mode 100644 src/config/manager.hpp create mode 100644 src/config/to-json-visitor.hpp create mode 100644 src/libConfig.pc.in diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..2118f07 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,66 @@ +# Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved +# +# 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 CMakeLists.txt +# @author Jacek Pielaszkiewicz (j.pielaszkie@samsung.com) +# +CMAKE_MINIMUM_REQUIRED (VERSION 2.6.2) +PROJECT(Config) + +## pkgconfig ################################################################### +INCLUDE(FindPkgConfig) + +## default CMAKE_INSTALL_* variables ########################################### +INCLUDE(GNUInstallDirs) + +## Compiler flags, depending on the build type ################################# +IF(NOT CMAKE_BUILD_TYPE) + SET(CMAKE_BUILD_TYPE "DEBUG") +ENDIF(NOT CMAKE_BUILD_TYPE) +MESSAGE(STATUS "Build type: ${CMAKE_BUILD_TYPE}") + +# special case for a GCC < 4.7, assume rest is fine +IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7) + SET(CXX_11_STD "c++0x") +else() + SET(CXX_11_STD "c++11") +endif() + +SET(CMAKE_C_FLAGS_PROFILING "-g -O0 -pg") +SET(CMAKE_CXX_FLAGS_PROFILING "-g -std=${CXX_11_STD} -O0 -pg") +SET(CMAKE_C_FLAGS_DEBUG "-g -O0 -ggdb") +SET(CMAKE_CXX_FLAGS_DEBUG "-g -std=${CXX_11_STD} -O0 -ggdb") +SET(CMAKE_C_FLAGS_RELEASE "-g -O2 -DNDEBUG") +SET(CMAKE_CXX_FLAGS_RELEASE "-g -std=${CXX_11_STD} -O2 -DNDEBUG") +SET(CMAKE_C_FLAGS_CCOV "-g -O2 --coverage") +SET(CMAKE_CXX_FLAGS_CCOV "-g -std=${CXX_11_STD} -O2 --coverage") + +ADD_DEFINITIONS("-fPIC") # Position Independent Code +ADD_DEFINITIONS("-Werror") # Make all warnings into errors +ADD_DEFINITIONS("-Wall") # Generate all warnings +ADD_DEFINITIONS("-Wextra") # Generate even more extra warnings +ADD_DEFINITIONS("-pedantic") # Be pedantic +ADD_DEFINITIONS("-pedantic-errors") # Make pedantic warnings into errors +ADD_DEFINITIONS(-DPROGRAM_VERSION="${VERSION}") +ADD_DEFINITIONS(-DPROJECT_SOURCE_DIR="${PROJECT_SOURCE_DIR}") + +## Subdirectories ############################################################## +SET(SRC_FOLDER ${PROJECT_SOURCE_DIR}/src) + +IF(NOT DEFINED INCLUDE_INSTALL_DIR) + SET(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_FULL_INCLUDEDIR}) +ENDIF(NOT DEFINED INCLUDE_INSTALL_DIR) + +ADD_SUBDIRECTORY(${SRC_FOLDER}) diff --git a/packaging/libConfig.spec b/packaging/libConfig.spec index 45a604f..f65c1fb 100644 --- a/packaging/libConfig.spec +++ b/packaging/libConfig.spec @@ -1,50 +1,53 @@ +%define lib_version 0.0.1 + Name: libConfig -Version: 0.0.1 +Version: %{lib_version} Release: 0 Source0: %{name}-%{version}.tar.gz License: Apache-2.0 Group: Security/Other -Summary: libConfig library. +Summary: Config library + +BuildRequires: cmake %description The package provides libConfig library. -%files -%manifest packaging/libConfig.manifest -%defattr(644,root,root,755) - %package devel -Summary: libConfig development +Summary: Development package for config library Group: Development/Libraries +Requires: boost-devel +Requires: pkgconfig(libLogger) +Requires: libjson-devel %description devel The package provides libConfig development tools and libs. %files devel %defattr(644,root,root,755) - -%package tests -Summary: libConfig tests -Group: Development/Libraries - -%description tests -The package provides libConfig test tools. - -%files tests -%defattr(644,root,root,755) +%{_includedir}/sc-tools +%{_libdir}/pkgconfig/*.pc %prep %setup -q %build +%{!?build_type:%define build_type "RELEASE"} -%install +%if %{build_type} == "DEBUG" || %{build_type} == "PROFILING" + CFLAGS="$CFLAGS -Wp,-U_FORTIFY_SOURCE" + CXXFLAGS="$CXXFLAGS -Wp,-U_FORTIFY_SOURCE" +%endif -%clean -rm -rf %{buildroot} +%cmake . \ + -D_LIB_VERSION_=%{lib_version} \ + -DVERSION=%{version} \ + -DCMAKE_BUILD_TYPE=%{build_type} -%post +make -k %{?jobs:-j%jobs} -%preun +%install +%make_install -%postun +%clean +rm -rf %{buildroot} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..437e6ca --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,35 @@ +# Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved +# +# 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 CMakeLists.txt +# @author Jacek Pielaszkiewicz (j.pielaszkie@samsung.com) +# +SET(PC_FILE "${SRC_FOLDER}/lib${PROJECT_NAME}.pc") + +MESSAGE(STATUS "Generating makefile for the libConfig sources...") +FILE(GLOB HEADERS "${SRC_FOLDER}/config/*.hpp") +FILE(GLOB_RECURSE SRCS "${SRC_FOLDER}" *.hpp *.cpp) + +## Setup target ################################################################ + +## Link libraries ############################################################# +INCLUDE_DIRECTORIES(${SRC_FOLDER}) +INCLUDE_DIRECTORIES(SYSTEM ${CONFIG_DEPS_INCLUDE_DIRS}) + +## Install ##################################################################### +CONFIGURE_FILE(${PC_FILE}.in "${CMAKE_CURRENT_BINARY_DIR}/${PC_FILE}" @ONLY) + +INSTALL(FILES ${HEADERS} DESTINATION "${INCLUDE_INSTALL_DIR}/sc-tools/config") +INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PC_FILE}" DESTINATION "/usr/lib/pkgconfig") diff --git a/src/config/config.hpp b/src/config/config.hpp new file mode 100644 index 0000000..a65c2ad --- /dev/null +++ b/src/config/config.hpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk (l.pawelczyk@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 Lukasz Pawelczyk (l.pawelczyk@partner.samsung.com) + * @brief Configuration file for the code + */ + +#ifndef CONFIG_HPP +#define CONFIG_HPP + +#ifdef __clang__ +#define CLANG_VERSION (__clang__major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) +#endif // __clang__ + +#if defined __GNUC__ && !defined __clang__ // clang also defines GCC versions +#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif // __GNUC__ + +#ifdef GCC_VERSION + +#if GCC_VERSION < 40800 +// GCC 4.8 is the first where those defines are not required for +// std::this_thread::sleep_for() and ::yield(). They might exist though +// in previous versions depending on the build configuration of the GCC. +#ifndef _GLIBCXX_USE_NANOSLEEP +#define _GLIBCXX_USE_NANOSLEEP +#endif // _GLIBCXX_USE_NANOSLEEP +#ifndef _GLIBCXX_USE_SCHED_YIELD +#define _GLIBCXX_USE_SCHED_YIELD +#endif // _GLIBCXX_USE_SCHED_YIELD +#endif // GCC_VERSION < 40800 + +#if GCC_VERSION < 40700 +// Those appeared in 4.7 with full c++11 support +#define final +#define override +#define thread_local __thread // use GCC extension instead of C++11 +#endif // GCC_VERSION < 40700 + +#endif // GCC_VERSION + +#endif // CONFIG_HPP diff --git a/src/config/exception.hpp b/src/config/exception.hpp new file mode 100644 index 0000000..6489c73 --- /dev/null +++ b/src/config/exception.hpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * 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 Lukasz Pawelczyk (l.pawelczyk@partner.samsung.com) + * @brief Exceptions for the configuration + */ + +#ifndef CONFIG_EXCEPTION_HPP +#define CONFIG_EXCEPTION_HPP + +#include + +namespace config { + +/** + * Base class for exceptions in configuration. + * Error occured during a config file parsing, + * e.g. syntax error + */ +struct ConfigException: public std::runtime_error { + + ConfigException(const std::string& error = "") : std::runtime_error(error) {} +}; + +} // namespace config + +#endif // CONFIG_EXCEPTION_HPP diff --git a/src/config/fields.hpp b/src/config/fields.hpp new file mode 100644 index 0000000..3269856 --- /dev/null +++ b/src/config/fields.hpp @@ -0,0 +1,76 @@ +/* + * 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 Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) + * @brief Macros for registering configuration fields + */ + +#ifndef CONFIG_FIELDS_HPP +#define CONFIG_FIELDS_HPP + +#include +#include + +#if BOOST_PP_VARIADICS != 1 +#error variadic macros not supported +#endif + +/** + * Use this macro to register config fields. + * + * Example: + * struct Foo + * { + * std::string bar; + * std::vector tab; + * + * // SubConfigA must also register config fields + * SubConfigA sub_a; + * + * // SubConfigB must also register config fields + * std::vector tab_sub; + * + * CONFIG_REGISTER + * ( + * bar, + * tab, + * sub_a + * ) + * }; + */ +#define CONFIG_REGISTER(...) \ + template \ + void accept(Visitor v) { \ + GENERATE_ELEMENTS__(__VA_ARGS__) \ + } \ + template \ + void accept(Visitor v) const { \ + GENERATE_ELEMENTS__(__VA_ARGS__) \ + } \ + +#define GENERATE_ELEMENTS__(...) \ + BOOST_PP_LIST_FOR_EACH(GENERATE_ELEMENT__, \ + _, \ + BOOST_PP_VARIADIC_TO_LIST(__VA_ARGS__)) \ + +#define GENERATE_ELEMENT__(r, _, element) \ + v.visit(#element, element); \ + +#endif // CONFIG_FIELDS_HPP diff --git a/src/config/from-json-visitor.hpp b/src/config/from-json-visitor.hpp new file mode 100644 index 0000000..a3b502d --- /dev/null +++ b/src/config/from-json-visitor.hpp @@ -0,0 +1,141 @@ +/* + * 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 Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) + * @brief JSON visitor + */ + +#ifndef CONFIG_FROM_JSON_VISITOR_HPP +#define CONFIG_FROM_JSON_VISITOR_HPP + +#include "config/is-visitable.hpp" +#include "config/exception.hpp" + +#include +#include +#include + +namespace config { + +class FromJsonVisitor { +public: + explicit FromJsonVisitor(const std::string& jsonString) + : mObject(nullptr) + { + mObject = json_tokener_parse(jsonString.c_str()); + if (mObject == nullptr) { + throw ConfigException("Json parsing error"); + } + } + + FromJsonVisitor(const FromJsonVisitor& visitor) + : mObject(json_object_get(visitor.mObject)) + { + } + + ~FromJsonVisitor() + { + json_object_put(mObject); + } + + template + void visit(const std::string& name, T& value) + { + json_object* object = nullptr; + if (!json_object_object_get_ex(mObject, name.c_str(), &object)) { + throw ConfigException("Missing field '" + name + "' in json"); + } + fromJsonObject(object, value); + } + +private: + json_object* mObject; + + FromJsonVisitor& operator=(const FromJsonVisitor&) = delete; + + explicit FromJsonVisitor(json_object* object) + : mObject(json_object_get(object)) + { + } + + static void checkType(json_object* object, json_type type) + { + if (type != json_object_get_type(object)) { + throw ConfigException("Invalid field type"); + } + } + + static void fromJsonObject(json_object* object, int& value) + { + checkType(object, json_type_int); + std::int64_t value64 = json_object_get_int64(object); + if (value64 > INT32_MAX || value64 < INT32_MIN) { + throw ConfigException("Value out of range"); + } + value = static_cast(value64); + } + + static void fromJsonObject(json_object* object, std::int64_t& value) + { + checkType(object, json_type_int); + value = json_object_get_int64(object); + } + + static void fromJsonObject(json_object* object, bool& value) + { + checkType(object, json_type_boolean); + value = json_object_get_boolean(object); + } + + static void fromJsonObject(json_object* object, double& value) + { + checkType(object, json_type_double); + value = json_object_get_double(object); + } + + static void fromJsonObject(json_object* object, std::string& value) + { + checkType(object, json_type_string); + value = json_object_get_string(object); + } + + template + static void fromJsonObject(json_object* object, std::vector& value) + { + checkType(object, json_type_array); + int length = json_object_array_length(object); + value.resize(static_cast(length)); + for (int i = 0; i < length; ++i) { + fromJsonObject(json_object_array_get_idx(object, i), value[static_cast(i)]); + } + } + + template::value>::type> + static void fromJsonObject(json_object* object, T& value) + { + checkType(object, json_type_object); + FromJsonVisitor visitor(object); + value.accept(visitor); + } +}; + +} // namespace config + +#endif // CONFIG_FROM_JSON_VISITOR_HPP diff --git a/src/config/is-visitable.hpp b/src/config/is-visitable.hpp new file mode 100644 index 0000000..74f6036 --- /dev/null +++ b/src/config/is-visitable.hpp @@ -0,0 +1,53 @@ +/* + * 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 Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) + * @brief Internal configuration helper + */ + +#ifndef CONFIG_IS_VISITABLE_HPP +#define CONFIG_IS_VISITABLE_HPP + +#include + +namespace config { + +template +struct isVisitableHelper__ { + struct Visitor {}; + + template static std::true_type + test(decltype(std::declval().template accept(Visitor()))*); + + template static std::false_type + test(...); + + static constexpr bool value = std::is_same(0)), std::true_type>::value; +}; + +/** + * Helper for compile-time checking against existance of template method 'accept'. + */ +template +struct isVisitable : public std::integral_constant::value> {}; + +} // namespace config + +#endif // CONFIG_IS_VISITABLE_HPP diff --git a/src/config/manager.hpp b/src/config/manager.hpp new file mode 100644 index 0000000..902633f --- /dev/null +++ b/src/config/manager.hpp @@ -0,0 +1,127 @@ +/* + * 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 Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) + * @brief Configuration management functions + */ + +#ifndef CONFIG_MANAGER_HPP +#define CONFIG_MANAGER_HPP + +#include "config/to-json-visitor.hpp" +#include "config/from-json-visitor.hpp" +#include "config/is-visitable.hpp" +#include "logger/logger.hpp" + +#include +#include + + +namespace config { + +template +void loadFromString(const std::string& jsonString, Config& config) +{ + static_assert(isVisitable::value, "Use CONFIG_REGISTER macro"); + + FromJsonVisitor visitor(jsonString); + config.accept(visitor); +} + +template +std::string saveToString(const Config& config) +{ + static_assert(isVisitable::value, "Use CONFIG_REGISTER macro"); + + ToJsonVisitor visitor; + config.accept(visitor); + return visitor.toString(); +} + +static bool readFileContent(const std::string& path, std::string& result) +{ + std::ifstream file(path); + + if (!file) { + LOGD(path << ": could not open for reading"); + return false; + } + + file.seekg(0, std::ios::end); + std::streampos length = file.tellg(); + if (length < 0) { + LOGD(path << ": tellg failed"); + return false; + } + result.resize(static_cast(length)); + file.seekg(0, std::ios::beg); + + file.read(&result[0], length); + if (!file) { + LOGD(path << ": read error"); + result.clear(); + return false; + } + + return true; +} + +static bool saveFileContent(const std::string& path, const std::string& content) +{ + std::ofstream file(path); + if (!file) { + LOGD(path << ": could not open for writing"); + return false; + } + file.write(content.data(), content.size()); + if (!file) { + LOGD(path << ": could not write to"); + return false; + } + return true; +} + +template +void loadFromFile(const std::string& filename, Config& config) +{ + try { + std::string content; + if (!readFileContent(filename, content)) { + throw ConfigException("Could not load " + filename); + } + loadFromString(content, config); + } + catch(...) { + throw ConfigException("Could not load configuration."); + } +} + +template +void saveToFile(const std::string& filename, const Config& config) +{ + const std::string content = saveToString(config); + if (!saveFileContent(filename, content)) { + throw ConfigException("Could not save " + filename); + } +} + +} // namespace config + +#endif // CONFIG_MANAGER_HPP diff --git a/src/config/to-json-visitor.hpp b/src/config/to-json-visitor.hpp new file mode 100644 index 0000000..5b70eb9 --- /dev/null +++ b/src/config/to-json-visitor.hpp @@ -0,0 +1,122 @@ +/* + * 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 Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) + * @brief JSON visitor + */ + +#ifndef CONFIG_TO_JSON_VISITOR_HPP +#define CONFIG_TO_JSON_VISITOR_HPP + +#include "config/is-visitable.hpp" + +#include +#include +#include + +namespace config { + +class ToJsonVisitor { + +public: + ToJsonVisitor() + : mObject(json_object_new_object()) + { + } + + ToJsonVisitor(const ToJsonVisitor& visitor) + : mObject(json_object_get(visitor.mObject)) + { + } + + ~ToJsonVisitor() + { + json_object_put(mObject); + } + + std::string toString() const + { + return json_object_to_json_string(mObject); + } + + template + void visit(const std::string& name, const T& value) + { + json_object_object_add(mObject, name.c_str(), toJsonObject(value)); + } +private: + json_object* mObject; + + ToJsonVisitor& operator=(const ToJsonVisitor&) = delete; + + json_object* detach() + { + json_object* ret = mObject; + mObject = nullptr; + return ret; + } + + static json_object* toJsonObject(int value) + { + return json_object_new_int(value); + } + + static json_object* toJsonObject(std::int64_t value) + { + return json_object_new_int64(value); + } + + static json_object* toJsonObject(bool value) + { + return json_object_new_boolean(value); + } + + static json_object* toJsonObject(double value) + { + return json_object_new_double(value); + } + + static json_object* toJsonObject(const std::string& value) + { + return json_object_new_string(value.c_str()); + } + + template + static json_object* toJsonObject(const std::vector& value) + { + json_object* array = json_object_new_array(); + for (const T& v : value) { + json_object_array_add(array, toJsonObject(v)); + } + return array; + } + + template::value>::type> + static json_object* toJsonObject(const T& value) + { + ToJsonVisitor visitor; + value.accept(visitor); + return visitor.detach(); + } +}; + +} // namespace config + +#endif // CONFIG_TO_JSON_VISITOR_HPP diff --git a/src/libConfig.pc.in b/src/libConfig.pc.in new file mode 100644 index 0000000..67f53d6 --- /dev/null +++ b/src/libConfig.pc.in @@ -0,0 +1,8 @@ +# Package Information for pkg-config + +includedir=@INCLUDE_INSTALL_DIR@ + +Name: libConfig +Description: Config library +Version: @VERSION@ +Cflags: -I${includedir}/sc_tools -- 2.7.4 From f1a8930290c1bb8784484acbab45d9f98c3204bb Mon Sep 17 00:00:00 2001 From: Piotr Bartosiewicz Date: Tue, 29 Jul 2014 15:33:37 +0200 Subject: [PATCH 4/4] Fix install libdir and version in pc file [Bug/Feature] Hardcoded lib dir, no version in pc file. [Cause] N/A [Solution] N/A [Verification] Build, install Change-Id: Ic36d716917cdf0dbc69f8cd63045645bf895365f --- CMakeLists.txt | 6 ++++++ src/CMakeLists.txt | 2 +- src/libConfig.pc.in | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2118f07..1ee9397 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,8 @@ CMAKE_MINIMUM_REQUIRED (VERSION 2.6.2) PROJECT(Config) +SET(_VERSION_ "0.0.1") + ## pkgconfig ################################################################### INCLUDE(FindPkgConfig) @@ -59,6 +61,10 @@ ADD_DEFINITIONS(-DPROJECT_SOURCE_DIR="${PROJECT_SOURCE_DIR}") ## Subdirectories ############################################################## SET(SRC_FOLDER ${PROJECT_SOURCE_DIR}/src) +IF(NOT DEFINED LIB_INSTALL_DIR) + SET(LIB_INSTALL_DIR "${CMAKE_INSTALL_FULL_LIBDIR}") +ENDIF(NOT DEFINED LIB_INSTALL_DIR) + IF(NOT DEFINED INCLUDE_INSTALL_DIR) SET(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_FULL_INCLUDEDIR}) ENDIF(NOT DEFINED INCLUDE_INSTALL_DIR) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 437e6ca..9c1d5c8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -32,4 +32,4 @@ INCLUDE_DIRECTORIES(SYSTEM ${CONFIG_DEPS_INCLUDE_DIRS}) CONFIGURE_FILE(${PC_FILE}.in "${CMAKE_CURRENT_BINARY_DIR}/${PC_FILE}" @ONLY) INSTALL(FILES ${HEADERS} DESTINATION "${INCLUDE_INSTALL_DIR}/sc-tools/config") -INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PC_FILE}" DESTINATION "/usr/lib/pkgconfig") +INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PC_FILE}" DESTINATION "${LIB_INSTALL_DIR}/pkgconfig") diff --git a/src/libConfig.pc.in b/src/libConfig.pc.in index 67f53d6..d18f860 100644 --- a/src/libConfig.pc.in +++ b/src/libConfig.pc.in @@ -4,5 +4,5 @@ includedir=@INCLUDE_INSTALL_DIR@ Name: libConfig Description: Config library -Version: @VERSION@ +Version: @_VERSION_@ Cflags: -I${includedir}/sc_tools -- 2.7.4