tizen 2.4 release accepted/tizen_2.4_mobile tizen_2.4 accepted/tizen/2.4/mobile/20151029.033211 submit/tizen_2.4/20151028.064138 tizen_2.4_mobile_release
authorjk7744.park <jk7744.park@samsung.com>
Mon, 26 Oct 2015 06:45:03 +0000 (15:45 +0900)
committerjk7744.park <jk7744.park@samsung.com>
Mon, 26 Oct 2015 06:45:03 +0000 (15:45 +0900)
23 files changed:
CMakeLists.txt [new file with mode: 0644]
LICENSE.Apache-2.0 [new file with mode: 0644]
License.txt [new file with mode: 0644]
NOTICE [new file with mode: 0644]
README [new file with mode: 0644]
config.kdev4 [new file with mode: 0644]
config/.plugin-adaptor-example.csv [new file with mode: 0644]
config/.plugin-adaptor-example.gitconfig [new file with mode: 0644]
config/.plugin-adaptor-example.ini [new file with mode: 0644]
config/pluginmanager.ini [new file with mode: 0644]
include/libservice_plugin_log.h [new file with mode: 0644]
include/pluginConfig.h [new file with mode: 0644]
include/pluginConfig.hpp [new file with mode: 0644]
include/pluginConfigLog.h [new file with mode: 0644]
include/pluginConfigTypes.h [new file with mode: 0644]
include/plugin_message.h [new file with mode: 0644]
packaging/plugin-config.spec [new file with mode: 0644]
pkgconfig/plugin-config.pc.in [new file with mode: 0644]
src/pluginConfig.c [new file with mode: 0644]
src/pluginConfig.cpp [new file with mode: 0644]
src/plugin_message.c [new file with mode: 0644]
src/trimming.c [new file with mode: 0644]
uninstall.cmake.in [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..512e478
--- /dev/null
@@ -0,0 +1,130 @@
+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)
diff --git a/LICENSE.Apache-2.0 b/LICENSE.Apache-2.0
new file mode 100644 (file)
index 0000000..d645695
--- /dev/null
@@ -0,0 +1,202 @@
+
+                                 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.
diff --git a/License.txt b/License.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/NOTICE b/NOTICE
new file mode 100644 (file)
index 0000000..579ba56
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,3 @@
+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.
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/config.kdev4 b/config.kdev4
new file mode 100644 (file)
index 0000000..db9d4d1
--- /dev/null
@@ -0,0 +1,3 @@
+[Project]
+Manager=KDevCMakeManager
+Name=config
diff --git a/config/.plugin-adaptor-example.csv b/config/.plugin-adaptor-example.csv
new file mode 100644 (file)
index 0000000..5ea7643
--- /dev/null
@@ -0,0 +1,4 @@
+general;plugin_dir;/usr/libs
+general;concurency;8
+debugging;log;verbose
+
diff --git a/config/.plugin-adaptor-example.gitconfig b/config/.plugin-adaptor-example.gitconfig
new file mode 100644 (file)
index 0000000..34762bd
--- /dev/null
@@ -0,0 +1,6 @@
+[general]
+    plugin_dir = /usr/libs
+    concurency = 8
+[debugging]
+    log = verbose
+
diff --git a/config/.plugin-adaptor-example.ini b/config/.plugin-adaptor-example.ini
new file mode 100644 (file)
index 0000000..028dd48
--- /dev/null
@@ -0,0 +1,8 @@
+[general]
+plugin_dir=/usr/libs
+concurency=8
+;[empty]
+;[empty2]
+[debugging]
+log=verbose
+
diff --git a/config/pluginmanager.ini b/config/pluginmanager.ini
new file mode 100644 (file)
index 0000000..028dd48
--- /dev/null
@@ -0,0 +1,8 @@
+[general]
+plugin_dir=/usr/libs
+concurency=8
+;[empty]
+;[empty2]
+[debugging]
+log=verbose
+
diff --git a/include/libservice_plugin_log.h b/include/libservice_plugin_log.h
new file mode 100644 (file)
index 0000000..809c32b
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+* 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__ */
diff --git a/include/pluginConfig.h b/include/pluginConfig.h
new file mode 100644 (file)
index 0000000..ae278e5
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+* 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 */
+
diff --git a/include/pluginConfig.hpp b/include/pluginConfig.hpp
new file mode 100644 (file)
index 0000000..3890261
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+* 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 &section, 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 &section, 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 &section, 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 &section, 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 &section, 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 &section, const std::string &key);
+
+    private:
+        bool _loaded;
+        internal::ConfigData *_configuration;
+    };
+}
+#endif /* PLUGIN_CONFIG_HPP_INCLUDED */
diff --git a/include/pluginConfigLog.h b/include/pluginConfigLog.h
new file mode 100644 (file)
index 0000000..ed837ca
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+* 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__ */
diff --git a/include/pluginConfigTypes.h b/include/pluginConfigTypes.h
new file mode 100644 (file)
index 0000000..49f01d2
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+* 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 */
diff --git a/include/plugin_message.h b/include/plugin_message.h
new file mode 100644 (file)
index 0000000..90cc1ea
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+* 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__ */
diff --git a/packaging/plugin-config.spec b/packaging/plugin-config.spec
new file mode 100644 (file)
index 0000000..b5f5b55
--- /dev/null
@@ -0,0 +1,54 @@
+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
+
diff --git a/pkgconfig/plugin-config.pc.in b/pkgconfig/plugin-config.pc.in
new file mode 100644 (file)
index 0000000..8785f58
--- /dev/null
@@ -0,0 +1,13 @@
+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}
diff --git a/src/pluginConfig.c b/src/pluginConfig.c
new file mode 100644 (file)
index 0000000..c49fb75
--- /dev/null
@@ -0,0 +1,1458 @@
+/*
+* 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;
+}
diff --git a/src/pluginConfig.cpp b/src/pluginConfig.cpp
new file mode 100644 (file)
index 0000000..3121de8
--- /dev/null
@@ -0,0 +1,794 @@
+/*
+* 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 &ltrim(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 &section) 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 &section, 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 &section, 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 &section, 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 &section, 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 &section, 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 &section, const std::string &key)
+    {
+        return _getRaw(section, key);
+    }
+
+    const std::string *Config::getStringPtr(const std::string &section, const std::string &key)
+    {
+        return _getRawPtr(section, key);
+    }
+
+    int Config::getInt(const std::string &section, const std::string &key)
+    {
+        return std::atoi(_getRaw(section, key).c_str());
+    }
+
+    double Config::getDouble(const std::string &section, 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
diff --git a/src/plugin_message.c b/src/plugin_message.c
new file mode 100644 (file)
index 0000000..b543d97
--- /dev/null
@@ -0,0 +1,1257 @@
+/*
+* 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;
+}
+
diff --git a/src/trimming.c b/src/trimming.c
new file mode 100644 (file)
index 0000000..9b44af9
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+* 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));
+}
diff --git a/uninstall.cmake.in b/uninstall.cmake.in
new file mode 100644 (file)
index 0000000..7a7b059
--- /dev/null
@@ -0,0 +1,23 @@
+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)