--- /dev/null
+cmake_minimum_required(VERSION 2.8)
+
+set(CMAKE_BUILD_TYPE Release)
+
+set (PLUGIN_CONFIG_VERSION_MAJOR 0)
+set (PLUGIN_CONFIG_VERSION_MINOR 1)
+set (PLUGIN_CONFIG_VERSION_PATCH 0)
+
+set (PLUGIN_CONFIG_SOVERSION 1)
+
+option(CPP_IMPLEMENTATION "Choose C++ implementation" OFF)
+
+if(CPP_IMPLEMENTATION)
+ project(plugin-config CXX)
+
+ add_definitions(-DCPP_IMPLEMENTATION)
+ file(GLOB SOURCES
+ src/*.cpp
+ )
+
+ file(GLOB INTERFACE_INCLUDES
+ include/*.h
+ include/*.hpp
+ )
+else(CPP_IMPLEMENTATION)
+ project(plugin-config C)
+
+ file(GLOB SOURCES
+ src/*.c
+ )
+
+ file(GLOB INTERFACE_INCLUDES
+ include/*.h
+ )
+endif(CPP_IMPLEMENTATION)
+
+#The path to the top level of the source tree.
+message (${CMAKE_SOURCE_DIR})
+
+# Add include directories to the build.
+include_directories(${CMAKE_SOURCE_DIR}/include)
+
+include(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED
+ glib-2.0
+ gthread-2.0
+ dlog
+gobject-2.0
+gio-2.0
+json-glib-1.0
+
+)
+
+foreach(flag ${pkgs_CFLAGS})
+ set(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+endforeach(flag)
+
+# Set the compiler flags for compiling C++ sources
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -std=c++0x -Wall -Wextra -fPIC")
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -std=gnu99 -Wall -Wextra -fPIC")
+
+# macro(REMOVE_C_FLAG flag)
+# string(REPLACE "${flag}" "-O0" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
+# string(REPLACE "${flag}" "-O0" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+# endmacro()
+# REMOVE_C_FLAG("-O2")
+# REMOVE_C_FLAG("-O3")
+
+set(EXTRA_LIBS ${EXTRA_LIBS} ${pkgs_LDFLAGS})
+
+set(SHARED_LIBRARY ${PROJECT_NAME})
+add_library(${SHARED_LIBRARY} SHARED ${SOURCES})
+
+#Link a target to given libraries.
+target_link_libraries(${SHARED_LIBRARY} ${EXTRA_LIBS})
+
+set_target_properties(${SHARED_LIBRARY} PROPERTIES VERSION ${PLUGIN_CONFIG_VERSION_MAJOR}.${PLUGIN_CONFIG_VERSION_MINOR} SOVERSION ${PLUGIN_CONFIG_SOVERSION})
+
+# Add an executable to the project using the specified source files.
+
+#Link a target to given libraries.
+target_link_libraries(${EXECUTABLE} ${SHARED_LIBRARY} ${EXTRA_LIBS})
+
+set(USER $ENV{USER})
+set(HOME_DIR /home/${USER})
+
+# Provides an option that the user can optionally select.
+option(INSTALL_INTO_HOME_DIR "Install targets into home directory (for test pusrposes)" OFF)
+if(INSTALL_INTO_HOME_DIR)
+ # Install directory used by install
+ set(CMAKE_INSTALL_PREFIX ${HOME_DIR}/pluginconfig)
+endif(INSTALL_INTO_HOME_DIR)
+
+#Generate ex-04.pc file from ex-04.pc.in located in the top level source tree subdirectory pkgconfig.
+configure_file(
+ "${CMAKE_SOURCE_DIR}/pkgconfig/${PROJECT_NAME}.pc.in"
+ "${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc"
+ @ONLY)
+
+# uninstall target
+# Generate uninstall.cmake file from uninstall.cmake.in located in the top level source tree directory.
+configure_file(
+ "${CMAKE_CURRENT_SOURCE_DIR}/uninstall.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/uninstall.cmake"
+ IMMEDIATE @ONLY)
+
+# Add custom command uninstall intended to unistall previously installed files
+# ( process ${CMAKE_CURRENT_BINARY_DIR}/uninstall.cmake)
+add_custom_target(uninstall
+ COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/uninstall.cmake)
+
+install(TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin)
+install(TARGETS ${SHARED_LIBRARY} DESTINATION lib)
+install(FILES ${INTERFACE_INCLUDES} DESTINATION include)
+install(FILES "${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc" DESTINATION lib/pkgconfig)
+#install(FILES "${CMAKE_SOURCE_DIR}/config/pluginmanager.ini" DESTINATION /usr/share/cloudbox/config)
+
+# build a CPack driven installer package
+include (InstallRequiredSystemLibraries)
+set (CPACK_RESOURCE_FILE_LICENSE
+ "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
+set (CPACK_PACKAGE_VERSION_MAJOR "${PLUGIN_CONFIG_VERSION_MAJOR}")
+set (CPACK_PACKAGE_VERSION_MINOR "${PLUGIN_CONFIG_VERSION_MINOR}")
+set (CPACK_PACKAGE_VERSION_PATCH "${PLUGIN_CONFIG_VERSION_PATCH}")
+set (CPACK_SYSTEM_NAME ${CMAKE_LIBRARY_ARCHITECTURE})
+set (CPACK_GENERATOR "DEB")
+set (CPACK_DEBIAN_PACKAGE_MAINTAINER "Yongjin Kim") #required
+set (CPACK_PACKAGE_CONTACT "youth.kim@samsung.com") #required
+
+include (CPack)
--- /dev/null
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
--- /dev/null
+Copyright (c) Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, this software is licensed under Apache License, Version 2.
+Please, see the LICENSE.Apache-2.0 file for Apache License terms and conditions.
--- /dev/null
+[Project]
+Manager=KDevCMakeManager
+Name=config
--- /dev/null
+general;plugin_dir;/usr/libs
+general;concurency;8
+debugging;log;verbose
+
--- /dev/null
+[general]
+ plugin_dir = /usr/libs
+ concurency = 8
+[debugging]
+ log = verbose
+
--- /dev/null
+[general]
+plugin_dir=/usr/libs
+concurency=8
+;[empty]
+;[empty2]
+[debugging]
+log=verbose
+
--- /dev/null
+[general]
+plugin_dir=/usr/libs
+concurency=8
+;[empty]
+;[empty2]
+[debugging]
+log=verbose
+
--- /dev/null
+/*
+* Copyright (c) 2011 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.
+*/
+
+#ifndef __LIB_SERVICE_PLUGIN_LOG_H__
+#define __LIB_SERVICE_PLUGIN_LOG_H__
+
+/**
+ * HOW TO USE IT:
+ * First you need to set platform logging on the device:
+ *
+ * # dlogctrl set platformlog 1
+ *
+ * After reboot you are able to see logs from this application, when you launch dlogutil with a proper filter e.g.:
+ *
+ * # dlogutil HELLO_WORLD_TEMP:D
+ *
+ * You may use different logging levels as: D (debug), I (info), W (warning), E (error) or F (fatal).
+ * Higher level messages are included by default e.g. dlogutil CLOUDBOX:W prints warnings but also errors and fatal messages.
+ */
+
+#include <unistd.h>
+#include <linux/unistd.h>
+
+/* These defines must be located before #include <dlog.h> */
+#define TIZEN_ENGINEER_MODE
+// TODO: Investigate why this macro is defined somewhere else
+#ifndef TIZEN_DEBUG_ENABLE
+#define TIZEN_DEBUG_ENABLE
+#endif
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+/* Literal to filter logs from dlogutil */
+#define LOG_TAG "LIBSERVICE_PLUGIN"
+
+#include <dlog.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ /**
+ * Colors of font
+ */
+#define FONT_COLOR_RESET "\033[0m"
+#define FONT_COLOR_BLACK "\033[30m" /* Black */
+#define FONT_COLOR_RED "\033[31m" /* Red */
+#define FONT_COLOR_GREEN "\033[32m" /* Green */
+#define FONT_COLOR_YELLOW "\033[33m" /* Yellow */
+#define FONT_COLOR_BLUE "\033[34m" /* Blue */
+#define FONT_COLOR_PURPLE "\033[35m" /* Purple */
+#define FONT_COLOR_CYAN "\033[36m" /* Cyan */
+#define FONT_COLOR_WHITE "\033[37m" /* White */
+#define FONT_COLOR_BOLDBLACK "\033[1m\033[30m" /* Bold Black */
+#define FONT_COLOR_BOLDRED "\033[1m\033[31m" /* Bold Red */
+#define FONT_COLOR_BOLDGREEN "\033[1m\033[32m" /* Bold Green */
+#define FONT_COLOR_BOLDYELLOW "\033[1m\033[33m" /* Bold Yellow */
+#define FONT_COLOR_BOLDBLUE "\033[1m\033[34m" /* Bold Blue */
+#define FONT_COLOR_BOLDPURPLE "\033[1m\033[35m" /* Bold Purple */
+#define FONT_COLOR_BOLDCYAN "\033[1m\033[36m" /* Bold Cyan */
+#define FONT_COLOR_BOLDWHITE "\033[1m\033[37m" /* Bold White */
+
+ /**
+ * Gets thread ID
+ */
+#define LSP_LOG_gettid() syscall(__NR_gettid)
+
+/**
+ * @brief Macro for returning value if expression is satisfied
+ * @param[in] expr Expression to be checked
+ * @param[out] val Value to be returned when expression is true
+ */
+#define LSP_LOG_retv_if(expr, val) do { \
+ if(expr) { \
+ LOGE(FONT_COLOR_PURPLE"[%d]"FONT_COLOR_RESET, LSP_LOG_gettid()); \
+ return (val); \
+ } \
+ } while (0)
+
+/**
+ * @brief Prints debug messages
+ * @param[in] fmt Format of data to be displayed
+ * @param[in] args Arguments to be displayed
+ */
+#define LSP_LOG_debug(fmt, arg...) do { \
+ LOGD(FONT_COLOR_GREEN"[%d]"fmt""FONT_COLOR_RESET, LSP_LOG_gettid(), ##arg); \
+ } while (0)
+
+/**
+ * @brief Prints info messages
+ * @param[in] fmt Format of data to be displayed
+ * @param[in] args Arguments to be displayed
+ */
+#define LSP_LOG_info(fmt, arg...) do { \
+ LOGI(FONT_COLOR_BLUE"[%d]"fmt""FONT_COLOR_RESET, LSP_LOG_gettid() ,##arg); \
+ } while (0)
+
+/**
+ * @brief Prints warning messages
+ * @param[in] fmt Format of data to be displayed
+ * @param[in] args Arguments to be displayed
+ */
+#define LSP_LOG_warning(fmt, arg...) do { \
+ LOGW(FONT_COLOR_YELLOW"[%d]"fmt""FONT_COLOR_RESET,LSP_LOG_gettid(), ##arg); \
+ } while (0)
+
+/**
+ * @brief Prints error messages
+ * @param[in] fmt Format of data to be displayed
+ * @param[in] args Arguments to be displayed
+ */
+#define LSP_LOG_error(fmt, arg...) do { \
+ LOGE(FONT_COLOR_RED"[%d]"fmt""FONT_COLOR_RESET,LSP_LOG_gettid(), ##arg); \
+ } while (0)
+
+/**
+ * @brief Prints fatal messages
+ * @param[in] fmt Format of data to be displayed
+ * @param[in] args Arguments to be displayed
+ */
+#define LSP_LOG_fatal(fmt, arg...) do { \
+ LOGF(FONT_COLOR_BOLDRED"[%d]"fmt""FONT_COLOR_RESET,LSP_LOG_gettid(), ##arg); \
+ } while (0)
+
+/**
+ * @brief Prints debug message on entry to particular function
+ * @param[in] fmt Format of data to be displayed
+ * @param[in] args Arguments to be displayed
+ */
+#define LSP_LOG_debug_func(fmt, arg...) do { \
+ LOGD(FONT_COLOR_CYAN"[%d]"fmt""FONT_COLOR_RESET, LSP_LOG_gettid(), ##arg); \
+ } while (0)
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __LIB_SERVICE_PLUGIN_LOG_H__ */
--- /dev/null
+/*
+* Copyright (c) 2011 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.
+*/
+
+#ifndef PLUGIN_CONFIG_H_INCLUDED
+#define PLUGIN_CONFIG_H_INCLUDED
+
+#include <stdbool.h>
+
+/**
+ * @file pluginConfig.h
+ * @author Dawid Kozinski (d.kozinski@samsung.com)
+ *
+ * @brief Plugin configuration parser done in C++.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "pluginConfigTypes.h"
+
+ /**
+ * @brief ...
+ **/
+ typedef void *ConfigHandle;
+
+ /**
+ * @brief General-purpose, class for loading and reading configuration from
+ * simple plaintext files.
+ **/
+
+ /**
+ * @brief Creates a new empty Config object and returns an opaque "handle"
+ *
+ * @return ConfigHandle an opaque pointer to Config object.
+ **/
+ ConfigHandle plugin_config_create();
+
+ /**
+ * @brief Destroy config object
+ *
+ * @param config_handle an opaque pointer to Config object
+ * @return void
+ **/
+ void plugin_config_delete(ConfigHandle config_handle);
+
+ /**
+ * @brief Loads the configuration from given file to memory.
+ *
+ * @param config_handle an opaque pointer to Config object
+ * @param filepath configuration will be _loaded from given filepath
+ * @param type expected type of configuration file, this value determines how
+ * the file is parsed
+ * @return void
+ **/
+ void plugin_config_load(ConfigHandle config_handle, const char *filepath, PluginConfigType type);
+
+ /**
+ * @brief Unloads the configuration from the memory.
+ *
+ * The configuration is automatically un_loaded when the program is exitting,
+ * so this method does not have to be executed unless you need to extremely
+ * lower memory usage and few bytes matter.
+ *
+ * @param config_handle an opaque pointer to Config object
+ * @return void
+ **/
+ void plugin_config_unload(ConfigHandle config_handle);
+
+ /**
+ * @brief From _loaded configuration, gets string value attached to given key.
+ *
+ * @param config_handle an opaque pointer to Config object
+ * @param section will return value attached to a key from this section
+ * @param key will return value attached to this key
+ * @return :string
+ **/
+ const char *plugin_config_get_string(ConfigHandle config_handle, const char *section, const char *key);
+
+ /**
+ * @brief From _loaded configuration, gets integer value attached to given key.
+ *
+ * @param config_handle an opaque pointer to Config object
+ * @param section will return value attached to a key from this section
+ * @param key will return value attached to this key
+ * @return int
+ **/
+ int plugin_config_get_int(ConfigHandle config_handle, const char *section, const char *key);
+
+ /**
+ * @brief From _loaded configuration, gets double value attached to given key.
+ *
+ * @param config_handle an opaque pointer to Config object
+ * @param section will return value attached to a key from this section
+ * @param key will return value attached to this key
+ * @return double
+ **/
+ double plugin_config_get_double(ConfigHandle config_handle, const char *section, const char *key);
+
+ /**
+ * @brief Checks wheteher config file has been loaded.
+ *
+ * @param config_handle an opaque pointer to Config object
+ * @return 0 if config is not loaded
+ * 1 if config is loaded
+ **/
+ bool plugin_config_is_loaded(ConfigHandle config_handle);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* PLUGIN_CONFIG_H_INCLUDED */
+
--- /dev/null
+/*
+* Copyright (c) 2011 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.
+*/
+
+#ifndef PLUGIN_CONFIG_HPP_INCLUDED
+#define PLUGIN_CONFIG_HPP_INCLUDED
+
+/**
+ * @file pluginConfig.hpp
+ * @author
+ * @date
+ *
+ * @author
+ *
+ * @brief
+ */
+
+// comment this to enter release mode (i.e. diable couts)
+#define DEBUG
+
+// debug and printing
+#ifdef DEBUG
+#include <iostream>
+#endif
+
+#include "pluginConfigTypes.h"
+
+/**
+ * @brief Namespace for all content related to plugin.
+ **/
+namespace plugin
+{
+ /**
+ * Internal backing storage for configuration.
+ */
+ namespace internal
+ {
+ class ConfigData;
+ }
+
+ /**
+ * @brief General-purpose, class for loading and reading configuration from
+ * simple plaintext files.
+ **/
+ class Config
+ {
+ public:
+ /**
+ * @brief Constructor
+ *
+ **/
+ Config();
+
+ /**
+ * @brief Destructor
+ *
+ **/
+ virtual ~Config();
+
+ /**
+ * @brief Loads configuration to memory and/or gets raw data from configuration.
+ *
+ * @param section will return value attached to a key from this section
+ * @param key will return value attached to this key
+ * @return :string
+ **/
+ std::string _getRaw(const std::string §ion, const std::string &key);
+
+ /**
+ * @brief Loads configuration to memory and/or gets raw data from configuration.
+ *
+ * @param section will return value attached to a key from this section
+ * @param key will return value attached to this key
+ * @return :string pointer
+ **/
+ const std::string *_getRawPtr(const std::string §ion, const std::string &key);
+
+ public:
+ /**
+ * @brief Loads the configuration from a given file into memory.
+ *
+ * @param filepath path to the configuration file that will be loaded
+ * @param type expected type of configuration file, this value determines
+ * how the file is parsed
+ * @return int return true if successful, false otherwise
+ **/
+ bool load(const std::string &filepath, PluginConfigType type);
+
+ /**
+ * @brief Unloads the configuration from the memory.
+ *
+ * The configuration is automatically unloaded when the Config object is
+ * destoyed, so this method does not have to be executed unless you need
+ * to extremely lower memory usage and few bytes matter.
+ *
+ * @return void
+ **/
+ void unload();
+
+ /**
+ * @brief Checks wheteher config file has been loaded.
+ *
+ * @return bool return true if successful, false otherwise
+ **/
+ bool isLoaded();
+
+ public:
+ /**
+ * @brief From loaded configuration, gets string value attached to given key.
+ *
+ * @param section ...
+ * @param key ...
+ * @return :string value attached to the key from the section
+ **/
+ std::string getString(const std::string §ion, const std::string &key);
+
+ /**
+ * @brief From loaded configuration, gets string pointer attached to given key.
+ *
+ * @param section ...
+ * @param key ...
+ * @return :string pointer attached to the key from the section
+ **/
+ const std::string *getStringPtr(const std::string §ion, const std::string &key);
+
+ /**
+ * @brief From loaded configuration, gets integer value attached to given key.
+ *
+ * @param section will return value attached to a key from this section
+ * @param key will return value attached to this key
+ * @return int
+ **/
+ int getInt(const std::string §ion, const std::string &key);
+
+ /**
+ * @brief From _loaded configuration, gets double value attached to given key.
+ *
+ * @param section will return value attached to a key from this section
+ * @param key will return value attached to this key
+ * @return double
+ **/
+ double getDouble(const std::string §ion, const std::string &key);
+
+ private:
+ bool _loaded;
+ internal::ConfigData *_configuration;
+ };
+}
+#endif /* PLUGIN_CONFIG_HPP_INCLUDED */
--- /dev/null
+/*
+* Copyright (c) 2011 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.
+*/
+
+#ifndef __PLUGIN_CONFIG_LOG_H__
+#define __PLUGIN_CONFIG_LOG_H__
+
+/**
+ * HOW TO USE IT:
+ * First you need to set platform logging on the device:
+ *
+ * # dlogctrl set platformlog 1
+ *
+ * After reboot you are able to see logs from this application, when you launch dlogutil with a proper filter e.g.:
+ *
+ * # dlogutil PLUGIN_CONFIG
+ *
+ * You may use different logging levels as: D (debug), I (info), W (warning), E (error) or F (fatal).
+ * Higher level messages are included by default e.g. dlogutil PLUGIN_CONFIG:W prints warnings but also errors and fatal messages.
+ */
+
+#include <unistd.h>
+#include <linux/unistd.h>
+
+/* These defines must be located before #include <dlog.h> */
+#define TIZEN_ENGINEER_MODE
+// TODO: Investigate why this macro is defined somewhere else
+#ifndef TIZEN_DEBUG_ENABLE
+#define TIZEN_DEBUG_ENABLE
+#endif
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+/* Literal to filter logs from dlogutil */
+#define LOG_TAG "PLUGIN_CONFIG"
+
+#include <dlog.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ /**
+ * Colors of font
+ */
+#define FONT_COLOR_RESET "\033[0m"
+#define FONT_COLOR_BLACK "\033[30m" /* Black */
+#define FONT_COLOR_RED "\033[31m" /* Red */
+#define FONT_COLOR_GREEN "\033[32m" /* Green */
+#define FONT_COLOR_YELLOW "\033[33m" /* Yellow */
+#define FONT_COLOR_BLUE "\033[34m" /* Blue */
+#define FONT_COLOR_PURPLE "\033[35m" /* Purple */
+#define FONT_COLOR_CYAN "\033[36m" /* Cyan */
+#define FONT_COLOR_WHITE "\033[37m" /* White */
+#define FONT_COLOR_BOLDBLACK "\033[1m\033[30m" /* Bold Black */
+#define FONT_COLOR_BOLDRED "\033[1m\033[31m" /* Bold Red */
+#define FONT_COLOR_BOLDGREEN "\033[1m\033[32m" /* Bold Green */
+#define FONT_COLOR_BOLDYELLOW "\033[1m\033[33m" /* Bold Yellow */
+#define FONT_COLOR_BOLDBLUE "\033[1m\033[34m" /* Bold Blue */
+#define FONT_COLOR_BOLDPURPLE "\033[1m\033[35m" /* Bold Purple */
+#define FONT_COLOR_BOLDCYAN "\033[1m\033[36m" /* Bold Cyan */
+#define FONT_COLOR_BOLDWHITE "\033[1m\033[37m" /* Bold White */
+
+ /**
+ * Gets thread ID
+ */
+#define plugin_config_gettid() syscall(__NR_gettid)
+
+ /**
+ * @brief Macro for returning value if expression is satisfied
+ * @param[in] expr Expression to be checked
+ * @param[out] val Value to be returned when expression is true
+ */
+#define plugin_config_retv_if(expr, val) do { \
+ if(expr) { \
+ LOGE(FONT_COLOR_PURPLE"[%d]"FONT_COLOR_RESET, plugin_config_gettid()); \
+ return (val); \
+ } \
+} while (0)
+
+/**
+ * @brief Prints debug messages
+ * @param[in] fmt Format of data to be displayed
+ * @param[in] args Arguments to be displayed
+ */
+#define plugin_config_debug(fmt, arg...) do { \
+ LOGD(FONT_COLOR_GREEN"[%d]"fmt""FONT_COLOR_RESET, plugin_config_gettid(), ##arg); \
+} while (0)
+
+/**
+ * @brief Prints info messages
+ * @param[in] fmt Format of data to be displayed
+ * @param[in] args Arguments to be displayed
+ */
+#define plugin_config_info(fmt, arg...) do { \
+ LOGI(FONT_COLOR_BLUE"[%d]"fmt""FONT_COLOR_RESET, plugin_config_gettid() ,##arg); \
+} while (0)
+
+/**
+ * @brief Prints warning messages
+ * @param[in] fmt Format of data to be displayed
+ * @param[in] args Arguments to be displayed
+ */
+#define plugin_config_warning(fmt, arg...) do { \
+ LOGW(FONT_COLOR_YELLOW"[%d]"fmt""FONT_COLOR_RESET, plugin_config_gettid(), ##arg); \
+} while (0)
+
+/**
+ * @brief Prints error messages
+ * @param[in] fmt Format of data to be displayed
+ * @param[in] args Arguments to be displayed
+ */
+#define plugin_config_error(fmt, arg...) do { \
+ LOGE(FONT_COLOR_RED"[%d]"fmt""FONT_COLOR_RESET, plugin_config_gettid(), ##arg); \
+} while (0)
+
+/**
+ * @brief Prints fatal messages
+ * @param[in] fmt Format of data to be displayed
+ * @param[in] args Arguments to be displayed
+ */
+#define plugin_config_fatal(fmt, arg...) do { \
+ LOGF(FONT_COLOR_BOLDRED"[%d]"fmt""FONT_COLOR_RESET, plugin_config_gettid(), ##arg); \
+} while (0)
+
+/**
+ * @brief Prints debug message on entry to particular function
+ * @param[in] fmt Format of data to be displayed
+ * @param[in] args Arguments to be displayed
+ */
+#define plugin_config_debug_func(fmt, arg...) do { \
+ LOGD(FONT_COLOR_CYAN"[%d]"fmt""FONT_COLOR_RESET, plugin_config_gettid(), ##arg); \
+} while (0)
+
+#define startfunc plugin_config_debug_func("+- START -");
+#define endfunc plugin_config_debug_func("+- END -");
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __PLUGIN_CONFIG_LOG_H__ */
--- /dev/null
+/*
+* Copyright (c) 2011 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.
+*/
+
+#ifndef PLUGIN_CONFIG_TYPES
+#define PLUGIN_CONFIG_TYPES
+
+/**
+ * @file pluginConfigTypes.h
+ * @author Dawid Kozinski (d.kozinski@samsung.com)
+ *
+ * @brief Plugin configuration parser done in C++.
+ */
+
+/**
+ * @brief Types of supported configuration files.
+ **/
+typedef enum PluginConfigType
+{
+ /**
+ * @brief INI file format, as defined here: https://en.wikipedia.org/wiki/INI_file#Format
+ **/
+ CCT_INI = 1,
+
+ /**
+ * @brief Git config file format, as defined here:
+ **/
+ CCT_GIT = 1 << 1,
+
+ /**
+ * @brief Three column CSV file, columns are: section, key, value.
+ * They are separated with commas.
+ **/
+ CCT_CSV_COMMA = 1 << 2,
+
+ /**
+ * @brief Three column CSV file, columns are: section, key, value.
+ * They are separated with tabs.
+ **/
+ CCT_CSV_TAB = 1 << 3,
+
+ /**
+ * @brief Three column CSV file, columns are: section, key, value.
+ * They are separated with colons.
+ **/
+ CCT_CSV_COLON = 1 << 4,
+
+ /**
+ * @brief Three column CSV file, columns are: section, key, value.
+ * They are separated with semicolons.
+ **/
+ CCT_CSV_SEMICOLON = 1 << 5,
+
+ /**
+ * @brief As the name suggessts.
+ **/
+ CCT_INVALID = 0
+} PluginConfigType;
+
+#endif /* PLUGIN_CONFIG_TYPES */
--- /dev/null
+/*
+* Copyright (c) 2011 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.
+*/
+
+#ifndef __TIZEN_SOCIAL_LIBSERVICE_PLUGIN_MESSAGE_H__
+#define __TIZEN_SOCIAL_LIBSERVICE_PLUGIN_MESSAGE_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef enum
+{
+ PLUGIN_MESSAGE_TYPE_FUNCTION = 1,
+ PLUGIN_MESSAGE_TYPE_CALLBACK = 2,
+} plugin_message_type_e;
+
+/*
+#define PLUGIN_DATA_TYPE_INT 'i'
+#define PLUGIN_DATA_TYPE_LONG 'l'
+*/
+
+// INT/LONG -> NUM (64bit)
+#define PLUGIN_DATA_TYPE_NUM 'n'
+#define PLUGIN_DATA_TYPE_STRING 's'
+#define PLUGIN_DATA_TYPE_BOOL 'b'
+#define PLUGIN_DATA_TYPE_ARRAY 'a'
+#define PLUGIN_DATA_TYPE_UNKNOWN 'u'
+
+typedef char plugin_data_type;
+
+
+/*
+typedef enum
+{
+ PM_TYPE_FALSE = 0,
+ PM_TYPE_TRUE = 1,
+} pmbool_type_e;
+*/
+
+typedef long long int pmnumber;
+typedef char *pmstring;
+typedef bool pmbool;
+
+typedef enum
+{
+ PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+ PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+ PLUGIN_MESSAGE_ELEMENT_PARAMETER_MANDATORY,
+ PLUGIN_MESSAGE_ELEMENT_PARAMETER_OPTIONAL,
+ PLUGIN_MESSAGE_ELEMENT_REQUEST_ID,
+ PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+ PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+ PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+} plugin_message_element_e;
+
+typedef struct _plugin_message_s *plugin_message_h;
+
+typedef struct _plugin_message_array_s *plugin_message_array_h;
+
+
+int plugin_message_create(plugin_message_h *message);
+
+void plugin_message_destroy(plugin_message_h message);
+
+int plugin_message_set_value_number(plugin_message_h message, plugin_message_element_e field, pmnumber value);
+
+int plugin_message_get_value_number(plugin_message_h message, plugin_message_element_e field, pmnumber *value);
+
+int plugin_message_set_value_string(plugin_message_h message, plugin_message_element_e field, const char *value);
+
+int plugin_message_get_value_string(plugin_message_h message, plugin_message_element_e field, char **value);
+
+int plugin_message_set_value_bool(plugin_message_h message, plugin_message_element_e field, bool value);
+
+int plugin_message_get_value_bool(plugin_message_h message, plugin_message_element_e field, bool *value);
+
+
+int plugin_message_set_param_number(plugin_message_h message, int param_index, pmnumber value);
+
+int plugin_message_get_param_number(plugin_message_h message, int param_index, pmnumber *value);
+
+int plugin_message_set_param_string(plugin_message_h message, int param_index, const char *value);
+
+int plugin_message_get_param_string(plugin_message_h message, int param_index, char **value);
+
+int plugin_message_set_param_bool(plugin_message_h message, int param_index, bool value);
+
+int plugin_message_get_param_bool(plugin_message_h message, int param_index, bool *value);
+
+int plugin_message_set_param_array(plugin_message_h message, int param_index, plugin_message_array_h value);
+
+int plugin_message_get_param_array(plugin_message_h message, int param_index, plugin_message_array_h *value);
+
+
+int plugin_message_set_opt_param_number(plugin_message_h message, int param_index, pmnumber value);
+
+int plugin_message_get_opt_param_number(plugin_message_h message, int param_index, pmnumber *value);
+
+int plugin_message_set_opt_param_string(plugin_message_h message, int param_index, const char *value);
+
+int plugin_message_get_opt_param_string(plugin_message_h message, int param_index, char **value);
+
+int plugin_message_set_opt_param_bool(plugin_message_h message, int param_index, bool value);
+
+int plugin_message_get_opt_param_bool(plugin_message_h message, int param_index, bool *value);
+
+int plugin_message_set_opt_param_array(plugin_message_h message, int param_index, plugin_message_array_h value);
+
+int plugin_message_get_opt_param_array(plugin_message_h message, int param_index, plugin_message_array_h *value);
+
+
+int plugin_message_serialize(plugin_message_h message, char **data);
+
+int plugin_message_deserialize(const char *data, plugin_message_h *message);
+
+
+int plugin_message_array_create(const plugin_data_type *type_string, plugin_message_array_h *array);
+
+void plugin_message_array_destroy(plugin_message_array_h array);
+
+int plugin_message_array_add_element(plugin_message_array_h array, ...);
+
+int plugin_message_array_get_element(plugin_message_array_h array, int idx, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_SOCIAL_LIBSERVICE_PLUGIN_MESSAGE_H__ */
--- /dev/null
+Name: plugin-config
+Summary: Plugin Config for Tizen
+Version: 1.0.3
+Release: 1
+Group: TO_BE/FILLED_IN
+License: Apache-2.0
+Source0: %{name}-%{version}.tar.gz
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(gthread-2.0)
+BuildRequires: cmake
+#BuildRequires: vim
+BuildRequires: pkgconfig(dlog)
+
+BuildRequires: pkgconfig(gobject-2.0)
+BuildRequires: pkgconfig(gio-2.0)
+BuildRequires: pkgconfig(json-glib-1.0)
+
+%description
+The package contains library for loading and reading configuration from simple
+plaintext files.
+
+%package devel
+Summary: Development tools for plugin-config
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}
+
+%description devel
+This package contains the libraries and includes files necessary to develop
+applications that make a use of cloudboxconfig library.
+
+%prep
+%setup -q -n %{name}-%{version}
+
+%build
+cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix}
+
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+%files
+#%manifest audioplayer.manifest
+%defattr(-,root,root,-)
+
+%{_libdir}/libplugin-config.so*
+
+%files devel
+#%manifest audioplayer.manifest
+%defattr(-,root,root,-)
+%{_includedir}/*.h*
+%{_libdir}/pkgconfig/plugin-config.pc
+
--- /dev/null
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=@CMAKE_INSTALL_PREFIX@/bin
+libdir=@CMAKE_INSTALL_PREFIX@/lib
+includedir=@CMAKE_INSTALL_PREFIX@/include
+
+Name: plugin-config
+Description:
+Version: @PLUGIN_CONFIG_VERSION_MAJOR@.@PLUGIN_CONFIG_VERSION_MINOR@.@PLUGIN_CONFIG_VERSION_PATCH@
+
+Requires: glib-2.0 gthread-2.0 json-glib-1.0
+
+Libs: -L${libdir} -lplugin-config
+Cflags: -I${includedir}
--- /dev/null
+/*
+* Copyright (c) 2011 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 pluginConfig.c
+ * @author Dawid Kozinski (d.kozinski@samsung.com)
+ *
+ * @brief Plugin configuration parser done in C99.
+ */
+
+/* threads */
+#include <glib.h>
+#include "pluginConfig.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <float.h>
+
+#include "pluginConfigLog.h"
+
+#define UNUSED(x) (void)(x)
+
+/*********************************************************************************
+ * C99 implementation
+ ******************************************************************************/
+/*bool a = true; */
+
+/******************************************************************************
+ *
+ * Implicit Declarations of trimming functions
+ * this only describes and assumes allocated elsewhere (trimming.c)
+ *
+ ******************************************************************************/
+/**
+* @brief trim from start, i.e. left side
+* Trimming leading whitespace from string
+*
+* @param s ...
+* @return :char*
+**/
+extern char *plugin_internal_ltrim(char *s);
+
+/**
+* @brief trim from end, i.e. right side
+* Trimming trailing whitespace from string
+*
+* @param s ...
+* @return :char*
+**/
+extern char *plugin_internal_rtrim(char *s);
+
+/**
+* @brief trim from both ends
+* Trimming leading and trailing whitespace from string
+* @param s ...
+* @return :string&
+**/
+extern char *plugin_internal_trim(char *s);
+
+/******************************************************************************
+ * Typedefs
+ ******************************************************************************/
+
+/******************************************************************************
+ * [unique name][cloud_adaptor_handle*]
+ ******************************************************************************/
+/**
+* @typedef plugin_internal_MapStrStr
+* Section data
+* |---------------------------|-----------------------------------------------|
+* | KEY : char* | VALUE : char* |
+* |---------------------------|-----------------------------------------------|
+* | KEY1 | VAL1 |
+* |---------------------------|-----------------------------------------------|
+* | KEY2 | VAL2 |
+* |---------------------------|-----------------------------------------------|
+* | KEY3 | VAL3 |
+* |---------------------------|-----------------------------------------------|
+*/
+typedef GHashTable plugin_internal_MapStrStr;
+
+/**
+* @typedef plugin_internal_MapStrSection
+* Sections
+* |---------------------------|-----------------------------------------------|
+* | SECTION NAME : char* | SECTION PTR : MapStrStr * |
+* |---------------------------|-----------------------------------------------|
+* | SN1 | SP1 |
+* |---------------------------|-----------------------------------------------|
+* | SN2 | SP2 |
+* |---------------------------|-----------------------------------------------|
+* | SN3 | SP3 |
+* |---------------------------|-----------------------------------------------|
+*/
+typedef GHashTable plugin_internal_MapStrSection;
+
+/**
+* @typedef plugin_internal_ListSection
+* Sections
+* |------------------------------------------|
+* | SECTION PTR : MapStrStr * |
+* |------------------------------------------|
+* | SP1 |
+* |------------------------------------------|
+* | SP2 |
+* |------------------------------------------|
+* | SN3 |
+* |------------------------------------------|
+*/
+typedef GList plugin_internal_ListSection;
+
+/******************************************************************************
+ * ConfigParserState struct
+ ******************************************************************************/
+typedef struct plugin_internal_ConfigParserState {
+ char *current_section_name;
+ plugin_internal_MapStrStr *current_section;
+} ConfigParserState;
+
+/******************************************************************************
+ * ConfigData class
+ ******************************************************************************/
+typedef struct plugin_internal_ConfigData {
+ GMutex *data_mutex;
+
+ /**
+ * @brief Filepath to the read configuration file.
+ **/
+ char *filepath;
+
+ /**
+ * @brief Describes layout of the data in the file.
+ **/
+ PluginConfigType type;
+
+ /**
+ * @brief Variable that stores the all sections of configuration,
+ * meant to be accessed through the field 'configuration'.
+ **/
+ plugin_internal_ListSection *sections;
+
+ /**
+ * @brief Variable that stores the whole configuration.
+ **/
+ plugin_internal_MapStrSection *configuration;
+} plugin_internal_ConfigData;
+
+/******************************************************************************
+ * Declarations (methods of ConfigData class)
+ ******************************************************************************/
+
+/******************************************************************************
+ * Calbacks
+ ******************************************************************************/
+
+/**
+ * @brief Function which is called when a data element of configuration map
+ * being a member of plugin_internal_ConfigData struct
+ * (@see plugin_internal_ConfigData) is destroyed.
+ * @see plugin_internal_MapStrSection
+ *
+ * @param data pointer to the user data
+ * @return void
+ **/
+static
+void plugin_internal_ConfigData_cbMapStrSectionFreeData(gpointer data);
+
+/**
+ * @brief Function passed to g_hash_table_foreach().
+ * Function is called for each key/value pair.
+ *
+ * @param key a key
+ * @param value the value corresponding to the key
+ * @param user_data user data passed to g_hash_table_foreach()
+ * @return void
+ **/
+static
+void plugin_internal_ConfigData_cbMapStrSectionEntryCopy(gpointer key,
+ gpointer value,
+ gpointer user_data);
+
+/**
+ * @brief Function passed to g_hash_table_foreach().
+ * Function is called for each key/value pair.
+ *
+ * @param key a key
+ * @param value the value corresponding to the key
+ * @param user_data user data passed to g_hash_table_foreach()
+ * @return void
+ **/
+static
+void plugin_internal_ConfigData_cbMapStrSectionCopy(gpointer key,
+ gpointer value,
+ gpointer user_data);
+/**
+ * @brief Function passed to g_list_foreach().
+ * The function called for each element's data.
+ *
+ * @param data the element's data.
+ * @param user_data user data passed to g_list_foreach() or g_slist_foreach().
+ * @return gpointer
+ **/
+static
+gpointer plugin_internal_ConfigData_cbListSectionCopy(gconstpointer data,
+ gpointer user_data);
+
+/**
+ * @brief The function to be called to free each element's data.
+ * The function which is called when a data element is destroyed.
+ * It is passed the pointer to the data element and should free any memory and
+ * resources allocated for it.
+ *
+ * @param data the data element.
+ * @return void
+ **/
+static
+void plugin_internal_ConfigData_cbDestroySectionsList(gpointer data);
+
+/******************************************************************************
+ * Constructing object
+ ******************************************************************************/
+/**
+ * @brief Contruct object of type plugin_internal_ConfigData
+ * @return plugin_internal_ConfigData*
+ **/
+/*plugin_internal_ConfigData *plugin_internal_ConfigData_new(); */
+
+/**
+* @brief Contruct object of type plugin_internal_ConfigData and loads
+* configuration from the specified file.
+*
+* @param filepath a path to the configuration file
+* @param type expected type of configuration file, this value
+* determines how the file is parsed
+**/
+static
+plugin_internal_ConfigData *
+plugin_internal_ConfigData_new(const char *filepath, PluginConfigType type);
+
+/**
+* @brief Copy constructor.
+*
+* @param source ...
+**/
+#if 0
+static
+plugin_internal_ConfigData *
+plugin_internal_ConfigData_copy(const plugin_internal_ConfigData *source);
+#endif
+
+/******************************************************************************
+ * Destroying obect
+ ******************************************************************************/
+/**
+* @brief Removes configuration from memory, rendering this configuration invalid.
+*
+* @return void
+**/
+static
+void plugin_internal_ConfigData_clear(plugin_internal_ConfigData *self);
+
+/**
+* @brief Destructor.
+*
+**/
+static
+void plugin_internal_ConfigData_delete(plugin_internal_ConfigData *self);
+
+/******************************************************************************
+ * private methods
+ ******************************************************************************/
+
+/**
+ * @brief parse line of INI file
+ *
+ * @param self pointer to object of type plugin_internal_ConfigData
+ * @param state ...
+ * @param line pointer to the string containing line of file
+ * @return void
+ **/
+static
+void plugin_internal_ConfigData_parseLineIni(plugin_internal_ConfigData *self,
+ ConfigParserState *state,
+ const char *line);
+
+/* TODO Provide implementation */
+/**
+ * @todo Provide implementation
+ *
+ * @brief parse line of GIT config file
+ *
+ * @param self pointer to object of type plugin_internal_ConfigData
+ * @param state ...
+ * @param line pointer to the string containing line of file
+ * @return void
+ **/
+static
+void plugin_internal_ConfigData_parseLineGit(plugin_internal_ConfigData *self,
+ ConfigParserState *state,
+ const char *line);
+
+/* TODO Provide implementation */
+/**
+ * @todo Provide implementation
+ *
+ * @brief parse line of CSV config file
+ *
+ * @param self pointer to object of type plugin_internal_ConfigData
+ * @param state ...
+ * @param line pointer to the string containing line of file
+ * @param separator ...
+ * @return void
+ **/
+static
+void plugin_internal_ConfigData_parseLineCsv(plugin_internal_ConfigData *self,
+ ConfigParserState *state,
+ const char *line,
+ char separator);
+
+/* Public */
+/**
+ * @brief ...
+ *
+ * @param self pointer to object of type plugin_internal_ConfigData
+ * @param section ...
+ * @return int
+ **/
+static
+bool
+plugin_internal_ConfigData_hasSection(const plugin_internal_ConfigData *self,
+ const char *section);
+
+/**
+* @brief This method assumes that the given section exists. Use hasSection()
+* first, or use hasSectionAndKey() instead.
+*
+* @param self pointer to object of type plugin_internal_ConfigData
+* @param section name of the configuration section
+* @param key name of the key within that section
+* @return int 1 if such key exists
+**/
+static
+bool
+plugin_internal_ConfigData_hasKey(const plugin_internal_ConfigData *self,
+ const char *section,
+ const char *key);
+
+/**
+ * @brief ...
+ *
+ * @param self pointer to object of type plugin_internal_ConfigData
+ * @param section ...
+ * @param key ...
+ * @return int
+ **/
+static
+bool
+plugin_internal_ConfigData_hasSectionAndKey(const plugin_internal_ConfigData *self,
+ const char *section,
+ const char *key);
+
+/**
+ * @brief ...
+ *
+ * @param self pointer to object of type plugin_internal_ConfigData
+ * @return const char*
+ **/
+static
+const char *
+plugin_internal_ConfigData_getFilepath(const plugin_internal_ConfigData *self);
+
+/**
+ * @brief ...
+ *
+ * @param self pointer to object of type plugin_internal_ConfigData
+ * @return PluginConfigType
+ **/
+static
+PluginConfigType
+plugin_internal_ConfigData_getType(const plugin_internal_ConfigData *self);
+
+/**
+ * @brief ...
+ *
+ * @param self pointer to object of type plugin_internal_ConfigData
+ * @param section_name ...
+ * @param section_key ...
+ * @return const char*
+ **/
+static
+const char *
+plugin_internal_ConfigData_getEntry(const plugin_internal_ConfigData *self,
+ const char *section_name,
+ const char *section_key);
+
+/******************************************************************************
+ * Definitions (methods of ConfigData class)
+ ******************************************************************************/
+
+/******************************************************************************/
+static
+void plugin_internal_ConfigData_cbMapStrSectionFreeData(gpointer data)
+{
+ /* TODO Is it enough ? */
+ /* free(data); */
+ /* data = NULL; */
+}
+
+#if 0
+/******************************************************************************/
+plugin_internal_ConfigData *plugin_internal_ConfigData_new()
+{
+ plugin_internal_ConfigData *self;
+ self = (plugin_internal_ConfigData *)calloc(1, sizeof(plugin_internal_ConfigData));
+
+ GMutex *data_mutex = (GMutex *)calloc(1, sizeof(GMutex));
+ g_mutex_init(data_mutex);
+
+ self->data_mutex = data_mutex;
+ self->filepath = NULL;
+ self->type = CCT_INI;
+ self->sections = NULL;
+ self->configuration = NULL;
+
+ self->configuration = g_hash_table_new_full(g_str_hash, /* Hash function */
+ g_str_equal, /* Comparator */
+ plugin_internal_ConfigData_cbMapStrSectionFreeData, /* Key destructor */
+ plugin_internal_ConfigData_cbMapStrSectionFreeData); /* Val destructor */
+
+ return self;
+}
+#endif
+
+/******************************************************************************/
+static
+plugin_internal_ConfigData *
+plugin_internal_ConfigData_new(const char *filepath, PluginConfigType type)
+{
+ startfunc;
+
+ if (NULL == filepath) {
+ return NULL;
+ }
+
+ if (CCT_INVALID == type) {
+ return NULL;
+ }
+
+ plugin_internal_ConfigData *self;
+ self = (plugin_internal_ConfigData *)calloc(1, sizeof(plugin_internal_ConfigData));
+
+ if (NULL == self) {
+ return NULL;
+ }
+
+ GMutex *data_mutex = (GMutex *)calloc(1, sizeof(GMutex));
+ if (NULL == data_mutex) {
+ free(self);
+ return NULL;
+ }
+
+ g_mutex_init(data_mutex);
+
+ self->data_mutex = data_mutex;
+ self->filepath = strdup(filepath);
+ self->type = CCT_INI;
+ self->sections = NULL; /* sections.reserve(128); */
+ self->configuration = NULL;
+
+ self->configuration =
+ g_hash_table_new_full(g_str_hash, /* Hash function */
+ g_str_equal, /* Comparator */
+ plugin_internal_ConfigData_cbMapStrSectionFreeData, /* Key destructor */
+ plugin_internal_ConfigData_cbMapStrSectionFreeData);/* Val destructor */
+
+ FILE *fp;
+ char *line;
+ size_t len = 0;
+ ssize_t read;
+
+ fp = fopen(filepath, "r");
+
+ if (NULL == fp) {
+ /* exit(EXIT_FAILURE); */
+ if (self) {
+ if (self->data_mutex) {
+ g_mutex_clear(self->data_mutex);
+ free(self->data_mutex);
+ }
+ if (self->filepath)
+ free(self->filepath);
+ if (self->configuration)
+ g_hash_table_destroy(self->configuration);
+ free(self);
+ }
+ return NULL;
+ }
+
+ ConfigParserState state;
+
+ while ((read = getline(&line, &len, fp)) != -1) {
+ /* printf("Retrieved line of length %zu :\n", read); */
+ /* printf("%s", line); */
+
+ if (strlen(line) == 0)
+ continue;
+
+ switch (type) {
+ case CCT_INI:
+ plugin_internal_ConfigData_parseLineIni(self, &state, line);
+ break;
+ case CCT_GIT:
+ plugin_internal_ConfigData_parseLineGit(self, &state, line);
+ break;
+ case CCT_CSV_COMMA:
+ plugin_internal_ConfigData_parseLineCsv(self, &state, line, ',');
+ break;
+ case CCT_CSV_TAB:
+ plugin_internal_ConfigData_parseLineCsv(self, &state, line, '\t');
+ break;
+ case CCT_CSV_COLON:
+ plugin_internal_ConfigData_parseLineCsv(self, &state, line, ':');
+ break;
+ case CCT_CSV_SEMICOLON:
+ plugin_internal_ConfigData_parseLineCsv(self, &state, line, ';');
+ break;
+ default:
+ break;
+ }
+
+ free(line);
+ line = NULL;
+ }
+
+/* printf("configuration file %s was loaded\n", filepath); */
+ fclose(fp);
+
+ endfunc;
+ return self;
+}
+
+/******************************************************************************/
+static
+void plugin_internal_ConfigData_cbMapStrSectionEntryCopy(gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ startfunc;
+
+ plugin_internal_MapStrStr *copy_section = (plugin_internal_MapStrStr *)user_data;
+ g_hash_table_insert(copy_section, strdup((char *)key), strdup((char *)value));
+
+ endfunc;
+}
+
+/******************************************************************************/
+static
+void plugin_internal_ConfigData_cbMapStrSectionCopy(gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ startfunc;
+
+ plugin_internal_MapStrSection *copy_configuration = (plugin_internal_MapStrSection *)user_data;
+
+ plugin_internal_MapStrStr *section = (plugin_internal_MapStrStr *)value;
+
+ plugin_internal_MapStrStr *copy_section =
+ g_hash_table_new_full(g_str_hash, /* Hash function */
+ g_str_equal, /* Comparator */
+ plugin_internal_ConfigData_cbMapStrSectionFreeData, /* Key destructor */
+ plugin_internal_ConfigData_cbMapStrSectionFreeData); /* Val destructor */
+
+ g_hash_table_foreach(section, (GHFunc)plugin_internal_ConfigData_cbMapStrSectionEntryCopy, copy_section);
+
+ g_hash_table_insert(copy_configuration, strdup((char *)key), copy_section);
+
+ endfunc;
+}
+
+/******************************************************************************/
+static
+gpointer plugin_internal_ConfigData_cbListSectionCopy(gconstpointer src,
+ gpointer data)
+{
+ startfunc;
+
+ UNUSED(data);
+
+ plugin_internal_MapStrStr *section = (plugin_internal_MapStrStr *)src;
+
+ plugin_internal_MapStrStr *copy_section =
+ g_hash_table_new_full(g_str_hash, /* Hash function */
+ g_str_equal, /* Comparator */
+ plugin_internal_ConfigData_cbMapStrSectionFreeData, /* Key destructor */
+ plugin_internal_ConfigData_cbMapStrSectionFreeData); /* Val destructor */
+
+ g_hash_table_foreach(section,
+ (GHFunc)plugin_internal_ConfigData_cbMapStrSectionEntryCopy,
+ copy_section);
+
+ endfunc;
+ return copy_section;
+}
+
+/******************************************************************************/
+#if 0
+static
+plugin_internal_ConfigData *
+plugin_internal_ConfigData_copy(const plugin_internal_ConfigData *source)
+{
+ startfunc;
+
+ if (NULL == source) {
+ return NULL;
+ }
+
+ plugin_internal_ConfigData *self;
+ self = (plugin_internal_ConfigData *)calloc(1, sizeof(plugin_internal_ConfigData));
+
+ GMutex *data_mutex = (GMutex *)calloc(1, sizeof(GMutex));
+ g_mutex_init(data_mutex);
+
+ g_mutex_lock(source->data_mutex);
+
+ self->data_mutex = data_mutex;
+ self->filepath = strdup(source->filepath);
+ self->type = source->type;
+
+ self->sections = NULL;
+
+ self->configuration =
+ g_hash_table_new_full(g_str_hash, /* Hash function */
+ g_str_equal, /* Comparator */
+ plugin_internal_ConfigData_cbMapStrSectionFreeData, /* Key destructor */
+ plugin_internal_ConfigData_cbMapStrSectionFreeData);/* Val destructor */
+
+ /* copy source->configuration to self->configuration */
+ g_hash_table_foreach(source->configuration,
+ (GHFunc)plugin_internal_ConfigData_cbMapStrSectionCopy,
+ self->configuration);
+
+ /* copy source->sections to self->sections */
+ self->sections = g_list_copy_deep(source->sections,
+ plugin_internal_ConfigData_cbListSectionCopy,
+ NULL);
+
+ g_mutex_unlock(source->data_mutex);
+
+ endfunc;
+ return NULL;
+}
+#endif
+/******************************************************************************/
+static
+void plugin_internal_ConfigData_delete(plugin_internal_ConfigData *self)
+{
+ startfunc;
+
+ if (self) {
+ plugin_internal_ConfigData_clear(self);
+ }
+
+ endfunc;
+}
+
+/******************************************************************************
+ * PRIVATE
+ ******************************************************************************/
+static
+void
+plugin_internal_ConfigData_parseLineIni(plugin_internal_ConfigData *self,
+ ConfigParserState *state,
+ const char *line)
+{
+ startfunc;
+
+ if (NULL == self || NULL == line) {
+ return;
+ }
+
+ if (line[0] == ';')
+ return;
+
+ if (line[0] == '[') {
+ line = plugin_internal_trim((char *)line);
+
+ char *begin = strchr((char *)line, '[');
+ char *end = strrchr((char *)line, ']');
+
+ if (NULL == end) {
+ printf("Invalid section name %p\n", line);
+ return;
+ }
+
+ int section_name_len = end - begin - 1;
+
+ char *section_name = (char *)calloc(1, section_name_len + 1);
+ if (NULL == section_name) {
+ return;
+ }
+
+ strncpy(section_name, line + 1, section_name_len);
+ section_name[section_name_len] = '\0';
+
+ plugin_internal_MapStrStr *section =
+ g_hash_table_new_full(g_str_hash, /* Hash function */
+ g_str_equal, /* Comparator */
+ plugin_internal_ConfigData_cbMapStrSectionFreeData, /* Key destructor */
+ plugin_internal_ConfigData_cbMapStrSectionFreeData); /* Val destructor */
+
+ self->sections = g_list_append(self->sections, section);
+ /*sections.push_back(MapStrStr()); */
+
+ /*MapStrStr *section = &(sections[sections.size() - 1]); */
+ g_hash_table_insert(self->configuration, strdup(section_name), section);
+
+ /* configuration[section_name] = section; */
+
+ state->current_section_name = section_name;
+ state->current_section = section;
+ } else {
+ /* ---------------------------------------------------------------------
+ * |0|1|2|3|4|5|6|7|8|
+ * ---------------------------------------------------------------------
+ * |K|E|Y|1|=|V|A|L|1|
+ * ---------------------------------------------------------------------
+ * pch = 4
+ * len_key = 4
+ * len_val = 4
+ * len = 9
+ */
+ line = plugin_internal_trim((char *)line);
+ const char *pch = strchr((char *)line, '=');
+
+ if (pch != NULL) {
+ int len = strlen(line);
+ int key_len = pch - line + 1 ; /* +'\0' */
+ int value_len = len - key_len + 1; /* +'\0' */
+
+ char *key = (char *)calloc(1, key_len);
+ char *value = (char *)calloc(1, value_len);
+
+ if (NULL != key && NULL != value) {
+ strncpy(key, line, key_len - 1);
+ key[key_len - 1] = '\0';
+
+ strncpy(value, pch + 1, value_len - 1);
+ value[value_len - 1] = '\0';
+
+ g_hash_table_insert(state->current_section, strdup(key), strdup(value));
+ }
+ if (NULL != key) {
+ free(key);
+ key = NULL;
+ }
+ if (NULL != value) {
+ free(value);
+ value = NULL;
+ }
+ }
+ }
+
+ endfunc;
+}
+
+/******************************************************************************/
+static
+void
+plugin_internal_ConfigData_parseLineGit(plugin_internal_ConfigData *self,
+ ConfigParserState *state,
+ const char *line)
+{
+ startfunc;
+
+ if (NULL == self) {
+ return;
+ }
+
+ UNUSED(state);
+ UNUSED(line);
+
+ endfunc;
+}
+
+/******************************************************************************/
+static
+void
+plugin_internal_ConfigData_parseLineCsv(plugin_internal_ConfigData *self,
+ ConfigParserState *state,
+ const char *line,
+ char separator)
+{
+ startfunc;
+
+ if (NULL == self) {
+ return;
+ }
+
+ UNUSED(state);
+ UNUSED(line);
+ UNUSED(separator);
+
+ endfunc;
+}
+
+/******************************************************************************/
+static
+void plugin_internal_ConfigData_cbDestroySectionsList(gpointer data)
+{
+ startfunc;
+
+ plugin_internal_MapStrStr *section = (plugin_internal_MapStrStr *)data;
+ g_hash_table_destroy(section);
+
+ endfunc;
+}
+
+/******************************************************************************/
+static
+void plugin_internal_ConfigData_clear(plugin_internal_ConfigData *self)
+{
+ startfunc;
+
+ if (NULL == self) {
+ return;
+ }
+
+ free(self->filepath);
+
+ self->type = CCT_INVALID;
+
+ g_hash_table_destroy(self->configuration);
+ self->configuration = NULL;
+ g_list_free_full(self->sections, plugin_internal_ConfigData_cbDestroySectionsList);
+
+ endfunc;
+}
+
+/******************************************************************************/
+static
+bool
+plugin_internal_ConfigData_hasKey(const plugin_internal_ConfigData *self,
+ const char *section_name,
+ const char *section_key)
+{
+ startfunc;
+
+ if (NULL == self || NULL == self->configuration) {
+ return false;
+ }
+
+ g_mutex_lock(self->data_mutex);
+
+ gconstpointer lookup_key = (gconstpointer)section_name;
+ gpointer orig_key = NULL; /* key of self->configuration */
+ gpointer value = NULL; /* value of self->configuration */
+
+ gboolean result = g_hash_table_lookup_extended(self->configuration,
+ lookup_key,
+ &orig_key,
+ &value);
+
+ if (TRUE == result && value) {
+ plugin_internal_MapStrStr *ptrMapSection = (plugin_internal_MapStrStr *)value ;
+
+ lookup_key = (gconstpointer)section_key;
+ orig_key = NULL; /* key of ptrMapSection */
+ value = NULL; /* value of ptrMapSection */
+
+ result = g_hash_table_lookup_extended(ptrMapSection,
+ lookup_key,
+ &orig_key,
+ &value);
+ }
+
+ g_mutex_unlock(self->data_mutex);
+
+ endfunc;
+ return result;
+}
+
+/******************************************************************************
+ * PUBLIC
+ ******************************************************************************/
+static
+bool
+plugin_internal_ConfigData_hasSection(const plugin_internal_ConfigData *self,
+ const char *section_name)
+{
+ startfunc;
+
+ if (NULL == self) {
+ return false;
+ }
+
+ g_mutex_lock(self->data_mutex);
+
+ gconstpointer lookup_key = (gconstpointer)section_name;
+ gpointer orig_key = NULL; /* key of self->configuration */
+ gpointer value = NULL; /* value of self->configuration */
+
+ gboolean result = g_hash_table_lookup_extended(self->configuration,
+ lookup_key,
+ &orig_key,
+ &value);
+
+ g_mutex_unlock(self->data_mutex);
+
+ endfunc;
+ return result;
+}
+
+/******************************************************************************/
+static
+bool
+plugin_internal_ConfigData_hasSectionAndKey(const plugin_internal_ConfigData *self,
+ const char *section_name,
+ const char *section_key)
+{
+ startfunc;
+
+ if (NULL == self) {
+ return false;
+ }
+
+ g_mutex_lock(self->data_mutex);
+
+ gconstpointer lookup_key = (gconstpointer)section_name;
+ gpointer orig_key = NULL; /* key of self->configuration */
+ gpointer value = NULL; /* value of self->configuration */
+
+ gboolean result = g_hash_table_lookup_extended(self->configuration,
+ lookup_key,
+ &orig_key,
+ &value);
+
+ if (TRUE == result && value) {
+ plugin_internal_MapStrStr *ptrMapSection = (plugin_internal_MapStrStr *)value ;
+ lookup_key = (gconstpointer)section_key;
+ orig_key = NULL; /* key of ptrMapSection */
+ value = NULL; /* value of ptrMapSection */
+
+ result = g_hash_table_lookup_extended(ptrMapSection,
+ lookup_key,
+ &orig_key,
+ &value);
+ }
+
+ g_mutex_unlock(self->data_mutex);
+
+ endfunc;
+ return result;
+}
+
+/******************************************************************************/
+static
+const char *
+plugin_internal_ConfigData_getFilepath(const plugin_internal_ConfigData *self)
+{
+ startfunc;
+
+ if (NULL == self) {
+ return NULL;
+ }
+
+ g_mutex_lock(self->data_mutex);
+
+ const char *result = self->filepath;
+
+ g_mutex_unlock(self->data_mutex);
+
+ endfunc;
+ return result;
+}
+
+/******************************************************************************/
+static
+PluginConfigType
+plugin_internal_ConfigData_getType(const plugin_internal_ConfigData *self)
+{
+ startfunc;
+
+ if (NULL == self) {
+ return CCT_INVALID;
+ }
+
+ g_mutex_lock(self->data_mutex);
+
+ PluginConfigType result = self->type;
+
+ g_mutex_unlock(self->data_mutex);
+
+ endfunc;
+ return result;
+}
+
+/******************************************************************************/
+static
+const char *
+plugin_internal_ConfigData_getEntry(const plugin_internal_ConfigData *self,
+ const char *section_name,
+ const char *section_key)
+{
+ startfunc;
+
+ if (NULL == self) {
+ return NULL;
+ }
+
+ g_mutex_lock(self->data_mutex);
+
+ gconstpointer lookup_key = (gconstpointer)section_name;
+ gpointer orig_key = NULL; /* key of self->configuration */
+ gpointer value = NULL; /* value of self->configuration */
+
+ gboolean result = g_hash_table_lookup_extended(self->configuration,
+ lookup_key,
+ &orig_key,
+ &value);
+
+ if (TRUE == result && value) {
+ plugin_internal_MapStrStr *ptrMapSection = (plugin_internal_MapStrStr *)value ;
+
+ lookup_key = (gconstpointer)section_key;
+ orig_key = NULL; /* key of ptrMapSection */
+ value = NULL; /* value of ptrMapSection */
+
+ result = g_hash_table_lookup_extended(ptrMapSection,
+ lookup_key,
+ &orig_key,
+ &value);
+ }
+
+ g_mutex_unlock(self->data_mutex);
+
+ endfunc;
+ return (char *)value;
+}
+
+/******************************************************************************
+ * Config class
+ ******************************************************************************/
+/**
+ * @brief General-purpose, class for loading and reading configuration from
+ * simple plaintext files.
+ **/
+typedef struct plugin_Config {
+ bool _loaded;
+ plugin_internal_ConfigData *_configuration;
+} plugin_Config;
+
+/******************************************************************************
+ * Declarations (methods of Config class)
+ ******************************************************************************/
+
+/**
+ * @brief Construct object of type plugin_Config
+ *
+ * @return plugin_Config*
+ **/
+static
+plugin_Config *plugin_Config_new();
+
+/**
+ * @brief Destroy object of type plugin_Config
+ *
+ * @param self pointer to object of type plugin_Config
+ * @return void
+ **/
+static
+void plugin_Config_delete(plugin_Config *self);
+
+/**
+ * @brief Loads configuration to memory and/or gets raw data from configuration.
+ *
+ * @param self pointer to object of type plugin_Config
+ * @param section will return value attached to a key from this section
+ * @param key will return value attached to this key
+ * @return char*
+ **/
+static
+const char *
+plugin_Config_getRaw(plugin_Config *self, const char *section, const char *key);
+
+/**
+ * @brief Loads the configuration from a given file into memory.
+ *
+ * @param self pointer to object of type plugin_Config
+ * @param filepath path to the configuration file that will be loaded
+ * @param type expected type of configuration file, this value determines
+ * how the file is parsed
+ * @return int return 1 if successful, 0 otherwise
+ */
+static
+int
+plugin_Config_load(plugin_Config *self, const char *filepath, PluginConfigType type);
+
+/**
+ * @brief Unloads the configuration from the memory.
+ *
+ * The configuration is automatically unloaded when the Config object is
+ * destoyed, so this method does not have to be executed unless you need
+ * to extremely lower memory usage and few bytes matter.
+ *
+ * @param self pointer to object of type plugin_Config
+ * @return void
+ **/
+static void plugin_Config_unload(plugin_Config *self);
+
+/**
+* @brief Checks wheteher config file has been loaded.
+*
+* @return int return 1 if successful, 0 otherwise
+**/
+static bool plugin_Config_isLoaded(plugin_Config *self);
+
+/**
+ * @brief From loaded configuration, gets string value attached to given key.
+ *
+ * @param self pointer to object of type plugin_Config
+ * @param section ...
+ * @param key ...
+ * @return char* value attached to the key from the section
+ **/
+static
+const char *
+plugin_Config_getString(plugin_Config *self, const char *section, const char *key);
+
+/**
+ * @brief From loaded configuration, gets integer value attached to given key.
+ *
+ * @param self pointer to object of type plugin_Config
+ * @param section will return value attached to a key from this section
+ * @param key will return value attached to this key
+ * @return int
+ **/
+static
+int plugin_Config_getInt(plugin_Config *self, const char *section, const char *key);
+
+/**
+ * @brief From _loaded configuration, gets double value attached to given key.
+ *
+ * @param self pointer to object of type plugin_Config
+ * @param section will return value attached to a key from this section
+ * @param key will return value attached to this key
+ * @return double
+ **/
+static
+double getDouble(plugin_Config *self, const char *section, const char *key);
+
+/******************************************************************************
+ * Definitiions (methods of Config class)
+ ******************************************************************************/
+static
+plugin_Config *plugin_Config_new()
+{
+ startfunc;
+
+ plugin_Config *self;
+ self = (plugin_Config *)calloc(1, sizeof(plugin_Config));
+
+ if (NULL == self) {
+ return NULL;
+ }
+
+ self->_loaded = false;
+ self->_configuration = NULL;
+
+ endfunc;
+ return self;
+}
+
+/******************************************************************************/
+static
+void plugin_Config_delete(plugin_Config *self)
+{
+ startfunc;
+
+ if (self && self->_configuration) {
+ free(self->_configuration);
+ self->_configuration = NULL;
+ } else {
+ plugin_config_error("Invalid parameter");
+ }
+ free(self);
+
+ endfunc;
+}
+
+/******************************************************************************/
+static
+const char *
+plugin_Config_getRaw(plugin_Config *self, const char *section, const char *key)
+{
+ startfunc;
+
+ const char *ret = NULL;
+
+ if (self && self->_configuration) {
+ if (plugin_internal_ConfigData_hasSectionAndKey(
+ (const plugin_internal_ConfigData *)self->_configuration, section, key)) {
+ ret = plugin_internal_ConfigData_getEntry((const plugin_internal_ConfigData *)self->_configuration,
+ section,
+ key);
+ }
+ } else {
+ plugin_config_error("Invalid parameter");
+ }
+
+ endfunc;
+ return ret;
+}
+
+/******************************************************************************/
+static
+int plugin_Config_load(plugin_Config *self, const char *filepath, PluginConfigType type)
+{
+ startfunc;
+ int ret = 0;
+
+ if (self) {
+ if (self->_configuration) {
+ plugin_internal_ConfigData_delete(self->_configuration);
+ self->_configuration = NULL;
+ }
+
+ if (filepath && strlen(filepath) > 0) {
+ self->_configuration = plugin_internal_ConfigData_new(filepath, type);
+
+ if (self->_configuration) {
+ self->_loaded = 1;
+ ret = 1;
+ }
+ }
+ } else {
+ plugin_config_error("Invalid parameter");
+ }
+
+ endfunc;
+ return ret;
+}
+
+/******************************************************************************/
+static
+void plugin_Config_unload(plugin_Config *self)
+{
+ startfunc;
+
+ if (self && self->_configuration) {
+ plugin_internal_ConfigData_delete(self->_configuration);
+ self->_configuration = NULL;
+ self->_loaded = false;
+ } else {
+ plugin_config_error("Invalid parameter");
+ }
+
+ endfunc;
+}
+
+/******************************************************************************/
+static
+bool plugin_Config_isLoaded(plugin_Config *self)
+{
+ startfunc;
+
+ bool ret = false;
+
+ if (self) {
+ ret = self->_loaded;
+ } else {
+ plugin_config_error("Invalid parameter");
+ }
+
+ endfunc;
+ return ret;
+}
+
+/******************************************************************************/
+static
+const char *
+plugin_Config_getString(plugin_Config *self, const char *section, const char *key)
+{
+ plugin_config_debug_func();
+
+ return plugin_Config_getRaw(self, section, key);
+}
+
+
+/******************************************************************************/
+static
+int plugin_Config_getInt(plugin_Config *self, const char *section, const char *key)
+{
+ plugin_config_debug_func();
+
+ const char *result = plugin_Config_getRaw(self, section, key);
+ if (NULL == result) {
+ return INT_MIN;
+ }
+
+ return atoi(result);
+
+}
+
+/******************************************************************************/
+static
+double plugin_Config_getDouble(plugin_Config *self, const char *section, const char *key)
+{
+ plugin_config_debug_func();
+
+ const char *result = plugin_Config_getRaw(self, section, key);
+ if (NULL == result) {
+ return DBL_MIN;
+ }
+
+ return atof(result);
+}
+
+/******************************************************************************
+ * C API implementation
+ ******************************************************************************/
+
+/******************************************************************************/
+ConfigHandle plugin_config_create()
+{
+ plugin_config_debug_func();
+
+ return (ConfigHandle)plugin_Config_new();
+}
+
+/******************************************************************************/
+void plugin_config_delete(ConfigHandle config_handle)
+{
+ startfunc;
+
+ plugin_Config_delete((plugin_Config *)config_handle);
+
+ endfunc;
+}
+
+/******************************************************************************/
+void plugin_config_load(ConfigHandle config_handle, const char *filepath,
+ PluginConfigType type)
+{
+ startfunc;
+
+ if (config_handle) {
+ plugin_Config *pConfig = (plugin_Config *)(config_handle);
+ plugin_Config_load(pConfig, filepath, type);
+ } else {
+ plugin_config_error("Invalid parameter");
+ }
+
+ endfunc;
+}
+
+/******************************************************************************/
+void plugin_config_unload(ConfigHandle config_handle)
+{
+ startfunc;
+
+ if (config_handle) {
+ plugin_Config *pConfig = (plugin_Config *)(config_handle);
+ plugin_Config_unload(pConfig);
+ } else {
+ plugin_config_error("Invalid parameter");
+ }
+
+ endfunc;
+}
+
+/******************************************************************************/
+const char *plugin_config_get_string(ConfigHandle config_handle,
+ const char *section, const char *key)
+{
+ startfunc;
+
+ const char *val = NULL;
+
+ if (config_handle) {
+ plugin_Config *pConfig = (plugin_Config *)(config_handle);
+ val = plugin_Config_getString(pConfig, section, key);
+ } else {
+ plugin_config_error("Invalid parameter");
+ }
+
+ endfunc;
+ return val;
+}
+
+/******************************************************************************/
+int plugin_config_get_int(ConfigHandle config_handle, const char *section, const char *key)
+{
+ startfunc;
+
+ int ret = 0;
+
+ if (config_handle) {
+ plugin_Config *pConfig = (plugin_Config *)(config_handle);
+ ret = plugin_Config_getInt(pConfig, section, key);
+ } else {
+ plugin_config_error("Invalid parameter");
+ }
+
+ endfunc;
+ return ret;
+}
+
+/******************************************************************************/
+double plugin_config_get_double(ConfigHandle config_handle, const char *section, const char *key)
+{
+ startfunc;
+
+ double ret = 0;
+
+ if (config_handle) {
+ plugin_Config *pConfig = (plugin_Config *)(config_handle);
+ ret = plugin_Config_getDouble(pConfig, section, key);
+ } else {
+ plugin_config_error("Invalid parameter");
+ }
+
+ endfunc;
+ return ret;
+}
+
+/******************************************************************************/
+bool plugin_config_is_loaded(ConfigHandle config_handle)
+{
+ startfunc;
+ bool ret = false;
+
+ if (config_handle) {
+ plugin_Config *pConfig = (plugin_Config *)(config_handle);
+ ret = plugin_Config_isLoaded(pConfig);
+ } else {
+ plugin_config_error("Invalid parameter");
+ }
+
+ endfunc;
+ return ret;
+}
--- /dev/null
+/*
+* Copyright (c) 2011 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 pluginConfig.hpp
+ * @author
+ * @date
+ *
+ * @author
+ *
+ * @brief Plugin configuration parser done in C++.
+ */
+
+#include <fstream>
+#include <string>
+#include <map>
+#include <vector>
+//
+// // threads
+#include <glib.h>
+//
+// // internal
+#include <algorithm>
+
+#include "pluginConfig.h"
+#include "pluginConfig.hpp"
+
+#define UNUSED(x) (void)(x)
+
+////////////////////////////////////////////////////////////////////////////////
+// Trimming functions
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @brief Namespace for all content related to plugin.
+ **/
+namespace plugin
+{
+
+ /**
+ * @brief Namespace for internal code related to configuration.
+ **/
+ namespace internal
+ {
+
+// trimming functions taken from:
+// https://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring
+
+ /**
+ * @brief trim from start, i.e. left side
+ *
+ * @param s ...
+ * @return :string&
+ **/
+ static inline std::string <rim(std::string &s)
+ {
+ s.erase(s.begin(), std::find_if(s.begin(), s.end(),
+ std::not1(std::ptr_fun<int, int>(std::isspace))));
+ return s;
+ }
+
+ /**
+ * @brief trim from end, i.e. right side
+ *
+ * @param s ...
+ * @return :string&
+ **/
+ static inline std::string &rtrim(std::string &s)
+ {
+ s.erase(std::find_if(s.rbegin(), s.rend(),
+ std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
+ return s;
+ }
+
+ /**
+ * @brief trim from both ends
+ *
+ * @param s ...
+ * @return :string&
+ **/
+ static inline std::string &trim(std::string &s)
+ {
+ return ltrim(rtrim(s));
+ }
+ } // end of namespace internal
+} // endof plugin
+
+////////////////////////////////////////////////////////////////////////////////
+//
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * @brief Namespace for all content related to plugin.
+ **/
+namespace plugin
+{
+ /**
+ * @brief Namespace for internal code related to configuration.
+ **/
+ namespace internal
+ {
+ /**
+ * @brief Typedef for configuration key-value map.
+ * @typedef MapStrStr
+ * Section data
+ * |---------------------------|----------------------------------------|
+ * | KEY : char* | VALUE : char* |
+ * |---------------------------|----------------------------------------|
+ * | KEY1 | VAL1 |
+ * |---------------------------|----------------------------------------|
+ * | KEY2 | VAL2 |
+ * |---------------------------|----------------------------------------|
+ * | KEY3 | VAL3 |
+ * |---------------------------|----------------------------------------|
+ */
+ typedef std::map<std::string, std::string> MapStrStr;
+
+ typedef std::pair<std::string, std::string> MapStrStrEntry;
+
+ /**
+ * @typedef ListSection
+ * Sections
+ * |------------------------------------------|
+ * | SECTION PTR : MapStrStr * |
+ * |------------------------------------------|
+ * | SP1 |
+ * |------------------------------------------|
+ * | SP2 |
+ * |------------------------------------------|
+ * | SN3 |
+ * |------------------------------------------|
+ */
+ typedef std::vector<MapStrStr> ListSection;
+
+
+ /**
+ * @brief Typedef for configuration key-value map.
+ * @typedef plugin_internal_MapStrSection
+ * Sections
+ * |---------------------------|----------------------------------------|
+ * | SECTION NAME : char* | SECTION PTR : MapStrStr * |
+ * |---------------------------|----------------------------------------|
+ * | SN1 | SP1 |
+ * |---------------------------|----------------------------------------|
+ * | SN2 | SP2 |
+ * |---------------------------|----------------------------------------|
+ * | SN3 | SP3 |
+ * |---------------------------|----------------------------------------|
+ */
+ typedef std::map<std::string, MapStrStr *> MapStrSection;
+
+ typedef std::pair<std::string, MapStrStr *> MapStrSectionEntry;
+
+ } // end of namespace internal
+} // end of namespace plugin
+
+////////////////////////////////////////////////////////////////////////////////
+// ConfigParserState class
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @brief Namespace for all content related to plugin.
+ **/
+namespace plugin
+{
+ /**
+ * @brief Namespace for internal code related to configuration.
+ **/
+ namespace internal
+ {
+ /**
+ * @brief For storing state of the parser between running line-parsing functions.
+ **/
+ class ConfigParserState
+ {
+ public:
+ std::string current_section_name;
+ MapStrStr *current_section;
+ };
+ } // end of namespace internal
+} // end of namespace plugin
+
+/**
+ * @brief Namespace for all content related to plugin.
+ **/
+namespace plugin
+{
+ /**
+ * @brief Namespace for internal code related to configuration.
+ **/
+ namespace internal
+ {
+ ////////////////////////////////////////////////////////////////////////
+ /**
+ * @brief Internal backing storage for configuration.
+ *
+ * Getters and assignment operator are thread safe, constructors and destructor are not.
+ *
+ **/
+ class ConfigData
+ {
+ private:
+
+ GMutex *data_mutex;
+
+ /**
+ * @brief Filepath to the read configuration file.
+ **/
+ std::string filepath;
+
+ /**
+ * @brief Describes layout of the data in the file.
+ **/
+ PluginConfigType type;
+
+ /**
+ * @brief Variable that stores the all sections of configuration,
+ * meant to be accessed through the field 'configuration'.
+ **/
+ ListSection sections;
+
+ /**
+ * @brief Variable that stores the whole configuration.
+ **/
+ MapStrSection configuration;
+
+ public:
+ ConfigData()
+ : data_mutex(new GMutex), filepath()
+ {
+ g_mutex_init(data_mutex);
+ }
+
+ /**
+ * @brief Loads configuration from the specified file.
+ *
+ * @param filepath a path to the configuration file
+ * @param type expected type of configuration file, this value
+ * determines how the file is parsed
+ **/
+ ConfigData(const std::string &filepath, PluginConfigType type)
+ : data_mutex(new GMutex), filepath(filepath), type(type)
+ {
+ g_mutex_init(data_mutex);
+ sections.reserve(128);
+ std::ifstream in(filepath);
+ ConfigParserState state;
+
+ while (in.good())
+ {
+ std::string line;
+ std::getline(in, line);
+
+ if (line.length() == 0)
+ continue;
+
+ switch (type)
+ {
+ case PluginConfigType::CCT_INI:
+ parseLineIni(state, line);
+ break;
+ case PluginConfigType::CCT_GIT:
+ parseLineGit(state, line);
+ break;
+ case PluginConfigType::CCT_CSV_COMMA:
+ parseLineCsv(state, line, ',');
+ break;
+ case PluginConfigType::CCT_CSV_TAB:
+ parseLineCsv(state, line, '\t');
+ break;
+ case PluginConfigType::CCT_CSV_COLON:
+ parseLineCsv(state, line, ':');
+ break;
+ case PluginConfigType::CCT_CSV_SEMICOLON:
+ parseLineCsv(state, line, ';');
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (in.is_open())
+ {
+#ifdef DEBUG
+ std::cout << "* configuration file " << filepath << " was _loaded" << std::endl;
+#endif
+ in.close();
+ }
+ }
+
+ /**
+ * @brief Copy constructor.
+ *
+ * @param source ...
+ **/
+ ConfigData(const plugin::internal::ConfigData &source)
+ : data_mutex(new GMutex), filepath(), type(), sections(), configuration()
+ {
+ g_mutex_init(data_mutex);
+ g_mutex_lock(source.data_mutex);
+ filepath = source.filepath;
+ type = source.type;
+ sections = source.sections;
+
+ for (auto it = source.configuration.begin(); it != source.configuration.end(); ++it)
+ {
+ size_t index = 0;
+ bool found = false;
+
+ for (auto sit = source.sections.begin(); sit != source.sections.end(); ++sit, ++index)
+ if (it->second == &(*sit))
+ {
+ found = true;
+ break;
+ }
+
+ if (!found)
+ continue;
+
+ configuration[it->first] = &(sections.data()[index]);
+ }
+
+ g_mutex_unlock(source.data_mutex);
+ }
+
+ /**
+ * @brief Assignment operator.
+ *
+ * @param source ...
+ * @return :internal::ConfigData&
+ **/
+ plugin::internal::ConfigData &operator=(const plugin::internal::ConfigData &source)
+ {
+ if (this == &source)
+ return *this;
+
+ if (this < &source)
+ {
+ g_mutex_lock(data_mutex);
+ g_mutex_lock(source.data_mutex);
+ }
+ else
+ {
+ g_mutex_lock(source.data_mutex);
+ g_mutex_lock(data_mutex);
+ }
+
+ filepath = source.filepath;
+ type = source.type;
+ sections = source.sections;
+ configuration = MapStrSection();
+
+ for (auto it = source.configuration.begin(); it != source.configuration.end(); ++it)
+ {
+ size_t index = 0;
+ bool found = false;
+
+ for (auto sit = source.sections.begin(); sit != source.sections.end(); ++sit, ++index)
+ if (it->second == &(*sit))
+ {
+ found = true;
+ break;
+ }
+
+ if (!found)
+ continue;
+
+ configuration[it->first] = &(sections.data()[index]);
+ }
+
+ if (this < &source)
+ {
+ g_mutex_unlock(source.data_mutex);
+ g_mutex_unlock(data_mutex);
+ }
+ else
+ {
+ g_mutex_unlock(data_mutex);
+ g_mutex_unlock(source.data_mutex);
+ }
+
+ return *this;
+ }
+
+ /**
+ * @brief Destructor.
+ *
+ **/
+ ~ConfigData()
+ {
+ clear();
+ g_mutex_clear(data_mutex);
+ delete data_mutex;
+ }
+
+ private:
+ void parseLineIni(ConfigParserState &state, const std::string &line)
+ {
+ if (line[0] == ';')
+ return;
+
+ if (line[0] == '[')
+ {
+ std::string section_name = line.substr(1, line.length() - 2);
+ sections.push_back(MapStrStr());
+ MapStrStr *section = &(sections[sections.size() - 1]);
+ configuration[section_name] = section;
+ state.current_section_name = section_name;
+ state.current_section = section;
+ }
+ else
+ {
+ size_t pos = line.find('=');
+ std::string key = line.substr(0, pos);
+ std::string value = line.substr(pos + 1);
+ state.current_section->insert(MapStrStrEntry(key, value));
+ }
+ }
+
+ void parseLineGit(ConfigParserState &state, const std::string &line)
+ {
+ if (line[0] == ';' || line[0] == '#')
+ return;
+
+ if (line[0] == '[')
+ {
+ std::string section_name = line.substr(1, line.length() - 2);
+ sections.push_back(MapStrStr());
+ MapStrStr *section = &(sections[sections.size() - 1]);
+ configuration[section_name] = section;
+ state.current_section_name = section_name;
+ state.current_section = section;
+ }
+ else
+ {
+ size_t pos = line.find(" = ");
+ std::string key = line.substr(0, pos);
+ std::string value = line.substr(pos + 3);
+ ltrim(key);
+ state.current_section->insert(MapStrStrEntry(key, value));
+ }
+ }
+
+ void parseLineCsv(ConfigParserState &state, const std::string &line, char separator)
+ {
+ UNUSED(state);
+ size_t pos1 = line.find_first_of(separator);
+ size_t pos2 = line.find_last_of(separator);
+ std::string section = line.substr(0, pos1);
+ std::string key = line.substr(pos1 + 1, pos2 - pos1 - 1);
+ std::string value = line.substr(pos2 + 1);
+ auto it = configuration.find(section);
+
+ if (it == configuration.end())
+ {
+ sections.push_back(MapStrStr());
+ configuration[section] = &(sections[sections.size() - 1]);
+ configuration[section]->insert(MapStrStrEntry(key, value));
+ }
+ else
+ it->second->insert(MapStrStrEntry(key, value));
+ }
+
+ /**
+ * @brief Removes configuration from memory, rendering this configuration invalid.
+ *
+ * @return void
+ **/
+ void clear()
+ {
+ filepath = std::string();
+ //for(auto it = configuration.begin(); it != configuration.end(), ++it)
+ // delete *it;
+ type = PluginConfigType::CCT_INVALID;
+ configuration.clear();
+ sections.clear();
+ }
+
+ public:
+ inline bool hasSection(const std::string §ion) const
+ {
+ g_mutex_lock(data_mutex);
+ bool result = configuration.find(section) != configuration.end();
+ g_mutex_unlock(data_mutex);
+ return result;
+ }
+
+
+ /**
+ * @brief This method assumes that the given section exists. Use hasSection()
+ * first, or use hasSectionAndKey() instead.
+ *
+ * @param section name of the configuration section
+ * @param key name of the key within that section
+ * @return bool true if such key exists
+ **/
+ inline bool hasKey(const std::string §ion, const std::string &key) const
+ {
+ g_mutex_lock(data_mutex);
+ bool result = configuration.at(section)->find(key) != configuration.at(section)->end();
+ g_mutex_unlock(data_mutex);
+ return result;
+ }
+
+ inline bool hasSectionAndKey(const std::string §ion, const std::string &key) const
+ {
+ g_mutex_lock(data_mutex);
+ bool result = configuration.find(section) != configuration.end()
+ && configuration.at(section)->find(key) != configuration.at(section)->end();
+ g_mutex_unlock(data_mutex);
+ return result;
+ }
+
+ inline const std::string &getFilepath() const
+ {
+ g_mutex_lock(data_mutex);
+ const std::string &result = filepath;
+ g_mutex_unlock(data_mutex);
+ return result;
+ }
+
+ inline PluginConfigType getType() const
+ {
+ g_mutex_lock(data_mutex);
+ PluginConfigType result = type;
+ g_mutex_unlock(data_mutex);
+ return result;
+ }
+
+ // not thread-safe
+ //inline const MapStrStr& get_section(const std::string& section) const;
+
+ inline const std::string &getEntry(const std::string §ion, const std::string &key) const
+ {
+ g_mutex_lock(data_mutex);
+ const std::string &result = configuration.at(section)->at(key);
+ g_mutex_unlock(data_mutex);
+ return result;
+ }
+
+ public:
+ friend std::ostream &operator<<(std::ostream &out, const ConfigData &configuration)
+ {
+ out << "sections: " << configuration.configuration.size() << std::endl;
+
+ for (auto it = configuration.configuration.begin(); it != configuration.configuration.end(); ++it)
+ {
+ out << "'" << it->first << "'" << std::endl;
+
+#ifdef __GNUC__
+#include <features.h>
+#if __GNUC_PREREQ(4,7)
+
+ // If gcc_version >= 4.7
+ if (it->second == nullptr)
+ {
+#else
+
+ if (it->second == NULL)
+ {
+#endif
+#else
+
+ // If not gcc
+ if (it->second == NULL)
+ {
+#endif
+ out << " nullptr!" << std::endl;
+ }
+ else
+ {
+ out << " entries: " << it->second->size() << std::endl;
+
+ for (auto sit = it->second->begin(); sit != it->second->end(); ++sit)
+ out << " '" << sit->first << "' -> '" << sit->second << "'" << std::endl;
+ }
+ }
+
+ return out;
+ }
+
+ }; // end of class ConfigData
+ } // end of namespace internal
+} // end of namespace plugin
+
+////////////////////////////////////////////////////////////////////////////////
+// C++ API implementation
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @brief Namespace for all content related to plugin.
+ **/
+namespace plugin
+{
+ Config::Config()
+ {
+ _loaded = false;
+ _configuration = NULL;
+ }
+
+ Config::~Config()
+ {
+ if (_configuration != NULL)
+ {
+ delete _configuration;
+ _configuration = NULL;
+ }
+ }
+
+ std::string Config::_getRaw(const std::string §ion, const std::string &key)
+ {
+ if (NULL == _configuration)
+ {
+ return std::string();
+ }
+
+ if (!_configuration->hasSectionAndKey(section, key))
+ return std::string();
+
+ return _configuration->getEntry(section, key);
+ }
+
+ const std::string *Config::_getRawPtr(const std::string §ion, const std::string &key)
+ {
+ if (NULL == _configuration)
+ {
+ return NULL;
+ }
+
+ if (!_configuration->hasSectionAndKey(section, key))
+ return NULL;
+
+ return &(_configuration->getEntry(section, key));
+ }
+
+ bool Config::load(const std::string &filepath, PluginConfigType type)
+ {
+ if (NULL != _configuration)
+ {
+ delete _configuration;
+ _configuration = NULL;
+ }
+
+ if (filepath.length() > 0)
+ {
+ _configuration = new internal::ConfigData(filepath, type);
+ _loaded = true;
+ return true;
+ }
+
+ return false;
+ }
+
+ void Config::unload()
+ {
+ if (NULL != _configuration)
+ {
+ delete _configuration;
+ _configuration = NULL;
+ _loaded = false;
+ }
+ }
+
+ std::string Config::getString(const std::string §ion, const std::string &key)
+ {
+ return _getRaw(section, key);
+ }
+
+ const std::string *Config::getStringPtr(const std::string §ion, const std::string &key)
+ {
+ return _getRawPtr(section, key);
+ }
+
+ int Config::getInt(const std::string §ion, const std::string &key)
+ {
+ return std::atoi(_getRaw(section, key).c_str());
+ }
+
+ double Config::getDouble(const std::string §ion, const std::string &key)
+ {
+ return std::atof(_getRaw(section, key).c_str());
+ }
+
+ bool Config::isLoaded()
+ {
+ return _loaded;
+ }
+
+} // end of namespace plugin
+
+////////////////////////////////////////////////////////////////////////////////
+// C API implementation
+////////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ ConfigHandle plugin_config_create()
+ {
+ return reinterpret_cast<ConfigHandle>(new plugin::Config());
+ }
+
+ void plugin_config_delete(ConfigHandle config_handle)
+ {
+ delete reinterpret_cast<plugin::Config *>(config_handle);
+ }
+
+ void plugin_config_load(ConfigHandle config_handle, const char *filepath,
+ PluginConfigType type)
+ {
+ if (config_handle)
+ {
+ plugin::Config *pConfig = reinterpret_cast<plugin::Config *>(config_handle);
+ pConfig->load(filepath, type);
+ }
+ }
+
+ void plugin_config_unload(ConfigHandle config_handle)
+ {
+ if (config_handle)
+ {
+ plugin::Config *pConfig =
+ reinterpret_cast<plugin::Config *>(config_handle);
+ pConfig->unload();
+ }
+ }
+
+ const char *plugin_config_get_string(ConfigHandle config_handle,
+ const char *section, const char *key)
+ {
+ if (config_handle)
+ {
+ plugin::Config *pConfig = reinterpret_cast<plugin::Config *>(config_handle);
+
+ const std::string *val = pConfig->getStringPtr(section, key);
+ if (val)
+ return val->c_str();
+ }
+
+ return "";
+ }
+
+ int plugin_config_get_int(ConfigHandle config_handle, const char *section, const char *key)
+ {
+ if (config_handle)
+ {
+ plugin::Config *pConfig = reinterpret_cast<plugin::Config *>(config_handle);
+
+ return pConfig->getInt(section, key);
+ }
+
+ return 0;
+ }
+
+ double plugin_config_get_double(ConfigHandle config_handle, const char *section, const char *key)
+ {
+ if (config_handle)
+ {
+ plugin::Config *pConfig = reinterpret_cast<plugin::Config *>(config_handle);
+
+ return pConfig->getDouble(section, key);
+ }
+
+ return 0;
+ }
+
+ bool plugin_config_is_loaded(ConfigHandle config_handle)
+ {
+ if (config_handle)
+ {
+ plugin::Config *pConfig = reinterpret_cast<plugin::Config *>(config_handle);
+
+ return pConfig->isLoaded();
+ }
+
+ return false;
+ }
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/*
+* Copyright (c) 2011 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.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <glib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <glib-unix.h>
+#include <glib-object.h>
+
+#include "libservice_plugin_log.h"
+#include <plugin_message.h>
+#include <json-glib/json-glib.h>
+
+/* For debug */
+/*#define CONSOLE_MODE */
+
+#ifdef CONSOLE_MODE
+#define PRINT_LOG printf
+#else
+#define PRINT_LOG LSP_LOG_debug
+#endif
+
+#define FUNC_START() do {PRINT_LOG("\033[1m\033[32m""Start >>%s>>\n""\033[0m", __FUNCTION__); } while (0)
+#define FUNC_END() do {PRINT_LOG("\033[1m\033[36m""End <<%s<<\n""\033[0m", __FUNCTION__); } while (0)
+
+
+#define PLUGIN_MESSAGE_ELEMENT_KEY_CONTEXT_ID "ctx_id"
+#define PLUGIN_MESSAGE_ELEMENT_KEY_FUNCTION_NAME "func_id"
+#define PLUGIN_MESSAGE_ELEMENT_KEY_PARAMETER_MANDATORY "man_param"
+#define PLUGIN_MESSAGE_ELEMENT_KEY_PARAMETER_OPTIONAL "opt_param"
+#define PLUGIN_MESSAGE_ELEMENT_KEY_REQUEST_ID "req_id"
+#define PLUGIN_MESSAGE_ELEMENT_KEY_MESSAGE_TYPE "msg_id"
+#define PLUGIN_MESSAGE_ELEMENT_KEY_RESULT_CODE "rcode"
+#define PLUGIN_MESSAGE_ELEMENT_KEY_RESULT_MESSAGE "rmsg"
+
+
+#define SUCCESS 0
+#define FAIL -1
+
+#define PLUGIN_PARAMETER_BUF_SIZE_MAX 10
+
+#define JSON_EMPTY_NODE_FILL_NULL(node) do {if (0 == json_node_get_value_type((node))) { \
+ json_node_free((node)); \
+ (node) = NULL; \
+ (node) = json_node_new(JSON_NODE_NULL); } } while (0)
+
+
+struct _plugin_message_s {
+ JsonNode *context;
+ JsonNode *function;
+ JsonNode *parameter_mandatory;
+ JsonNode *parameter_optional;
+ JsonNode *request_id;
+ JsonNode *message_type;
+ JsonNode *rcode;
+ JsonNode *rmsg;
+};
+
+struct _plugin_message_array_s {
+ JsonArray *element;
+ plugin_data_type *types;
+};
+
+int plugin_message_create(plugin_message_h *message)
+{
+ FUNC_START();
+ if (NULL != message) {
+ plugin_message_h _msg = (plugin_message_h) calloc(1, sizeof(struct _plugin_message_s));
+ if (NULL != _msg) {
+ _msg->context = json_node_new(JSON_NODE_VALUE);
+ _msg->function = json_node_new(JSON_NODE_VALUE);
+ _msg->parameter_mandatory = json_node_new(JSON_NODE_OBJECT);
+ _msg->parameter_optional = json_node_new(JSON_NODE_OBJECT);
+ _msg->request_id = json_node_new(JSON_NODE_VALUE);
+ _msg->message_type = json_node_new(JSON_NODE_VALUE);
+ _msg->rcode = json_node_new(JSON_NODE_VALUE);
+ _msg->rmsg = json_node_new(JSON_NODE_VALUE);
+
+ json_node_set_object(_msg->parameter_mandatory, json_object_new());
+ json_node_set_object(_msg->parameter_optional, json_object_new());
+
+ *message = _msg;
+
+ FUNC_END();
+ return SUCCESS;
+ }
+ FUNC_END();
+ }
+ return FAIL;
+}
+
+void plugin_message_destroy(plugin_message_h message)
+{
+ FUNC_START();
+ if (NULL != message) {
+ json_node_free(message->context);
+ json_node_free(message->function);
+ json_node_free(message->parameter_mandatory);
+ json_node_free(message->parameter_optional);
+ json_node_free(message->request_id);
+ json_node_free(message->message_type);
+ json_node_free(message->rcode);
+ json_node_free(message->rmsg);
+
+ free(message);
+ }
+ FUNC_END();
+}
+
+/*
+int plugin_message_set_value_int(plugin_message_h message, plugin_message_element_e field, int value)
+{
+ if (NULL == message)
+ {
+ return FAIL;
+ }
+
+ switch (field)
+ {
+ case PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID:
+ json_node_set_int(message->context, (gint64)value);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME:
+ json_node_set_int(message->function, (gint64)value);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_REQUEST_ID:
+ json_node_set_int(message->request_id, (gint64)value);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE:
+ json_node_set_int(message->message_type, (gint64)value);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_RESULT_CODE:
+ json_node_set_int(message->rcode, (gint64)value);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE:
+ json_node_set_int(message->rmsg, (gint64)value);
+ break;
+ default:
+ return FAIL;
+ }
+
+ return SUCCESS;
+}
+
+int plugin_message_get_value_int(plugin_message_h message, plugin_message_element_e field, int *value)
+{
+ if ((NULL == message) || (NULL == value))
+ {
+ return FAIL;
+ }
+
+ switch (field)
+ {
+ case PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID:
+ *value = (int)json_node_get_int(message->context);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME:
+ *value = (int)json_node_get_int(message->function);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_REQUEST_ID:
+ *value = (int)json_node_get_int(message->request_id);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE:
+ *value = (int)json_node_get_int(message->message_type);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_RESULT_CODE:
+ *value = (int)json_node_get_int(message->rcode);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE:
+ *value = (int)json_node_get_int(message->rmsg);
+ break;
+ default:
+ return FAIL;
+ }
+
+ return SUCCESS;
+}
+*/
+
+int plugin_message_set_value_number(plugin_message_h message, plugin_message_element_e field, pmnumber value)
+{
+ FUNC_START();
+ if (NULL == message) {
+ return FAIL;
+ }
+
+ switch (field) {
+ case PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID:
+ json_node_set_int(message->context, (gint64)value);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME:
+ json_node_set_int(message->function, (gint64)value);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_REQUEST_ID:
+ json_node_set_int(message->request_id, (gint64)value);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE:
+ json_node_set_int(message->message_type, (gint64)value);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_RESULT_CODE:
+ json_node_set_int(message->rcode, (gint64)value);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE:
+ json_node_set_int(message->rmsg, (gint64)value);
+ break;
+ default:
+ return FAIL;
+ }
+
+ FUNC_END();
+ return SUCCESS;
+}
+
+int plugin_message_get_value_number(plugin_message_h message, plugin_message_element_e field, pmnumber *value)
+{
+ FUNC_START();
+ if ((NULL == message) || (NULL == value)) {
+ return FAIL;
+ }
+
+ switch (field) {
+ case PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID:
+ *value = (long long int)json_node_get_int(message->context);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME:
+ *value = (long long int)json_node_get_int(message->function);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_REQUEST_ID:
+ *value = (long long int)json_node_get_int(message->request_id);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE:
+ *value = (long long int)json_node_get_int(message->message_type);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_RESULT_CODE:
+ *value = (long long int)json_node_get_int(message->rcode);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE:
+ *value = (long long int)json_node_get_int(message->rmsg);
+ break;
+ default:
+ return FAIL;
+ }
+
+ FUNC_END();
+ return SUCCESS;
+}
+
+int plugin_message_set_value_string(plugin_message_h message, plugin_message_element_e field, const char *value)
+{
+ FUNC_START();
+ if (NULL == message) {
+ return FAIL;
+ }
+
+ switch (field) {
+ case PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID:
+ json_node_set_string(message->context, value);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME:
+ json_node_set_string(message->function, value);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_REQUEST_ID:
+ json_node_set_string(message->request_id, value);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE:
+ json_node_set_string(message->message_type, value);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_RESULT_CODE:
+ json_node_set_string(message->rcode, value);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE:
+ json_node_set_string(message->rmsg, value);
+ break;
+ default:
+ return FAIL;
+ }
+
+ FUNC_END();
+ return SUCCESS;
+}
+
+int plugin_message_get_value_string(plugin_message_h message, plugin_message_element_e field, char **value)
+{
+ FUNC_START();
+ if ((NULL == message) || (NULL == value)) {
+ return FAIL;
+ }
+
+ switch (field) {
+ case PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID:
+ *value = (char *)json_node_dup_string(message->context);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME:
+ *value = (char *)json_node_dup_string(message->function);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_REQUEST_ID:
+ *value = (char *)json_node_dup_string(message->request_id);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE:
+ *value = (char *)json_node_dup_string(message->message_type);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_RESULT_CODE:
+ *value = (char *)json_node_dup_string(message->rcode);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE:
+ *value = (char *)json_node_dup_string(message->rmsg);
+ break;
+ default:
+ return FAIL;
+ }
+
+ FUNC_END();
+ return SUCCESS;
+}
+
+int plugin_message_set_value_bool(plugin_message_h message, plugin_message_element_e field, bool value)
+{
+ FUNC_START();
+ if (NULL == message) {
+ return FAIL;
+ }
+
+ switch (field) {
+ case PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID:
+ json_node_set_boolean(message->context, value);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME:
+ json_node_set_boolean(message->function, value);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_REQUEST_ID:
+ json_node_set_boolean(message->request_id, value);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE:
+ json_node_set_boolean(message->message_type, value);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_RESULT_CODE:
+ json_node_set_boolean(message->rcode, value);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE:
+ json_node_set_boolean(message->rmsg, value);
+ break;
+ default:
+ return FAIL;
+ }
+
+ FUNC_END();
+ return SUCCESS;
+}
+
+int plugin_message_get_value_bool(plugin_message_h message, plugin_message_element_e field, bool *value)
+{
+ FUNC_START();
+ if ((NULL == message) || (NULL == value)) {
+ return FAIL;
+ }
+
+ switch (field) {
+ case PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID:
+ *value = (bool)json_node_get_boolean(message->context);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME:
+ *value = (bool)json_node_get_boolean(message->function);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_REQUEST_ID:
+ *value = (bool)json_node_get_boolean(message->request_id);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE:
+ *value = (bool)json_node_get_boolean(message->message_type);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_RESULT_CODE:
+ *value = (bool)json_node_get_boolean(message->rcode);
+ break;
+ case PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE:
+ *value = (bool)json_node_get_boolean(message->rmsg);
+ break;
+ default:
+ return FAIL;
+ }
+
+ FUNC_END();
+ return SUCCESS;
+}
+
+/*
+int _plugin_message_set_parameter_value_int(JsonNode *node, int param_index, int value)
+{
+ char index[PLUGIN_PARAMETER_BUF_SIZE_MAX+1] = {0, };
+ if (0 > param_index)
+ {
+ return FAIL;
+ }
+ snprintf(index, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", param_index);
+
+ JsonObject *params;
+ params = json_node_get_object(node);
+
+ // release memory of legacy node
+
+// JsonNode *legacy_node = json_object_get_member(params, index);
+// if (NULL != legacy_node)
+// {
+// json_node_free(legacy_node);
+// }
+
+ JsonNode *new_node = json_node_new(JSON_NODE_VALUE);
+ json_node_set_int(new_node, (gint64)value);
+ json_object_set_member(params, index, new_node);
+
+ return SUCCESS;
+}
+
+int _plugin_message_get_parameter_value_int(JsonNode *node, int param_index, int *value)
+{
+ char index[PLUGIN_PARAMETER_BUF_SIZE_MAX+1] = {0, };
+ if (0 > param_index)
+ {
+ return FAIL;
+ }
+ snprintf(index, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", param_index);
+
+ JsonObject *params;
+ params = json_node_get_object(node);
+
+ JsonNode *legacy_node = json_object_get_member(params, index);
+ if (NULL != legacy_node)
+ {
+ *value = (int)json_node_get_int(legacy_node);
+ }
+ else
+ {
+ return FAIL;
+ }
+
+ return SUCCESS;
+}
+*/
+
+int _plugin_message_set_parameter_value_number(JsonNode *node, int param_index, pmnumber value)
+{
+ FUNC_START();
+ char index[PLUGIN_PARAMETER_BUF_SIZE_MAX+1] = {0, };
+ if (0 > param_index) {
+ return FAIL;
+ }
+ snprintf(index, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", param_index);
+
+ JsonObject *params;
+ params = json_node_get_object(node);
+
+ /* release memory of legacy node */
+/*
+ JsonNode *legacy_node = json_object_get_member(params, index);
+ if (NULL != legacy_node)
+ {
+ json_node_free(legacy_node);
+ }
+*/
+ JsonNode *new_node = json_node_new(JSON_NODE_VALUE);
+ json_node_set_int(new_node, (gint64)value);
+ json_object_set_member(params, index, new_node);
+
+ FUNC_END();
+ return SUCCESS;
+}
+
+int _plugin_message_get_parameter_value_number(JsonNode *node, int param_index, pmnumber *value)
+{
+ FUNC_START();
+ char index[PLUGIN_PARAMETER_BUF_SIZE_MAX+1] = {0, };
+ if (0 > param_index) {
+ return FAIL;
+ }
+ snprintf(index, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", param_index);
+
+ JsonObject *params;
+ params = json_node_get_object(node);
+
+ JsonNode *legacy_node = json_object_get_member(params, index);
+ if (NULL != legacy_node) {
+ *value = (long long int)json_node_get_int(legacy_node);
+ } else {
+ return FAIL;
+ }
+
+ FUNC_END();
+ return SUCCESS;
+}
+
+int _plugin_message_set_parameter_value_string(JsonNode *node, int param_index, const char *value)
+{
+ FUNC_START();
+ char index[PLUGIN_PARAMETER_BUF_SIZE_MAX+1] = {0, };
+ if (0 > param_index) {
+ return FAIL;
+ }
+ snprintf(index, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", param_index);
+
+ JsonObject *params;
+ params = json_node_get_object(node);
+
+ /* release memory of legacy node */
+/*
+ JsonNode *legacy_node = json_object_get_member(params, index);
+ if (NULL != legacy_node)
+ {
+ json_node_free(legacy_node);
+ }
+*/
+ JsonNode *new_node = json_node_new(JSON_NODE_VALUE);
+ json_node_set_string(new_node, value);
+ json_object_set_member(params, index, new_node);
+
+ FUNC_END();
+ return SUCCESS;
+}
+
+int _plugin_message_get_parameter_value_string(JsonNode *node, int param_index, char **value)
+{
+ FUNC_START();
+ char index[PLUGIN_PARAMETER_BUF_SIZE_MAX+1] = {0, };
+ if (0 > param_index) {
+ return FAIL;
+ }
+ snprintf(index, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", param_index);
+
+ JsonObject *params;
+ params = json_node_get_object(node);
+
+ JsonNode *legacy_node = json_object_get_member(params, index);
+ if (NULL != legacy_node) {
+ *value = (char *)json_node_dup_string(legacy_node);
+ } else {
+ return FAIL;
+ }
+
+ FUNC_END();
+ return SUCCESS;
+}
+int _plugin_message_set_parameter_value_bool(JsonNode *node, int param_index, bool value)
+{
+ FUNC_START();
+ char index[PLUGIN_PARAMETER_BUF_SIZE_MAX+1] = {0, };
+ if (0 > param_index) {
+ return FAIL;
+ }
+ snprintf(index, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", param_index);
+
+ JsonObject *params;
+ params = json_node_get_object(node);
+
+ /* release memory of legacy node */
+/*
+ JsonNode *legacy_node = json_object_get_member(params, index);
+ if (NULL != legacy_node)
+ {
+ json_node_free(legacy_node);
+ }
+*/
+ JsonNode *new_node = json_node_new(JSON_NODE_VALUE);
+ json_node_set_boolean(new_node, value);
+ json_object_set_member(params, index, new_node);
+
+ FUNC_END();
+ return SUCCESS;
+}
+
+int _plugin_message_get_parameter_value_bool(JsonNode *node, int param_index, bool *value)
+{
+ FUNC_START();
+ char index[PLUGIN_PARAMETER_BUF_SIZE_MAX+1] = {0, };
+ if (0 > param_index) {
+ return FAIL;
+ }
+ snprintf(index, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", param_index);
+
+ JsonObject *params;
+ params = json_node_get_object(node);
+
+ JsonNode *legacy_node = json_object_get_member(params, index);
+ if (NULL != legacy_node) {
+ *value = (bool)json_node_get_boolean(legacy_node);
+ } else {
+ return FAIL;
+ }
+
+ FUNC_END();
+ return SUCCESS;
+}
+
+int _plugin_message_set_parameter_value_array(JsonNode *node, int param_index, plugin_message_array_h value)
+{
+ FUNC_START();
+ char index[PLUGIN_PARAMETER_BUF_SIZE_MAX+1] = {0, };
+ if (0 > param_index) {
+ return FAIL;
+ }
+ snprintf(index, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", param_index);
+
+ JsonObject *params;
+ params = json_node_get_object(node);
+
+ /* release memory of legacy node */
+/*
+ JsonNode *legacy_node = json_object_get_member(params, index);
+ if (NULL != legacy_node)
+ {
+ json_node_free(legacy_node);
+ }
+*/
+ JsonNode *new_node = json_node_new(JSON_NODE_ARRAY);
+ json_node_set_array(new_node, value->element);
+ json_object_set_member(params, index, new_node);
+
+ FUNC_END();
+ return SUCCESS;
+}
+
+int _plugin_message_get_parameter_value_array(JsonNode *node, int param_index, plugin_message_array_h *value)
+{
+ FUNC_START();
+ char index[PLUGIN_PARAMETER_BUF_SIZE_MAX+1] = {0, };
+ if (0 > param_index) {
+ return FAIL;
+ }
+ snprintf(index, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", param_index);
+
+ JsonObject *params;
+ params = json_node_get_object(node);
+
+
+ JsonNode *legacy_node = json_object_get_member(params, index);
+ if ((NULL != legacy_node) && (JSON_NODE_ARRAY == json_node_get_node_type(legacy_node))) {
+ JsonArray *j_array = NULL;
+ PRINT_LOG("duplacate json array\n");
+ j_array = json_node_dup_array(legacy_node);
+
+ if (NULL != j_array) {
+ plugin_message_array_h _array = (plugin_message_array_h) calloc(1, sizeof(struct _plugin_message_array_s));
+ if (NULL == _array) {
+ PRINT_LOG("Memory allocation failed\n");
+ return FAIL;
+ }
+
+ _array->element = j_array;
+
+ PRINT_LOG("get object from json array\n");
+ JsonObject *job = json_array_get_object_element(j_array, 0);
+
+ int len = (int) json_object_get_size(job);
+
+ PRINT_LOG("json object length : %d\n", len);
+ _array->types = (plugin_data_type *) calloc((len + 1), sizeof(plugin_data_type));
+ if (NULL == _array->types) {
+ PRINT_LOG("Memory allocation failed\n");
+ free(_array);
+ return FAIL;
+ }
+
+ int i;
+ JsonNode *iter_node;
+ char idx[PLUGIN_PARAMETER_BUF_SIZE_MAX];
+
+ for (i = 0; i < len; i++) {
+ snprintf(idx, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", i+1);
+
+ iter_node = json_object_get_member(job, idx);
+ if (JSON_NODE_VALUE == json_node_get_node_type(iter_node)) {
+ GType value_type = json_node_get_value_type(iter_node);
+ if (G_TYPE_INT64 == value_type) {
+ PRINT_LOG("node type (long == int)\n");
+ _array->types[i] = PLUGIN_DATA_TYPE_NUM;
+ } else if (G_TYPE_BOOLEAN == value_type) {
+ PRINT_LOG("node type (bool)\n");
+ _array->types[i] = PLUGIN_DATA_TYPE_BOOL;
+ } else if (G_TYPE_STRING == value_type) {
+ PRINT_LOG("node type (string)\n");
+ _array->types[i] = PLUGIN_DATA_TYPE_STRING;
+ } else {
+ PRINT_LOG("node type (unknown)\n");
+ _array->types[i] = PLUGIN_DATA_TYPE_UNKNOWN;
+ }
+ } else {
+ PRINT_LOG("node type (no value node)\n");
+ _array->types[i] = PLUGIN_DATA_TYPE_UNKNOWN;
+ }
+ }
+
+ *value = _array;
+
+ FUNC_END();
+ return SUCCESS;
+ }
+ }
+
+ FUNC_END();
+ return FAIL;
+}
+/*
+int plugin_message_set_param_int(plugin_message_h message, int param_index, int value)
+{
+ if (NULL == message)
+ {
+ return FAIL;
+ }
+
+ return _plugin_message_set_parameter_value_int(message->parameter_mandatory, param_index, value);
+}
+
+int plugin_message_get_param_int(plugin_message_h message, int param_index, int *value)
+{
+ if ((NULL == message) || (NULL == value))
+ {
+ return FAIL;
+ }
+
+ return _plugin_message_get_parameter_value_int(message->parameter_mandatory, param_index, value);
+}
+*/
+
+int plugin_message_set_param_number(plugin_message_h message, int param_index, pmnumber value)
+{
+ FUNC_START();
+ if (NULL == message) {
+ return FAIL;
+ }
+
+ FUNC_END();
+ return _plugin_message_set_parameter_value_number(message->parameter_mandatory, param_index, value);
+}
+
+int plugin_message_get_param_number(plugin_message_h message, int param_index, pmnumber *value)
+{
+ FUNC_START();
+ if ((NULL == message) || (NULL == value)) {
+ return FAIL;
+ }
+
+ FUNC_END();
+ return _plugin_message_get_parameter_value_number(message->parameter_mandatory, param_index, value);
+}
+
+int plugin_message_set_param_string(plugin_message_h message, int param_index, const char *value)
+{
+ FUNC_START();
+ if ((NULL == message) || (NULL == value)) {
+ return FAIL;
+ }
+
+ FUNC_END();
+ return _plugin_message_set_parameter_value_string(message->parameter_mandatory, param_index, value);
+}
+
+int plugin_message_get_param_string(plugin_message_h message, int param_index, char **value)
+{
+ FUNC_START();
+ if ((NULL == message) || (NULL == value)) {
+ return FAIL;
+ }
+
+ FUNC_END();
+ return _plugin_message_get_parameter_value_string(message->parameter_mandatory, param_index, value);
+}
+
+int plugin_message_set_param_bool(plugin_message_h message, int param_index, bool value)
+{
+ FUNC_START();
+ if (NULL == message) {
+ return FAIL;
+ }
+
+ FUNC_END();
+ return _plugin_message_set_parameter_value_bool(message->parameter_mandatory, param_index, value);
+}
+
+int plugin_message_get_param_bool(plugin_message_h message, int param_index, bool *value)
+{
+ FUNC_START();
+ if ((NULL == message) || (NULL == value)) {
+ return FAIL;
+ }
+
+ FUNC_END();
+ return _plugin_message_get_parameter_value_bool(message->parameter_mandatory, param_index, value);
+}
+
+int plugin_message_set_param_array(plugin_message_h message, int param_index, plugin_message_array_h value)
+{
+ FUNC_START();
+ if ((NULL == message) || (NULL == value)) {
+ return FAIL;
+ }
+
+ FUNC_END();
+ return _plugin_message_set_parameter_value_array(message->parameter_mandatory, param_index, value);
+}
+
+int plugin_message_get_param_array(plugin_message_h message, int param_index, plugin_message_array_h *value)
+{
+ FUNC_START();
+ if ((NULL == message) || (NULL == value)) {
+ return FAIL;
+ }
+
+ FUNC_END();
+ return _plugin_message_get_parameter_value_array(message->parameter_mandatory, param_index, value);
+}
+
+/*
+int plugin_message_set_opt_param_int(plugin_message_h message, int param_index, int value)
+{
+ FUNC_START();
+ if (NULL == message)
+ {
+ return FAIL;
+ }
+
+ FUNC_END();
+ return _plugin_message_set_parameter_value_int(message->parameter_optional, param_index, value);
+}
+
+int plugin_message_get_opt_param_int(plugin_message_h message, int param_index, int *value)
+{
+ FUNC_START();
+ if ((NULL == message) || (NULL == value))
+ {
+ return FAIL;
+ }
+
+ FUNC_END();
+ return _plugin_message_get_parameter_value_int(message->parameter_optional, param_index, value);
+}
+*/
+
+int plugin_message_set_opt_param_number(plugin_message_h message, int param_index, pmnumber value)
+{
+ FUNC_START();
+ if (NULL == message) {
+ return FAIL;
+ }
+
+ FUNC_END();
+ return _plugin_message_set_parameter_value_number(message->parameter_optional, param_index, value);
+}
+
+int plugin_message_get_opt_param_number(plugin_message_h message, int param_index, pmnumber *value)
+{
+ FUNC_START();
+ if ((NULL == message) || (NULL == value)) {
+ return FAIL;
+ }
+
+ FUNC_END();
+ return _plugin_message_get_parameter_value_number(message->parameter_optional, param_index, value);
+}
+
+int plugin_message_set_opt_param_string(plugin_message_h message, int param_index, const char *value)
+{
+ FUNC_START();
+ if ((NULL == message) || (NULL == value)) {
+ return FAIL;
+ }
+
+ FUNC_END();
+ return _plugin_message_set_parameter_value_string(message->parameter_optional, param_index, value);
+}
+
+int plugin_message_get_opt_param_string(plugin_message_h message, int param_index, char **value)
+{
+ FUNC_START();
+ if ((NULL == message) || (NULL == value)) {
+ return FAIL;
+ }
+
+ FUNC_END();
+ return _plugin_message_get_parameter_value_string(message->parameter_optional, param_index, value);
+}
+
+int plugin_message_set_opt_param_bool(plugin_message_h message, int param_index, bool value)
+{
+ FUNC_START();
+ if (NULL == message) {
+ return FAIL;
+ }
+
+ FUNC_END();
+ return _plugin_message_set_parameter_value_bool(message->parameter_optional, param_index, value);
+}
+
+int plugin_message_get_opt_param_bool(plugin_message_h message, int param_index, bool *value)
+{
+ FUNC_START();
+ if ((NULL == message) || (NULL == value)) {
+ return FAIL;
+ }
+
+ FUNC_END();
+ return _plugin_message_get_parameter_value_bool(message->parameter_optional, param_index, value);
+}
+
+int plugin_message_set_opt_param_array(plugin_message_h message, int param_index, plugin_message_array_h value)
+{
+ FUNC_START();
+ if ((NULL == message) || (NULL == value)) {
+ return FAIL;
+ }
+
+ FUNC_END();
+ return _plugin_message_set_parameter_value_array(message->parameter_optional, param_index, value);
+}
+
+int plugin_message_get_opt_param_array(plugin_message_h message, int param_index, plugin_message_array_h *value)
+{
+ FUNC_START();
+ if ((NULL == message) || (NULL == value)) {
+ return FAIL;
+ }
+
+ FUNC_END();
+ return _plugin_message_get_parameter_value_array(message->parameter_optional, param_index, value);
+}
+
+char *_json_serialize_by_jnode(JsonNode *total_node)
+{
+ FUNC_START();
+ JsonGenerator *gen = json_generator_new();
+ json_generator_set_root(gen, total_node);
+
+ char *t_data = NULL;
+ gsize len = 0;
+ t_data = json_generator_to_data(gen, &len);
+
+ g_object_unref(gen);
+
+ FUNC_END();
+ return t_data;
+/* return t; */
+}
+
+JsonNode *_json_deserialize_by_data(const char *data)
+{
+ FUNC_START();
+ JsonParser *parser = json_parser_new();
+ json_parser_load_from_data(parser, data, strlen(data), NULL);
+
+ PRINT_LOG("next\n");
+
+ JsonNode *node = json_parser_get_root(parser);
+
+ JsonNodeType nt = json_node_get_node_type(node);
+ if (nt == JSON_NODE_OBJECT)
+ PRINT_LOG("object type\n");
+ if (nt == JSON_NODE_ARRAY)
+ PRINT_LOG("array type\n");
+ if (nt == JSON_NODE_VALUE)
+ PRINT_LOG("value type\n");
+ if (nt == JSON_NODE_NULL)
+ PRINT_LOG("null type\n");
+
+ FUNC_END();
+ return node;
+}
+
+int plugin_message_serialize(plugin_message_h message, char **data)
+{
+ FUNC_START();
+ if ((NULL == message) || (NULL == data)) {
+ return FAIL;
+ }
+
+ JsonObject *obj = json_object_new();
+
+ JsonNode *context_id = json_node_copy(message->context);
+ JsonNode *function_name = json_node_copy(message->function);
+ JsonNode *parameter_mandatory = json_node_copy(message->parameter_mandatory);
+ JsonNode *parameter_optional = json_node_copy(message->parameter_optional);
+ JsonNode *request_id = json_node_copy(message->request_id);
+ JsonNode *message_type = json_node_copy(message->message_type);
+ JsonNode *rcode = json_node_copy(message->rcode);
+ JsonNode *rmsg = json_node_copy(message->rmsg);
+
+ JSON_EMPTY_NODE_FILL_NULL(context_id);
+ JSON_EMPTY_NODE_FILL_NULL(function_name);
+ JSON_EMPTY_NODE_FILL_NULL(parameter_mandatory);
+ JSON_EMPTY_NODE_FILL_NULL(parameter_optional);
+ JSON_EMPTY_NODE_FILL_NULL(request_id);
+ JSON_EMPTY_NODE_FILL_NULL(message_type);
+ JSON_EMPTY_NODE_FILL_NULL(rcode);
+ JSON_EMPTY_NODE_FILL_NULL(rmsg);
+
+ json_object_set_member(obj, PLUGIN_MESSAGE_ELEMENT_KEY_CONTEXT_ID, context_id);
+ json_object_set_member(obj, PLUGIN_MESSAGE_ELEMENT_KEY_FUNCTION_NAME, function_name);
+ json_object_set_member(obj, PLUGIN_MESSAGE_ELEMENT_KEY_PARAMETER_MANDATORY, parameter_mandatory);
+ json_object_set_member(obj, PLUGIN_MESSAGE_ELEMENT_KEY_PARAMETER_OPTIONAL, parameter_optional);
+ json_object_set_member(obj, PLUGIN_MESSAGE_ELEMENT_KEY_REQUEST_ID, request_id);
+ json_object_set_member(obj, PLUGIN_MESSAGE_ELEMENT_KEY_MESSAGE_TYPE, message_type);
+ json_object_set_member(obj, PLUGIN_MESSAGE_ELEMENT_KEY_RESULT_CODE, rcode);
+ json_object_set_member(obj, PLUGIN_MESSAGE_ELEMENT_KEY_RESULT_MESSAGE, rmsg);
+
+ JsonNode *node = json_node_new(JSON_NODE_OBJECT);
+ json_node_take_object(node, obj);
+
+ char *_data = NULL;
+ _data = _json_serialize_by_jnode(node);
+/*
+ json_node_free(node);
+ json_object_unref(obj);
+
+ json_node_free(context_id);
+ json_node_free(function_name);
+ json_node_free(parameter_mandatory);
+ json_node_free(parameter_optional);
+ json_node_free(request_id);
+ json_node_free(message_type);
+ json_node_free(rcode);
+ json_node_free(rmsg);
+*/
+ *data = _data;
+ FUNC_END();
+ return SUCCESS;
+}
+
+int plugin_message_deserialize(const char *data, plugin_message_h *message)
+{
+ FUNC_START();
+ if ((NULL == message) || (NULL == data)) {
+ return FAIL;
+ }
+
+ plugin_message_h _msg = (plugin_message_h) calloc(1, sizeof(struct _plugin_message_s));
+ if (NULL == _msg) {
+ return FAIL;
+ }
+
+ JsonNode *root_node = _json_deserialize_by_data(data);
+
+ JsonObject *root_object = json_node_get_object(root_node);
+
+ _msg->context = json_object_dup_member(root_object, PLUGIN_MESSAGE_ELEMENT_KEY_CONTEXT_ID);
+ _msg->function = json_object_dup_member(root_object, PLUGIN_MESSAGE_ELEMENT_KEY_FUNCTION_NAME);
+ _msg->parameter_mandatory = json_object_dup_member(root_object, PLUGIN_MESSAGE_ELEMENT_KEY_PARAMETER_MANDATORY);
+ _msg->parameter_optional = json_object_dup_member(root_object, PLUGIN_MESSAGE_ELEMENT_KEY_PARAMETER_OPTIONAL);
+ _msg->request_id = json_object_dup_member(root_object, PLUGIN_MESSAGE_ELEMENT_KEY_REQUEST_ID);
+ _msg->message_type = json_object_dup_member(root_object, PLUGIN_MESSAGE_ELEMENT_KEY_MESSAGE_TYPE);
+ _msg->rcode = json_object_dup_member(root_object, PLUGIN_MESSAGE_ELEMENT_KEY_RESULT_CODE);
+ _msg->rmsg = json_object_dup_member(root_object, PLUGIN_MESSAGE_ELEMENT_KEY_RESULT_MESSAGE);
+
+ *message = _msg;
+
+ json_node_free(root_node);
+
+ return SUCCESS;
+}
+
+int plugin_message_array_create(const plugin_data_type *type_string, plugin_message_array_h *array)
+{
+ FUNC_START();
+ if ((NULL == type_string) || (NULL == array)) {
+ return FAIL;
+ }
+ int i = 0, len = strlen(type_string);
+ for (i = 0; i < len; i++) {
+ switch (type_string[i]) {
+ case PLUGIN_DATA_TYPE_NUM:
+ case PLUGIN_DATA_TYPE_BOOL:
+ case PLUGIN_DATA_TYPE_STRING:
+ break;
+ default:
+ return FAIL;
+ }
+ }
+
+ plugin_message_array_h _array = (plugin_message_array_h) calloc(1, sizeof(struct _plugin_message_array_s));
+ plugin_data_type *_types = (plugin_data_type *) calloc(strlen(type_string)+1, sizeof(plugin_data_type));
+
+ if ((NULL == _array) || (NULL == _types)) {
+ free(_array);
+ free(_types);
+ return FAIL;
+ }
+
+ _array->element = json_array_new();
+
+ _array->types = _types;
+ strncpy(_array->types, type_string, strlen(type_string));
+
+ *array = _array;
+
+ FUNC_END();
+ return SUCCESS;
+}
+
+void plugin_message_array_destroy(plugin_message_array_h array)
+{
+ FUNC_START();
+ if (NULL != array) {
+ json_array_unref(array->element);
+ free(array->types);
+ free(array);
+ }
+ FUNC_END();
+}
+
+int plugin_message_array_add_element(plugin_message_array_h array, ...)
+{
+ FUNC_START();
+ if (NULL == array) {
+ return FAIL;
+ }
+
+ plugin_data_type *types = array->types;
+
+ int count = strlen(types);
+ int i = 0;
+ char index[PLUGIN_PARAMETER_BUF_SIZE_MAX+1] = {0, };
+
+ JsonObject *obj = json_object_new();
+ JsonNode *new_node;
+
+ PRINT_LOG("[%d]count : %d\n", __LINE__, count);
+
+ va_list vl;
+ va_start(vl, array);
+
+ for (i = 0; i < count; i++) {
+ memset(index, 0, PLUGIN_PARAMETER_BUF_SIZE_MAX);
+ snprintf(index, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", i+1);
+ PRINT_LOG("[%d]index : %s, type : %c\n", __LINE__, index, types[i]);
+
+ switch (types[i]) {
+/*
+ case PLUGIN_DATA_TYPE_INT:
+ new_node = json_node_new(JSON_NODE_VALUE);
+ json_node_set_int(new_node, (gint64)va_arg(vl, int));
+ json_object_set_member(obj, index, new_node);
+ PRINT_LOG("[%d]index : %s\n", __LINE__, index);
+ break;
+*/
+ case PLUGIN_DATA_TYPE_NUM:
+ new_node = json_node_new(JSON_NODE_VALUE);
+ json_node_set_int(new_node, (gint64)va_arg(vl, long long int));
+ json_object_set_member(obj, index, new_node);
+ PRINT_LOG("[%d]index : %s\n", __LINE__, index);
+ break;
+ case PLUGIN_DATA_TYPE_BOOL:
+ new_node = json_node_new(JSON_NODE_VALUE);
+ json_node_set_boolean(new_node, va_arg(vl, int) ? true : false);
+ json_object_set_member(obj, index, new_node);
+ PRINT_LOG("[%d]index : %s\n", __LINE__, index);
+ break;
+ case PLUGIN_DATA_TYPE_STRING:
+ new_node = json_node_new(JSON_NODE_VALUE);
+ json_node_set_string(new_node, va_arg(vl, char *));
+ json_object_set_member(obj, index, new_node);
+ PRINT_LOG("[%d]index : %s\n", __LINE__, index);
+ break;
+ default:
+ new_node = json_node_new(JSON_NODE_NULL);
+ json_object_set_member(obj, index, new_node);
+ PRINT_LOG("[%d]index : %s <unknown dada, function fail>\n", __LINE__, index);
+ va_end(vl);
+ return FAIL;
+ }
+ }
+ va_end(vl);
+
+ PRINT_LOG("array length : %u\n", json_object_get_size(obj));
+ json_array_add_object_element(array->element, obj);
+
+ FUNC_END();
+ return SUCCESS;
+}
+
+int plugin_message_array_get_element(plugin_message_array_h array, int idx, ...)
+{
+ FUNC_START();
+ if ((NULL == array) || (1 > idx)) {
+ return FAIL;
+ }
+
+ if (json_array_get_length(array->element) < idx) {
+ return FAIL;
+ }
+
+ JsonObject *obj = json_array_get_object_element(array->element, idx-1);
+
+ if (NULL == obj) {
+ return FAIL;
+ }
+
+ plugin_data_type *types = array->types;
+
+ int count = strlen(types);
+ int i = 0;
+ char index[PLUGIN_PARAMETER_BUF_SIZE_MAX+1] = {0, };
+
+ JsonNode *new_node;
+
+ PRINT_LOG("[%d]count : %d\n", __LINE__, count);
+
+ va_list vl;
+ va_start(vl, idx);
+
+ for (i = 0; i < count; i++) {
+ memset(index, 0, PLUGIN_PARAMETER_BUF_SIZE_MAX);
+ snprintf(index, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", i+1);
+ PRINT_LOG("[%d]index : %s, type : %c\n", __LINE__, index, types[i]);
+ new_node = json_object_get_member(obj, index);
+
+ switch (types[i]) {
+/*
+ case PLUGIN_DATA_TYPE_INT:
+ *(va_arg(vl, int *)) = (int) json_node_get_int(new_node);
+ PRINT_LOG("[%d]index : %s\n", __LINE__, index);
+ break;
+*/
+ case PLUGIN_DATA_TYPE_NUM:
+ *(va_arg(vl, long long int *)) = (long long int) json_node_get_int(new_node);
+ PRINT_LOG("[%d]index : %s\n", __LINE__, index);
+ break;
+ case PLUGIN_DATA_TYPE_BOOL:
+ *(va_arg(vl, bool *)) = (bool) json_node_get_boolean(new_node);
+ PRINT_LOG("[%d]index : %s\n", __LINE__, index);
+ break;
+ case PLUGIN_DATA_TYPE_STRING:
+ *(va_arg(vl, char **)) = (char *) json_node_dup_string(new_node);
+ PRINT_LOG("[%d]index : %s\n", __LINE__, index);
+ break;
+ default:
+ PRINT_LOG("[%d]index : %s\n", __LINE__, index);
+ break;
+ }
+ }
+ va_end(vl);
+
+ FUNC_END();
+ return SUCCESS;
+}
+
--- /dev/null
+/*
+* Copyright (c) 2011 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 trimming.c
+ * @author Dawid Kozinski (d.kozinski@samsung.com)
+ *
+ * @brief Trimming functions taken from
+ * http://stackoverflow.com/questions/122616/how-do-i-trim-leading-trailing-whitespace-in-a-standard-way
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+/**
+* @brief trim from start, i.e. left side
+* Trimming leading whitespace from string
+*
+* @param s ...
+* @return :char*
+**/
+char *plugin_internal_ltrim(char *s);
+
+/**
+* @brief trim from end, i.e. right side
+* Trimming trailing whitespace from string
+*
+* @param s ...
+* @return :char*
+**/
+char *plugin_internal_rtrim(char *s);
+
+/**
+* @brief trim from both ends
+* Trimming leading and trailing whitespace from string
+* @param s ...
+* @return :string&
+**/
+char *plugin_internal_trim(char *s);
+
+/* ////////////////////////////////////////////////////////////////////////////////
+ // Implementation
+ //////////////////////////////////////////////////////////////////////////////// */
+char *plugin_internal_ltrim(char *s)
+{
+ char *newstart = s;
+
+ while (isspace(*newstart)) {
+ ++newstart;
+ }
+
+ /* newstart points to first non-whitespace char (which might be '\0') */
+ memmove(s, newstart, strlen(newstart) + 1); /* don't forget to move the '\0' terminator */
+
+ return s;
+}
+
+char *plugin_internal_rtrim(char *s)
+{
+ char *end = s + strlen(s);
+
+ /* find the last non-whitespace character */
+ while ((end != s) && isspace(*(end - 1))) {
+ --end;
+ }
+
+ /* at this point either (end == s) and s is either empty or all whitespace
+ so it needs to be made empty, or
+ end points just past the last non-whitespace character (it might point
+ at the '\0' terminator, in which case there's no problem writing
+ another there). */
+ *end = '\0';
+
+ return s;
+}
+
+char *plugin_internal_trim(char *s)
+{
+ return plugin_internal_rtrim(plugin_internal_ltrim(s));
+}
--- /dev/null
+if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+ message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
+endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+
+cmake_policy(SET CMP0007 OLD)
+file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
+string(REGEX REPLACE "\n" ";" files "${files}")
+list(REVERSE files)
+foreach (file ${files})
+ message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
+ if (EXISTS "$ENV{DESTDIR}${file}")
+ execute_process(
+ COMMAND @CMAKE_COMMAND@ -E remove "$ENV{DESTDIR}${file}"
+ OUTPUT_VARIABLE rm_out
+ RESULT_VARIABLE rm_retval
+ )
+ if(NOT ${rm_retval} EQUAL 0)
+ message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
+ endif (NOT ${rm_retval} EQUAL 0)
+ else (EXISTS "$ENV{DESTDIR}${file}")
+ message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
+ endif (EXISTS "$ENV{DESTDIR}${file}")
+endforeach(file)