Source directories are moved to src.
- src/bundle
- src/parcel
- src/tizen-database
- src/tizen-shared-queue
Change-Id: I3b0dd75dd1d18d5e6611d08e90754df3b393e9d5
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
-CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
-PROJECT(bundle C CXX)
-IF("${VERSION}" STREQUAL "")
- MESSAGE(FATAL_ERROR "VERSION is not defined")
-ENDIF()
-STRING(REGEX MATCH "^[0-9]+" VERSION_MAJOR ${VERSION})
-IF("${VERSION_MAJOR}" STREQUAL "")
- MESSAGE(FATAL_ERROR "can't get VERSION_MAJOR")
-ENDIF()
+CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
-INCLUDE(FindPkgConfig)
-PKG_CHECK_MODULES(pkgs REQUIRED
- glib-2.0 dlog capi-base-common json-glib-1.0
-)
-
-FOREACH(flag ${pkgs_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -flto -Wall -Werror -Winline -Wno-noexcept-type")
-
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -std=c++17")
-SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
-
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src)
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/)
+PROJECT(bundle)
-AUX_SOURCE_DIRECTORY(src SOURCES)
-
-ADD_LIBRARY (${PROJECT_NAME} SHARED ${SOURCES})
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(VERSION ${FULLVER})
-SET_TARGET_PROPERTIES(bundle PROPERTIES SOVERSION ${VERSION_MAJOR})
-SET_TARGET_PROPERTIES(bundle PROPERTIES VERSION "${VERSION}")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-zdefs")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Winline")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-noexcept-type")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -flto")
-SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS} -fPIE")
-SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES LINK_FLAGS "-pie")
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS})
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_C_FLAGS_RELEASE "-O2")
-### Make pkgconfig file
-SET(PREFIX ${CMAKE_INSTALL_PREFIX})
-CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/bundle.pc.in ${CMAKE_BINARY_DIR}/bundle.pc @ONLY)
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_C_FLAGS} -std=c++17")
+SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
-### Install
-INSTALL(TARGETS bundle DESTINATION ${LIB_INSTALL_DIR})
-INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ DESTINATION include/)
-INSTALL(FILES ${CMAKE_BINARY_DIR}/bundle.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig/)
+SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
-ADD_SUBDIRECTORY(parcel)
-ADD_DEPENDENCIES(parcel bundle)
+SET(TARGET_BUNDLE "bundle")
+SET(TARGET_PARCEL "parcel")
+SET(TARGET_TIZEN_DATABASE "tizen-database")
+SET(TARGET_TIZEN_SHARED_QUEUE "tizen-shared-queue")
+SET(TARGET_BUNDLE_UNITTESTS "bundle_unittests")
+SET(TARGET_PARCEL_UNITTESTS "parcel_unittests")
+SET(TARGET_TIZEN_DATABASE_UNITTESTS "tizen-database_unittests")
+SET(TARGET_TIZEN_SHARED_QUEUE_UNITTESTS "tizen-shared-queue_unittests")
-ADD_SUBDIRECTORY(tizen-database)
-ADD_SUBDIRECTORY(tizen-shared-queue)
+INCLUDE(FindPkgConfig)
+INCLUDE(ApplyPkgConfig)
-IF(NOT DEFINED MINIMUM_BUILD)
-ENABLE_TESTING()
-SET(BUNDLE_UNITTESTS bundle_unittests)
-ADD_TEST(NAME ${BUNDLE_UNITTESTS} COMMAND ${BUNDLE_UNITTESTS}
- WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests/bundle_unittests)
+PKG_CHECK_MODULES(CAPI_BASE_COMMON_DEPS REQUIRED capi-base-common)
+PKG_CHECK_MODULES(DLOG_DEPS REQUIRED dlog)
+PKG_CHECK_MODULES(GLIB_DEPS REQUIRED glib-2.0)
+PKG_CHECK_MODULES(GMOCK_DEPS REQUIRED gmock)
+PKG_CHECK_MODULES(JSON_GLIB_DEPS REQUIRED json-glib-1.0)
+PKG_CHECK_MODULES(SQLITE3_DEPS REQUIRED sqlite3)
+ADD_SUBDIRECTORY(src)
ADD_SUBDIRECTORY(tests)
-ADD_DEPENDENCIES(bundle_unittests bundle)
-SET(PARCEL_UNITTESTS parcel_unittests)
-ADD_TEST(NAME ${PARCEL_UNITTESTS} COMMAND ${PARCEL_UNITTESTS}
- WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests/parcel_unittests)
+ENABLE_TESTING()
+ADD_TEST(NAME ${TARGET_BUNDLE_UNITTESTS}
+ COMMAND ${TARGET_BUNDLE_UNITTESTS}
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests/bundle_unittests)
-ADD_DEPENDENCIES(parcel_unittests parcel)
+ADD_TEST(NAME ${TARGET_PARCEL_UNITTESTS}
+ COMMAND ${TARGET_PARCEL_UNITTESTS}
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests/parcel_unittests)
-SET(TIZEN_DATABASE_UNITTESTS tizen-database_unittests)
-ADD_TEST(NAME ${TIZEN_DATABASE_UNITTESTS} COMMAND ${TIZEN_DATABASE_UNITTESTS}
- WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests/tizen-database_unittests)
+ADD_TEST(NAME ${TARGET_TIZEN_DATABASE_UNITTESTS}
+ COMMAND ${TARGET_TIZEN_DATABASE_UNITTESTS}
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests/tizen-database_unittests)
-SET(TIZEN_SHARED_QUEUE_UNITTESTS tizen-shared-queue_unittests)
-ADD_TEST(NAME ${TIZEN_SHARED_QUEUE_UNITTESTS}
- COMMAND ${TIZEN_SHARED_QUEUE_UNITTESTS}
+ADD_TEST(NAME ${TARGET_TIZEN_SHARED_QUEUE_UNITTESTS}
+ COMMAND ${TARGET_TIZEN_SHARED_QUEUE_UNITTESTS}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests/tizen-shared-queue_unittests)
-
-ENDIF(NOT DEFINED MINIMUM_BUILD)
+++ /dev/null
-# Package Information for pkg-config
-
-prefix=@PREFIX@
-exec_prefix=${prefix}
-libdir=@LIB_INSTALL_DIR@
-includedir=${prefix}/include
-
-Name: bundle
-Description: Simple string key/val dictionary library
-Version: @VERSION@
-Requires: capi-base-common
-Libs: -L${libdir} -lbundle
-Cflags: -I${includedir}
-cppflags: -I${includedir}
--- /dev/null
+# Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+#
+# This function applies external (out of source tree) dependencies
+# to given target. Arguments are:
+# TARGET - valid cmake target
+# PRIVACY - dependency can be inherited by dependent targets or not:
+# PUBLIC - this should be used by default, cause compile/link flags passing
+# PRIVATE - do not passes any settings to dependent targets,
+# may be usefull for static libraries from the inside of the project
+# Argument ARGV2 and following are supposed to be names of checked pkg config
+# packages. This function will use variables created by check_pkg_modules().
+# - ${DEP_NAME}_LIBRARIES
+# - ${DEP_NAME}_INCLUDE_DIRS
+# - ${DEP_NAME}_CFLAGS
+#
+FUNCTION(APPLY_PKG_CONFIG TARGET PRIVACY)
+ MATH(EXPR DEST_INDEX "${ARGC}-1")
+ FOREACH(I RANGE 2 ${DEST_INDEX})
+ IF(NOT ${ARGV${I}}_FOUND)
+ MESSAGE(FATAL_ERROR "Not found dependency - ${ARGV${I}}_FOUND")
+ ENDIF(NOT ${ARGV${I}}_FOUND)
+ TARGET_LINK_LIBRARIES(${TARGET} ${PRIVACY} "${${ARGV${I}}_LIBRARIES}")
+ TARGET_INCLUDE_DIRECTORIES(${TARGET} ${PRIVACY} SYSTEM "${${ARGV${I}}_INCLUDE_DIRS}")
+ STRING(REPLACE ";" " " CFLAGS_STR "${${ARGV${I}}_CFLAGS}")
+ SET(CFLAGS_LIST ${CFLAGS_STR})
+ SEPARATE_ARGUMENTS(CFLAGS_LIST)
+ FOREACH(OPTION ${CFLAGS_LIST})
+ TARGET_COMPILE_OPTIONS(${TARGET} ${PRIVACY} ${OPTION})
+ ENDFOREACH(OPTION)
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES SKIP_BUILD_RPATH true)
+ ENDFOREACH(I RANGE 2 ${DEST_INDEX})
+ENDFUNCTION(APPLY_PKG_CONFIG TARGET PRIVACY)
+++ /dev/null
-/*
- * Copyright (c) 2000 - 2020 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.
- */
-
-/**
- *
- * @ingroup SLP_PG
- * @defgroup bundle_PG Bundle
- * @brief A simple string-based dictionary ADT.
- * @{
-
-<h1 class="pg">Introduction</h1>
-
-<p> Bundle is a string based Dictionary ADT. A dictionary is an ordered or unordered list of key element pairs, where keys are used to locate elements in the list. </p><br/>
-
-<p> ADT (Abstract data type) An Abstract Data type is defined as a mathematical model of the data objects that make up a data type as well
-as the functions that operate on these objects.</p>
-
-<h1 class="pg">Features</h1>
-<ul>
- <li> Bundle provides string based Dictionary ADT to
- map/store key-value pairs. Eg. Clock </li>
- <li> Bundle provides Application Data Exchange (ADE):
- <ul>
- <li> Transfer application argument between caller and callee by creating a bundle and storing key-value pairs in it. </li>
- <li> This bundle object can be passed between applications by encoding and decoding the bundle objects. </li>
- </ul> </li>
-
-</ul>
-
-<h1 class="pg">Properties</h1>
-<ul>
- <li>Only string type is allowed for key and value.</li>
- <li>Each key and value is duplicated into the bundle object.</li>
- <li>Unlimited number of key/value pairs. (Memory limit is still to be considered)</li>
- <li>No key overlap : You cannot assign new values with existing key.</li>
-</ul>
-
-<h1 class="pg">Bundle Logical View diagram</h1>
-\image html SLP_bundle_PG_images_logical_view.png "Picture 1. Logical view"
-
-
-<h1 class="pg">Functional architecture diagram</h1>
-\image html SLP_bundle_PG_image01.png "Picture 2. Functional architecture"
-
-<p> Bundle requests are received by the Bundle interface. It passes the requests to bundle manager. Bundle Manager checks the type of the request and handles it accordingly. If string key-value needs to be handled in the request it interacts with String manager to provide the required functionality. If the request is based on array of string key-value pair then, Bundle manager interacts with Array manager to provide the required functionality.</p>
-
-<h1 class="pg"> Bundle encode decode life cycle </h1>
-\image html SLP_bundle_PG_images_encode_decode.png "Picture 2. Encode decode life cycle"
-
-<h1 class="pg"> Bundle export import life cycle </h1>
-\image html SLP_bundle_PG_images_export_import.png "Picture 2. Export import life cycle"
-
-<h1 class="pg">API list and description</h1>
-<ul>
- <li>bundle_create() : Create a bundle object.</li>
- <li>bundle_free() : Free a bundle object.</li>
- <li>bundle_add() : Add a key/value pair into the bundle object.</li>
- <li>bundle_del() : Delete a key/value pair by given key from the bundle object.</li>
- <li>bundle_get_val() : Get a value by key.</li>
- <li>bundle_get_count() : Get number of key/value pairs in the bundle object.</li>
- <li>bundle_dup() : Duplicate give bundle object</li>
- <li>bundle_iterate() : Run iterator function for each key/value pair in the bundle object.</li>
- <li>bundle_encode() : Encode bundle object into a byte code.</li>
- <li>bundle_decode() : Decode byt code into a bundle object.</li>
- <li></li>
-</ul>
-
-<h1 class="pg">Programming Guide</h1>
-<p> bundle library is very easy to use, and the sample code below would enough to understand how to use bundle. </p><br>
-<p>Detailed API instructions are in API reference in doxygen document.</p>
-<h2 class="pg">Note</h2>
-<ul>
- <li>Only string type(char *) keys/values are allowed.</li>
- <li>A bundle object must be freed certainly by bundle_free(). </li>
- <li>Values retrived by bundle_get_val() cannot be modified.<br> If you want to modify value string, duplicate it.</li>
-</ul>
-<h2 class="pg"> Header file </h2>
-<p> header file name: <strong> bundle.h </strong></p>
-<h2 class="pg">Code</h2>
-@code
-#include <stdio.h>
-#include <bundle.h>
-
-// This is a sample iterator callback function
-void print_bundle_item(const char *key, const char *val, void *data);
-
-// Sample code
-int
-main(int argc, char **argv)
-{
- char *str;
- int count;
-
- bundle *b, *b_dup;
-
- // Create a new bundle object
- b = bundle_new();
-
- // Add a string with key "a"
- bundle_add(b, "a", "123abc");
-
- // Add another string with key "b"
- bundle_add("b", "456def");
-
- // str = "123abc"
- // You cannot modify string!
- str = bundle_get_val(b, "a");
-
- // Run iterator function with each items
- bundle_iterate(b, print_bundle_item, NULL);
-
- // count = 2
- count = bundle_get_count(b);
-
- // Delete an item with key "a"
- bundle_del(b, "a");
-
- // count = 1
- count = bundle_get_count(b);
-
- // If "a" key is requested, NULL is returned
- // str = NULL, errno = ENOKEY
- str = bundle_get_val(b, "a");
-
- // Duplicate bundle object
- b_dup = bundle_dup(b);
-
- // Free bundle objects
- bundle_free(b);
- bundle_free(b_dup);
-
- return 0;
-}
-
-void
-print_bundle_item(const char *key, const char *val, void *data)
-{
- printf("%s -> %s\n", key, val);
-}
-@endcode
-
- * @}
- */
+++ /dev/null
-/*
- * Copyright (c) 2000 - 2020 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 __BUNDLE_H__
-#define __BUNDLE_H__
-
-/**
- * @file bundle.h
- * @brief This file declares API of the bundle library.
- */
-
-/**
- * @addtogroup CORE_LIB_BUNDLE_MODULE
- * @{
- */
-
-#include <errno.h>
-#include <stddef.h>
-#include <tizen_error.h>
-
-#ifdef __cplusplus
-extern "C" {
-# endif
-
-/**
- * @brief Enumeration for error codes of Bundle.
- * @since_tizen 2.3
- */
-typedef enum {
- BUNDLE_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
- BUNDLE_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */
- BUNDLE_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
- BUNDLE_ERROR_KEY_NOT_AVAILABLE = TIZEN_ERROR_KEY_NOT_AVAILABLE, /**< Required key not available */
- BUNDLE_ERROR_KEY_EXISTS = TIZEN_ERROR_BUNDLE | 0x01, /**< Key exists */
- BUNDLE_ERROR_ARRAY_INDEX_OUT_OF_BOUNDS = TIZEN_ERROR_BUNDLE | 0x02 /**< The index is out of bounds of the array */
-} bundle_error_e;
-
-
-/**
- * @brief The bundle handle.
- * @since_tizen 2.3
- */
-typedef struct _bundle_t bundle;
-
-
-/**
- * @brief The encoded data type.
- * @since_tizen 2.3
- * @see bundle_encode()
- * @see bundle_decode()
- */
-typedef unsigned char bundle_raw;
-
-
-/**
- * @brief Enumeration for key-value pair types.
- * @since_tizen 2.3
- */
-enum bundle_type_property {
- BUNDLE_TYPE_ARRAY = 0x0100, /**< Array type */
- BUNDLE_TYPE_PRIMITIVE = 0x0200, /**< Primitive type */
- BUNDLE_TYPE_MEASURABLE = 0x0400 /**< Measurable type */
-};
-
-
-/**
- * @brief Enumeration for bundle types.
- * @since_tizen 2.3
- */
-enum bundle_type {
- BUNDLE_TYPE_NONE = -1, /**< None */
- BUNDLE_TYPE_ANY = 0, /**< Any type */
- BUNDLE_TYPE_STR = 1 | BUNDLE_TYPE_MEASURABLE, /**< String type (Default) */
- BUNDLE_TYPE_STR_ARRAY = BUNDLE_TYPE_STR | BUNDLE_TYPE_ARRAY | BUNDLE_TYPE_MEASURABLE, /**< String array type */
- BUNDLE_TYPE_BYTE = 2, /**< Byte type */
- BUNDLE_TYPE_BYTE_ARRAY = BUNDLE_TYPE_BYTE | BUNDLE_TYPE_ARRAY /**< Byte array type */
-};
-
-
-/**
- * @brief The key-value pair handle.
- * @since_tizen 2.3
- * @see bundle_iterator_t
- */
-typedef struct keyval_t bundle_keyval_t;
-
-
-/**
- * @brief Called for every key-value pair.
- * @since_tizen 2.3
- * @param[in] key The key of key-value pair
- * @param[in] type The type of bundle
- * @param[in] kv The handle of key-value pair
- * @param[in] user_data The user data
- * @see bundle_foreach()
- */
-typedef void (*bundle_iterator_t) (const char *key, const int type, const bundle_keyval_t *kv, void *user_data);
-
-
-/**
- * @brief Creates a bundle object.
- * @since_tizen 2.3
- * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
- * @return The bundle object,
- * @c NULL - Failure
- * @exception #BUNDLE_ERROR_NONE Success
- * @exception #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
- * @see bundle_free()
- *
- * @code
- #include <bundle.h>
- bundle *b = bundle_create(); // Create a new bundle object
- bundle_free(b); // Free the bundle
- * @endcode
- */
-bundle *bundle_create(void);
-
-
-/**
- * @brief Frees the given bundle object with key-value pairs in it.
- * @since_tizen 2.3
- * @param[in] b The bundle object to be freed
- * @return The operation result
- * @retval #BUNDLE_ERROR_NONE Success
- * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @pre @a b must be a valid bundle object.
- * @see bundle_create()
- *
- * @code
- #include <bundle.h>
- bundle *b = bundle_create(); // Create a new bundle object
- bundle_free(b); // Free the bundle
- * @endcode
- */
-int bundle_free(bundle *b);
-
-
-/**
- * @brief Adds a strings array type key-value pair into a given bundle.
- * @since_tizen 2.3
- * @param[in] b The bundle object
- * @param[in] key The key
- * @param[in] str_array The string type value; if @c NULL, an empty array is created; you can change an item with
- * @param[in] len The length of the array
- * @return The operation result
- * @retval #BUNDLE_ERROR_NONE Success
- * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #BUNDLE_ERROR_KEY_EXISTS Key already exists
- * @retval #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
- * @pre @a b must be a valid bundle object.
- * @see bundle_get_str_array()
- *
- * @code
- #include <bundle.h>
- char *sa = {"aaa", "bbb", "ccc"}; // String array of length 3
- bundle *b = bundle_create();
- bundle_add_str_array(b, "foo", sa, 3); // Add a key-value pair
- bundle_free(b);
- * @endcode
- */
-int bundle_add_str_array(bundle *b, const char *key, const char **str_array, const int len);
-
-
-/**
- * @brief Deletes a key-value object with the given key.
- * @since_tizen 2.3
- * @param[in] b The bundle object
- * @param[in] key The given key
- * @return The operation result
- * @retval #BUNDLE_ERROR_NONE Success
- * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #BUNDLE_ERROR_KEY_NOT_AVAILABLE Key not available
- * @pre @a b must be a valid bundle object.
- *
- * @code
- #include <bundle.h>
- bundle *b = bundle_create(); // Create a new bundle object
- bundle_add_str(b, "foo_key", "bar_val"); // Add a key-value pair
- bundle_del(b, "foo_key"); // Delete "foo_key" from b
-
- bundle_free(b);
- * @endcode
- */
-int bundle_del(bundle *b, const char *key);
-
-
-/**
- * @brief Gets a string array from a given key.
- * @since_tizen 2.3
- * @remarks You MUST NOT free or modify the returned string. \n
- * The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
- * @param[in] b The bundle object
- * @param[in] key The key
- * @param[out] len The array length
- * @return The pointer to the array of strings,
- * @c NULL - Key not found
- * @exception #BUNDLE_ERROR_NONE Success
- * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @exception #BUNDLE_ERROR_KEY_NOT_AVAILABLE Key not available
- * @pre @a b must be a valid bundle object.
- * @see bundle_add_str_array()
- *
- * @code
- #include <bundle.h>
- bundle *b = bundle_create();
- char *sa = {"aaa", "bbb", "ccc"}; // String array of length 3
- bundle_add_str_array(b, "foo", sa, 3); // Add a key-value pair
-
- char **str_array = NULL;
- int len_str_array = 0;
-
- str_array=bundle_get_str_array(b, "foo", &len_str_array);
- // str_array = {"aaa", "bbb", "ccc"}, and len_str_array = 3
-
- bundle_free(b);
- * @endcode
- */
-const char **bundle_get_str_array(bundle *b, const char *key, int *len);
-
-
-/**
- * @brief Gets the number of bundle items.
- * @since_tizen 2.3
- * @param[in] b The bundle object
- * @return The number of bundle items
- * @pre @a b must be a valid bundle object.
- *
- * @code
- #include <bundle.h>
- bundle *b = bundle_create(); // Create a new bundle object
- bundle_add_str(b, "key1", "val1"); // Add a key-value pair
- int count = bundle_get_count(b); // count = 1
- bundle_add_str(b, "key2", "val2"); // Add another key-value pair
- count = bundle_get_count(b); // count = 2
-
- bundle_free(b);
- * @endcode
- */
-int bundle_get_count(bundle *b);
-
-
-/**
- * @brief Gets the type of the value with a given key.
- * @since_tizen 2.3
- * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
- * @param[in] b A bundle
- * @param[in] key A key in the bundle
- * @return The type of a key in @a b
- * @exception #BUNDLE_ERROR_NONE Success
- * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @exception #BUNDLE_ERROR_KEY_NOT_AVAILABLE Key not available
- * @pre @a b must be a valid bundle object.
- * @see bundle_type
- */
-int bundle_get_type(bundle *b, const char *key);
-
-
-/**
- * @brief Duplicates a given bundle object.
- * @since_tizen 2.4
- * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
- * The returned value should be released using bundle_free().
- * @param[in] b_from The bundle object to be duplicated
- * @return The new bundle object,
- * @c NULL - Failure
- * @exception #BUNDLE_ERROR_NONE Success
- * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @pre @a b_from must be a valid bundle object.
- *
- * @code
- #include <bundle.h>
- bundle *b = bundle_create(); // Create a new bundle object
- bundle_add_str(b, "foo_key", "bar_val"); // Add a key-value pair
- bundle *b_dup = bundle_dup(b); // Duplicate b
-
- bundle_free(b);
- bundle_free(b_dup);
- * @endcode
- */
-bundle *bundle_dup(bundle *b_from);
-
-
-/**
- * @brief Iterates a callback function for each key-value pair in a given bundle.
- * @details Supports all types of values.
- * @since_tizen 2.3
- * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section. \n
- * This function supports all types.
- * @param[in] b The bundle object
- * @param[in] iter The iteration callback function
- * @param[in] user_data The data for the callback function
- * @exception #BUNDLE_ERROR_NONE Success
- * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @pre @a b must be a valid bundle object.
- * @see bundle_keyval_get_type()
- * @see bundle_keyval_type_is_array()
- * @see bundle_keyval_get_basic_val()
- * @see bundle_keyval_get_array_val()
- *
- * @code
- #include <stdio.h>
- #include <bundle.h>
- void
- sample_cb(const char *key, const int type, const bundle_keyval_t *kv, void *user_data)
- {
- void *basic_val = NULL;
- size_t basic_size = 0;
- void **array_val = NULL;
- int array_len = 0;
- size_t *array_elem_size = NULL;
-
- printf("Key:%s, Type:%d\n", key, type);
- if (bundle_keyval_type_is_array(kv)) {
- bundle_keyval_get_array_val(kv, &array_val, &array_len, &array_elem_size);
- // Do something
- }
- else {
- bundle_keyval_get_basic_val(kv, &basic_val, &basic_size);
- // Do something
- }
- }
-
- int main(void)
- {
- bundle *b = bundle_create(); // Create a new bundle object
- bundle_add_str(b, "k1", "v1"); // Add a key-value pair
- bundle_add_byte(b, "k2", "v2", 3); // Add a key-value pair
- char *s_arr[] = {"abc", "bcd", "cde"};
- bundle_add_str_array(b, "k3", s_arr, 3); // Add a key-value pair
- bundle_foreach(b, sample_cb, NULL); // Iterate sample_cb() for each key/value
-
- return 0;
- }
- * @endcode
- */
-void bundle_foreach(bundle *b, bundle_iterator_t iter, void *user_data);
-
-
-/**
- * @brief Gets the type of a key-value pair.
- * @since_tizen 2.3
- * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
- * @param[in] kv A bundle_keyval_t object
- * @return The type of @a kv,
- * @c -1 - Failure
- * @exception #BUNDLE_ERROR_NONE Success
- * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @pre @a kv must be a valid bundle_keyval_t object.
- * @see bundle_foreach()
- */
-int bundle_keyval_get_type(bundle_keyval_t *kv);
-
-
-/**
- * @brief Determines whether the type of a key-value pair is an array.
- * @since_tizen 2.3
- * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
- * @param[in] kv A bundle_keyval_t object
- * @return The operation result
- * @c 1 - @a kv is an array
- * @c 0 - @a kv is not an array
- * @exception #BUNDLE_ERROR_NONE Success
- * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @pre @a kv must be a valid bundle_keyval_t object.
- * @see bundle_foreach()
- */
-int bundle_keyval_type_is_array(bundle_keyval_t *kv);
-
-
-/**
- * @brief Gets the value and size of the value from a key-value pair of basic type.
- * @since_tizen 2.3
- * @remarks You must not free @a val.
- * @param[in] kv A bundle_keyval_t object
- * @param[out] val The value
- * @param[out] size The size of @a val
- * @return The operation result
- * @retval #BUNDLE_ERROR_NONE Success
- * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @pre @a kv must be a valid bundle_keyval_t object.
- * @post @a val and @a size are set.
- * @see bundle_foreach()
- */
-int bundle_keyval_get_basic_val(bundle_keyval_t *kv, void **val, size_t *size);
-
-
-/**
- * @brief Gets the value array, length of the array, and size of each array item.
- * @since_tizen 2.3
- * @remarks The @a array_val should not be released.
- * The @a array_element_size should not be released.
- * @param[in] kv A bundle_keyval_t object
- * @param[out] array_val The array pointer of values
- * @param[out] array_len The length of @a array_val
- * @param[out] array_element_size The array of size of each array element
- * @return The operation result
- * @retval #BUNDLE_ERROR_NONE Success
- * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @pre @a kv must be a valid bundle_keyval_t object.
- * @post @a array_val, @a array_len, @a array_element_size are set.
- * @code
- #include <stdio.h>
- #include <bundle.h>
- void
- sample_cb(const char *key, const int type, const bundle_keyval_t *kv, void *user_data)
- {
- void **array_val = NULL;
- unsigned int array_len = 0;
- size_t *array_elem_size = NULL;
- unsigned int i;
-
- printf("Key: %s, Type: %d\n", key, type);
- if (bundle_keyval_type_is_array(kv)) {
- bundle_keyval_get_array_val(kv, &array_val, &array_len, &array_elem_size);
- for (i = 0; i < array_len; ++i) {
- printf("Value[%u]: %s\n", i, (const char *)array_val[i]);
- }
- }
- }
-
- int main(void)
- {
- bundle *b = bundle_create();
- const char *s_arr[] = {"abc", "bcd", "cde"};
- bundle_add_str_array(b, "k3", s_arr, 3); // Add a key-value pair
- bundle_foreach(b, sample_cb, NULL);
- bundle_free(b);
- return 0;
- }
- * @endcode
- * @see bundle_foreach()
- */
-int bundle_keyval_get_array_val(bundle_keyval_t *kv, void ***array_val, unsigned int *array_len, size_t **array_element_size);
-
-
-/**
- * @brief Encodes a bundle to the bundle_raw format (uses base64 format).
- * @since_tizen 2.3
- * @remarks The @a r should be released using free().
- * @param[in] b The bundle object
- * @param[out] r The returned bundle_raw data(byte data)
- * @a r MUST BE FREED by free(r)
- * @param[out] len The size of @a r (in bytes)
- * @return The size of the raw data
- * @retval #BUNDLE_ERROR_NONE Success
- * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @pre @a b must be a valid bundle object.
- *
- * @code
- #include <bundle.h>
- bundle *b = bundle_create(); // Create a new bundle object
- bundle_add_str(b, "foo_key", "bar_val"); // Add a key-value pair
- bundle_raw *r;
- int len;
- bundle_encode(b, &r, &len); // Encode b
- bundle_free(b);
- free(r);
- * @endcode
- */
-int bundle_encode(bundle *b, bundle_raw **r, int *len);
-
-
-/**
- * @brief Deserializes bundle_raw and gets the bundle object.
- * @since_tizen 2.3
- * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
- * The returned value should be released using bundle_free().
- * @param[in] r The bundle_raw data to be converted to bundle object
- * @param[in] len The size of @a r
- * @return The bundle object,
- * @c NULL - Failure
- * @exception #BUNDLE_ERROR_NONE Success
- * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @pre @a r must be a valid bundle object.
- *
- * @code
- #include <bundle.h>
- bundle *b = bundle_create(); // Create a new bundle object
- bundle_add_str(b, "foo_key", "bar_val"); // Add a key-value pair
-
- bundle_raw *encoded_b;
- int len;
- bundle_encode(b, &encoded_b, &len); // Encode b
-
- bundle *b_dup;
- b_dup = bundle_decode(encoded_b, len); // Decoded bundle object
-
- bundle_free(b);
- free(encoded_b);
- bundle_free(b_dup);
- * @endcode
- */
-bundle *bundle_decode(const bundle_raw *r, const int len);
-
-
-/**
- * @brief Adds a string type key-value pair into a bundle.
- * @since_tizen 2.3
- * @param[in] b The bundle object
- * @param[in] key The key
- * @param[in] str The string type value
- * @return The operation result
- * @retval #BUNDLE_ERROR_NONE Success
- * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #BUNDLE_ERROR_KEY_EXISTS Key already exists
- * @retval #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
- * @pre @a b must be a valid bundle object.
- * @see bundle_get_str()
- * @code
- #include <bundle.h>
- bundle *b = bundle_create(); // Create a new bundle object
- bundle_add_str(b, "foo", "bar"); // Add a key-value pair
-
- bundle_free(b);
- * @endcode
- */
-int bundle_add_str(bundle *b, const char *key, const char *str);
-
-
-/**
- * @brief Adds a byte sequence type key-value pair into a bundle.
- * @details The bundle will contain a copy of the added byte sequence.
- * @since_tizen 2.3
- * @param[in] b The bundle object
- * @param[in] key The key
- * @param[in] bytes The byte sequence
- * @param[in] size The byte sequence size in bytes
- * @return The operation result
- * @retval #BUNDLE_ERROR_NONE Success
- * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #BUNDLE_ERROR_KEY_EXISTS Key already exists
- * @retval #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
- * @pre @a b must be a valid bundle object.
- * @see bundle_get_byte()
- *
- * @code
- #include <bundle.h>
- bundle *b = bundle_create(); // Create a new bundle object
- bundle_add_byte(b, "foo", "bar\0", 4); // Add a key-value pair
-
- int number = 12345;
- bundle_add_byte(b, "number", &number, sizeof(int));
-
- bundle_free(b);
- * @endcode
- */
-int bundle_add_byte(bundle *b, const char *key, const void *bytes, const size_t size);
-
-
-/**
- * @brief Gets the string value with the given key.
- * @since_tizen 2.3
- * @remarks You must not free str.
- * @param[in] b The bundle object
- * @param[in] key The key
- * @param[out] str The returned value
- * @return The operation result
- * @retval #BUNDLE_ERROR_NONE Success
- * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #BUNDLE_ERROR_KEY_NOT_AVAILABLE Key not available
- * @pre @a b must be a valid bundle object.
- * @see bundle_add_str()
- *
- * @code
- #include <bundle.h>
- bundle *b = bundle_create(); // Create a new bundle object
- bundle_add_str(b, "foo_key", "bar_val"); // Add a key-value pair
-
- char *v = NULL;
- bundle_get_str(b, "foo_key", &v); // v = "bar_val"
-
- bundle_free(b); // After freeing b, v becomes a dangling pointer
- v = NULL;
- * @endcode
- */
-int bundle_get_str(bundle *b, const char *key, char **str);
-
-
-/**
- * @brief Gets the byte sequence with the given key.
- * @since_tizen 2.3
- * @remarks You must not free @a bytes.
- * @param[in] b The bundle object
- * @param[in] key The key
- * @param[out] bytes The byte sequence
- * @param[out] size The byte sequence size in bytes
- * @return The operation result
- * @retval #BUNDLE_ERROR_NONE Success
- * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #BUNDLE_ERROR_KEY_NOT_AVAILABLE Key not available
- * @pre @a b must be a valid bundle object.
- * @see bundle_add_byte()
- *
- * @code
- #include <bundle.h>
- bundle *b = bundle_create(); // Create a new bundle object
- bundle_add_byte(b, "foo", "bar\0", 4); // Add a string to the bundle
- int number = 12345;
- bundle_add_byte(b, "number", (const void**)&number, sizeof(int)); // Add an integer to the bundle
-
- unsigned char *v = NULL;
- size_t v_size;
- bundle_get_byte(b, "foo", (void**)&v, &v_size); // v = "bar\0"
- int *n = NULL;
- size_t n_size;
- bundle_get_byte(b, "number", (void**)&n, &n_size); // number = 12345
-
- bundle_free(b); // After freeing b, v and n become a dangling pointer
- * @endcode
- */
-int bundle_get_byte(bundle *b, const char *key, void **bytes, size_t *size);
-
-/**
- * @brief Adds an 'array of byte sequences' type key-value pair into a bundle.
- * @since_tizen 5.5
- * @remarks To set the value of the byte array element, you should use bundle_set_byte_array_element().
- * This function is only for creating a buffer of the byte array.
- *
- * @param[in] b The bundle object
- * @param[in] key The key
- * @param[in] len The length of the array to be created
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #BUNDLE_ERROR_NONE Successful
- * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #BUNDLE_ERROR_KEY_EXISTS Key already exists
- * @retval #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
- *
- * @see bundle_get_byte_array()
- * @see bundle_set_byte_array_element()
- */
-int bundle_add_byte_array(bundle *b, const char *key, const unsigned int len);
-
-/**
- * @brief Sets an element of an array of byte sequences.
- * @details The array will contain its own copy of the added value.
- * @since_tizen 5.5
- *
- * @param[in] b The bundle object
- * @param[in] key The key
- * @param[in] idx The index of the array element to be changed
- * @param[in] bytes The byte sequence
- * @param[in] size The byte sequence size in bytes
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #BUNDLE_ERROR_NONE Successful
- * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #BUNDLE_ERROR_KEY_NOT_AVAILABLE Key not available
- * @retval #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
- * @retval #BUNDLE_ERROR_ARRAY_INDEX_OUT_OF_BOUNDS The index is out of bounds of the array
- *
- * @see bundle_add_byte_array()
- * @see bundle_get_byte_array()
- */
-int bundle_set_byte_array_element(bundle *b, const char *key, const unsigned int idx, const void *bytes, const size_t size);
-
-/**
- * @brief Gets the array of byte sequences with the given key.
- * @since_tizen 5.5
- * @remarks You should not release @a byte_array, @a len and @a array_element_size.
- * @a byte_array, @a len and @a array_element_size will be released when the bundle containing them is released with bundle_free().
- *
- * @param[in] b The bundle object
- * @param[in] key The key
- * @param[out] byte_array The array pointer of the byte value
- * @param[out] len The array length
- * @param[out] array_element_size An array of sizes of each @a byte_array element
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #BUNDLE_ERROR_NONE Successful
- * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #BUNDLE_ERROR_KEY_NOT_AVAILABLE Key not available
- *
- * @see bundle_add_byte_array()
- * @see bundle_set_byte_array_element()
-*/
-int bundle_get_byte_array(bundle *b, const char *key, void ***byte_array, unsigned int *len, unsigned int **array_element_size);
-
-#ifdef __cplusplus
-}
-#endif
-
-/**
- * @}
- */
-
-#endif /* __BUNDLE_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2019 - 2020 Samsung Electronics Co., Ltd.
- *
- * 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 BUNDLE_CPP_H_
-#define BUNDLE_CPP_H_
-
-/**
- * @file bundle_cpp.h
- * @brief This file declares API of the bundle C++ library.
- */
-
-/**
- * @addtogroup CORE_LIB_BUNDLE_CPP_MODULE
- * @{
- */
-
-#include <bundle.h>
-
-#include <cstdio>
-#include <initializer_list>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#ifndef EXPORT_API
-#define EXPORT_API __attribute__((visibility("default")))
-#endif
-
-namespace tizen_base {
-
-/**
- * @brief The class for bundle APIs.
- * @since_tizen 5.5
- */
-class EXPORT_API Bundle final {
- public:
- /**
- * @brief The type for raw bundle.
- * @since_tizen 5.5
- */
- using BundleRaw =
- std::pair<std::unique_ptr<bundle_raw, decltype(std::free)*>, int>;
-
- /**
- * @brief The class for information of keys.
- * @since_tizen 5.5
- */
- class KeyInfo final {
- public:
- /**
- * @brief Constructor.
- * @since_tizen 5.5
- * @param[in] handle The handle for type bundle_keyval_t
- * @param[in] name The key string
- * @param[in] own True if this object owns the handle
- */
- KeyInfo(const bundle_keyval_t* handle, std::string name, bool own = false);
-
- /**
- * @brief Destructor.
- * @since_tizen 5.5
- */
- ~KeyInfo();
-
- /**
- * @brief Copy-constructor.
- * @since_tizen 5.5
- * @param[in] b The object to copy
- */
- KeyInfo(const KeyInfo& b);
-
- /**
- * @brief Assignment.
- * @since_tizen 5.5
- * @param[in] b The object to copy
- */
- KeyInfo& operator = (const KeyInfo& b);
-
- /**
- * @brief Move-constructor.
- * @since_tizen 5.5
- * @param[in] b The object to move
- */
- KeyInfo(KeyInfo&& b) noexcept;
-
- /**
- * @brief Assignment.
- * @since_tizen 5.5
- * @param[in] b The object to move
- */
- KeyInfo& operator = (KeyInfo&& b) noexcept;
-
- /**
- * @brief Gets the type of a key-value pair.
- * @since_tizen 5.5
- * @return The type
- */
- bundle_type GetType() const;
-
- /**
- * @brief Determines whether the type of a key-value pair is an array.
- * @since_tizen 5.5
- * @return True when it is an array
- */
- bool IsArray() const;
-
- /**
- * @brief Gets the key string.
- * @since_tizen 5.5
- * @return The key string
- */
- const std::string& GetName() const;
-
- private:
- class Impl;
- std::unique_ptr<Impl> impl_;
- };
-
- /**
- * @brief Constructor.
- * @since_tizen 5.5
- */
- Bundle();
-
- /**
- * @brief Constructor.
- * @since_tizen 6.5
- * @param[in] key_values The list of key-value pair
- */
- Bundle(std::initializer_list<
- std::pair<std::string, std::string>> key_values);
-
- /**
- * @brief Constructor.
- * @since_tizen 5.5
- * @param[in] raw The object for BundleRaw
- * @param[in] base64 @c true, @a raw is the encoded raw data using base64-encoding
- */
- explicit Bundle(BundleRaw raw, bool base64 = true);
-
- /**
- * @brief Constructor.
- * @since_tizen 5.5
- * @param[in] raw The string object for raw bundle
- */
- explicit Bundle(const std::string& raw);
-
- /**
- * @brief Constructor.
- * @since_tizen 5.5
- * @param[in] b The handle for bundle
- * @param[in] copy True if this object wants to copy it from the handle
- * @param[in] own True if this object owns the handle
- */
- explicit Bundle(bundle* b, bool copy = true, bool own = true);
-
- /**
- * @brief Destructor.
- * @since_tizen 5.5
- */
- ~Bundle();
-
- /**
- * @brief Copy-constructor.
- * @since_tizen 5.5
- * @param[in] b The object to copy
- */
- Bundle(const Bundle& b);
-
- /**
- * @brief Assignment.
- * @since_tizen 5.5
- * @param[in] b The object to copy
- */
- Bundle& operator = (const Bundle& b);
-
- /**
- * @brief Move-constructor.
- * @since_tizen 5.5
- * @param[in] b The object to move
- */
- Bundle(Bundle&& b) noexcept;
-
- /**
- * @brief Assignment.
- * @since_tizen 5.5
- * @param[in] b The object to move
- */
- Bundle& operator = (Bundle&& b) noexcept;
-
- /**
- * @brief Check the bundle is empty or not.
- * @since_tizen 6.0
- * @return true if the bundle is empty
- */
- bool IsEmpty() const noexcept;
-
- /**
- * @brief Gets keys in bundle object.
- * @since_tizen 5.5
- * @return A string array of object KeyInfo
- */
- std::vector<KeyInfo> GetKeys();
-
- /**
- * @brief Adds a string type key-value pair into a bundle.
- * @since_tizen 5.5
- * @param[in] key The string key
- * @param[in] val The string value
- * @return The operation result
- * @retval BUNDLE_ERROR_NONE Success
- * @retval BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval BUNDLE_ERROR_KEY_EXISTS Key already exists
- * @retval BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
- */
- int Add(const std::string& key, const std::string& val);
-
- /**
- * @brief Adds a string type key-value pair into a bundle.
- * @since_tizen 5.5
- * @param[in] key The string key
- * @param[in] val The array of strings
- * @return The operation result
- * @retval BUNDLE_ERROR_NONE Success
- * @retval BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval BUNDLE_ERROR_KEY_EXISTS Key already exists
- * @retval BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
- */
- int Add(const std::string& key, const std::vector<std::string>& val);
-
- /**
- * @brief Adds a string type key-value pair into a bundle.
- * @since_tizen 5.5
- * @param[in] key The string key
- * @param[in] val The array of bytes
- * @return The operation result
- * @retval BUNDLE_ERROR_NONE Success
- * @retval BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval BUNDLE_ERROR_KEY_EXISTS Key already exists
- * @retval BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
- */
- int Add(const std::string& key, const std::vector<unsigned char>& val);
-
- /**
- * @brief Deletes a key-value object with the given key.
- * @since_tizen 5.5
- * @param[in] key The string key
- * @return The operation result
- * @retval BUNDLE_ERROR_NONE Success
- * @retval BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval BUNDLE_ERROR_KEY_NOT_AVAILABLE Key not available
- */
- int Delete(const std::string& key);
-
- /**
- * @brief Gets a string from the key.
- * @since_tizen 5.5
- * @param[in] key The string key
- * @return The string
- */
- std::string GetString(const std::string& key) const;
-
- /**
- * @brief Gets strings from the key.
- * @since_tizen 5.5
- * @param[in] key The string key
- * @return The array of strings
- */
- std::vector<std::string> GetStringArray(const std::string& key) const;
-
- /**
- * @brief Gets bytes from the key.
- * @since_tizen 5.5
- * @param[in] key The string key
- * @return Bytes
- */
- std::vector<unsigned char> GetByte(const std::string& key) const;
-
- /**
- * @brief Converts this object to BundleRaw type.
- * @since_tizen 5.5
- * @param[in] base64 @c true, the BundleRaw will be encoded using base64-encoding.
- * @return The object of BundleRaw
- */
- BundleRaw ToRaw(bool base64 = true);
-
- /**
- * @brief Gets the count of keys.
- * @since_tizen 5.5
- * @return The count
- */
- int GetCount() const;
-
- /**
- * @brief Gets the data type from the key.
- * @since_tizen 5.5
- * @param[in] key The string key
- * @return The data type
- */
- bundle_type GetType(const std::string& key) const;
-
- /**
- * @brief Gets the handle for bundle APIs.
- * @since_tizen 5.5
- * @return The handle for bundle
- */
- bundle* GetHandle() const;
-
- /**
- * @brief Moves this object into the bundle handle.
- * @since_tizen 5.5
- * @return The handle for bundle
- */
- bundle* Detach();
-
- /**
- * @brief Exports bundle to an argument vector.
- * @since_tizen 6.5
- * @return The argument vector
- */
- std::vector<std::string> Export() const;
-
- private:
- class Impl;
- std::unique_ptr<Impl> impl_;
-};
-
-} // namespace tizen_base
-
-/**
- * @}
- */
-
-#endif // BUNDLE_CPP_H_
+++ /dev/null
-/*
- * Copyright (c) 2000 - 2020 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 __BUNDLE_INTERNAL_H__
-#define __BUNDLE_INTERNAL_H__
-
-/**
- * @file bundle_internal.h
- * @brief This file declares has API of the bundle library
- */
-
-/**
- * @addtogroup CORE_LIB_BUNDLE_MODULE
- * @{
- */
-
-#include <bundle.h>
-
-#ifdef __cplusplus
-extern "C" {
-# endif
-
-/**
- * @brief Called for every key-value pair.
- * @since_tizen 2.3
- * @remarks This type is obsolete. You must not use this type any more.
- * @see bundle_iterate()
- */
-typedef void (*bundle_iterate_cb_t) (const char *key, const char *val, void *data);
-
-/**
- * @brief Adds a string type key-value pair into a given bundle.
- * @since_tizen 2.3
- * @param[in] b The bundle object
- * @param[in] key The key
- * @param[in] val The value
- * @return The operation result
- * @retval #BUNDLE_ERROR_NONE Success
- * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #BUNDLE_ERROR_KEY_EXISTS Key already exists
- * @retval #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
- * @pre @a b must be a valid bundle object.
- * @see bundle_add_str()
- @code
- #include <bundle_internal.h>
- bundle *b = bundle_create(); // Create new bundle object
- bundle_add(b, "foo_key", "bar_val"); // add a key-val pair
-
- bundle_free(b);
- @endcode
- */
-int bundle_add(bundle *b, const char *key, const char *val);
-
-/**
- * @brief Gets a value with a given key.
- * @since_tizen 2.3
- * @remarks You MUST NOT free or modify the returned string!
- * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
- * @param[in] b The bundle object
- * @param[in] key The key
- * @return The pointer for the value string
- * @retval @c NULL - Key not found
- * @exception #BUNDLE_ERROR_NONE Success
- * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @exception #BUNDLE_ERROR_KEY_NOT_AVAILABLE Key not available
- * @pre @a b must be a valid bundle object.
- * @see bundle_get_str()
- @code
- #include <bundle_internal.h>
- bundle *b = bundle_create(); // Create new bundle object
- bundle_add_str(b, "foo", "bar"); //add a key-val pair
- char *val = bundle_get_val(b, "foo_key"); // val = "bar_val"
-
- bundle_free(b); // After freeing b, val becomes a dangling pointer.
- val = NULL;
- @endcode
- */
-const char *bundle_get_val(bundle *b, const char *key);
-
-/**
- * @brief Iterates a callback function for each key-value pairs in a given bundle.
- * @details (NOTE: Only BUNDLE_TYPE_STR type values come!)
- * @since_tizen 2.3
- * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
- * @remarks This function is obsolete and does not give values whose types are not BUNDLE_TYPE_STR.
- * @param[in] b The bundle object
- * @param[in] callback The iteration callback function
- * @param[in] cb_data The data for callback function
- * @exception #BUNDLE_ERROR_NONE Success
- * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @pre @a b must be a valid bundle object.
- @code
- #include <stdio.h>
- #include <bundle_internal.h>
- void sample_cb(const char *k, const char *v, void *data) {
- printf("%s -> %s\n", k, v);
- }
-
- int main(void) {
- bundle *b = bundle_create(); // Create new bundle object
- bundle_add_str(b, "k1", "v1"); // add a key-val pair
- bundle_add_str(b, "k2", "v2"); // add a key-val pair
- bundle_add_str(b, "k3", "v3"); // add a key-val pair
- bundle_iterate(b, sample_cb, NULL); // iterate sample_cb() for each key/val
- return 0;
- }
- @endcode
- */
-void bundle_iterate(bundle *b, bundle_iterate_cb_t callback, void *cb_data);
-
-/**
- * @brief Determines whether the type of a key-value pair is measurable.
- * @since_tizen 2.3
- * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
- * @param[in] kv A bundle_keyval_t object
- * @return The operation result
- * @retval @c 1 - @a kv is an measurable
- * @retval @c 0 - @a kv is not an measurable
- * @exception #BUNDLE_ERROR_NONE Success
- * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @pre @a kv must be a valid bundle_keyval_t object.
- * @see bundle_foreach()
- */
-int bundle_keyval_type_is_measurable(bundle_keyval_t *kv);
-
-/**
- * @brief Duplicates key-value pair.
- * @since_tizen 5.5
- * @param[in] kv A bundle_keyval_t object
- * @return The bundle object
- * @retval @c NULL - Failure
- * @pre @a kv must be a valid bundle_keyval_t object.
- */
-bundle_keyval_t *bundle_keyval_dup(const bundle_keyval_t *kv);
-
-/**
- * @brief Frees the encoded rawdata.
- * @since_tizen 2.3
- * @param[in] r The rawdata
- * @return The operation result
- * @retval #BUNDLE_ERROR_NONE Success
- * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @pre @a r is a valid rawdata generated by bundle_encode().
- * @see bundle_encode()
- */
-int bundle_free_encoded_rawdata(bundle_raw **r);
-
-/**
- * @brief Encodes a bundle to the bundle_raw format.
- * @since_tizen 2.3
- * @param[in] b The bundle object
- * @param[out] r The returned bundle_raw data(byte data)
- * @a r MUST BE FREED by free(r)
- * @param[out] len The size of @a r (in bytes)
- * @return The size of the raw data
- * @retval #BUNDLE_ERROR_NONE Success
- * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
- * @pre @a b must be a valid bundle object.
- @code
- #include <bundle_internal.h>
- bundle *b = bundle_create(); // Create new bundle object
- bundle_add_str(b, "foo_key", "bar_val"); // add a key-val pair
- bundle_raw *r;
- int len;
- bundle_encode_raw(b, &r, &len); // encode b
-
- bundle_free(b);
- @endcode
- */
-int bundle_encode_raw(bundle *b, bundle_raw **r, int *len);
-
-/**
- * @brief Deserializes bundle_raw and gets a bundle object.
- * @since_tizen 2.3
- * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
- * @param[in] r The bundle_raw data to be converted to a bundle object
- * @param[in] len The size of @a r
- * @return The bundle object
- * @retval @c NULL - Failure
- * @exception #BUNDLE_ERROR_NONE Success
- * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @pre @a r must be a valid bundle object.
- @code
- #include <bundle_internal.h>
- bundle *b = bundle_create(); // Create new bundle object
- bundle_add_str(b, "foo_key", "bar_val"); // add a key-val pair
-
- bundle_raw *encoded_b;
- int len;
- bundle_encode(b, &encoded_b, &len); // encode b
-
- bundle *b_dup;
- b_dup = bundle_decode_raw(encoded_b, len); // decoded bundle object
-
- bundle_free(b);
- free(encoded_b);
- bundle_free(b_dup);
- @endcode
- */
-bundle *bundle_decode_raw(const bundle_raw *r, const int len);
-
-/**
- * @brief Exports bundle to @a argv.
- * @since_tizen 2.3
- * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
- * @param[in] b The bundle object
- * @param[out] argv The pointer of the string array; \n
- * This array has NULL values for the first and last item; \n
- * First NULL is for argv[0], and last NULL is a terminator for execv() \n
- * @return The number of item in @a argv. This value is equal to the actual count of argv - 1. (Last NULL terminator is not counted.)
- * @retval @c -1 - Failure
- * @exception #BUNDLE_ERROR_NONE Success
- * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @exception #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
- * @pre @a b is a valid bundle object.
- * @post @a argv is a pointer of newly allocated memory. It must be freed.
- * @see bundle_import_from_argv()
- @code
- #include <bundle_internal.h>
- bundle *b = bundle_create(); // Create new bundle object
- bundle_add_str(b, "foo_key", "bar_val"); // add a key-val pair
-
- int argc = 0;
- char **argv = NULL;
- argc = bundle_export_to_argv(b, &argv); // export to argv
- if(0 > argc) error("export failure");
-
- int i;
- for(i=0; i < argc; i++) {
- printf("%s\n", argv[i]); // print argv
- }
- bundle_free_exported_argv(argc, argv); // argv must be freed after being used.
-
- bundle_free(b);
- @endcode
- */
-int bundle_export_to_argv(bundle *b, char ***argv);
-
-/**
- * @brief Frees the exported @a argv.
- * @since_tizen 2.3
- * @remarks You must not use this API when you use global @a argv.
- * @param[in] argc The number of args, which is the return value of bundle_export_to_argv()
- * @param[in] argv The array from bundle_export_to_argv()
- * @return The operation result
- * @retval #BUNDLE_ERROR_NONE Success
- * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @pre @a argv is a valid string array generated from bundle_export_to_argv().
- * @see bundle_export_to_argv()
- @code
- bundle *b = bundle_create();
- bundle_add_str(b, "foo", "bar");
-
- int argc = 0;
- char **argv = NULL;
- argc = bundle_export_to_argv(b, &argv);
- if(0 > argc) error("export failure");
-
- // Use argv...
-
- bundle_free_exported_argv(argc, argv);
- argv = NULL;
-
- bundle_free(b);
- @endcode
- */
-int bundle_free_exported_argv(int argc, char ***argv);
-
-/**
- * @brief Imports a bundle from @a argv.
- * @since_tizen 2.3
- * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
- * @param[in] argc The argument count
- * @param[in] argv The argument vector
- * @return The new bundle object
- * @retval @c NULL - Failure
- * @exception #BUNDLE_ERROR_NONE Success
- * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @exception #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
- * @pre @a argv is a valid string array, which is created by bundle_export_to_argv().
- * @post The returned bundle @a b must be freed.
- * @see bundle_export_to_argv()
- @code
- #include <bundle_internal.h>
-
- int main(int argc, char **argv) {
- bundle *b = bundle_import_from_argv(argc, argv); // import from argc+argv
- char *val = bundle_get_val(b, "foo_key"); // value for "foo_key"
- // ......
- bundle_free(b); // After freeing b, val becomes a dangling pointer.
- val = NULL;
- }
- @endcode
- */
-bundle *bundle_import_from_argv(int argc, char **argv);
-
-/**
- * @brief Sets a value of string array elements.
- * @since_tizen 2.3
- * @param[in] b The bundle object
- * @param[in] key The key
- * @param[in] idx The index of the array element to be changed
- * @param[in] val The string type value; if @c NULL, an empty array is created; you can change an item with
- * @return The operation result
- * @retval #BUNDLE_ERROR_NONE Success
- * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @pre @a b must be a valid bundle object.
- * @see bundle_add_str_array()
- * @see bundle_get_str_array()
- @code
- #include <bundle_internal.h>
- bundle *b = bundle_create();
- bundle_add_str_array(b, "foo", NULL, 3); // add a key-val pair
- bundle_set_str_array_element(b, "foo", 0, "aaa");
- bundle_set_str_array_element(b, "foo", 1, "bbb");
- bundle_set_str_array_element(b, "foo", 2, "ccc");
-
- char **str_array = NULL;
- int len_str_array = 0;
-
- str_array=bundle_get_str_array(b, "foo", &len_str_array);
- // str_array = { "aaa", "bbb", "ccc" }, and len_str_array = 3
-
- bundle_free(b);
- @endcode
- */
-int bundle_set_str_array_element(bundle *b, const char *key, const unsigned int idx, const char *val);
-
-/**
- * @brief Creates a JSON data from bundle.
- * @since_tizen 3.0
- * @remarks This function only supports the string type and the string array type.
- * @param[in] b The bundle object
- * @param[out] json The new created json data
- * @return The operation result
- * @retval #BUNDLE_ERROR_NONE Success
- * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
- * @pre @a b must be a valid bundle object.
- @code
- #include <bundle_internal.h>
- bundle *b = bundle_create();
- char *json;
- int ret;
-
- bundle_add_str(b, "foo", "bar");
- ret = bundle_to_json(b, &json);
- if (ret != BUNDLE_ERROR_NONE) {
- bundle_free(b);
- return;
- }
- // json = "{"foo":"bar"}"
- bundle_free(b);
- free(json);
- @endcode
- */
-int bundle_to_json(bundle *b, char **json);
-
-/**
- * @breif Creates a bundle object from json.
- * @since_tizen 3.0
- * @remarks This function only supports the string type and the string array type.
- * @param[in] json The json data
- * @param[out] b The bundle object
- * @return The operation result
- * @retval #BUNDLE_ERROR_NONE Success
- * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
- @code
- #include <bundle_internal.h>
- bundle *b;
- char *json = "{"foo":"bar"}";
- int ret;
-
- ret = bundle_from_json(json, &b);
- if (ret != BUNDLE_ERROR_NONE)
- return;
- bundle_free(b);
- @endcode
- */
-int bundle_from_json(const char *json, bundle **b);
-
-/**
- * @breif Compares the bundle 1, 2.
- * @since_tizen 3.0
- * @param[in] b1 The bundle object
- * @param[in] b2 The bundle object
- * @return The operation result
- * @retval @c 0 It is identical
- * @retval @c -1 Invalid parameter
- * @retval @c 1 It is not identical
- */
-int bundle_compare(bundle *b1, bundle *b2);
-
-/**
- * @brief Initializes a byte array type key-value pair into a bundle.
- * @details To set the value of the byte array element, you should use bundle_set_byte_array_element().
- * This function is only for creating a buffer of the byte array.
- * @since_tizen 5.5
- * @param[in] b The bundle object
- * @param[in] key The key
- * @param[in] len The length of the array to be created
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #BUNDLE_ERROR_NONE Successful
- * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #BUNDLE_ERROR_KEY_EXISTS Key already exists
- * @retval #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
- *
- * @see bundle_set_byte_array_element()
- */
-int bundle_init_byte_array(bundle *b, const char *key, const unsigned int len);
-
-/**
- * @brief Frees the given key-value pair.
- * @since_tizen 6.0
- * @param[in] kv The key-value pair
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #BUNDLE_ERROR_NONE Successful
- * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
- */
-int bundle_keyval_free(bundle_keyval_t *kv);
-
-#ifdef __cplusplus
-}
-#endif
-
-/**
- * @}
- * @}
- */
-
-#endif /* __BUNDLE__INTERNAL_H__ */
export LDFLAGS+=" -lgcov"
%endif
-%cmake -DVERSION=%{version} .
+MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
+%cmake . -DFULLVER=%{version} -DMAJORVER=${MAJORVER}
%__make %{?_smp_mflags}
%check
+export LD_LIBRARY_PATH="../../src/bundle:../../src/parcel"
ctest --verbose %{?_smp_mflags}
%if 0%{?gcov:1}
lcov -c --ignore-errors mismatch,graph,unused --no-external -b . -d . -o %{name}.info
+++ /dev/null
-CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
-PROJECT(parcel C CXX)
-
-INCLUDE(FindPkgConfig)
-PKG_CHECK_MODULES(pkgs REQUIRED dlog capi-base-common glib-2.0)
-
-FOREACH(flag ${pkgs_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -flto -Wall -Werror -Winline")
-
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -std=c++17")
-SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
-
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../)
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/)
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/api)
-
-AUX_SOURCE_DIRECTORY(${CMAKE_SOURCE_DIR}/parcel PARCEL_SRCS)
-
-ADD_LIBRARY (${PROJECT_NAME} SHARED ${PARCEL_SRCS})
-
-SET_TARGET_PROPERTIES(parcel PROPERTIES SOVERSION ${VERSION_MAJOR})
-SET_TARGET_PROPERTIES(parcel PROPERTIES VERSION "${VERSION}")
-
-SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS} -fPIE")
-SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES LINK_FLAGS "-pie")
-
-### Make pkgconfig file
-SET(PREFIX ${CMAKE_INSTALL_PREFIX})
-CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/parcel.pc.in
- ${CMAKE_BINARY_DIR}/parcel.pc @ONLY)
-
-### Install
-INSTALL(TARGETS parcel DESTINATION ${LIB_INSTALL_DIR})
-INSTALL(FILES ${CMAKE_BINARY_DIR}/parcel.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig/)
-
-SET(HEADER_PARCEL
- common.hh
- parcel.hh
- parcelable.hh
-)
-
-FOREACH(hfile ${HEADER_PARCEL})
- INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${hfile} DESTINATION include/parcel)
-ENDFOREACH(hfile)
-
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/api/parcel.h
- DESTINATION include/parcel)
+++ /dev/null
-/*
- * Copyright (c) 2020 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 __PARCEL_H__
-#define __PARCEL_H__
-
-#include <stdint.h>
-#include <stddef.h>
-#include <tizen.h>
-
-/**
- * @addtogroup CORE_LIB_PARCEL_MODULE
- * @{
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @brief The parcel handle.
- * @since_tizen 6.5
- */
-typedef void *parcel_h;
-
-/**
- * @brief The interface for converting data to/from a parcel.
- * @since_tizen 6.5
- */
-typedef struct {
- void (*to)(parcel_h parcel, void *data);
- void (*from)(parcel_h parcel, void *data);
-} parcelable_t;
-
-/**
- * @brief Enumeration for error codes for a parcel.
- * @since_tizen 6.5
- */
-typedef enum {
- PARCEL_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
- PARCEL_ERROR_ILLEGAL_BYTE_SEQ = TIZEN_ERROR_ILLEGAL_BYTE_SEQ, /**< Illegal byte sequence */
- PARCEL_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
- PARCEL_ERROR_NO_DATA = TIZEN_ERROR_NO_DATA, /**< No data available */
- PARCEL_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */
-} parcel_error_e;
-
-/**
- * @brief Creates a parcel handle.
- * @since_tizen 6.5
- * @remarks You MUST release @a parcel using parcel_destroy().
- * @param[out] parcel The parcel handle that is newly created
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #PARCEL_ERROR_OUT_OF_MEMORY Out of memory
- * @see parcel_destroy()
- */
-int parcel_create(parcel_h *parcel);
-
-/**
- * @brief Destroys a parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER
- * @see parcel_create()
- */
-int parcel_destroy(parcel_h parcel);
-
-/**
- * @brief Creates and returns a copy of the given parcel handle.
- * @since_tizen 6.5
- * @remarks A newly created parcel should be destroyed by calling the parcel_destroy() if it is no longer needed.
- * @param[in] parcel The parcel handle
- * @param[out] If successful, a newly created parcel handle will be returned
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @see parcel_destroy()
- */
-int parcel_clone(parcel_h parcel, parcel_h *clone);
-
-/**
- * @brief Writes bytes to the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[in] buf The array buffer to write
- * @param[in] size The size of bytes to write
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @see parcel_burst_read()
- */
-int parcel_burst_write(parcel_h parcel, const void *buf, uint32_t size);
-
-/**
- * @brief Reads bytes from the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[out] buf The array buffer to read
- * @param[in] size The size of bytes to read
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #PARCEL_ERROR_NO_DATA No data available
- * @retval #PARCEL_ERROR_ILLEGAL_BYTE_SEQ Illegal byte sequence
- * @see parcel_burst_write()
- */
-int parcel_burst_read(parcel_h parcel, void *buf, uint32_t size);
-
-/**
- * @brief Writes a boolean value into the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[in] val The boolean value
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @see parcel_read_bool()
- */
-int parcel_write_bool(parcel_h parcel, bool val);
-
-/**
- * @brief Writes a byte value into the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[in] val The byte value
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @see parcel_read_uint8()
- */
-int parcel_write_byte(parcel_h parcel, char val);
-
-/**
- * @brief Writes an unsigned short value into the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[in] val The unsigned short value
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @see parcel_read_uint16()
- */
-int parcel_write_uint16(parcel_h parcel, uint16_t val);
-
-/**
- * @brief Writes an unsigned integer value into the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[in] val The unsigned integer value
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @see parcel_read_uint32()
- */
-int parcel_write_uint32(parcel_h parcel, uint32_t val);
-
-/**
- * @brief Writes an unsigned long long integer value into the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[in] val The unsigned long long interger value
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @see parcel_read_uint64()
- */
-int parcel_write_uint64(parcel_h parcel, uint64_t val);
-
-/**
- * @brief Writes a signed short value into the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[in] val The signed short value
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @see parcel_read_int16()
- */
-int parcel_write_int16(parcel_h parcel, int16_t val);
-
-/**
- * @brief Writes a signed integer value into the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[in] val The signed integer value
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @see parcel_read_int32()
- */
-int parcel_write_int32(parcel_h parcel, int32_t val);
-
-/**
- * @brief Writes a signed long long integer value into the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[in] val The signedi long long integer value
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @see parcel_read_int64()
- */
-int parcel_write_int64(parcel_h parcel, int64_t val);
-
-/**
- * @brief Writes a floating point value into the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[in] val The floating point value
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @see parcel_read_float()
- */
-int parcel_write_float(parcel_h parcel, float val);
-
-/**
- * @brief Writes a double precision floating point value into the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[in] val The double precision floating point value
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCLE_ERROR_INVALID_PARAMETER Invalid parameter
- * @see parcel_read_double()
- */
-int parcel_write_double(parcel_h parcel, double val);
-
-/**
- * @brief Writes a string data into the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[in] str The string data
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @see parcel_read_string()
- */
-int parcel_write_string(parcel_h parcel, const char *str);
-
-/**
- * @brief Reads a boolean value from the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[out] val The boolean value
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #PARCEL_ERROR_NO_DATA No data available
- * @retval #PARCEL_ERROR_ILLEGAL_BYTE_SEQ Illegal byte sequence
- * @see parcel_write_bool()
- */
-int parcel_read_bool(parcel_h parcel, bool *val);
-
-/**
- * @brief Reads a byte value from the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[out] val The byte value
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #PARCEL_ERROR_NO_DATA No data available
- * @retval #PARCEL_ERROR_ILLEGAL_BYTE_SEQ Illegal byte sequence
- * @see parcel_write_uint8()
- */
-int parcel_read_byte(parcel_h parcel, char *val);
-
-/**
- * @brief Reads an unsigned short value from the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[out] val The unsigned short value
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #PARCEL_ERROR_NO_DATA No data available
- * @retval #PARCEL_ERROR_ILLEGAL_BYTE_SEQ Illegal byte sequence
- * @see parcel_write_uint16()
- */
-int parcel_read_uint16(parcel_h parcel, uint16_t *val);
-
-/**
- * @brief Reads an unsigned integer value from the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[out] val The unsigned integer value
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #PARCEL_ERROR_NO_DATA No data available
- * @retval #PARCEL_ERROR_ILLEGAL_BYTE_SEQ Illegal byte sequence
- * @see parcel_write_uint32()
- */
-int parcel_read_uint32(parcel_h parcel, uint32_t *val);
-
-/**
- * @brief Reads an unsigned long long integer value from the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[out] val The unsigned long long integer value
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #PARCEL_ERROR_NO_DATA No data available
- * @retval #PARCEL_ERROR_ILLEGAL_BYTE_SEQ Illegal byte sequence
- * @see parcel_write_uint64()
- */
-int parcel_read_uint64(parcel_h parcel, uint64_t *val);
-
-/**
- * @brief Reads a signed short value from the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[out] val The signed short value
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #PARCEL_ERROR_NO_DATA No data available
- * @retval #PARCEL_ERROR_ILLEGAL_BYTE_SEQ Illegal byte sequence
- * @see parcel_write_int16()
- */
-int parcel_read_int16(parcel_h parcel, int16_t *val);
-
-/**
- * @brief Reads a signed integer value from the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[out] val The signed integer value
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #PARCEL_ERROR_NO_DATA No data available
- * @retval #PARCEL_ERROR_ILLEGAL_BYTE_SEQ Illegal byte sequence
- * @see parcel_write_int32()
- */
-int parcel_read_int32(parcel_h parcel, int32_t *val);
-
-/**
- * @brief Reads a signed long long integer value from the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[out] val The signed long long integer value
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #PARCEL_ERROR_NO_DATA No data available
- * @retval #PARCEL_ERROR_ILLEGAL_BYTE_SEQ Illegal byte sequence
- * @see parcel_write_int64()
- */
-int parcel_read_int64(parcel_h parcel, int64_t *val);
-
-/**
- * @brief Reads a floating point value from the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[out] val The floating point value
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #PARCEL_ERROR_NO_DATA No data available
- * @retval #PARCEL_ERROR_ILLEGAL_BYTE_SEQ Illegal byte sequence
- * @see parcel_write_uint8()
- */
-int parcel_read_float(parcel_h parcel, float *val);
-
-/**
- * @brief Reads a double precision floating point value from the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[out] val The double precision floating point value
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #PARCEL_ERROR_NO_DATA No data available
- * @retval #PARCEL_ERROR_ILLEGAL_BYTE_SEQ Illegal byte sequence
- * @see parcel_write_uint8()
- */
-int parcel_read_double(parcel_h parcel, double *val);
-
-/**
- * @brief Reads a string data from the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[out] str The string data
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #PARCEL_ERROR_NO_DATA No data available
- * @retval #PARCEL_ERROR_ILLEGAL_BYTE_SEQ Illegal byte sequence
- * @retval #PARCEL_ERROR_OUT_OF_MEMORY Out of memory
- * @see parcel_write_uint8()
- */
-int parcel_read_string(parcel_h parcel, char **str);
-
-/**
- * @brief Resets the reader pointer of the parcel handle to the start.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- */
-int parcel_reset_reader(parcel_h parcel);
-
-/**
- * @brief Clears the data of the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- */
-int parcel_clear(parcel_h parcel);
-
-/**
- * @brief Resets the data of the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[in] buf The array buffer to write
- * @param[in] size The size of bytes to write
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- */
-int parcel_reset(parcel_h parcel, const void *buf, uint32_t size);
-
-/**
- * @brief Writes the data using @a parcelable to the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[in] parcelable The interface to write the data into the parcel handle
- * @param[in] data The user data which writes into the parcel handle
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @see parcel_read()
- */
-int parcel_write(parcel_h parcel, parcelable_t *parcelable, void *data);
-
-/**
- * @brief Reads the data using @a parcelable from the parcel handle.
- * @since_tizen 6.5
- * @param[in] parcel The parcel handle
- * @param[in] parcelable The interface to read the data from the parcel handle
- * @param[in] data The user data which reads from the parcel handle
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @see parcel_write()
- */
-int parcel_read(parcel_h parcel, parcelable_t *parcelable, void *data);
-
-/**
- * @brief Gets the raw data of the parcel handle.
- * @since_tizen 6.5
- * @remarks You MUST NOT release @a raw using free(). It's managed by platform.
- * @param[in] parcel The parcel handle
- * @param[out] raw The raw data
- * @param[out] size The size of the raw data
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- */
-int parcel_get_raw(parcel_h parcel, void **raw, uint32_t *size);
-
-/**
- * @brief Sets byte order of the parcel handle.
- * @since_tizen 6.5
- * @remarks The platform byte order is little-endian.
- * The network byte order is defined to always be big-endian.
- * If you want to change byte order of the raw data of the parcel handle,
- * you set byte order of the parcel handle using the function.
- * @param[in] parcel The parcel handle
- * @param[in] big_endian @ true, if byte order of the parcel is big-endian
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- */
-int parcel_set_byte_order(parcel_h parcle, bool big_endian);
-
-/**
- * @brief Gets the size of the data capacity of the parcel handle.
- * @since_tizen 7.0
- * @param[in] parcel The parcel handle
- * @param[out] size The size of the data capacity
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- */
-int parcel_get_data_capacity(parcel_h parcel, size_t *size);
-
-/**
- * @brief Sets the size of the data capacity of the parcel handle.
- * @since_tizen 7.0
- * @remarks The raw data will be reallocated using the given size.
- * @param[in] parcel The parcel handle
- * @param[in] size The size of the data capacity
- * @return @c 0 on success,
- * otherwise a negative error value
- * @retval #PARCEL_ERROR_NONE Successful
- * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #PARCEL_ERROR_OUT_OF_MEMORY
- */
-int parcel_set_data_capacity(parcel_h parcel, size_t size);
-
-#ifdef __cplusplus
-}
-#endif
-
-/**
- * @}
- */
-
-#endif /* __PARCEL_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2020 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 PARCEL_COMMON_HH_
-#define PARCEL_COMMON_HH_
-
-#undef EXPORT
-#define EXPORT __attribute__((visibility("default")))
-
-#endif // PARCEL_COMMON_HH_
+++ /dev/null
-/*
- * Copyright (c) 2020 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 PARCEL_LOG_PRIVATE_HH_
-#define PARCEL_LOG_PRIVATE_HH_
-
-#include <dlog.h>
-
-#undef LOG_TAG
-#define LOG_TAG "PARCEL"
-
-#undef _E
-#define _E LOGE
-
-#undef _W
-#define _W LOGW
-
-#undef _I
-#define _I LOGI
-
-#undef _D
-#define _D LOGD
-
-#endif // PARCEL_LOG_PRIVATE_HH_
+++ /dev/null
-/*
- * Copyright (c) 2020 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 <glib.h>
-
-#include <exception>
-#include <mutex>
-
-#include "parcel/common.hh"
-#include "parcel/log_private.hh"
-#include "parcel/parcel.hh"
-#include "parcel/parcel_implementation.hh"
-#include "parcel/parcelable.hh"
-
-namespace tizen_base {
-namespace {
-
-constexpr const size_t kDataCapacity = 1024;
-
-} // namespace
-
-Parcel::Impl::Impl(Parcel* parent, size_t data_capacity, uint8_t* data)
- : parent_(parent), data_capacity_(data_capacity), data_(data) {
- if (data_ != nullptr)
- data_size_ = data_capacity_;
- else
- data_ = static_cast<uint8_t*>(malloc(data_capacity_));
-}
-
-Parcel::Impl::~Impl() {
- free(data_);
-}
-
-void Parcel::Impl::Write(const void* buf, uint32_t size) {
- if (data_size_ + size > data_capacity_) {
- size_t new_size = (data_capacity_ + size) * 3 / 2;
- uint8_t* data = static_cast<uint8_t*>(realloc(data_, new_size));
- if (data == nullptr)
- throw std::bad_alloc();
-
- data_ = data;
- data_capacity_ = new_size;
- }
-
- memcpy(data_ + data_size_, buf, size);
- data_size_ += size;
-}
-
-int Parcel::Impl::Read(void* buf, uint32_t size) {
- if (data_size_ == 0)
- return TIZEN_ERROR_NO_DATA;
-
- if (reader_ + size > data_size_)
- return TIZEN_ERROR_ILLEGAL_BYTE_SEQ;
-
- memcpy(buf, data_ + reader_, size);
- reader_ += size;
- set_last_result(TIZEN_ERROR_NONE);
- return TIZEN_ERROR_NONE;
-}
-
-void Parcel::Impl::ResetReader() {
- reader_ = 0;
-}
-
-void Parcel::Impl::Clear() {
- data_size_ = 0;
- reader_ = 0;
-}
-
-void Parcel::Impl::Reset(const void* buf, uint32_t size) {
- Clear();
- Write(buf, size);
-}
-
-bool Parcel::Impl::IsEmpty() {
- return data_size_ == 0;
-}
-
-void Parcel::Impl::WriteSize(uint32_t size) {
- if (IsBigEndian())
- size = GUINT32_TO_BE(size);
-
- Write<uint32_t>(size);
-}
-
-template <typename T>
-void Parcel::Impl::Write(T d) {
- if (data_size_ + sizeof(T) > data_capacity_) {
- size_t new_size = (data_capacity_ + sizeof(T)) * 3 / 2;
- uint8_t* data = static_cast<uint8_t*>(realloc(data_, new_size));
- if (data == nullptr)
- throw std::bad_alloc();
-
- data_ = data;
- data_capacity_ = new_size;
- }
-
- auto* p = reinterpret_cast<uint8_t*>(&d);
- memcpy(data_ + data_size_, p, sizeof(T));
- data_size_ += sizeof(T);
-}
-
-int Parcel::Impl::ReadSize(uint32_t* size) {
- if (data_size_ == 0)
- return TIZEN_ERROR_NO_DATA;
-
- int ret = Read<uint32_t>(size);
- if (ret != TIZEN_ERROR_NONE)
- return ret;
-
- if (IsBigEndian())
- *size = GUINT32_FROM_BE(*size);
-
- return TIZEN_ERROR_NONE;
-}
-
-template <typename T>
-int Parcel::Impl::Read(T* d) {
- uint32_t size = static_cast<uint32_t>(sizeof(T));
- if (reader_ + size > data_size_)
- return TIZEN_ERROR_ILLEGAL_BYTE_SEQ;
-
- auto* p = reinterpret_cast<uint8_t*>(d);
- memcpy(p, data_ + reader_, size);
- reader_ += size;
- return TIZEN_ERROR_NONE;
-}
-
-void Parcel::Impl::SetByteOrder(bool big_endian) {
- big_endian_ = big_endian;
-}
-
-bool Parcel::Impl::IsBigEndian() const {
- return big_endian_;
-}
-
-uint8_t* Parcel::Impl::GetData() const {
- return data_;
-}
-
-size_t Parcel::Impl::GetDataSize() const {
- return data_size_;
-}
-
-size_t Parcel::Impl::GetDataCapacity() const {
- return data_capacity_;
-}
-
-void Parcel::Impl::SetDataCapacity(size_t size) {
- uint8_t* data = static_cast<uint8_t*>(realloc(data_, size));
- if (data == nullptr)
- throw std::bad_alloc();
-
- data_ = data;
- data_capacity_ = size;
-}
-
-uint8_t* Parcel::Impl::Detach(size_t* size) {
- uint8_t* data = data_;
- *size = data_size_;
- data_ = nullptr;
- data_capacity_ = 0;
- data_size_ = 0;
- reader_= 0;
- return data;
-}
-
-uint32_t Parcel::Impl::GetReader() const {
- return reader_;
-}
-
-std::vector<uint8_t> Parcel::Impl::ToRaw() {
- return std::vector<uint8_t>(data_, data_ + data_size_);
-}
-
-Parcel::Parcel()
- : impl_(new Impl(this, kDataCapacity, nullptr)) {
- if (impl_->data_ == nullptr)
- throw std::bad_alloc();
-}
-
-Parcel::Parcel(const void* buf, uint32_t size, bool copy)
- : impl_(new Impl(this, size,
- copy ? nullptr : static_cast<uint8_t*>(const_cast<void*>(buf)))) {
- if (impl_->data_ == nullptr)
- throw std::bad_alloc();
-
- if (copy)
- impl_->Write(buf, size);
-}
-
-Parcel::~Parcel() {};
-
-Parcel::Parcel(const Parcel& p)
- : impl_(new Impl(this, kDataCapacity)) {
- impl_->big_endian_ = p.impl_->big_endian_;
- impl_->data_capacity_ = p.impl_->data_capacity_;
- impl_->data_size_ = p.impl_->data_size_;
-
- uint8_t* data = static_cast<uint8_t*>(
- realloc(impl_->data_, impl_->data_capacity_));
- if (data == nullptr)
- throw std::bad_alloc();
-
- impl_->data_ = data;
- memcpy(impl_->data_, p.impl_->data_, impl_->data_size_);
-
- impl_->reader_ = p.impl_->reader_;
-}
-
-Parcel& Parcel::operator = (const Parcel& p) {
- if (this != &p) {
- impl_->big_endian_ = p.impl_->big_endian_;
- impl_->data_capacity_ = p.impl_->data_capacity_;
- impl_->data_size_ = p.impl_->data_size_;
-
- uint8_t* data = static_cast<uint8_t*>(
- realloc(impl_->data_, impl_->data_capacity_));
- if (data == nullptr)
- throw std::bad_alloc();
-
- impl_->data_ = data;
- memcpy(impl_->data_, p.impl_->data_, impl_->data_size_);
-
- impl_->reader_ = p.impl_->reader_;
- }
- return *this;
-}
-
-Parcel::Parcel(Parcel&& p) noexcept
- : impl_(new Impl(this, kDataCapacity)) {
- impl_->big_endian_ = p.impl_->big_endian_;
-
- impl_->data_size_ = p.impl_->data_size_;
- p.impl_->data_size_ = 0;
-
- uint8_t* data = impl_->data_;
- size_t data_capacity = impl_->data_capacity_;
-
- impl_->data_ = p.impl_->data_;
- impl_->data_capacity_ = p.impl_->data_capacity_;
-
- p.impl_->data_ = data;
- p.impl_->data_capacity_ = data_capacity;
-
- impl_->reader_ = p.impl_->reader_;
- p.impl_->reader_ = 0;
-}
-
-Parcel& Parcel::operator = (Parcel&& p) noexcept {
- if (this != &p) {
- impl_->big_endian_ = p.impl_->big_endian_;
-
- impl_->data_size_ = p.impl_->data_size_;
- p.impl_->data_size_ = 0;
-
- uint8_t* data = impl_->data_;
- size_t data_capacity = impl_->data_capacity_;
-
- impl_->data_ = p.impl_->data_;
- impl_->data_capacity_ = p.impl_->data_capacity_;
-
- p.impl_->data_ = data;
- p.impl_->data_capacity_ = data_capacity;
-
- impl_->reader_ = p.impl_->reader_;
- p.impl_->reader_ = 0;
- }
- return *this;
-}
-
-bool Parcel::IsEmpty() const noexcept {
- return impl_->IsEmpty();
-}
-
-void Parcel::Write(const void* buf, uint32_t size) {
- impl_->Write(buf, size);
-}
-
-int Parcel::Read(void* buf, uint32_t size) {
- return impl_->Read(buf, size);
-}
-
-void Parcel::WriteBool(bool val) {
- impl_->Write<bool>(val);
-}
-
-void Parcel::WriteByte(char val) {
- impl_->Write<char>(val);
-}
-
-void Parcel::WriteUInt16(uint16_t val) {
- if (impl_->IsBigEndian())
- val = GUINT16_TO_BE(val);
-
- impl_->Write<uint16_t>(val);
-}
-
-void Parcel::WriteUInt32(uint32_t val) {
- if (impl_->IsBigEndian())
- val = GUINT32_TO_BE(val);
-
- impl_->Write<uint32_t>(val);
-}
-
-void Parcel::WriteUInt64(uint64_t val) {
- if (impl_->IsBigEndian())
- val = GUINT64_TO_BE(val);
-
- impl_->Write<uint64_t>(val);
-}
-
-void Parcel::WriteInt16(int16_t val) {
- if (impl_->IsBigEndian())
- val = GINT16_TO_BE(val);
-
- impl_->Write<int16_t>(val);
-}
-
-void Parcel::WriteInt32(int32_t val) {
- if (impl_->IsBigEndian())
- val = GINT32_TO_BE(val);
-
- impl_->Write<int32_t>(val);
-}
-
-void Parcel::WriteInt64(int64_t val) {
- if (impl_->IsBigEndian())
- val = GINT64_TO_BE(val);
-
- impl_->Write<int64_t>(val);
-}
-
-void Parcel::WriteFloat(float val) {
- if (impl_->IsBigEndian())
- val = static_cast<float>(GINT32_TO_BE(val));
-
- impl_->Write<float>(val);
-}
-
-void Parcel::WriteDouble(double val) {
- if (impl_->IsBigEndian())
- val = static_cast<double>(GINT64_TO_BE(val));
-
- impl_->Write<double>(val);
-}
-
-void Parcel::WriteString(const std::string& str) {
- impl_->WriteSize(str.length() + 1);
- impl_->Write(str.c_str(), str.length() + 1);
-}
-
-void Parcel::WriteCString(const char* str) {
- impl_->WriteSize(strlen(str) + 1);
- impl_->Write(str, strlen(str) + 1);
-}
-
-int Parcel::ReadBool(bool* val) {
- return impl_->Read<bool>(val);
-}
-
-int Parcel::ReadByte(char* val) {
- return impl_->Read<char>(val);
-}
-
-int Parcel::ReadUInt16(uint16_t* val) {
- int ret = impl_->Read<uint16_t>(val);
- if (impl_->IsBigEndian())
- *val = GUINT16_FROM_BE(*val);
-
- return ret;
-}
-
-int Parcel::ReadUInt32(uint32_t* val) {
- int ret = impl_->Read<uint32_t>(val);
- if (impl_->IsBigEndian())
- *val = GUINT32_FROM_BE(*val);
-
- return ret;
-}
-
-int Parcel::ReadUInt64(uint64_t* val) {
- int ret = impl_->Read<uint64_t>(val);
- if (impl_->IsBigEndian())
- *val = GUINT64_FROM_BE(*val);
-
- return ret;
-}
-
-int Parcel::ReadInt16(int16_t* val) {
- int ret = impl_->Read<int16_t>(val);
- if (impl_->IsBigEndian())
- *val = GINT16_FROM_BE(*val);
-
- return ret;
-}
-
-int Parcel::ReadInt32(int32_t* val) {
- int ret = impl_->Read<int32_t>(val);
- if (impl_->IsBigEndian())
- *val = GINT32_FROM_BE(*val);
-
- return ret;
-}
-
-int Parcel::ReadInt64(int64_t* val) {
- int ret = impl_->Read<int64_t>(val);
- if (impl_->IsBigEndian())
- *val = GINT64_FROM_BE(*val);
-
- return ret;
-}
-
-int Parcel::ReadFloat(float* val) {
- int ret = impl_->Read<float>(val);
- if (impl_->IsBigEndian())
- *val = static_cast<float>(GINT32_FROM_BE(*val));
-
- return ret;
-}
-
-int Parcel::ReadDouble(double* val) {
- int ret = impl_->Read<double>(val);
- if (impl_->IsBigEndian())
- *val = static_cast<double>(GINT64_FROM_BE(*val));
-
- return ret;
-}
-
-std::string Parcel::ReadString() {
- uint32_t len = 0;
- int ret = impl_->ReadSize(&len);
- if (ret != TIZEN_ERROR_NONE) {
- set_last_result(ret);
- return {};
- }
-
- char* str = new (std::nothrow) char[len];
- if (str == nullptr) {
- set_last_result(TIZEN_ERROR_OUT_OF_MEMORY);
- return {};
- }
-
- auto ptr = std::unique_ptr<char[]>(str);
- ret = impl_->Read(str, len);
- if (ret != TIZEN_ERROR_NONE) {
- set_last_result(ret);
- return {};
- }
-
- set_last_result(TIZEN_ERROR_NONE);
- return std::string(str);
-}
-
-int Parcel::ReadCString(char** str) {
- uint32_t len = 0;
- int ret = impl_->ReadSize(&len);
- if (ret != TIZEN_ERROR_NONE)
- return ret;
-
- char* val = static_cast<char*>(calloc(len, sizeof(char)));
- if (val == nullptr)
- return TIZEN_ERROR_OUT_OF_MEMORY;
-
- ret = impl_->Read(val, len);
- if (ret != TIZEN_ERROR_NONE) {
- free(val);
- return ret;
- }
-
- *str = val;
- return TIZEN_ERROR_NONE;
-}
-
-void Parcel::ResetReader() {
- impl_->ResetReader();
-}
-
-void Parcel::Clear() {
- impl_->Clear();
-}
-
-void Parcel::Reset(const void* buf, uint32_t size) {
- impl_->Reset(buf, size);
-}
-
-void Parcel::WriteParcelable(const Parcelable& parcelable) {
- parcelable.WriteToParcel(this);
-}
-
-int Parcel::ReadParcelable(Parcelable* parcelable) {
- parcelable->ReadFromParcel(this);
- return TIZEN_ERROR_NONE;
-}
-
-void Parcel::SetByteOrder(bool big_endian) {
- impl_->SetByteOrder(big_endian);
-}
-
-uint8_t* Parcel::GetData() const {
- return impl_->GetData();
-}
-
-size_t Parcel::GetDataSize() const {
- return impl_->GetDataSize();
-}
-
-size_t Parcel::GetDataCapacity() const {
- return impl_->GetDataCapacity();
-}
-
-void Parcel::SetDataCapacity(size_t size) {
- impl_->SetDataCapacity(size);
-}
-
-uint8_t* Parcel::Detach(size_t* size) {
- return impl_->Detach(size);
-}
-
-uint32_t Parcel::GetReader() const {
- return impl_->GetReader();
-}
-
-std::vector<uint8_t> Parcel::ToRaw() {
- return impl_->ToRaw();
-}
-
-} // namespace tizen_base
+++ /dev/null
-/*
- * Copyright (c) 2020 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 PARCEL_PARCEL_HH_
-#define PARCEL_PARCEL_HH_
-
-/**
- * @addtogroup CORE_LIB_PARCEL_MODULE
- * @{
- */
-
-#include <tizen.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "parcel/common.hh"
-#include "parcel/parcelable.hh"
-
-namespace tizen_base {
-
-/**
- * @brief The class for Parcel API.
- * @since_tizen 6.5
- */
-class EXPORT Parcel final {
- public:
- /**
- * @brief Enumeration for parcel error.
- * @since_tizen 6.5
- */
- enum Error {
- None = TIZEN_ERROR_NONE, /**< Successful */
- IllegalByteSeq = TIZEN_ERROR_ILLEGAL_BYTE_SEQ, /**< Illegal byte sequence */
- InvalidParameter = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
- NoData = TIZEN_ERROR_NO_DATA, /**< No data available */
- OutOfMemory = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */
- };
-
- /**
- * @brief Constructor.
- * @since_tizen 6.5
- */
- Parcel();
-
- /**
- * @brief Constructor
- * @since_tizen 6.5
- * @param[in] buf The bytes to write
- * @param[in] size the size of bytes to write
- * @param[in] copy If @c is true, this object copies bytes.
- * If @c is false, this object takes ownership of @buf.
- */
- Parcel(const void* buf, uint32_t size, bool copy = true);
-
- /**
- * @brief Destructor
- * @since_tizen 6.5
- */
- ~Parcel();
-
- /**
- * @brief Copy-constructor.
- * @since_tizen 6.5
- * @param[in] p The object to copy
- */
- Parcel(const Parcel& p);
-
- /**
- * @brief Assignment.
- * @since_tizen 6.5
- * @param[in] b The object to copy
- */
- Parcel& operator = (const Parcel& p);
-
- /**
- * @brief Move-constructor.
- * @since_tizen 6.5
- * @param[in] p The object to move
- */
- Parcel(Parcel&& p) noexcept;
-
- /**
- * @brief Assignment.
- * @since_tizen 6.5
- * @param[in] p The object to move
- */
- Parcel& operator = (Parcel&& p) noexcept;
-
- /**
- * @brief Checks the parcel is empty or not.
- * @since_tizen 6.5
- * @return true if the parcel is empty
- */
- bool IsEmpty() const noexcept;
-
- /**
- * @brief Writes bytes into the parcel.
- * @since_tizen 6.5
- * @param[in] buf The bytes to write
- * @param[in] size The size of bytes to write
- */
- void Write(const void* buf, uint32_t size);
-
- /**
- * @brief Reads bytes from the parcel.
- * @since_tizen 6.5
- * @param[out] buf The bytes to read
- * @param[in] size The size of bytes to read
- * @return @c 0 on success,
- * otherwise a negative error value
- */
- int Read(void* buf, uint32_t size);
-
- /**
- * @brief Writes a boolean value into the parcel.
- * @since_tizen 6.5
- * @param[in] val The boolean value
- */
- void WriteBool(bool val);
-
- /**
- * @brief Writes a byte value into the parcel.
- * @since_tizen 6.5
- * @param[in] val The unsigned byte value
- */
- void WriteByte(char byte);
-
- /**
- * @brief Writes an unsigned short value into the parcel.
- * @since_tizen 6.5
- * @param[in] val The unsigned short value
- */
- void WriteUInt16(uint16_t val);
-
- /**
- * @brief Writes an unsigned integer value into the parcel.
- * @since_tizen 6.5
- * @param[in] val The unsigned integer value
- */
- void WriteUInt32(uint32_t val);
-
- /**
- * @brief Writes an unsigned long long integer into the parcel.
- * @since_tizen 6.5
- * @param[in] val The unsigned long long integer value
- */
- void WriteUInt64(uint64_t val);
-
- /**
- * @brief Writes a signed short value into the parcel.
- * @since_tizen 6.5
- * @param[in] val The signed short value
- */
- void WriteInt16(int16_t val);
-
- /**
- * @brief Writes a signed integer value into the parcel.
- * @since_tizen 6.5
- * @param[in] val The signed integer value
- */
- void WriteInt32(int32_t val);
-
- /**
- * @brief Writes a signed long long integer value into the parcel.
- * @since_tizen 6.5
- * @param[in] val The signed long long integer value
- */
- void WriteInt64(int64_t val);
-
- /**
- * @brief Writes a floating point value into the parcel.
- * @since_tizen 6.5
- * @param[in] val The floating point value
- */
- void WriteFloat(float val);
-
- /**
- * @brief Writes a double precision floating point value into the parcel.
- * @since_tizen 6.5
- * @param[in] val The double precision floating point value
- */
- void WriteDouble(double val);
-
- /**
- * @brief Writes a string data into the parcel.
- * @since_tizen 6.5
- * @param[in] str The string data
- */
- void WriteString(const std::string& str);
-
- /**
- * @brief Writes a string data into the parcel.
- * @since_tizen 6.5
- * @param[in] str The string data
- */
- void WriteCString(const char* str);
-
- /**
- * @brief Reads a boolean value from the parcel.
- * @since_tizen 6.5
- * @param[out] val The boolean value
- * @return @c 0 on success,
- * otherwise a negative error value
- */
- int ReadBool(bool* val);
-
- /**
- * @brief Reads a byte value from the parcel.
- * @since_tizen 6.5
- * @param[out] val The unsigned byte value
- * @return @c 0 on success,
- * otherwise a negative error value
- */
- int ReadByte(char* val);
-
- /**
- * @breif Reads an unsigned short value from the parcel.
- * @since_tizen 6.5
- * @param[out] val The unsigned short value
- * @return @c 0 on success,
- * otherwise a negative error value
- */
- int ReadUInt16(uint16_t* val);
-
- /**
- * @brief Reads an unsigned integer value from the parcel.
- * @since_tizen 6.5
- * @param[out] val The unsigned integer value
- * @return @c 0 on success,
- * otherwise a negative error value
- */
- int ReadUInt32(uint32_t* val);
-
- /**
- * @brief Reads an unsigned long long integer value from the parcel.
- * @since_tizen 6.5
- * @param[out] val The unsigned long long integer value
- * @return @c 0 on success,
- * otherwise a negative error value
- */
- int ReadUInt64(uint64_t* val);
-
- /**
- * @brief Reads a signed byte value from the parcel.
- * @since_tizen 6.5
- * @param[out] val The signed byte value
- * @return @c 0 on success,
- * otherwise a negative error value
- */
- int ReadInt8(int8_t* val);
-
- /**
- * @brief Reads a signed short value from the parcel.
- * @since_tizen 6.5
- * @param[out] val The signed short value
- * @return @c 0 on success,
- * otherwise a negative error value
- */
- int ReadInt16(int16_t* val);
-
- /**
- * @brief Reads a signed integer value from the parcel.
- * @since_tizen 6.5
- * @param[out] val The signed integer value
- * @return @c 0 on success,
- * otherwise a negative error value
- */
- int ReadInt32(int32_t* val);
-
- /**
- * @brief Reads a signed long long integer value from the parcel.
- * @since_tizen 6.5
- * @param[out] val The signed long long integer value
- * @return @c 0 on success,
- * otherwise a negative error value
- */
- int ReadInt64(int64_t* val);
-
- /**
- * @brief Reads a floating point value from the parcel.
- * @since_tizen 6.5
- * @param[out] val The floating point value
- * @return @c 0 on success,
- * otherwise a negative error value
- */
- int ReadFloat(float* val);
-
- /**
- * @brief Reads a double precision floating point value from the parcel.
- * @since_tizen 6.5
- * @param[out] val The double precision floating point value
- * @return @c 0 on success,
- * otherwise a negative error value
- */
- int ReadDouble(double* val);
-
- /**
- * @brief Reads a string data from the parcel.
- * @since_tizen 6.5
- * @return The string data
- * @remarks Before using the returned value, you should check the result using get_last_result().
- * @see get_last_result()
- */
- std::string ReadString();
-
- /**
- * @brief Reads a string data from the parcel.
- * @since_tizen 6.5
- * @remarks You should release @a str using free().
- * @param[out] str The string data
- * @return @c 0 on success,
- * otherwise a negative error value
- */
- int ReadCString(char** str);
-
- /**
- * @brief Resets the reader pointer of the parcel to the start.
- * @since_tizen 6.5
- */
- void ResetReader();
-
- /**
- * @brief Clears the data of the parcel.
- * @since_tizen 6.5
- */
- void Clear();
-
- /**
- * @brief Resets the parcel.
- * @since_tizen 6.5
- * @param[in] buf The bytes to write
- * @param[in] size The size of bytes to write
- */
- void Reset(const void* buf, uint32_t size);
-
- /**
- * @brief Writes the data using @a parcelable into the parcel.
- * @since_tizen 6.5
- * @param[in] parcelable The interface to write the data into the parcel
- */
- void WriteParcelable(const Parcelable& parcelable);
-
- /**
- * @brief Reads the data using @a parcelable from the parcel.
- * @since_tizen 6.5
- * @param[out] parcelable The interface to get data from the parcel
- * @return @c 0 on success,
- * otherwise a negative error value
- */
- int ReadParcelable(Parcelable* parcelable);
-
- /**
- * @brief Sets byte order of the parcel.
- * @since_tizen 6.5
- * @param[in] big_endian @c true, if byte order of the parcel is big-endian
- */
- void SetByteOrder(bool big_endian);
-
- /**
- * @brief Gets the raw data of the parcel.
- * @since_tizen 7.0
- * @return The raw data
- */
- uint8_t* GetData() const;
-
- /**
- * @breif Gets the size of the raw data of the parcel.
- * @since_tizen 7.0
- * @return The size of the raw data
- */
- size_t GetDataSize() const;
-
- /**
- * @brief Gets the size of the data capacity of the parcel.
- * @since_tizen 7.0
- * @return The size of the data capacity
- */
- size_t GetDataCapacity() const;
-
- /**
- * @breif Sets the size of the data capacity of the parcel.
- * @since_tizen 7.0
- * @param[in] size The size of the data capcity
- */
- void SetDataCapacity(size_t size);
-
- /**
- * @brief Detaches the raw data from the parcel.
- * @since_tizen 7.0
- * @param[out] size The size of the raw data
- * @return The raw data
- */
- uint8_t* Detach(size_t* size);
-
- /**
- * @brief Gets the position of the reader of the parcel.
- * @since_tizen 7.0
- * @return The position of the reader
- */
- uint32_t GetReader() const;
-
- /**
- * @brief Converts the raw data of the parcel to the vector.
- * @since_tizen 7.0
- * @return The vector of the raw data
- */
- std::vector<uint8_t> ToRaw();
-
- private:
- class Impl;
- std::unique_ptr<Impl> impl_;
-};
-
-} // naemspace tizen_base
-
-/**
- * @}
- */
-
-#endif // PARCEL_PARCEL_HH_
+++ /dev/null
-# Package Information for pkg-config
-
-prefix=@PREFIX@
-exec_prefix=${prefix}
-libdir=@LIB_INSTALL_DIR@
-includedir=${prefix}/include
-
-Name: parcel
-Description: Parcel library
-Version: @VERSION@
-Requires: capi-base-common
-Libs: -L${libdir} -lparcel
-Cflags: -I${includedir} -I${includedir}/parcel
-cppflags: -I${includedir} -I${includedir}/parcel
+++ /dev/null
-/*
- * Copyright (c) 2020 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 PARCEL_PARCEL_IMPLEMENTATION_HH_
-#define PARCEL_PARCEL_IMPLEMENTATION_HH_
-
-#include <string>
-#include <vector>
-
-#include "parcel/parcel.hh"
-#include "parcel/parcelable.hh"
-
-namespace tizen_base {
-
-class Parcel::Impl {
- public:
- virtual ~Impl();
-
- void Write(const void* buf, uint32_t size);
- int Read(void* buf, uint32_t size);
- void ResetReader();
- void Clear();
- void Reset(const void* buf, uint32_t size);
- bool IsEmpty();
- void WriteSize(uint32_t size);
- int ReadSize(uint32_t* size);
-
- template <typename T>
- void Write(T d);
- template <typename T>
- int Read(T* d);
-
- void SetByteOrder(bool big_endian);
- bool IsBigEndian() const;
- uint8_t* GetData() const;
- size_t GetDataSize() const;
- size_t GetDataCapacity() const;
- void SetDataCapacity(size_t size);
- uint8_t* Detach(size_t* size);
- uint32_t GetReader() const;
- std::vector<uint8_t> ToRaw();
-
- private:
- friend class Parcel;
- explicit Impl(Parcel* parent, size_t data_capacity, uint8_t* data = nullptr);
-
- private:
- Parcel* parent_;
- size_t data_capacity_;
- bool big_endian_ = false;
- size_t data_size_ = 0;
- uint8_t* data_ = nullptr;
- uint32_t reader_ = 0;
-};
-
-} // naemspace tizen_base
-
-#endif // PARCEL_PARCEL_IMPLEMENTATION_HH_
+++ /dev/null
-/*
- * Copyright (c) 2020 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 PARCEL_PARCELABLE_HH_
-#define PARCEL_PARCELABLE_HH_
-
-/**
- * @addtogroup CORE_LIB_PARCEL_MODULE
- * @{
- */
-
-#include "parcel/common.hh"
-
-namespace tizen_base {
-
-class Parcel;
-
-/**
- * @brief The Parcelable interface.
- * @since_tizen 6.5
- */
-class EXPORT Parcelable {
- public:
- /**
- * @brief Constructor.
- * @since_tizen 6.5
- */
- Parcelable() = default;
-
- /**
- * @brief Copy constructor.
- * @since_tizen 6.5
- */
- Parcelable(const Parcelable&) = default;
-
- /**
- * @brief Destructor.
- * @since_tizen 6.5
- */
- virtual ~Parcelable() = default;
-
- /**
- * @brief Writes the data into the parcel.
- * @since_tizen 6.5
- * @param[in] parcel The parcel object
- */
- virtual void WriteToParcel(Parcel* parcel) const = 0;
-
- /**
- * @brief Reads the data from the parcel.
- * @since_tizen 6.5
- * @param[in] parcel The parcel object
- */
- virtual void ReadFromParcel(Parcel* parcel) = 0;
-};
-
-} // naemspace tizen_base
-
-/**
- * @}
- */
-
-#endif // PARCEL_PARCELABLE_HH_
+++ /dev/null
-/*
- * Copyright (c) 2020 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 "parcel/api/parcel.h"
-
-#include <exception>
-
-#include "parcel/common.hh"
-#include "parcel/log_private.hh"
-#include "parcel/parcel.hh"
-#include "parcel/parcelable.hh"
-
-using namespace tizen_base;
-
-extern "C" EXPORT int parcel_create(parcel_h *parcel) {
- if (parcel == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = new (std::nothrow) Parcel();
- if (h == nullptr) {
- _E("Out of memory");
- return PARCEL_ERROR_OUT_OF_MEMORY;
- }
-
- *parcel = static_cast<parcel_h>(h);
- return PARCEL_ERROR_NONE;
-}
-
-extern "C" EXPORT int parcel_destroy(parcel_h parcel) {
- if (parcel == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- delete h;
- return PARCEL_ERROR_NONE;
-}
-
-extern "C" EXPORT int parcel_clone(parcel_h parcel, parcel_h* clone) {
- if (parcel == nullptr || clone == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- auto* c = new (std::nothrow) Parcel(*h);
- if (c == nullptr) {
- _E("Out of memory");
- return PARCEL_ERROR_OUT_OF_MEMORY;
- }
-
- *clone = static_cast<parcel_h>(c);
- return PARCEL_ERROR_NONE;
-}
-
-extern "C" EXPORT int parcel_burst_write(parcel_h parcel, const void *buf,
- uint32_t size) {
- if (parcel == nullptr || buf == nullptr || size == 0) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- h->Write(buf, size);
- return PARCEL_ERROR_NONE;
-}
-
-extern "C" EXPORT int parcel_burst_read(parcel_h parcel, void *buf,
- uint32_t size) {
- if (parcel == nullptr || buf == nullptr || size == 0) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- h->Read(buf, size);
- return PARCEL_ERROR_NONE;
-}
-
-extern "C" EXPORT int parcel_write_bool(parcel_h parcel, bool val) {
- if (parcel == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- h->WriteBool(val);
- return PARCEL_ERROR_NONE;
-}
-
-extern "C" EXPORT int parcel_write_byte(parcel_h parcel, char val) {
- if (parcel == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- h->WriteByte(val);
- return PARCEL_ERROR_NONE;
-}
-
-extern "C" EXPORT int parcel_write_uint16(parcel_h parcel, uint16_t val) {
- if (parcel == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- h->WriteUInt16(val);
- return PARCEL_ERROR_NONE;
-}
-
-extern "C" EXPORT int parcel_write_uint32(parcel_h parcel, uint32_t val) {
- if (parcel == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- h->WriteUInt32(val);
- return PARCEL_ERROR_NONE;
-}
-
-extern "C" EXPORT int parcel_write_uint64(parcel_h parcel, uint64_t val) {
- if (parcel == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- h->WriteUInt64(val);
- return PARCEL_ERROR_NONE;
-}
-
-extern "C" EXPORT int parcel_write_int16(parcel_h parcel, int16_t val) {
- if (parcel == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- h->WriteInt16(val);
- return PARCEL_ERROR_NONE;
-}
-
-extern "C" EXPORT int parcel_write_int32(parcel_h parcel, int32_t val) {
- if (parcel == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- h->WriteInt32(val);
- return PARCEL_ERROR_NONE;
-}
-
-extern "C" EXPORT int parcel_write_int64(parcel_h parcel, int64_t val) {
- if (parcel == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- h->WriteInt64(val);
- return PARCEL_ERROR_NONE;
-}
-
-extern "C" EXPORT int parcel_write_float(parcel_h parcel, float val) {
- if (parcel == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- h->WriteFloat(val);
- return PARCEL_ERROR_NONE;
-}
-
-extern "C" EXPORT int parcel_write_double(parcel_h parcel, double val) {
- if (parcel == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- h->WriteDouble(val);
- return PARCEL_ERROR_NONE;
-}
-
-extern "C" EXPORT int parcel_write_string(parcel_h parcel, const char* str) {
- if (parcel == nullptr || str == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- h->WriteCString(str);
- return PARCEL_ERROR_NONE;
-}
-
-extern "C" EXPORT int parcel_read_bool(parcel_h parcel, bool* val) {
- if (parcel == nullptr || val == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- return h->ReadBool(val);
-}
-
-extern "C" EXPORT int parcel_read_byte(parcel_h parcel, char* val) {
- if (parcel == nullptr || val == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- return h->ReadByte(val);
-}
-
-extern "C" EXPORT int parcel_read_uint16(parcel_h parcel, uint16_t* val) {
- if (parcel == nullptr || val == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- return h->ReadUInt16(val);
-}
-
-extern "C" EXPORT int parcel_read_uint32(parcel_h parcel, uint32_t* val) {
- if (parcel == nullptr || val == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- return h->ReadUInt32(val);
-}
-
-extern "C" EXPORT int parcel_read_uint64(parcel_h parcel, uint64_t* val) {
- if (parcel == nullptr || val == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- return h->ReadUInt64(val);
-}
-
-extern "C" EXPORT int parcel_read_int16(parcel_h parcel, int16_t* val) {
- if (parcel == nullptr || val == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- return h->ReadInt16(val);
-}
-
-extern "C" EXPORT int parcel_read_int32(parcel_h parcel, int32_t* val) {
- if (parcel == nullptr || val == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- return h->ReadInt32(val);
-}
-
-extern "C" EXPORT int parcel_read_int64(parcel_h parcel, int64_t* val) {
- if (parcel == nullptr || val == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- return h->ReadInt64(val);
-}
-
-extern "C" EXPORT int parcel_read_float(parcel_h parcel, float* val) {
- if (parcel == nullptr || val == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- return h->ReadFloat(val);
-}
-
-extern "C" EXPORT int parcel_read_double(parcel_h parcel, double* val) {
- if (parcel == nullptr || val == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- return h->ReadDouble(val);
-}
-
-extern "C" EXPORT int parcel_read_string(parcel_h parcel, char** str) {
- if (parcel == nullptr || str == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- return h->ReadCString(str);
-}
-
-extern "C" EXPORT int parcel_reset_reader(parcel_h parcel) {
- if (parcel == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- h->ResetReader();
- return PARCEL_ERROR_NONE;
-}
-
-extern "C" EXPORT int parcel_clear(parcel_h parcel) {
- if (parcel == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- h->Clear();
- return PARCEL_ERROR_NONE;
-}
-
-extern "C" EXPORT int parcel_reset(parcel_h parcel, const void* buf,
- uint32_t size) {
- if (parcel == nullptr || buf == nullptr || size == 0) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- h->Reset(buf, size);
- return PARCEL_ERROR_NONE;
-}
-
-extern "C" EXPORT int parcel_write(parcel_h parcel, parcelable_t* parcelable,
- void* data) {
- if (parcel == nullptr || parcelable == nullptr || parcelable->to == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- parcelable->to(parcel, data);
- return PARCEL_ERROR_NONE;
-}
-
-extern "C" EXPORT int parcel_read(parcel_h parcel, parcelable_t* parcelable,
- void* data) {
- if (parcel == nullptr || parcelable == nullptr ||
- parcelable->from == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- parcelable->from(parcel, data);
- return PARCEL_ERROR_NONE;
-}
-
-extern "C" EXPORT int parcel_get_raw(parcel_h parcel, void** raw,
- uint32_t* size) {
- if (parcel == nullptr || raw == nullptr || size == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- *raw = reinterpret_cast<void*>(h->GetData());
- *size = static_cast<uint32_t>(h->GetDataSize() & UINT32_MAX);
- return PARCEL_ERROR_NONE;
-}
-
-extern "C" EXPORT int parcel_set_byte_order(parcel_h parcel,
- bool big_endian) {
- if (parcel == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- h->SetByteOrder(big_endian);
- return PARCEL_ERROR_NONE;
-}
-
-extern "C" EXPORT int parcel_get_data_capacity(parcel_h parcel,
- size_t* size) {
- if (parcel == nullptr || size == nullptr) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- *size = h->GetDataCapacity();
- return PARCEL_ERROR_NONE;
-}
-
-extern "C" EXPORT int parcel_set_data_capacity(parcel_h parcel,
- size_t size) {
- if (parcel == nullptr || size == 0) {
- _E("Invalid parameter");
- return PARCEL_ERROR_INVALID_PARAMETER;
- }
-
- auto* h = static_cast<Parcel*>(parcel);
- try {
- h->SetDataCapacity(size);
- } catch (const std::bad_alloc& e) {
- _E("Exception occurs. error(%s)", e.what());
- return PARCEL_ERROR_OUT_OF_MEMORY;
- }
-
- return PARCEL_ERROR_NONE;
-}
--- /dev/null
+ADD_SUBDIRECTORY(bundle)
+ADD_SUBDIRECTORY(parcel)
+ADD_SUBDIRECTORY(tizen-database)
+ADD_SUBDIRECTORY(tizen-shared-queue)
+++ /dev/null
-/*
- * Copyright (c) 2020 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 "bundle-internal.h"
-
-#include <errno.h>
-#include <glib.h>
-
-#include <algorithm>
-#include <cstring>
-#include <memory>
-#include <utility>
-
-#include "include/bundle.h"
-
-#include "exception-internal.h"
-
-namespace tizen_base {
-namespace internal {
-
-static const int CHECKSUM_LENGTH = 32;
-
-Bundle::Bundle(unsigned char* raw, int size, bool base64) {
- if (size < 0)
- THROW(BUNDLE_ERROR_INVALID_PARAMETER);
-
- int ret;
- if (base64)
- ret = Decode(raw, static_cast<size_t>(size));
- else
- ret = DecodeRaw(raw, static_cast<size_t>(size));
- if (ret != BUNDLE_ERROR_NONE)
- THROW(ret);
-}
-
-Bundle::Bundle(int argc, char** argv) {
- int ret = Import(argc, argv);
- if (ret != BUNDLE_ERROR_NONE)
- THROW(ret);
-}
-
-Bundle::Bundle(const Bundle& b) {
- for (const auto& [key, val] : b.map_) {
- const KeyInfo& info = *val;
- auto new_val = std::make_shared<KeyInfo>(info);
- map_[key] = new_val;
- list_.push_back(std::move(new_val));
- }
-}
-
-Bundle& Bundle::operator = (const Bundle& b) {
- if (this != &b) {
- map_.clear();
- list_.clear();
- for (const auto& [key, val] : b.map_) {
- const KeyInfo& info = *val;
- auto new_val = std::make_shared<KeyInfo>(info);
- map_[key] = new_val;
- list_.push_back(std::move(new_val));
- }
- }
- return *this;
-}
-
-Bundle::Bundle(Bundle&& b) noexcept {
- map_ = std::move(b.map_);
- list_ = std::move(b.list_);
-}
-
-Bundle& Bundle::operator = (Bundle&& b) noexcept {
- if (this != &b) {
- map_ = std::move(b.map_);
- list_ = std::move(b.list_);
- }
- return *this;
-}
-
-bool Bundle::operator == (const Bundle& b) {
- if (this == &b)
- return true;
-
- if (map_.size() != b.map_.size())
- return false;
-
- for (const auto& kv : map_) {
- auto& lhs = kv.second;
- auto iter = b.map_.find(lhs->GetKey());
- if (iter == b.map_.end())
- return false;
-
- auto& rhs = iter->second;
- if (!(*lhs == *rhs))
- return false;
- }
-
- return true;
-}
-
-void Bundle::Remove(const std::string& key) {
- auto iter = map_.find(key);
- if (iter == map_.end())
- THROW(BUNDLE_ERROR_KEY_NOT_AVAILABLE);
-
- list_.remove(iter->second);
- map_.erase(iter);
-}
-
-void Bundle::Add(std::shared_ptr<KeyInfo> key_info) {
- auto iter = map_.find(key_info->GetKey());
- if (iter != map_.end())
- THROW(BUNDLE_ERROR_KEY_EXISTS);
-
- map_[key_info->GetKey()] = key_info;
- list_.push_back(std::move(key_info));
-}
-
-void Bundle::Set(const std::string& key, int index,
- std::vector<unsigned char> value) {
- auto iter = map_.find(key);
- if (iter == map_.end())
- THROW(BUNDLE_ERROR_KEY_NOT_AVAILABLE);
-
- int ret = iter->second->SetValue(index, value);
- if (ret != BUNDLE_ERROR_NONE)
- THROW(ret);
-}
-
-std::shared_ptr<KeyInfo>& Bundle::Get(const std::string& key) {
- auto iter = map_.find(key.c_str());
- if (iter == map_.end())
- THROW(BUNDLE_ERROR_KEY_NOT_AVAILABLE);
-
- return iter->second;
-}
-
-int Bundle::GetSize() {
- return map_.size();
-}
-
-int Bundle::GetType(const std::string& key) {
- auto iter = map_.find(key);
- if (iter == map_.end())
- THROW(BUNDLE_ERROR_KEY_NOT_AVAILABLE);
-
- return iter->second->GetType();
-}
-
-unsigned char* Bundle::Encode() {
- int size = 0;
- unsigned char* raw;
- try {
- raw = EncodeRaw(&size);
- } catch (const Exception& e) {
- THROW(e.GetErrorCode());
- }
-
- std::unique_ptr<unsigned char, decltype(std::free)*> raw_ptr(raw, std::free);
- char* encoded_data = reinterpret_cast<char*>(
- g_base64_encode(reinterpret_cast<guchar*>(raw),
- static_cast<gsize>(size)));
- if (encoded_data == nullptr)
- THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
-
- return reinterpret_cast<unsigned char*>(encoded_data);
-}
-
-int Bundle::Decode(unsigned char* raw, size_t size) {
- unsigned char* d_str = new (std::nothrow) unsigned char[(size / 4) * 3 + 3];
- if (d_str == nullptr)
- return BUNDLE_ERROR_OUT_OF_MEMORY;
-
- std::unique_ptr<unsigned char[]> d_ptr(d_str);
- gint state = 0;
- guint save = 0;
- size_t d_len_raw = static_cast<size_t>(g_base64_decode_step(
- reinterpret_cast<char*>(raw), size, d_str, &state, &save));
- if (d_len_raw < CHECKSUM_LENGTH)
- return BUNDLE_ERROR_OUT_OF_MEMORY;
-
- return DecodeRaw(d_str, d_len_raw);
-}
-
-unsigned char* Bundle::EncodeRaw(int* size) {
- std::vector<unsigned char> bytes;
- for (const auto& key_info : list_) {
- auto encoded_bytes = key_info->Encode();
- bytes.insert(bytes.end(),
- std::make_move_iterator(encoded_bytes.begin()),
- std::make_move_iterator(encoded_bytes.end()));
- }
-
- gchar* checksum = g_compute_checksum_for_string(
- G_CHECKSUM_MD5, reinterpret_cast<gchar*>(&bytes[0]),
- static_cast<gssize>(bytes.size()));
- if (checksum == nullptr)
- THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
-
- std::unique_ptr<gchar, decltype(g_free)*> ptr(checksum, g_free);
- unsigned char* p = reinterpret_cast<unsigned char*>(checksum);
- bytes.insert(bytes.begin(), p, p + CHECKSUM_LENGTH);
-
- unsigned char* raw = static_cast<unsigned char*>(malloc(bytes.size()));
- if (raw == nullptr)
- THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
-
- std::copy(std::make_move_iterator(bytes.begin()),
- std::make_move_iterator(bytes.end()), raw);
- *size = static_cast<int>(bytes.size());
- return raw;
-}
-
-int Bundle::DecodeRaw(unsigned char* raw, size_t size) {
- char* extract_checksum = new (std::nothrow) char[CHECKSUM_LENGTH + 1];
- if (extract_checksum == nullptr)
- return BUNDLE_ERROR_OUT_OF_MEMORY;
-
- std::unique_ptr<char[]> extract_ptr(extract_checksum);
- unsigned char* d_str = raw;
- size_t d_len_raw = size;
- strncpy(extract_checksum, reinterpret_cast<char*>(d_str), CHECKSUM_LENGTH);
- extract_checksum[CHECKSUM_LENGTH] = '\0';
-
- gchar* compute_checksum = g_compute_checksum_for_string(G_CHECKSUM_MD5,
- reinterpret_cast<gchar*>(d_str + CHECKSUM_LENGTH),
- d_len_raw - CHECKSUM_LENGTH);
- if (compute_checksum == nullptr)
- return BUNDLE_ERROR_OUT_OF_MEMORY;
-
- std::unique_ptr<gchar, decltype(g_free)*> compute_ptr(compute_checksum,
- g_free);
- if (strcmp(extract_checksum, static_cast<char*>(compute_checksum)) != 0)
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- unsigned char* d_r = d_str + CHECKSUM_LENGTH;
- size_t d_len = d_len_raw - CHECKSUM_LENGTH;
-
- unsigned int reader = 0;
- std::vector<unsigned char> bytes(d_r, d_r + d_len);
-
- while (reader < bytes.size()) {
- std::size_t total_size = -1;
- unsigned char* p = reinterpret_cast<unsigned char*>(&total_size);
- std::copy(&bytes[reader], &bytes[reader] + sizeof(total_size), p);
-
- std::vector<unsigned char> encoded_bytes(
- &bytes[reader], &bytes[reader] + total_size);
- reader += total_size;
-
- try {
- auto key_info = std::make_shared<KeyInfo>(std::move(encoded_bytes));
- auto iter = map_.find(key_info->GetKey());
- if (iter != map_.end())
- continue;
-
- map_[key_info->GetKey()] = key_info;
- list_.push_back(std::move(key_info));
- } catch (const Exception& e) {
- return e.GetErrorCode();
- } catch (const std::bad_alloc& ba) {
- return BUNDLE_ERROR_OUT_OF_MEMORY;
- }
- }
-
- return BUNDLE_ERROR_NONE;
-}
-
-const std::unordered_map<std::string, std::shared_ptr<KeyInfo>>&
-Bundle::GetMap() const {
- return map_;
-}
-
-std::vector<std::string> Bundle::Export() {
- std::vector<std::string> argv(2);
- for (const auto& key_info : list_) {
- argv.push_back(key_info->GetKey());
-
- auto encoded_bytes = key_info->Encode();
- auto* p = reinterpret_cast<unsigned char*>(&encoded_bytes[0]);
- auto* base64_bytes = g_base64_encode(p, encoded_bytes.size());
- if (base64_bytes == nullptr)
- THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
-
- std::unique_ptr<gchar, decltype(g_free)*> base64_bytes_ptr(base64_bytes,
- g_free);
- argv.push_back(base64_bytes);
- }
-
- return argv;
-}
-
-int Bundle::Import(int argc, char** argv) {
- if (argc < 2)
- return BUNDLE_ERROR_NONE;
-
- if (!argv[1] || std::strcmp(argv[1], TAG_IMPORT_EXPORT_CHECK)) {
- for (int idx = 1; idx + 1 < argc; idx += 2) {
- auto* p = reinterpret_cast<unsigned char*>(argv[idx +1]);
- auto len = strlen(argv[idx + 1]) + 1;
- std::vector<unsigned char> value(p, p + len);
-
- try {
- auto key_info = std::make_shared<KeyInfo>(Type::String, argv[idx],
- std::move(value));
- auto iter = map_.find(key_info->GetKey());
- if (iter != map_.end())
- continue;
-
- map_[key_info->GetKey()] = key_info;
- list_.push_back(std::move(key_info));
- } catch (const Exception& e) {
- return e.GetErrorCode();
- } catch (const std::bad_alloc& ba) {
- return BUNDLE_ERROR_OUT_OF_MEMORY;
- }
- }
-
- return BUNDLE_ERROR_NONE;
- }
-
- for (int idx = 2; idx + 1 < argc; idx += 2) {
- gsize out_len = 0;
- auto* bytes = g_base64_decode(argv[idx + 1], &out_len);
- if (bytes == nullptr)
- return BUNDLE_ERROR_OUT_OF_MEMORY;
-
- std::unique_ptr<guchar, decltype(g_free)*> bytes_ptr(bytes, g_free);
-
- if (out_len < sizeof(std::size_t))
- continue;
-
- auto* p = reinterpret_cast<unsigned char*>(bytes);
- std::vector<unsigned char> decoded_bytes(p, p + (out_len + 1));
-
- try {
- auto key_info = std::make_shared<KeyInfo>(std::move(decoded_bytes));
- auto iter = map_.find(key_info->GetKey());
- if (iter != map_.end())
- continue;
-
- map_[key_info->GetKey()] = key_info;
- list_.push_back(std::move(key_info));
- } catch (const Exception& e) {
- return e.GetErrorCode();
- } catch (const std::bad_alloc& ba) {
- return BUNDLE_ERROR_OUT_OF_MEMORY;
- }
- }
-
- return BUNDLE_ERROR_NONE;
-}
-
-} // namespace internal
-} // namespace tizen_base
+++ /dev/null
-/*
- * Copyright (c) 2020 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 BUNDLE_INTERNAL_H_
-#define BUNDLE_INTERNAL_H_
-
-#include <list>
-#include <memory>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-#include "include/bundle.h"
-
-#include "key-info-internal.h"
-
-namespace tizen_base {
-namespace internal {
-
-static const char TAG_IMPORT_EXPORT_CHECK[] = "`zaybxcwdveuftgsh`";
-
-class Bundle {
- public:
- enum Property {
- Array = BUNDLE_TYPE_ARRAY,
- Primitive = BUNDLE_TYPE_PRIMITIVE,
- Measurable = BUNDLE_TYPE_MEASURABLE,
- };
-
- enum Type {
- None = BUNDLE_TYPE_NONE,
- Any = BUNDLE_TYPE_ANY,
- String = BUNDLE_TYPE_STR,
- StringArray = BUNDLE_TYPE_STR_ARRAY,
- Byte = BUNDLE_TYPE_BYTE,
- ByteArray = BUNDLE_TYPE_BYTE_ARRAY,
- };
-
- Bundle() = default;
- Bundle(unsigned char* raw, int size, bool base64 = true);
- Bundle(int argc, char** argv);
- virtual ~Bundle() = default;
-
- Bundle(const Bundle& b);
- Bundle& operator = (const Bundle& b);
- Bundle(Bundle&& b) noexcept;
- Bundle& operator = (Bundle&& b) noexcept;
-
- bool operator == (const Bundle& b);
-
- void Remove(const std::string& key);
- void Add(std::shared_ptr<KeyInfo> key_info);
- void Set(const std::string& key, int index, std::vector<unsigned char> value);
-
- std::shared_ptr<KeyInfo>& Get(const std::string& key);
- int GetSize();
- int GetType(const std::string& key);
-
- unsigned char* Encode();
- unsigned char* EncodeRaw(int* size);
- int DecodeRaw(unsigned char* raw, size_t size);
- const std::unordered_map<std::string, std::shared_ptr<KeyInfo>>& GetMap() const;
- std::vector<std::string> Export();
-
- private:
- int Decode(unsigned char* raw, size_t size);
- int Import(int argc, char** argv);
-
- private:
- std::unordered_map<std::string, std::shared_ptr<KeyInfo>> map_;
- std::list<std::shared_ptr<KeyInfo>> list_;
-};
-
-} // namespace internal
-} // namespace tizen_base
-
-#endif // BUNDLE_INTERNAL_H_
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} BUNDLE_SRCS)
+
+ADD_LIBRARY(${TARGET_BUNDLE} SHARED ${BUNDLE_SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_BUNDLE} PROPERTIES SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(${TARGET_BUNDLE} PROPERTIES VERSION ${FULLVER})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_BUNDLE} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../)
+
+APPLY_PKG_CONFIG(${TARGET_BUNDLE} PUBLIC
+ CAPI_BASE_COMMON_DEPS
+ DLOG_DEPS
+ GLIB_DEPS
+ JSON_GLIB_DEPS)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(VERSION ${FULLVER})
+
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/bundle.pc.in
+ ${CMAKE_CURRENT_SOURCE_DIR}/bundle.pc @ONLY)
+
+INSTALL(TARGETS ${TARGET_BUNDLE} DESTINATION ${LIB_INSTALL_DIR})
+INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION include/)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/bundle.pc DESTINATION
+ ${LIB_INSTALL_DIR}/pkgconfig/)
--- /dev/null
+/*
+ * Copyright (c) 2020 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 "bundle-internal.h"
+
+#include <errno.h>
+#include <glib.h>
+
+#include <algorithm>
+#include <cstring>
+#include <memory>
+#include <utility>
+
+#include "include/bundle.h"
+
+#include "exception-internal.h"
+
+namespace tizen_base {
+namespace internal {
+
+static const int CHECKSUM_LENGTH = 32;
+
+Bundle::Bundle(unsigned char* raw, int size, bool base64) {
+ if (size < 0)
+ THROW(BUNDLE_ERROR_INVALID_PARAMETER);
+
+ int ret;
+ if (base64)
+ ret = Decode(raw, static_cast<size_t>(size));
+ else
+ ret = DecodeRaw(raw, static_cast<size_t>(size));
+ if (ret != BUNDLE_ERROR_NONE)
+ THROW(ret);
+}
+
+Bundle::Bundle(int argc, char** argv) {
+ int ret = Import(argc, argv);
+ if (ret != BUNDLE_ERROR_NONE)
+ THROW(ret);
+}
+
+Bundle::Bundle(const Bundle& b) {
+ for (const auto& [key, val] : b.map_) {
+ const KeyInfo& info = *val;
+ auto new_val = std::make_shared<KeyInfo>(info);
+ map_[key] = new_val;
+ list_.push_back(std::move(new_val));
+ }
+}
+
+Bundle& Bundle::operator = (const Bundle& b) {
+ if (this != &b) {
+ map_.clear();
+ list_.clear();
+ for (const auto& [key, val] : b.map_) {
+ const KeyInfo& info = *val;
+ auto new_val = std::make_shared<KeyInfo>(info);
+ map_[key] = new_val;
+ list_.push_back(std::move(new_val));
+ }
+ }
+ return *this;
+}
+
+Bundle::Bundle(Bundle&& b) noexcept {
+ map_ = std::move(b.map_);
+ list_ = std::move(b.list_);
+}
+
+Bundle& Bundle::operator = (Bundle&& b) noexcept {
+ if (this != &b) {
+ map_ = std::move(b.map_);
+ list_ = std::move(b.list_);
+ }
+ return *this;
+}
+
+bool Bundle::operator == (const Bundle& b) {
+ if (this == &b)
+ return true;
+
+ if (map_.size() != b.map_.size())
+ return false;
+
+ for (const auto& kv : map_) {
+ auto& lhs = kv.second;
+ auto iter = b.map_.find(lhs->GetKey());
+ if (iter == b.map_.end())
+ return false;
+
+ auto& rhs = iter->second;
+ if (!(*lhs == *rhs))
+ return false;
+ }
+
+ return true;
+}
+
+void Bundle::Remove(const std::string& key) {
+ auto iter = map_.find(key);
+ if (iter == map_.end())
+ THROW(BUNDLE_ERROR_KEY_NOT_AVAILABLE);
+
+ list_.remove(iter->second);
+ map_.erase(iter);
+}
+
+void Bundle::Add(std::shared_ptr<KeyInfo> key_info) {
+ auto iter = map_.find(key_info->GetKey());
+ if (iter != map_.end())
+ THROW(BUNDLE_ERROR_KEY_EXISTS);
+
+ map_[key_info->GetKey()] = key_info;
+ list_.push_back(std::move(key_info));
+}
+
+void Bundle::Set(const std::string& key, int index,
+ std::vector<unsigned char> value) {
+ auto iter = map_.find(key);
+ if (iter == map_.end())
+ THROW(BUNDLE_ERROR_KEY_NOT_AVAILABLE);
+
+ int ret = iter->second->SetValue(index, value);
+ if (ret != BUNDLE_ERROR_NONE)
+ THROW(ret);
+}
+
+std::shared_ptr<KeyInfo>& Bundle::Get(const std::string& key) {
+ auto iter = map_.find(key.c_str());
+ if (iter == map_.end())
+ THROW(BUNDLE_ERROR_KEY_NOT_AVAILABLE);
+
+ return iter->second;
+}
+
+int Bundle::GetSize() {
+ return map_.size();
+}
+
+int Bundle::GetType(const std::string& key) {
+ auto iter = map_.find(key);
+ if (iter == map_.end())
+ THROW(BUNDLE_ERROR_KEY_NOT_AVAILABLE);
+
+ return iter->second->GetType();
+}
+
+unsigned char* Bundle::Encode() {
+ int size = 0;
+ unsigned char* raw;
+ try {
+ raw = EncodeRaw(&size);
+ } catch (const Exception& e) {
+ THROW(e.GetErrorCode());
+ }
+
+ std::unique_ptr<unsigned char, decltype(std::free)*> raw_ptr(raw, std::free);
+ char* encoded_data = reinterpret_cast<char*>(
+ g_base64_encode(reinterpret_cast<guchar*>(raw),
+ static_cast<gsize>(size)));
+ if (encoded_data == nullptr)
+ THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
+
+ return reinterpret_cast<unsigned char*>(encoded_data);
+}
+
+int Bundle::Decode(unsigned char* raw, size_t size) {
+ unsigned char* d_str = new (std::nothrow) unsigned char[(size / 4) * 3 + 3];
+ if (d_str == nullptr)
+ return BUNDLE_ERROR_OUT_OF_MEMORY;
+
+ std::unique_ptr<unsigned char[]> d_ptr(d_str);
+ gint state = 0;
+ guint save = 0;
+ size_t d_len_raw = static_cast<size_t>(g_base64_decode_step(
+ reinterpret_cast<char*>(raw), size, d_str, &state, &save));
+ if (d_len_raw < CHECKSUM_LENGTH)
+ return BUNDLE_ERROR_OUT_OF_MEMORY;
+
+ return DecodeRaw(d_str, d_len_raw);
+}
+
+unsigned char* Bundle::EncodeRaw(int* size) {
+ std::vector<unsigned char> bytes;
+ for (const auto& key_info : list_) {
+ auto encoded_bytes = key_info->Encode();
+ bytes.insert(bytes.end(),
+ std::make_move_iterator(encoded_bytes.begin()),
+ std::make_move_iterator(encoded_bytes.end()));
+ }
+
+ gchar* checksum = g_compute_checksum_for_string(
+ G_CHECKSUM_MD5, reinterpret_cast<gchar*>(&bytes[0]),
+ static_cast<gssize>(bytes.size()));
+ if (checksum == nullptr)
+ THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
+
+ std::unique_ptr<gchar, decltype(g_free)*> ptr(checksum, g_free);
+ unsigned char* p = reinterpret_cast<unsigned char*>(checksum);
+ bytes.insert(bytes.begin(), p, p + CHECKSUM_LENGTH);
+
+ unsigned char* raw = static_cast<unsigned char*>(malloc(bytes.size()));
+ if (raw == nullptr)
+ THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
+
+ std::copy(std::make_move_iterator(bytes.begin()),
+ std::make_move_iterator(bytes.end()), raw);
+ *size = static_cast<int>(bytes.size());
+ return raw;
+}
+
+int Bundle::DecodeRaw(unsigned char* raw, size_t size) {
+ char* extract_checksum = new (std::nothrow) char[CHECKSUM_LENGTH + 1];
+ if (extract_checksum == nullptr)
+ return BUNDLE_ERROR_OUT_OF_MEMORY;
+
+ std::unique_ptr<char[]> extract_ptr(extract_checksum);
+ unsigned char* d_str = raw;
+ size_t d_len_raw = size;
+ strncpy(extract_checksum, reinterpret_cast<char*>(d_str), CHECKSUM_LENGTH);
+ extract_checksum[CHECKSUM_LENGTH] = '\0';
+
+ gchar* compute_checksum = g_compute_checksum_for_string(G_CHECKSUM_MD5,
+ reinterpret_cast<gchar*>(d_str + CHECKSUM_LENGTH),
+ d_len_raw - CHECKSUM_LENGTH);
+ if (compute_checksum == nullptr)
+ return BUNDLE_ERROR_OUT_OF_MEMORY;
+
+ std::unique_ptr<gchar, decltype(g_free)*> compute_ptr(compute_checksum,
+ g_free);
+ if (strcmp(extract_checksum, static_cast<char*>(compute_checksum)) != 0)
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ unsigned char* d_r = d_str + CHECKSUM_LENGTH;
+ size_t d_len = d_len_raw - CHECKSUM_LENGTH;
+
+ unsigned int reader = 0;
+ std::vector<unsigned char> bytes(d_r, d_r + d_len);
+
+ while (reader < bytes.size()) {
+ std::size_t total_size = -1;
+ unsigned char* p = reinterpret_cast<unsigned char*>(&total_size);
+ std::copy(&bytes[reader], &bytes[reader] + sizeof(total_size), p);
+
+ std::vector<unsigned char> encoded_bytes(
+ &bytes[reader], &bytes[reader] + total_size);
+ reader += total_size;
+
+ try {
+ auto key_info = std::make_shared<KeyInfo>(std::move(encoded_bytes));
+ auto iter = map_.find(key_info->GetKey());
+ if (iter != map_.end())
+ continue;
+
+ map_[key_info->GetKey()] = key_info;
+ list_.push_back(std::move(key_info));
+ } catch (const Exception& e) {
+ return e.GetErrorCode();
+ } catch (const std::bad_alloc& ba) {
+ return BUNDLE_ERROR_OUT_OF_MEMORY;
+ }
+ }
+
+ return BUNDLE_ERROR_NONE;
+}
+
+const std::unordered_map<std::string, std::shared_ptr<KeyInfo>>&
+Bundle::GetMap() const {
+ return map_;
+}
+
+std::vector<std::string> Bundle::Export() {
+ std::vector<std::string> argv(2);
+ for (const auto& key_info : list_) {
+ argv.push_back(key_info->GetKey());
+
+ auto encoded_bytes = key_info->Encode();
+ auto* p = reinterpret_cast<unsigned char*>(&encoded_bytes[0]);
+ auto* base64_bytes = g_base64_encode(p, encoded_bytes.size());
+ if (base64_bytes == nullptr)
+ THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
+
+ std::unique_ptr<gchar, decltype(g_free)*> base64_bytes_ptr(base64_bytes,
+ g_free);
+ argv.push_back(base64_bytes);
+ }
+
+ return argv;
+}
+
+int Bundle::Import(int argc, char** argv) {
+ if (argc < 2)
+ return BUNDLE_ERROR_NONE;
+
+ if (!argv[1] || std::strcmp(argv[1], TAG_IMPORT_EXPORT_CHECK)) {
+ for (int idx = 1; idx + 1 < argc; idx += 2) {
+ auto* p = reinterpret_cast<unsigned char*>(argv[idx +1]);
+ auto len = strlen(argv[idx + 1]) + 1;
+ std::vector<unsigned char> value(p, p + len);
+
+ try {
+ auto key_info = std::make_shared<KeyInfo>(Type::String, argv[idx],
+ std::move(value));
+ auto iter = map_.find(key_info->GetKey());
+ if (iter != map_.end())
+ continue;
+
+ map_[key_info->GetKey()] = key_info;
+ list_.push_back(std::move(key_info));
+ } catch (const Exception& e) {
+ return e.GetErrorCode();
+ } catch (const std::bad_alloc& ba) {
+ return BUNDLE_ERROR_OUT_OF_MEMORY;
+ }
+ }
+
+ return BUNDLE_ERROR_NONE;
+ }
+
+ for (int idx = 2; idx + 1 < argc; idx += 2) {
+ gsize out_len = 0;
+ auto* bytes = g_base64_decode(argv[idx + 1], &out_len);
+ if (bytes == nullptr)
+ return BUNDLE_ERROR_OUT_OF_MEMORY;
+
+ std::unique_ptr<guchar, decltype(g_free)*> bytes_ptr(bytes, g_free);
+
+ if (out_len < sizeof(std::size_t))
+ continue;
+
+ auto* p = reinterpret_cast<unsigned char*>(bytes);
+ std::vector<unsigned char> decoded_bytes(p, p + (out_len + 1));
+
+ try {
+ auto key_info = std::make_shared<KeyInfo>(std::move(decoded_bytes));
+ auto iter = map_.find(key_info->GetKey());
+ if (iter != map_.end())
+ continue;
+
+ map_[key_info->GetKey()] = key_info;
+ list_.push_back(std::move(key_info));
+ } catch (const Exception& e) {
+ return e.GetErrorCode();
+ } catch (const std::bad_alloc& ba) {
+ return BUNDLE_ERROR_OUT_OF_MEMORY;
+ }
+ }
+
+ return BUNDLE_ERROR_NONE;
+}
+
+} // namespace internal
+} // namespace tizen_base
--- /dev/null
+/*
+ * Copyright (c) 2020 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 BUNDLE_INTERNAL_H_
+#define BUNDLE_INTERNAL_H_
+
+#include <list>
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include "include/bundle.h"
+
+#include "key-info-internal.h"
+
+namespace tizen_base {
+namespace internal {
+
+static const char TAG_IMPORT_EXPORT_CHECK[] = "`zaybxcwdveuftgsh`";
+
+class Bundle {
+ public:
+ enum Property {
+ Array = BUNDLE_TYPE_ARRAY,
+ Primitive = BUNDLE_TYPE_PRIMITIVE,
+ Measurable = BUNDLE_TYPE_MEASURABLE,
+ };
+
+ enum Type {
+ None = BUNDLE_TYPE_NONE,
+ Any = BUNDLE_TYPE_ANY,
+ String = BUNDLE_TYPE_STR,
+ StringArray = BUNDLE_TYPE_STR_ARRAY,
+ Byte = BUNDLE_TYPE_BYTE,
+ ByteArray = BUNDLE_TYPE_BYTE_ARRAY,
+ };
+
+ Bundle() = default;
+ Bundle(unsigned char* raw, int size, bool base64 = true);
+ Bundle(int argc, char** argv);
+ virtual ~Bundle() = default;
+
+ Bundle(const Bundle& b);
+ Bundle& operator = (const Bundle& b);
+ Bundle(Bundle&& b) noexcept;
+ Bundle& operator = (Bundle&& b) noexcept;
+
+ bool operator == (const Bundle& b);
+
+ void Remove(const std::string& key);
+ void Add(std::shared_ptr<KeyInfo> key_info);
+ void Set(const std::string& key, int index, std::vector<unsigned char> value);
+
+ std::shared_ptr<KeyInfo>& Get(const std::string& key);
+ int GetSize();
+ int GetType(const std::string& key);
+
+ unsigned char* Encode();
+ unsigned char* EncodeRaw(int* size);
+ int DecodeRaw(unsigned char* raw, size_t size);
+ const std::unordered_map<std::string, std::shared_ptr<KeyInfo>>& GetMap() const;
+ std::vector<std::string> Export();
+
+ private:
+ int Decode(unsigned char* raw, size_t size);
+ int Import(int argc, char** argv);
+
+ private:
+ std::unordered_map<std::string, std::shared_ptr<KeyInfo>> map_;
+ std::list<std::shared_ptr<KeyInfo>> list_;
+};
+
+} // namespace internal
+} // namespace tizen_base
+
+#endif // BUNDLE_INTERNAL_H_
--- /dev/null
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=${prefix}
+libdir=@LIB_INSTALL_DIR@
+includedir=${prefix}/include
+
+Name: bundle
+Description: Simple string key/val dictionary library
+Version: @VERSION@
+Requires: capi-base-common
+Libs: -L${libdir} -lbundle
+Cflags: -I${includedir}
+cppflags: -I${includedir}
--- /dev/null
+/*
+ * Copyright (c) 2019 - 2020 Samsung Electronics Co., Ltd.
+ *
+ * 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 <memory>
+#include <stdexcept>
+
+#include "bundle_cpp.h"
+#include "bundle_cpp_implementation.h"
+#include "bundle_internal.h"
+#include "log-private.h"
+
+namespace tizen_base {
+Bundle::Impl::Impl(Bundle* parent, bool copy, bool own)
+ : copy_(copy), own_(own), parent_(parent) {
+}
+
+Bundle::Impl::Impl(Bundle* parent) : parent_(parent) {
+}
+
+Bundle::Impl::~Impl() = default;
+
+Bundle::Bundle()
+ : impl_(new Impl(this)) {
+ impl_->handle_ = bundle_create();
+ if (impl_->handle_ == nullptr)
+ throw std::bad_alloc();
+}
+
+Bundle::Bundle(std::initializer_list<
+ std::pair<std::string, std::string>> key_values)
+ : impl_(new Impl(this)) {
+ impl_->handle_ = bundle_create();
+ if (impl_->handle_ == nullptr)
+ throw std::bad_alloc();
+ for (auto& i : key_values)
+ Add(i.first, i.second);
+}
+
+Bundle::Bundle(BundleRaw raw, bool base64)
+ : impl_(new Impl(this)) {
+ if (base64)
+ impl_->handle_ = bundle_decode(raw.first.get(), raw.second);
+ else
+ impl_->handle_ = bundle_decode_raw(raw.first.get(), raw.second);
+ if (impl_->handle_ == nullptr)
+ throw std::bad_alloc();
+}
+
+Bundle::Bundle(const std::string& raw)
+ : impl_(new Impl(this)) {
+ impl_->handle_ = bundle_decode(reinterpret_cast<const bundle_raw*>(
+ raw.c_str()), raw.length());
+ if (impl_->handle_ == nullptr)
+ throw std::bad_alloc();
+}
+
+Bundle::Bundle(bundle* b, bool copy, bool own)
+ : impl_(new Impl(this, copy, own)) {
+ if (b == nullptr)
+ throw std::invalid_argument("b cannot be null");
+
+ if (!impl_->copy_) {
+ impl_->handle_ = b;
+ } else {
+ impl_->handle_ = bundle_dup(b);
+ if (impl_->handle_ == nullptr)
+ throw std::bad_alloc();
+ }
+}
+
+Bundle::~Bundle() {
+ if (impl_ && impl_->handle_ && (impl_->own_ || impl_->copy_))
+ bundle_free(impl_->handle_);
+}
+
+Bundle::Bundle(const Bundle& b)
+ : impl_(new Impl(this)) {
+ impl_->handle_ = bundle_dup(b.impl_->handle_);
+ if (impl_->handle_ == nullptr)
+ throw std::bad_alloc();
+}
+
+Bundle::KeyInfo::KeyInfo(const bundle_keyval_t* handle, std::string name,
+ bool own)
+ : impl_(new Impl(this, handle, std::move(name), own)) {
+}
+
+Bundle::KeyInfo::~KeyInfo() {
+ if (impl_ && impl_->handle_ && impl_->own_)
+ bundle_keyval_free(const_cast<bundle_keyval_t*>(impl_->handle_));
+}
+
+Bundle::KeyInfo::Impl::~Impl() = default;
+
+Bundle::KeyInfo::Impl::Impl(Bundle::KeyInfo* parent,
+ const bundle_keyval_t* handle,
+ std::string name,
+ bool own)
+ : handle_(handle), name_(name), parent_(parent), own_(own) {
+}
+
+Bundle::KeyInfo::Impl::Impl(Bundle::KeyInfo* parent) : parent_(parent) {
+}
+
+Bundle::KeyInfo::KeyInfo(const KeyInfo& k)
+ : impl_(new Impl(this)) {
+ impl_->handle_ = bundle_keyval_dup(k.impl_->handle_);
+ impl_->name_ = k.impl_->name_;
+ impl_->own_ = true;
+ if (impl_->handle_ == nullptr)
+ throw std::bad_alloc();
+}
+
+Bundle::KeyInfo& Bundle::KeyInfo::operator = (const Bundle::KeyInfo& k) {
+ if (this != &k) {
+ if (impl_->handle_ && impl_->own_)
+ bundle_keyval_free(const_cast<bundle_keyval_t*>(impl_->handle_));
+
+ impl_->handle_ = bundle_keyval_dup(k.impl_->handle_);
+ impl_->name_ = k.impl_->name_;
+ if (impl_->handle_ == nullptr)
+ throw std::bad_alloc();
+
+ impl_->own_ = true;
+ }
+ return *this;
+}
+
+Bundle::KeyInfo::KeyInfo(Bundle::KeyInfo&& k) noexcept {
+ impl_ = std::move(k.impl_);
+ impl_->parent_ = this;
+}
+
+Bundle::KeyInfo& Bundle::KeyInfo::operator = (Bundle::KeyInfo&& k) noexcept {
+ if (this != &k) {
+ if (impl_->handle_ && impl_->own_)
+ bundle_keyval_free(const_cast<bundle_keyval_t*>(impl_->handle_));
+
+ impl_->handle_ = k.impl_->handle_;
+ impl_->name_ = k.impl_->name_;
+ impl_->own_ = k.impl_->own_;
+ k.impl_->handle_ = nullptr;
+ k.impl_->name_ = "";
+ k.impl_->own_ = false;
+ }
+ return *this;
+}
+
+bundle_type Bundle::KeyInfo::GetType() const {
+ return static_cast<bundle_type>(
+ bundle_keyval_get_type(const_cast<bundle_keyval_t*>(impl_->handle_)));
+}
+
+bool Bundle::KeyInfo::IsArray() const {
+ return bundle_keyval_type_is_array(const_cast<bundle_keyval_t*>(
+ impl_->handle_));
+}
+
+const std::string& Bundle::KeyInfo::GetName() const {
+ return impl_->name_;
+}
+
+Bundle& Bundle::operator = (const Bundle& b) {
+ if (this != &b) {
+ if (impl_->handle_ && (impl_->own_ || impl_->copy_))
+ bundle_free(impl_->handle_);
+
+ impl_->handle_ = bundle_dup(b.impl_->handle_);
+ if (impl_->handle_ == nullptr)
+ throw std::bad_alloc();
+
+ impl_->own_ = true;
+ impl_->copy_ = true;
+ }
+ return *this;
+}
+
+Bundle::Bundle(Bundle&& b) noexcept {
+ impl_ = std::move(b.impl_);
+ impl_->parent_ = this;
+ b.impl_.reset(new Impl(&b));
+ b.impl_->handle_ = bundle_create();
+}
+
+Bundle& Bundle::operator = (Bundle&& b) noexcept {
+ if (this != &b) {
+ if (impl_->handle_ && (impl_->own_ || impl_->copy_))
+ bundle_free(impl_->handle_);
+
+ impl_->handle_ = b.impl_->handle_;
+ b.impl_->handle_ = nullptr;
+ impl_->own_ = b.impl_->own_;
+ b.impl_->own_ = false;
+ impl_->copy_ = b.impl_->copy_;
+ b.impl_->copy_ = false;
+ }
+ return *this;
+}
+
+bool Bundle::IsEmpty() const noexcept {
+ return (bundle_get_count(impl_->handle_) == 0) ? true : false;
+}
+
+std::vector<Bundle::KeyInfo> Bundle::GetKeys() {
+ std::vector<Bundle::KeyInfo> v;
+
+ bundle_foreach(impl_->handle_, [](const char *key, const int type,
+ const bundle_keyval_t *kv, void *user_data) {
+ auto* v = static_cast<std::vector<KeyInfo>*>(user_data);
+ v->emplace_back(kv, key, false);
+ }, &v);
+
+ return v;
+}
+
+int Bundle::Add(const std::string& key, const std::string& val) {
+ int ret = bundle_add_str(impl_->handle_, key.c_str(), val.c_str());
+ if (ret != BUNDLE_ERROR_NONE)
+ LOGE("Add fail key(%s), val(%s), ret(%d)", key.c_str(), val.c_str(), ret);
+ return ret;
+}
+
+int Bundle::Add(const std::string& key, const std::vector<std::string>& val) {
+ std::vector<const char*> v;
+ for (auto& i : val) {
+ v.push_back(i.c_str());
+ }
+
+ int ret = bundle_add_str_array(
+ impl_->handle_, key.c_str(), v.data(), v.size());
+ if (ret != BUNDLE_ERROR_NONE)
+ LOGE("Add fail key(%s), ret(%d)", key.c_str(), ret);
+
+ return ret;
+}
+
+int Bundle::Add(const std::string& key, const std::vector<unsigned char>& val) {
+ int ret = bundle_add_byte(impl_->handle_, key.c_str(), val.data(), val.size());
+ if (ret != BUNDLE_ERROR_NONE)
+ LOGE("Add fail key(%s), ret(%d)", key.c_str(), ret);
+ return ret;
+}
+
+int Bundle::Delete(const std::string& key) {
+ return bundle_del(impl_->handle_, key.c_str());
+}
+
+std::string Bundle::GetString(const std::string& key) const {
+ char* str = nullptr;
+ bundle_get_str(impl_->handle_, key.c_str(), &str);
+
+ if (!str)
+ return "";
+
+ return std::string(str);
+}
+
+std::vector<std::string> Bundle::GetStringArray(const std::string& key) const {
+ std::vector<std::string> v;
+
+ const char** str_array = nullptr;
+ int len = 0;
+
+ str_array = bundle_get_str_array(impl_->handle_, key.c_str(), &len);
+
+ for (int i = 0; i < len; i++) {
+ v.emplace_back(str_array[i]);
+ }
+
+ return v;
+}
+
+std::vector<unsigned char> Bundle::GetByte(const std::string& key) const {
+ size_t size;
+ unsigned char* bytes = nullptr;
+ int ret = bundle_get_byte(impl_->handle_, key.c_str(),
+ reinterpret_cast<void**>(&bytes), &size);
+ if (ret != BUNDLE_ERROR_NONE) {
+ LOGE("bundle_get_byte() is failed");
+ return {};
+ }
+
+ return std::vector<unsigned char>(bytes, bytes + size);
+}
+
+Bundle::BundleRaw Bundle::ToRaw(bool base64) {
+ bundle_raw* raw = nullptr;
+ int len = 0;
+ int ret;
+ if (base64)
+ ret = bundle_encode(impl_->handle_, &raw, &len);
+ else
+ ret = bundle_encode_raw(impl_->handle_, &raw, &len);
+ if (raw == nullptr) {
+ LOGE("Fail to encode data (%d)", ret);
+ throw std::bad_alloc();
+ }
+
+ return BundleRaw(
+ std::unique_ptr<bundle_raw, decltype(std::free)*>(raw, std::free), len);
+}
+
+int Bundle::GetCount() const {
+ return bundle_get_count(impl_->handle_);
+}
+
+bundle_type Bundle::GetType(const std::string& key) const {
+ return static_cast<bundle_type>(bundle_get_type(impl_->handle_, key.c_str()));
+}
+
+bundle* Bundle::GetHandle() const {
+ return impl_->handle_;
+}
+
+bundle* Bundle::Detach() {
+ auto* h = impl_->handle_;
+ impl_->handle_ = nullptr;
+ return h;
+}
+
+std::vector<std::string> Bundle::Export() const {
+ char** argv = nullptr;
+ int argc = bundle_export_to_argv(impl_->handle_, &argv);
+ if (argc < 0) {
+ LOGE("bundle_export_to_argv() is failed");
+ return {};
+ }
+
+ std::vector<std::string> args(1);
+ for (int i = 1; i < argc; ++i)
+ args.push_back(argv[i]);
+
+ bundle_free_exported_argv(argc, &argv);
+ return args;
+}
+
+} // namespace tizen_base
--- /dev/null
+/*
+ * Copyright (c) 2019 - 2020 Samsung Electronics Co., Ltd.
+ *
+ * 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 BUNDLE_CPP_IMPLEMENTATION_H_
+#define BUNDLE_CPP_IMPLEMENTATION_H_
+
+#include <string>
+#include <memory>
+#include <list>
+
+#include "include/bundle_cpp.h"
+
+namespace tizen_base {
+
+class Bundle::KeyInfo::Impl {
+ public:
+ virtual ~Impl();
+
+ private:
+ Impl(Bundle::KeyInfo* parent, const bundle_keyval_t* handle,
+ std::string name, bool own);
+ explicit Impl(Bundle::KeyInfo* parent);
+
+ private:
+ friend class Bundle::KeyInfo;
+
+ private:
+ const bundle_keyval_t* handle_ = nullptr;
+ std::string name_;
+ Bundle::KeyInfo* parent_;
+ bool own_ = false;
+};
+
+class Bundle::Impl {
+ public:
+ virtual ~Impl();
+
+ private:
+ explicit Impl(Bundle* parent);
+ Impl(Bundle* parent, bool copy, bool own);
+
+ private:
+ friend class Bundle;
+
+ bundle* handle_ = nullptr;
+ bool copy_ = true;
+ bool own_ = true;
+ Bundle* parent_ = nullptr;
+};
+
+} // namespace tizen_base
+
+#endif // BUNDLE_CPP_IMPLEMENTATION_H_
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * 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 EXCEPTION_INTERNAL_H_
+#define EXCEPTION_INTERNAL_H_
+
+#include <string>
+#include <exception>
+
+#include "log-private.h"
+
+#define THROW(error_code) throw Exception(error_code)
+
+namespace tizen_base {
+namespace internal {
+
+class Exception : public std::exception {
+ public:
+ explicit Exception(int error_code, std::string file = __FILE__,
+ int line = __LINE__ ) {
+ error_code_ = error_code;
+ message_ = file.substr(file.find_last_of("/") + 1) + ":"
+ + std::to_string(line) + " code:" + std::to_string(error_code_);
+ }
+
+ virtual ~Exception() {}
+
+ virtual const char *what(void) const noexcept {
+ return message_.c_str();
+ }
+
+ int GetErrorCode() const {
+ return error_code_;
+ }
+
+ private:
+ int error_code_;
+ std::string message_;
+};
+
+} // namespace internal
+} // namespace tizen_base
+
+#endif // EXCEPTION_INTERNAL_H_
--- /dev/null
+/*
+ * Copyright (c) 2020 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 EXPORT_API_INTERNAL_H_
+#define EXPORT_API_INTERNAL_H_
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+#endif // EXPORT_API_INTERNAL_H_
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2020 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.
+ */
+
+/**
+ *
+ * @ingroup SLP_PG
+ * @defgroup bundle_PG Bundle
+ * @brief A simple string-based dictionary ADT.
+ * @{
+
+<h1 class="pg">Introduction</h1>
+
+<p> Bundle is a string based Dictionary ADT. A dictionary is an ordered or unordered list of key element pairs, where keys are used to locate elements in the list. </p><br/>
+
+<p> ADT (Abstract data type) An Abstract Data type is defined as a mathematical model of the data objects that make up a data type as well
+as the functions that operate on these objects.</p>
+
+<h1 class="pg">Features</h1>
+<ul>
+ <li> Bundle provides string based Dictionary ADT to
+ map/store key-value pairs. Eg. Clock </li>
+ <li> Bundle provides Application Data Exchange (ADE):
+ <ul>
+ <li> Transfer application argument between caller and callee by creating a bundle and storing key-value pairs in it. </li>
+ <li> This bundle object can be passed between applications by encoding and decoding the bundle objects. </li>
+ </ul> </li>
+
+</ul>
+
+<h1 class="pg">Properties</h1>
+<ul>
+ <li>Only string type is allowed for key and value.</li>
+ <li>Each key and value is duplicated into the bundle object.</li>
+ <li>Unlimited number of key/value pairs. (Memory limit is still to be considered)</li>
+ <li>No key overlap : You cannot assign new values with existing key.</li>
+</ul>
+
+<h1 class="pg">Bundle Logical View diagram</h1>
+\image html SLP_bundle_PG_images_logical_view.png "Picture 1. Logical view"
+
+
+<h1 class="pg">Functional architecture diagram</h1>
+\image html SLP_bundle_PG_image01.png "Picture 2. Functional architecture"
+
+<p> Bundle requests are received by the Bundle interface. It passes the requests to bundle manager. Bundle Manager checks the type of the request and handles it accordingly. If string key-value needs to be handled in the request it interacts with String manager to provide the required functionality. If the request is based on array of string key-value pair then, Bundle manager interacts with Array manager to provide the required functionality.</p>
+
+<h1 class="pg"> Bundle encode decode life cycle </h1>
+\image html SLP_bundle_PG_images_encode_decode.png "Picture 2. Encode decode life cycle"
+
+<h1 class="pg"> Bundle export import life cycle </h1>
+\image html SLP_bundle_PG_images_export_import.png "Picture 2. Export import life cycle"
+
+<h1 class="pg">API list and description</h1>
+<ul>
+ <li>bundle_create() : Create a bundle object.</li>
+ <li>bundle_free() : Free a bundle object.</li>
+ <li>bundle_add() : Add a key/value pair into the bundle object.</li>
+ <li>bundle_del() : Delete a key/value pair by given key from the bundle object.</li>
+ <li>bundle_get_val() : Get a value by key.</li>
+ <li>bundle_get_count() : Get number of key/value pairs in the bundle object.</li>
+ <li>bundle_dup() : Duplicate give bundle object</li>
+ <li>bundle_iterate() : Run iterator function for each key/value pair in the bundle object.</li>
+ <li>bundle_encode() : Encode bundle object into a byte code.</li>
+ <li>bundle_decode() : Decode byt code into a bundle object.</li>
+ <li></li>
+</ul>
+
+<h1 class="pg">Programming Guide</h1>
+<p> bundle library is very easy to use, and the sample code below would enough to understand how to use bundle. </p><br>
+<p>Detailed API instructions are in API reference in doxygen document.</p>
+<h2 class="pg">Note</h2>
+<ul>
+ <li>Only string type(char *) keys/values are allowed.</li>
+ <li>A bundle object must be freed certainly by bundle_free(). </li>
+ <li>Values retrived by bundle_get_val() cannot be modified.<br> If you want to modify value string, duplicate it.</li>
+</ul>
+<h2 class="pg"> Header file </h2>
+<p> header file name: <strong> bundle.h </strong></p>
+<h2 class="pg">Code</h2>
+@code
+#include <stdio.h>
+#include <bundle.h>
+
+// This is a sample iterator callback function
+void print_bundle_item(const char *key, const char *val, void *data);
+
+// Sample code
+int
+main(int argc, char **argv)
+{
+ char *str;
+ int count;
+
+ bundle *b, *b_dup;
+
+ // Create a new bundle object
+ b = bundle_new();
+
+ // Add a string with key "a"
+ bundle_add(b, "a", "123abc");
+
+ // Add another string with key "b"
+ bundle_add("b", "456def");
+
+ // str = "123abc"
+ // You cannot modify string!
+ str = bundle_get_val(b, "a");
+
+ // Run iterator function with each items
+ bundle_iterate(b, print_bundle_item, NULL);
+
+ // count = 2
+ count = bundle_get_count(b);
+
+ // Delete an item with key "a"
+ bundle_del(b, "a");
+
+ // count = 1
+ count = bundle_get_count(b);
+
+ // If "a" key is requested, NULL is returned
+ // str = NULL, errno = ENOKEY
+ str = bundle_get_val(b, "a");
+
+ // Duplicate bundle object
+ b_dup = bundle_dup(b);
+
+ // Free bundle objects
+ bundle_free(b);
+ bundle_free(b_dup);
+
+ return 0;
+}
+
+void
+print_bundle_item(const char *key, const char *val, void *data)
+{
+ printf("%s -> %s\n", key, val);
+}
+@endcode
+
+ * @}
+ */
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2020 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 __BUNDLE_H__
+#define __BUNDLE_H__
+
+/**
+ * @file bundle.h
+ * @brief This file declares API of the bundle library.
+ */
+
+/**
+ * @addtogroup CORE_LIB_BUNDLE_MODULE
+ * @{
+ */
+
+#include <errno.h>
+#include <stddef.h>
+#include <tizen_error.h>
+
+#ifdef __cplusplus
+extern "C" {
+# endif
+
+/**
+ * @brief Enumeration for error codes of Bundle.
+ * @since_tizen 2.3
+ */
+typedef enum {
+ BUNDLE_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
+ BUNDLE_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */
+ BUNDLE_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
+ BUNDLE_ERROR_KEY_NOT_AVAILABLE = TIZEN_ERROR_KEY_NOT_AVAILABLE, /**< Required key not available */
+ BUNDLE_ERROR_KEY_EXISTS = TIZEN_ERROR_BUNDLE | 0x01, /**< Key exists */
+ BUNDLE_ERROR_ARRAY_INDEX_OUT_OF_BOUNDS = TIZEN_ERROR_BUNDLE | 0x02 /**< The index is out of bounds of the array */
+} bundle_error_e;
+
+
+/**
+ * @brief The bundle handle.
+ * @since_tizen 2.3
+ */
+typedef struct _bundle_t bundle;
+
+
+/**
+ * @brief The encoded data type.
+ * @since_tizen 2.3
+ * @see bundle_encode()
+ * @see bundle_decode()
+ */
+typedef unsigned char bundle_raw;
+
+
+/**
+ * @brief Enumeration for key-value pair types.
+ * @since_tizen 2.3
+ */
+enum bundle_type_property {
+ BUNDLE_TYPE_ARRAY = 0x0100, /**< Array type */
+ BUNDLE_TYPE_PRIMITIVE = 0x0200, /**< Primitive type */
+ BUNDLE_TYPE_MEASURABLE = 0x0400 /**< Measurable type */
+};
+
+
+/**
+ * @brief Enumeration for bundle types.
+ * @since_tizen 2.3
+ */
+enum bundle_type {
+ BUNDLE_TYPE_NONE = -1, /**< None */
+ BUNDLE_TYPE_ANY = 0, /**< Any type */
+ BUNDLE_TYPE_STR = 1 | BUNDLE_TYPE_MEASURABLE, /**< String type (Default) */
+ BUNDLE_TYPE_STR_ARRAY = BUNDLE_TYPE_STR | BUNDLE_TYPE_ARRAY | BUNDLE_TYPE_MEASURABLE, /**< String array type */
+ BUNDLE_TYPE_BYTE = 2, /**< Byte type */
+ BUNDLE_TYPE_BYTE_ARRAY = BUNDLE_TYPE_BYTE | BUNDLE_TYPE_ARRAY /**< Byte array type */
+};
+
+
+/**
+ * @brief The key-value pair handle.
+ * @since_tizen 2.3
+ * @see bundle_iterator_t
+ */
+typedef struct keyval_t bundle_keyval_t;
+
+
+/**
+ * @brief Called for every key-value pair.
+ * @since_tizen 2.3
+ * @param[in] key The key of key-value pair
+ * @param[in] type The type of bundle
+ * @param[in] kv The handle of key-value pair
+ * @param[in] user_data The user data
+ * @see bundle_foreach()
+ */
+typedef void (*bundle_iterator_t) (const char *key, const int type, const bundle_keyval_t *kv, void *user_data);
+
+
+/**
+ * @brief Creates a bundle object.
+ * @since_tizen 2.3
+ * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
+ * @return The bundle object,
+ * @c NULL - Failure
+ * @exception #BUNDLE_ERROR_NONE Success
+ * @exception #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
+ * @see bundle_free()
+ *
+ * @code
+ #include <bundle.h>
+ bundle *b = bundle_create(); // Create a new bundle object
+ bundle_free(b); // Free the bundle
+ * @endcode
+ */
+bundle *bundle_create(void);
+
+
+/**
+ * @brief Frees the given bundle object with key-value pairs in it.
+ * @since_tizen 2.3
+ * @param[in] b The bundle object to be freed
+ * @return The operation result
+ * @retval #BUNDLE_ERROR_NONE Success
+ * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre @a b must be a valid bundle object.
+ * @see bundle_create()
+ *
+ * @code
+ #include <bundle.h>
+ bundle *b = bundle_create(); // Create a new bundle object
+ bundle_free(b); // Free the bundle
+ * @endcode
+ */
+int bundle_free(bundle *b);
+
+
+/**
+ * @brief Adds a strings array type key-value pair into a given bundle.
+ * @since_tizen 2.3
+ * @param[in] b The bundle object
+ * @param[in] key The key
+ * @param[in] str_array The string type value; if @c NULL, an empty array is created; you can change an item with
+ * @param[in] len The length of the array
+ * @return The operation result
+ * @retval #BUNDLE_ERROR_NONE Success
+ * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #BUNDLE_ERROR_KEY_EXISTS Key already exists
+ * @retval #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
+ * @pre @a b must be a valid bundle object.
+ * @see bundle_get_str_array()
+ *
+ * @code
+ #include <bundle.h>
+ char *sa = {"aaa", "bbb", "ccc"}; // String array of length 3
+ bundle *b = bundle_create();
+ bundle_add_str_array(b, "foo", sa, 3); // Add a key-value pair
+ bundle_free(b);
+ * @endcode
+ */
+int bundle_add_str_array(bundle *b, const char *key, const char **str_array, const int len);
+
+
+/**
+ * @brief Deletes a key-value object with the given key.
+ * @since_tizen 2.3
+ * @param[in] b The bundle object
+ * @param[in] key The given key
+ * @return The operation result
+ * @retval #BUNDLE_ERROR_NONE Success
+ * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #BUNDLE_ERROR_KEY_NOT_AVAILABLE Key not available
+ * @pre @a b must be a valid bundle object.
+ *
+ * @code
+ #include <bundle.h>
+ bundle *b = bundle_create(); // Create a new bundle object
+ bundle_add_str(b, "foo_key", "bar_val"); // Add a key-value pair
+ bundle_del(b, "foo_key"); // Delete "foo_key" from b
+
+ bundle_free(b);
+ * @endcode
+ */
+int bundle_del(bundle *b, const char *key);
+
+
+/**
+ * @brief Gets a string array from a given key.
+ * @since_tizen 2.3
+ * @remarks You MUST NOT free or modify the returned string. \n
+ * The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
+ * @param[in] b The bundle object
+ * @param[in] key The key
+ * @param[out] len The array length
+ * @return The pointer to the array of strings,
+ * @c NULL - Key not found
+ * @exception #BUNDLE_ERROR_NONE Success
+ * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @exception #BUNDLE_ERROR_KEY_NOT_AVAILABLE Key not available
+ * @pre @a b must be a valid bundle object.
+ * @see bundle_add_str_array()
+ *
+ * @code
+ #include <bundle.h>
+ bundle *b = bundle_create();
+ char *sa = {"aaa", "bbb", "ccc"}; // String array of length 3
+ bundle_add_str_array(b, "foo", sa, 3); // Add a key-value pair
+
+ char **str_array = NULL;
+ int len_str_array = 0;
+
+ str_array=bundle_get_str_array(b, "foo", &len_str_array);
+ // str_array = {"aaa", "bbb", "ccc"}, and len_str_array = 3
+
+ bundle_free(b);
+ * @endcode
+ */
+const char **bundle_get_str_array(bundle *b, const char *key, int *len);
+
+
+/**
+ * @brief Gets the number of bundle items.
+ * @since_tizen 2.3
+ * @param[in] b The bundle object
+ * @return The number of bundle items
+ * @pre @a b must be a valid bundle object.
+ *
+ * @code
+ #include <bundle.h>
+ bundle *b = bundle_create(); // Create a new bundle object
+ bundle_add_str(b, "key1", "val1"); // Add a key-value pair
+ int count = bundle_get_count(b); // count = 1
+ bundle_add_str(b, "key2", "val2"); // Add another key-value pair
+ count = bundle_get_count(b); // count = 2
+
+ bundle_free(b);
+ * @endcode
+ */
+int bundle_get_count(bundle *b);
+
+
+/**
+ * @brief Gets the type of the value with a given key.
+ * @since_tizen 2.3
+ * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
+ * @param[in] b A bundle
+ * @param[in] key A key in the bundle
+ * @return The type of a key in @a b
+ * @exception #BUNDLE_ERROR_NONE Success
+ * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @exception #BUNDLE_ERROR_KEY_NOT_AVAILABLE Key not available
+ * @pre @a b must be a valid bundle object.
+ * @see bundle_type
+ */
+int bundle_get_type(bundle *b, const char *key);
+
+
+/**
+ * @brief Duplicates a given bundle object.
+ * @since_tizen 2.4
+ * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
+ * The returned value should be released using bundle_free().
+ * @param[in] b_from The bundle object to be duplicated
+ * @return The new bundle object,
+ * @c NULL - Failure
+ * @exception #BUNDLE_ERROR_NONE Success
+ * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre @a b_from must be a valid bundle object.
+ *
+ * @code
+ #include <bundle.h>
+ bundle *b = bundle_create(); // Create a new bundle object
+ bundle_add_str(b, "foo_key", "bar_val"); // Add a key-value pair
+ bundle *b_dup = bundle_dup(b); // Duplicate b
+
+ bundle_free(b);
+ bundle_free(b_dup);
+ * @endcode
+ */
+bundle *bundle_dup(bundle *b_from);
+
+
+/**
+ * @brief Iterates a callback function for each key-value pair in a given bundle.
+ * @details Supports all types of values.
+ * @since_tizen 2.3
+ * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section. \n
+ * This function supports all types.
+ * @param[in] b The bundle object
+ * @param[in] iter The iteration callback function
+ * @param[in] user_data The data for the callback function
+ * @exception #BUNDLE_ERROR_NONE Success
+ * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre @a b must be a valid bundle object.
+ * @see bundle_keyval_get_type()
+ * @see bundle_keyval_type_is_array()
+ * @see bundle_keyval_get_basic_val()
+ * @see bundle_keyval_get_array_val()
+ *
+ * @code
+ #include <stdio.h>
+ #include <bundle.h>
+ void
+ sample_cb(const char *key, const int type, const bundle_keyval_t *kv, void *user_data)
+ {
+ void *basic_val = NULL;
+ size_t basic_size = 0;
+ void **array_val = NULL;
+ int array_len = 0;
+ size_t *array_elem_size = NULL;
+
+ printf("Key:%s, Type:%d\n", key, type);
+ if (bundle_keyval_type_is_array(kv)) {
+ bundle_keyval_get_array_val(kv, &array_val, &array_len, &array_elem_size);
+ // Do something
+ }
+ else {
+ bundle_keyval_get_basic_val(kv, &basic_val, &basic_size);
+ // Do something
+ }
+ }
+
+ int main(void)
+ {
+ bundle *b = bundle_create(); // Create a new bundle object
+ bundle_add_str(b, "k1", "v1"); // Add a key-value pair
+ bundle_add_byte(b, "k2", "v2", 3); // Add a key-value pair
+ char *s_arr[] = {"abc", "bcd", "cde"};
+ bundle_add_str_array(b, "k3", s_arr, 3); // Add a key-value pair
+ bundle_foreach(b, sample_cb, NULL); // Iterate sample_cb() for each key/value
+
+ return 0;
+ }
+ * @endcode
+ */
+void bundle_foreach(bundle *b, bundle_iterator_t iter, void *user_data);
+
+
+/**
+ * @brief Gets the type of a key-value pair.
+ * @since_tizen 2.3
+ * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
+ * @param[in] kv A bundle_keyval_t object
+ * @return The type of @a kv,
+ * @c -1 - Failure
+ * @exception #BUNDLE_ERROR_NONE Success
+ * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre @a kv must be a valid bundle_keyval_t object.
+ * @see bundle_foreach()
+ */
+int bundle_keyval_get_type(bundle_keyval_t *kv);
+
+
+/**
+ * @brief Determines whether the type of a key-value pair is an array.
+ * @since_tizen 2.3
+ * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
+ * @param[in] kv A bundle_keyval_t object
+ * @return The operation result
+ * @c 1 - @a kv is an array
+ * @c 0 - @a kv is not an array
+ * @exception #BUNDLE_ERROR_NONE Success
+ * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre @a kv must be a valid bundle_keyval_t object.
+ * @see bundle_foreach()
+ */
+int bundle_keyval_type_is_array(bundle_keyval_t *kv);
+
+
+/**
+ * @brief Gets the value and size of the value from a key-value pair of basic type.
+ * @since_tizen 2.3
+ * @remarks You must not free @a val.
+ * @param[in] kv A bundle_keyval_t object
+ * @param[out] val The value
+ * @param[out] size The size of @a val
+ * @return The operation result
+ * @retval #BUNDLE_ERROR_NONE Success
+ * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre @a kv must be a valid bundle_keyval_t object.
+ * @post @a val and @a size are set.
+ * @see bundle_foreach()
+ */
+int bundle_keyval_get_basic_val(bundle_keyval_t *kv, void **val, size_t *size);
+
+
+/**
+ * @brief Gets the value array, length of the array, and size of each array item.
+ * @since_tizen 2.3
+ * @remarks The @a array_val should not be released.
+ * The @a array_element_size should not be released.
+ * @param[in] kv A bundle_keyval_t object
+ * @param[out] array_val The array pointer of values
+ * @param[out] array_len The length of @a array_val
+ * @param[out] array_element_size The array of size of each array element
+ * @return The operation result
+ * @retval #BUNDLE_ERROR_NONE Success
+ * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre @a kv must be a valid bundle_keyval_t object.
+ * @post @a array_val, @a array_len, @a array_element_size are set.
+ * @code
+ #include <stdio.h>
+ #include <bundle.h>
+ void
+ sample_cb(const char *key, const int type, const bundle_keyval_t *kv, void *user_data)
+ {
+ void **array_val = NULL;
+ unsigned int array_len = 0;
+ size_t *array_elem_size = NULL;
+ unsigned int i;
+
+ printf("Key: %s, Type: %d\n", key, type);
+ if (bundle_keyval_type_is_array(kv)) {
+ bundle_keyval_get_array_val(kv, &array_val, &array_len, &array_elem_size);
+ for (i = 0; i < array_len; ++i) {
+ printf("Value[%u]: %s\n", i, (const char *)array_val[i]);
+ }
+ }
+ }
+
+ int main(void)
+ {
+ bundle *b = bundle_create();
+ const char *s_arr[] = {"abc", "bcd", "cde"};
+ bundle_add_str_array(b, "k3", s_arr, 3); // Add a key-value pair
+ bundle_foreach(b, sample_cb, NULL);
+ bundle_free(b);
+ return 0;
+ }
+ * @endcode
+ * @see bundle_foreach()
+ */
+int bundle_keyval_get_array_val(bundle_keyval_t *kv, void ***array_val, unsigned int *array_len, size_t **array_element_size);
+
+
+/**
+ * @brief Encodes a bundle to the bundle_raw format (uses base64 format).
+ * @since_tizen 2.3
+ * @remarks The @a r should be released using free().
+ * @param[in] b The bundle object
+ * @param[out] r The returned bundle_raw data(byte data)
+ * @a r MUST BE FREED by free(r)
+ * @param[out] len The size of @a r (in bytes)
+ * @return The size of the raw data
+ * @retval #BUNDLE_ERROR_NONE Success
+ * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre @a b must be a valid bundle object.
+ *
+ * @code
+ #include <bundle.h>
+ bundle *b = bundle_create(); // Create a new bundle object
+ bundle_add_str(b, "foo_key", "bar_val"); // Add a key-value pair
+ bundle_raw *r;
+ int len;
+ bundle_encode(b, &r, &len); // Encode b
+ bundle_free(b);
+ free(r);
+ * @endcode
+ */
+int bundle_encode(bundle *b, bundle_raw **r, int *len);
+
+
+/**
+ * @brief Deserializes bundle_raw and gets the bundle object.
+ * @since_tizen 2.3
+ * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
+ * The returned value should be released using bundle_free().
+ * @param[in] r The bundle_raw data to be converted to bundle object
+ * @param[in] len The size of @a r
+ * @return The bundle object,
+ * @c NULL - Failure
+ * @exception #BUNDLE_ERROR_NONE Success
+ * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre @a r must be a valid bundle object.
+ *
+ * @code
+ #include <bundle.h>
+ bundle *b = bundle_create(); // Create a new bundle object
+ bundle_add_str(b, "foo_key", "bar_val"); // Add a key-value pair
+
+ bundle_raw *encoded_b;
+ int len;
+ bundle_encode(b, &encoded_b, &len); // Encode b
+
+ bundle *b_dup;
+ b_dup = bundle_decode(encoded_b, len); // Decoded bundle object
+
+ bundle_free(b);
+ free(encoded_b);
+ bundle_free(b_dup);
+ * @endcode
+ */
+bundle *bundle_decode(const bundle_raw *r, const int len);
+
+
+/**
+ * @brief Adds a string type key-value pair into a bundle.
+ * @since_tizen 2.3
+ * @param[in] b The bundle object
+ * @param[in] key The key
+ * @param[in] str The string type value
+ * @return The operation result
+ * @retval #BUNDLE_ERROR_NONE Success
+ * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #BUNDLE_ERROR_KEY_EXISTS Key already exists
+ * @retval #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
+ * @pre @a b must be a valid bundle object.
+ * @see bundle_get_str()
+ * @code
+ #include <bundle.h>
+ bundle *b = bundle_create(); // Create a new bundle object
+ bundle_add_str(b, "foo", "bar"); // Add a key-value pair
+
+ bundle_free(b);
+ * @endcode
+ */
+int bundle_add_str(bundle *b, const char *key, const char *str);
+
+
+/**
+ * @brief Adds a byte sequence type key-value pair into a bundle.
+ * @details The bundle will contain a copy of the added byte sequence.
+ * @since_tizen 2.3
+ * @param[in] b The bundle object
+ * @param[in] key The key
+ * @param[in] bytes The byte sequence
+ * @param[in] size The byte sequence size in bytes
+ * @return The operation result
+ * @retval #BUNDLE_ERROR_NONE Success
+ * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #BUNDLE_ERROR_KEY_EXISTS Key already exists
+ * @retval #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
+ * @pre @a b must be a valid bundle object.
+ * @see bundle_get_byte()
+ *
+ * @code
+ #include <bundle.h>
+ bundle *b = bundle_create(); // Create a new bundle object
+ bundle_add_byte(b, "foo", "bar\0", 4); // Add a key-value pair
+
+ int number = 12345;
+ bundle_add_byte(b, "number", &number, sizeof(int));
+
+ bundle_free(b);
+ * @endcode
+ */
+int bundle_add_byte(bundle *b, const char *key, const void *bytes, const size_t size);
+
+
+/**
+ * @brief Gets the string value with the given key.
+ * @since_tizen 2.3
+ * @remarks You must not free str.
+ * @param[in] b The bundle object
+ * @param[in] key The key
+ * @param[out] str The returned value
+ * @return The operation result
+ * @retval #BUNDLE_ERROR_NONE Success
+ * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #BUNDLE_ERROR_KEY_NOT_AVAILABLE Key not available
+ * @pre @a b must be a valid bundle object.
+ * @see bundle_add_str()
+ *
+ * @code
+ #include <bundle.h>
+ bundle *b = bundle_create(); // Create a new bundle object
+ bundle_add_str(b, "foo_key", "bar_val"); // Add a key-value pair
+
+ char *v = NULL;
+ bundle_get_str(b, "foo_key", &v); // v = "bar_val"
+
+ bundle_free(b); // After freeing b, v becomes a dangling pointer
+ v = NULL;
+ * @endcode
+ */
+int bundle_get_str(bundle *b, const char *key, char **str);
+
+
+/**
+ * @brief Gets the byte sequence with the given key.
+ * @since_tizen 2.3
+ * @remarks You must not free @a bytes.
+ * @param[in] b The bundle object
+ * @param[in] key The key
+ * @param[out] bytes The byte sequence
+ * @param[out] size The byte sequence size in bytes
+ * @return The operation result
+ * @retval #BUNDLE_ERROR_NONE Success
+ * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #BUNDLE_ERROR_KEY_NOT_AVAILABLE Key not available
+ * @pre @a b must be a valid bundle object.
+ * @see bundle_add_byte()
+ *
+ * @code
+ #include <bundle.h>
+ bundle *b = bundle_create(); // Create a new bundle object
+ bundle_add_byte(b, "foo", "bar\0", 4); // Add a string to the bundle
+ int number = 12345;
+ bundle_add_byte(b, "number", (const void**)&number, sizeof(int)); // Add an integer to the bundle
+
+ unsigned char *v = NULL;
+ size_t v_size;
+ bundle_get_byte(b, "foo", (void**)&v, &v_size); // v = "bar\0"
+ int *n = NULL;
+ size_t n_size;
+ bundle_get_byte(b, "number", (void**)&n, &n_size); // number = 12345
+
+ bundle_free(b); // After freeing b, v and n become a dangling pointer
+ * @endcode
+ */
+int bundle_get_byte(bundle *b, const char *key, void **bytes, size_t *size);
+
+/**
+ * @brief Adds an 'array of byte sequences' type key-value pair into a bundle.
+ * @since_tizen 5.5
+ * @remarks To set the value of the byte array element, you should use bundle_set_byte_array_element().
+ * This function is only for creating a buffer of the byte array.
+ *
+ * @param[in] b The bundle object
+ * @param[in] key The key
+ * @param[in] len The length of the array to be created
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #BUNDLE_ERROR_NONE Successful
+ * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #BUNDLE_ERROR_KEY_EXISTS Key already exists
+ * @retval #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @see bundle_get_byte_array()
+ * @see bundle_set_byte_array_element()
+ */
+int bundle_add_byte_array(bundle *b, const char *key, const unsigned int len);
+
+/**
+ * @brief Sets an element of an array of byte sequences.
+ * @details The array will contain its own copy of the added value.
+ * @since_tizen 5.5
+ *
+ * @param[in] b The bundle object
+ * @param[in] key The key
+ * @param[in] idx The index of the array element to be changed
+ * @param[in] bytes The byte sequence
+ * @param[in] size The byte sequence size in bytes
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #BUNDLE_ERROR_NONE Successful
+ * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #BUNDLE_ERROR_KEY_NOT_AVAILABLE Key not available
+ * @retval #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #BUNDLE_ERROR_ARRAY_INDEX_OUT_OF_BOUNDS The index is out of bounds of the array
+ *
+ * @see bundle_add_byte_array()
+ * @see bundle_get_byte_array()
+ */
+int bundle_set_byte_array_element(bundle *b, const char *key, const unsigned int idx, const void *bytes, const size_t size);
+
+/**
+ * @brief Gets the array of byte sequences with the given key.
+ * @since_tizen 5.5
+ * @remarks You should not release @a byte_array, @a len and @a array_element_size.
+ * @a byte_array, @a len and @a array_element_size will be released when the bundle containing them is released with bundle_free().
+ *
+ * @param[in] b The bundle object
+ * @param[in] key The key
+ * @param[out] byte_array The array pointer of the byte value
+ * @param[out] len The array length
+ * @param[out] array_element_size An array of sizes of each @a byte_array element
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #BUNDLE_ERROR_NONE Successful
+ * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #BUNDLE_ERROR_KEY_NOT_AVAILABLE Key not available
+ *
+ * @see bundle_add_byte_array()
+ * @see bundle_set_byte_array_element()
+*/
+int bundle_get_byte_array(bundle *b, const char *key, void ***byte_array, unsigned int *len, unsigned int **array_element_size);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}
+ */
+
+#endif /* __BUNDLE_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2019 - 2020 Samsung Electronics Co., Ltd.
+ *
+ * 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 BUNDLE_CPP_H_
+#define BUNDLE_CPP_H_
+
+/**
+ * @file bundle_cpp.h
+ * @brief This file declares API of the bundle C++ library.
+ */
+
+/**
+ * @addtogroup CORE_LIB_BUNDLE_CPP_MODULE
+ * @{
+ */
+
+#include <bundle.h>
+
+#include <cstdio>
+#include <initializer_list>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+namespace tizen_base {
+
+/**
+ * @brief The class for bundle APIs.
+ * @since_tizen 5.5
+ */
+class EXPORT_API Bundle final {
+ public:
+ /**
+ * @brief The type for raw bundle.
+ * @since_tizen 5.5
+ */
+ using BundleRaw =
+ std::pair<std::unique_ptr<bundle_raw, decltype(std::free)*>, int>;
+
+ /**
+ * @brief The class for information of keys.
+ * @since_tizen 5.5
+ */
+ class KeyInfo final {
+ public:
+ /**
+ * @brief Constructor.
+ * @since_tizen 5.5
+ * @param[in] handle The handle for type bundle_keyval_t
+ * @param[in] name The key string
+ * @param[in] own True if this object owns the handle
+ */
+ KeyInfo(const bundle_keyval_t* handle, std::string name, bool own = false);
+
+ /**
+ * @brief Destructor.
+ * @since_tizen 5.5
+ */
+ ~KeyInfo();
+
+ /**
+ * @brief Copy-constructor.
+ * @since_tizen 5.5
+ * @param[in] b The object to copy
+ */
+ KeyInfo(const KeyInfo& b);
+
+ /**
+ * @brief Assignment.
+ * @since_tizen 5.5
+ * @param[in] b The object to copy
+ */
+ KeyInfo& operator = (const KeyInfo& b);
+
+ /**
+ * @brief Move-constructor.
+ * @since_tizen 5.5
+ * @param[in] b The object to move
+ */
+ KeyInfo(KeyInfo&& b) noexcept;
+
+ /**
+ * @brief Assignment.
+ * @since_tizen 5.5
+ * @param[in] b The object to move
+ */
+ KeyInfo& operator = (KeyInfo&& b) noexcept;
+
+ /**
+ * @brief Gets the type of a key-value pair.
+ * @since_tizen 5.5
+ * @return The type
+ */
+ bundle_type GetType() const;
+
+ /**
+ * @brief Determines whether the type of a key-value pair is an array.
+ * @since_tizen 5.5
+ * @return True when it is an array
+ */
+ bool IsArray() const;
+
+ /**
+ * @brief Gets the key string.
+ * @since_tizen 5.5
+ * @return The key string
+ */
+ const std::string& GetName() const;
+
+ private:
+ class Impl;
+ std::unique_ptr<Impl> impl_;
+ };
+
+ /**
+ * @brief Constructor.
+ * @since_tizen 5.5
+ */
+ Bundle();
+
+ /**
+ * @brief Constructor.
+ * @since_tizen 6.5
+ * @param[in] key_values The list of key-value pair
+ */
+ Bundle(std::initializer_list<
+ std::pair<std::string, std::string>> key_values);
+
+ /**
+ * @brief Constructor.
+ * @since_tizen 5.5
+ * @param[in] raw The object for BundleRaw
+ * @param[in] base64 @c true, @a raw is the encoded raw data using base64-encoding
+ */
+ explicit Bundle(BundleRaw raw, bool base64 = true);
+
+ /**
+ * @brief Constructor.
+ * @since_tizen 5.5
+ * @param[in] raw The string object for raw bundle
+ */
+ explicit Bundle(const std::string& raw);
+
+ /**
+ * @brief Constructor.
+ * @since_tizen 5.5
+ * @param[in] b The handle for bundle
+ * @param[in] copy True if this object wants to copy it from the handle
+ * @param[in] own True if this object owns the handle
+ */
+ explicit Bundle(bundle* b, bool copy = true, bool own = true);
+
+ /**
+ * @brief Destructor.
+ * @since_tizen 5.5
+ */
+ ~Bundle();
+
+ /**
+ * @brief Copy-constructor.
+ * @since_tizen 5.5
+ * @param[in] b The object to copy
+ */
+ Bundle(const Bundle& b);
+
+ /**
+ * @brief Assignment.
+ * @since_tizen 5.5
+ * @param[in] b The object to copy
+ */
+ Bundle& operator = (const Bundle& b);
+
+ /**
+ * @brief Move-constructor.
+ * @since_tizen 5.5
+ * @param[in] b The object to move
+ */
+ Bundle(Bundle&& b) noexcept;
+
+ /**
+ * @brief Assignment.
+ * @since_tizen 5.5
+ * @param[in] b The object to move
+ */
+ Bundle& operator = (Bundle&& b) noexcept;
+
+ /**
+ * @brief Check the bundle is empty or not.
+ * @since_tizen 6.0
+ * @return true if the bundle is empty
+ */
+ bool IsEmpty() const noexcept;
+
+ /**
+ * @brief Gets keys in bundle object.
+ * @since_tizen 5.5
+ * @return A string array of object KeyInfo
+ */
+ std::vector<KeyInfo> GetKeys();
+
+ /**
+ * @brief Adds a string type key-value pair into a bundle.
+ * @since_tizen 5.5
+ * @param[in] key The string key
+ * @param[in] val The string value
+ * @return The operation result
+ * @retval BUNDLE_ERROR_NONE Success
+ * @retval BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval BUNDLE_ERROR_KEY_EXISTS Key already exists
+ * @retval BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
+ */
+ int Add(const std::string& key, const std::string& val);
+
+ /**
+ * @brief Adds a string type key-value pair into a bundle.
+ * @since_tizen 5.5
+ * @param[in] key The string key
+ * @param[in] val The array of strings
+ * @return The operation result
+ * @retval BUNDLE_ERROR_NONE Success
+ * @retval BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval BUNDLE_ERROR_KEY_EXISTS Key already exists
+ * @retval BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
+ */
+ int Add(const std::string& key, const std::vector<std::string>& val);
+
+ /**
+ * @brief Adds a string type key-value pair into a bundle.
+ * @since_tizen 5.5
+ * @param[in] key The string key
+ * @param[in] val The array of bytes
+ * @return The operation result
+ * @retval BUNDLE_ERROR_NONE Success
+ * @retval BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval BUNDLE_ERROR_KEY_EXISTS Key already exists
+ * @retval BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
+ */
+ int Add(const std::string& key, const std::vector<unsigned char>& val);
+
+ /**
+ * @brief Deletes a key-value object with the given key.
+ * @since_tizen 5.5
+ * @param[in] key The string key
+ * @return The operation result
+ * @retval BUNDLE_ERROR_NONE Success
+ * @retval BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval BUNDLE_ERROR_KEY_NOT_AVAILABLE Key not available
+ */
+ int Delete(const std::string& key);
+
+ /**
+ * @brief Gets a string from the key.
+ * @since_tizen 5.5
+ * @param[in] key The string key
+ * @return The string
+ */
+ std::string GetString(const std::string& key) const;
+
+ /**
+ * @brief Gets strings from the key.
+ * @since_tizen 5.5
+ * @param[in] key The string key
+ * @return The array of strings
+ */
+ std::vector<std::string> GetStringArray(const std::string& key) const;
+
+ /**
+ * @brief Gets bytes from the key.
+ * @since_tizen 5.5
+ * @param[in] key The string key
+ * @return Bytes
+ */
+ std::vector<unsigned char> GetByte(const std::string& key) const;
+
+ /**
+ * @brief Converts this object to BundleRaw type.
+ * @since_tizen 5.5
+ * @param[in] base64 @c true, the BundleRaw will be encoded using base64-encoding.
+ * @return The object of BundleRaw
+ */
+ BundleRaw ToRaw(bool base64 = true);
+
+ /**
+ * @brief Gets the count of keys.
+ * @since_tizen 5.5
+ * @return The count
+ */
+ int GetCount() const;
+
+ /**
+ * @brief Gets the data type from the key.
+ * @since_tizen 5.5
+ * @param[in] key The string key
+ * @return The data type
+ */
+ bundle_type GetType(const std::string& key) const;
+
+ /**
+ * @brief Gets the handle for bundle APIs.
+ * @since_tizen 5.5
+ * @return The handle for bundle
+ */
+ bundle* GetHandle() const;
+
+ /**
+ * @brief Moves this object into the bundle handle.
+ * @since_tizen 5.5
+ * @return The handle for bundle
+ */
+ bundle* Detach();
+
+ /**
+ * @brief Exports bundle to an argument vector.
+ * @since_tizen 6.5
+ * @return The argument vector
+ */
+ std::vector<std::string> Export() const;
+
+ private:
+ class Impl;
+ std::unique_ptr<Impl> impl_;
+};
+
+} // namespace tizen_base
+
+/**
+ * @}
+ */
+
+#endif // BUNDLE_CPP_H_
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2020 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 __BUNDLE_INTERNAL_H__
+#define __BUNDLE_INTERNAL_H__
+
+/**
+ * @file bundle_internal.h
+ * @brief This file declares has API of the bundle library
+ */
+
+/**
+ * @addtogroup CORE_LIB_BUNDLE_MODULE
+ * @{
+ */
+
+#include <bundle.h>
+
+#ifdef __cplusplus
+extern "C" {
+# endif
+
+/**
+ * @brief Called for every key-value pair.
+ * @since_tizen 2.3
+ * @remarks This type is obsolete. You must not use this type any more.
+ * @see bundle_iterate()
+ */
+typedef void (*bundle_iterate_cb_t) (const char *key, const char *val, void *data);
+
+/**
+ * @brief Adds a string type key-value pair into a given bundle.
+ * @since_tizen 2.3
+ * @param[in] b The bundle object
+ * @param[in] key The key
+ * @param[in] val The value
+ * @return The operation result
+ * @retval #BUNDLE_ERROR_NONE Success
+ * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #BUNDLE_ERROR_KEY_EXISTS Key already exists
+ * @retval #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
+ * @pre @a b must be a valid bundle object.
+ * @see bundle_add_str()
+ @code
+ #include <bundle_internal.h>
+ bundle *b = bundle_create(); // Create new bundle object
+ bundle_add(b, "foo_key", "bar_val"); // add a key-val pair
+
+ bundle_free(b);
+ @endcode
+ */
+int bundle_add(bundle *b, const char *key, const char *val);
+
+/**
+ * @brief Gets a value with a given key.
+ * @since_tizen 2.3
+ * @remarks You MUST NOT free or modify the returned string!
+ * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
+ * @param[in] b The bundle object
+ * @param[in] key The key
+ * @return The pointer for the value string
+ * @retval @c NULL - Key not found
+ * @exception #BUNDLE_ERROR_NONE Success
+ * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @exception #BUNDLE_ERROR_KEY_NOT_AVAILABLE Key not available
+ * @pre @a b must be a valid bundle object.
+ * @see bundle_get_str()
+ @code
+ #include <bundle_internal.h>
+ bundle *b = bundle_create(); // Create new bundle object
+ bundle_add_str(b, "foo", "bar"); //add a key-val pair
+ char *val = bundle_get_val(b, "foo_key"); // val = "bar_val"
+
+ bundle_free(b); // After freeing b, val becomes a dangling pointer.
+ val = NULL;
+ @endcode
+ */
+const char *bundle_get_val(bundle *b, const char *key);
+
+/**
+ * @brief Iterates a callback function for each key-value pairs in a given bundle.
+ * @details (NOTE: Only BUNDLE_TYPE_STR type values come!)
+ * @since_tizen 2.3
+ * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
+ * @remarks This function is obsolete and does not give values whose types are not BUNDLE_TYPE_STR.
+ * @param[in] b The bundle object
+ * @param[in] callback The iteration callback function
+ * @param[in] cb_data The data for callback function
+ * @exception #BUNDLE_ERROR_NONE Success
+ * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre @a b must be a valid bundle object.
+ @code
+ #include <stdio.h>
+ #include <bundle_internal.h>
+ void sample_cb(const char *k, const char *v, void *data) {
+ printf("%s -> %s\n", k, v);
+ }
+
+ int main(void) {
+ bundle *b = bundle_create(); // Create new bundle object
+ bundle_add_str(b, "k1", "v1"); // add a key-val pair
+ bundle_add_str(b, "k2", "v2"); // add a key-val pair
+ bundle_add_str(b, "k3", "v3"); // add a key-val pair
+ bundle_iterate(b, sample_cb, NULL); // iterate sample_cb() for each key/val
+ return 0;
+ }
+ @endcode
+ */
+void bundle_iterate(bundle *b, bundle_iterate_cb_t callback, void *cb_data);
+
+/**
+ * @brief Determines whether the type of a key-value pair is measurable.
+ * @since_tizen 2.3
+ * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
+ * @param[in] kv A bundle_keyval_t object
+ * @return The operation result
+ * @retval @c 1 - @a kv is an measurable
+ * @retval @c 0 - @a kv is not an measurable
+ * @exception #BUNDLE_ERROR_NONE Success
+ * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre @a kv must be a valid bundle_keyval_t object.
+ * @see bundle_foreach()
+ */
+int bundle_keyval_type_is_measurable(bundle_keyval_t *kv);
+
+/**
+ * @brief Duplicates key-value pair.
+ * @since_tizen 5.5
+ * @param[in] kv A bundle_keyval_t object
+ * @return The bundle object
+ * @retval @c NULL - Failure
+ * @pre @a kv must be a valid bundle_keyval_t object.
+ */
+bundle_keyval_t *bundle_keyval_dup(const bundle_keyval_t *kv);
+
+/**
+ * @brief Frees the encoded rawdata.
+ * @since_tizen 2.3
+ * @param[in] r The rawdata
+ * @return The operation result
+ * @retval #BUNDLE_ERROR_NONE Success
+ * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre @a r is a valid rawdata generated by bundle_encode().
+ * @see bundle_encode()
+ */
+int bundle_free_encoded_rawdata(bundle_raw **r);
+
+/**
+ * @brief Encodes a bundle to the bundle_raw format.
+ * @since_tizen 2.3
+ * @param[in] b The bundle object
+ * @param[out] r The returned bundle_raw data(byte data)
+ * @a r MUST BE FREED by free(r)
+ * @param[out] len The size of @a r (in bytes)
+ * @return The size of the raw data
+ * @retval #BUNDLE_ERROR_NONE Success
+ * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
+ * @pre @a b must be a valid bundle object.
+ @code
+ #include <bundle_internal.h>
+ bundle *b = bundle_create(); // Create new bundle object
+ bundle_add_str(b, "foo_key", "bar_val"); // add a key-val pair
+ bundle_raw *r;
+ int len;
+ bundle_encode_raw(b, &r, &len); // encode b
+
+ bundle_free(b);
+ @endcode
+ */
+int bundle_encode_raw(bundle *b, bundle_raw **r, int *len);
+
+/**
+ * @brief Deserializes bundle_raw and gets a bundle object.
+ * @since_tizen 2.3
+ * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
+ * @param[in] r The bundle_raw data to be converted to a bundle object
+ * @param[in] len The size of @a r
+ * @return The bundle object
+ * @retval @c NULL - Failure
+ * @exception #BUNDLE_ERROR_NONE Success
+ * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre @a r must be a valid bundle object.
+ @code
+ #include <bundle_internal.h>
+ bundle *b = bundle_create(); // Create new bundle object
+ bundle_add_str(b, "foo_key", "bar_val"); // add a key-val pair
+
+ bundle_raw *encoded_b;
+ int len;
+ bundle_encode(b, &encoded_b, &len); // encode b
+
+ bundle *b_dup;
+ b_dup = bundle_decode_raw(encoded_b, len); // decoded bundle object
+
+ bundle_free(b);
+ free(encoded_b);
+ bundle_free(b_dup);
+ @endcode
+ */
+bundle *bundle_decode_raw(const bundle_raw *r, const int len);
+
+/**
+ * @brief Exports bundle to @a argv.
+ * @since_tizen 2.3
+ * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
+ * @param[in] b The bundle object
+ * @param[out] argv The pointer of the string array; \n
+ * This array has NULL values for the first and last item; \n
+ * First NULL is for argv[0], and last NULL is a terminator for execv() \n
+ * @return The number of item in @a argv. This value is equal to the actual count of argv - 1. (Last NULL terminator is not counted.)
+ * @retval @c -1 - Failure
+ * @exception #BUNDLE_ERROR_NONE Success
+ * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @exception #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
+ * @pre @a b is a valid bundle object.
+ * @post @a argv is a pointer of newly allocated memory. It must be freed.
+ * @see bundle_import_from_argv()
+ @code
+ #include <bundle_internal.h>
+ bundle *b = bundle_create(); // Create new bundle object
+ bundle_add_str(b, "foo_key", "bar_val"); // add a key-val pair
+
+ int argc = 0;
+ char **argv = NULL;
+ argc = bundle_export_to_argv(b, &argv); // export to argv
+ if(0 > argc) error("export failure");
+
+ int i;
+ for(i=0; i < argc; i++) {
+ printf("%s\n", argv[i]); // print argv
+ }
+ bundle_free_exported_argv(argc, argv); // argv must be freed after being used.
+
+ bundle_free(b);
+ @endcode
+ */
+int bundle_export_to_argv(bundle *b, char ***argv);
+
+/**
+ * @brief Frees the exported @a argv.
+ * @since_tizen 2.3
+ * @remarks You must not use this API when you use global @a argv.
+ * @param[in] argc The number of args, which is the return value of bundle_export_to_argv()
+ * @param[in] argv The array from bundle_export_to_argv()
+ * @return The operation result
+ * @retval #BUNDLE_ERROR_NONE Success
+ * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre @a argv is a valid string array generated from bundle_export_to_argv().
+ * @see bundle_export_to_argv()
+ @code
+ bundle *b = bundle_create();
+ bundle_add_str(b, "foo", "bar");
+
+ int argc = 0;
+ char **argv = NULL;
+ argc = bundle_export_to_argv(b, &argv);
+ if(0 > argc) error("export failure");
+
+ // Use argv...
+
+ bundle_free_exported_argv(argc, argv);
+ argv = NULL;
+
+ bundle_free(b);
+ @endcode
+ */
+int bundle_free_exported_argv(int argc, char ***argv);
+
+/**
+ * @brief Imports a bundle from @a argv.
+ * @since_tizen 2.3
+ * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
+ * @param[in] argc The argument count
+ * @param[in] argv The argument vector
+ * @return The new bundle object
+ * @retval @c NULL - Failure
+ * @exception #BUNDLE_ERROR_NONE Success
+ * @exception #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @exception #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
+ * @pre @a argv is a valid string array, which is created by bundle_export_to_argv().
+ * @post The returned bundle @a b must be freed.
+ * @see bundle_export_to_argv()
+ @code
+ #include <bundle_internal.h>
+
+ int main(int argc, char **argv) {
+ bundle *b = bundle_import_from_argv(argc, argv); // import from argc+argv
+ char *val = bundle_get_val(b, "foo_key"); // value for "foo_key"
+ // ......
+ bundle_free(b); // After freeing b, val becomes a dangling pointer.
+ val = NULL;
+ }
+ @endcode
+ */
+bundle *bundle_import_from_argv(int argc, char **argv);
+
+/**
+ * @brief Sets a value of string array elements.
+ * @since_tizen 2.3
+ * @param[in] b The bundle object
+ * @param[in] key The key
+ * @param[in] idx The index of the array element to be changed
+ * @param[in] val The string type value; if @c NULL, an empty array is created; you can change an item with
+ * @return The operation result
+ * @retval #BUNDLE_ERROR_NONE Success
+ * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre @a b must be a valid bundle object.
+ * @see bundle_add_str_array()
+ * @see bundle_get_str_array()
+ @code
+ #include <bundle_internal.h>
+ bundle *b = bundle_create();
+ bundle_add_str_array(b, "foo", NULL, 3); // add a key-val pair
+ bundle_set_str_array_element(b, "foo", 0, "aaa");
+ bundle_set_str_array_element(b, "foo", 1, "bbb");
+ bundle_set_str_array_element(b, "foo", 2, "ccc");
+
+ char **str_array = NULL;
+ int len_str_array = 0;
+
+ str_array=bundle_get_str_array(b, "foo", &len_str_array);
+ // str_array = { "aaa", "bbb", "ccc" }, and len_str_array = 3
+
+ bundle_free(b);
+ @endcode
+ */
+int bundle_set_str_array_element(bundle *b, const char *key, const unsigned int idx, const char *val);
+
+/**
+ * @brief Creates a JSON data from bundle.
+ * @since_tizen 3.0
+ * @remarks This function only supports the string type and the string array type.
+ * @param[in] b The bundle object
+ * @param[out] json The new created json data
+ * @return The operation result
+ * @retval #BUNDLE_ERROR_NONE Success
+ * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
+ * @pre @a b must be a valid bundle object.
+ @code
+ #include <bundle_internal.h>
+ bundle *b = bundle_create();
+ char *json;
+ int ret;
+
+ bundle_add_str(b, "foo", "bar");
+ ret = bundle_to_json(b, &json);
+ if (ret != BUNDLE_ERROR_NONE) {
+ bundle_free(b);
+ return;
+ }
+ // json = "{"foo":"bar"}"
+ bundle_free(b);
+ free(json);
+ @endcode
+ */
+int bundle_to_json(bundle *b, char **json);
+
+/**
+ * @breif Creates a bundle object from json.
+ * @since_tizen 3.0
+ * @remarks This function only supports the string type and the string array type.
+ * @param[in] json The json data
+ * @param[out] b The bundle object
+ * @return The operation result
+ * @retval #BUNDLE_ERROR_NONE Success
+ * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
+ @code
+ #include <bundle_internal.h>
+ bundle *b;
+ char *json = "{"foo":"bar"}";
+ int ret;
+
+ ret = bundle_from_json(json, &b);
+ if (ret != BUNDLE_ERROR_NONE)
+ return;
+ bundle_free(b);
+ @endcode
+ */
+int bundle_from_json(const char *json, bundle **b);
+
+/**
+ * @breif Compares the bundle 1, 2.
+ * @since_tizen 3.0
+ * @param[in] b1 The bundle object
+ * @param[in] b2 The bundle object
+ * @return The operation result
+ * @retval @c 0 It is identical
+ * @retval @c -1 Invalid parameter
+ * @retval @c 1 It is not identical
+ */
+int bundle_compare(bundle *b1, bundle *b2);
+
+/**
+ * @brief Initializes a byte array type key-value pair into a bundle.
+ * @details To set the value of the byte array element, you should use bundle_set_byte_array_element().
+ * This function is only for creating a buffer of the byte array.
+ * @since_tizen 5.5
+ * @param[in] b The bundle object
+ * @param[in] key The key
+ * @param[in] len The length of the array to be created
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #BUNDLE_ERROR_NONE Successful
+ * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #BUNDLE_ERROR_KEY_EXISTS Key already exists
+ * @retval #BUNDLE_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @see bundle_set_byte_array_element()
+ */
+int bundle_init_byte_array(bundle *b, const char *key, const unsigned int len);
+
+/**
+ * @brief Frees the given key-value pair.
+ * @since_tizen 6.0
+ * @param[in] kv The key-value pair
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #BUNDLE_ERROR_NONE Successful
+ * @retval #BUNDLE_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int bundle_keyval_free(bundle_keyval_t *kv);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}
+ * @}
+ */
+
+#endif /* __BUNDLE__INTERNAL_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2020 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 "exception-internal.h"
+#include "json-internal.h"
+
+namespace tizen_base {
+namespace internal {
+
+Json::Json(std::string json) : json_(std::move(json)) {
+}
+
+Json::Json(Bundle* b) : b_(b) {
+}
+
+Bundle* Json::ToBundle() {
+ if (json_.empty())
+ return nullptr;
+
+ JsonParser* parser = json_parser_new();
+ if (parser == nullptr)
+ THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
+
+ std::unique_ptr<JsonParser, decltype(g_object_unref)*> parser_ptr(parser,
+ g_object_unref);
+
+ GError* error = nullptr;
+ json_parser_load_from_data(parser, json_.c_str(), json_.length(), &error);
+ if (error) {
+ g_error_free(error);
+ THROW(BUNDLE_ERROR_INVALID_PARAMETER);
+ }
+
+ JsonNode* root = json_parser_get_root(parser);
+ if (root == nullptr)
+ THROW(BUNDLE_ERROR_INVALID_PARAMETER);
+
+ JsonObject* root_obj = json_node_get_object(root);
+ if (root_obj == nullptr)
+ THROW(BUNDLE_ERROR_INVALID_PARAMETER);
+
+ Bundle* b = new (std::nothrow) Bundle();
+ if (b == nullptr)
+ THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
+
+ json_object_foreach_member(root_obj, OnJsonObjectMember, b);
+
+ return b;
+}
+
+std::string Json::ToString() {
+ if (b_ == nullptr)
+ THROW(BUNDLE_ERROR_INVALID_PARAMETER);
+
+ JsonObject* object = json_object_new();
+ if (object == nullptr)
+ THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
+
+ std::unique_ptr<JsonObject, decltype(json_object_unref)*> object_ptr(object,
+ json_object_unref);
+
+ for (const auto& kv : b_->GetMap()) {
+ auto& key_info = kv.second;
+ if (key_info->GetType() == Bundle::Type::StringArray) {
+ JsonArray* json_arr = json_array_new();
+ if (json_arr == nullptr)
+ THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
+
+ for (const auto& v : key_info->GetValues()) {
+ json_array_add_string_element(json_arr,
+ const_cast<const char*>(reinterpret_cast<char*>(v.get())));
+ }
+
+ json_object_set_array_member(object, key_info->GetKey().c_str(),
+ json_arr);
+ } else {
+ json_object_set_string_member(object, key_info->GetKey().c_str(),
+ const_cast<const char*>(
+ reinterpret_cast<char*>(
+ key_info->GetValues()[0].get())));
+ }
+ }
+
+ JsonNode* node = json_node_new(JSON_NODE_OBJECT);
+ if (node == nullptr)
+ THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
+
+ std::unique_ptr<JsonNode, decltype(json_node_free)*> node_ptr(node,
+ json_node_free);
+
+ json_node_set_object(node, object);
+
+ JsonGenerator* generator = json_generator_new();
+ if (generator == nullptr)
+ THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
+
+ std::unique_ptr<JsonGenerator, decltype(g_object_unref)*> generator_ptr(
+ generator, g_object_unref);
+
+ json_generator_set_root(generator, node);
+ gsize length = 0;
+ gchar* json = json_generator_to_data(generator, &length);
+ if (json == nullptr)
+ THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
+
+ std::unique_ptr<gchar, decltype(g_free)*> json_auto(json, g_free);
+ json_ = json;
+ return json_;
+}
+
+void Json::OnJsonObjectMember(JsonObject* object, const char* key,
+ JsonNode* node, gpointer user_data) {
+ auto* b = static_cast<Bundle*>(user_data);
+ KeyInfo* key_info;
+ JsonNodeType node_type = JSON_NODE_TYPE(node);
+ if (node_type == JSON_NODE_ARRAY) {
+ JsonArray* json_arr = json_node_get_array(node);
+ if (json_arr == nullptr)
+ return;
+
+ std::vector<std::vector<unsigned char>> values;
+ guint len = json_array_get_length(json_arr);
+ for (guint i = 0; i < len; ++i) {
+ auto* val = json_array_get_string_element(json_arr, i);
+ if (val == nullptr)
+ val = "";
+
+ auto* p = reinterpret_cast<unsigned char*>(const_cast<char*>(val));
+ std::vector<unsigned char> value(p, p + (strlen(val) + 1));
+ values.push_back(std::move(value));
+ }
+
+ try {
+ key_info = new KeyInfo(Bundle::Type::StringArray, key, std::move(values));
+ } catch (const Exception& e) {
+ _E("Error(%d)", e.GetErrorCode());
+ return;
+ } catch (const std::bad_alloc& ba) {
+ _E("bad alloc exception");
+ return;
+ }
+ } else {
+ auto* val = json_node_get_string(node);
+ if (val == nullptr)
+ val = "";
+
+ auto* p = reinterpret_cast<unsigned char*>(const_cast<char*>(val));
+ std::vector<unsigned char> value(p, p + (strlen(val) + 1));
+
+ try {
+ key_info = new KeyInfo(Bundle::Type::String, key, std::move(value));
+ } catch (const Exception& e) {
+ _E("Error(%d)", e.GetErrorCode());
+ return;
+ } catch (const std::bad_alloc& ba) {
+ _E("bad alloc exception");
+ return;
+ }
+ }
+
+ try {
+ b->Add(std::shared_ptr<KeyInfo>(key_info));
+ } catch (const Exception& e) {
+ _W("Add() is failed. error(%d)", e.GetErrorCode());
+ return;
+ }
+}
+
+} // namespace internal
+} // namespace tizen_base
--- /dev/null
+/*
+ * Copyright (c) 2020 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 JSON_INTERNAL_H_
+#define JSON_INTERNAL_H_
+
+#include <glib.h>
+#include <json-glib/json-glib.h>
+
+#include <memory>
+#include <string>
+
+#include "bundle-internal.h"
+
+namespace tizen_base {
+namespace internal {
+
+class Json {
+ public:
+ explicit Json(std::string json);
+ explicit Json(Bundle* b);
+ virtual ~Json() = default;
+
+ Bundle* ToBundle();
+ std::string ToString();
+
+ private:
+ static void OnJsonObjectMember(JsonObject* object, const char* key,
+ JsonNode* node, gpointer user_data);
+
+ private:
+ Bundle* b_ = nullptr;
+ std::string json_;
+};
+
+} // namespace internal
+} // namespace tizen_base
+
+#endif // JSON_INTERNAL_H_
--- /dev/null
+/*
+ * Copyright (c) 2020 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 <algorithm>
+#include <cstring>
+#include <utility>
+
+#include "include/bundle.h"
+
+#include "exception-internal.h"
+#include "key-info-internal.h"
+
+namespace tizen_base {
+namespace internal {
+
+KeyInfo::KeyInfo(int type, std::string key, std::vector<unsigned char> value)
+ : type_(type), key_(std::move(key)) {
+ int ret = SetValue(value);
+ if (ret != BUNDLE_ERROR_NONE)
+ THROW(ret);
+}
+
+KeyInfo::KeyInfo(int type, std::string key,
+ std::vector<std::vector<unsigned char>> values)
+ : type_(type), key_(std::move(key)) {
+ int ret = SetValues(values);
+ if (ret != BUNDLE_ERROR_NONE)
+ THROW(ret);
+}
+
+KeyInfo::KeyInfo(std::vector<unsigned char> encoded_bytes) {
+ int ret = Decode(encoded_bytes);
+ if (ret != BUNDLE_ERROR_NONE)
+ THROW(ret);
+}
+
+KeyInfo::KeyInfo(const KeyInfo& key_info) {
+ values_.reserve(key_info.values_.size());
+ try {
+ for (unsigned int i = 0; i < key_info.values_.size(); ++i) {
+ auto new_value =
+ std::make_unique<unsigned char[]>(key_info.values_size_[i]);
+ std::copy(key_info.values_[i].get(),
+ key_info.values_[i].get() + key_info.values_size_[i],
+ new_value.get());
+ values_.push_back(std::move(new_value));
+ }
+ } catch (const std::bad_alloc& e) {
+ THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
+ }
+
+ type_ = key_info.type_;
+ key_ = key_info.key_;
+ values_size_ = key_info.values_size_;
+ uvalues_size_ = key_info.uvalues_size_;
+}
+
+KeyInfo& KeyInfo::operator=(const KeyInfo& key_info) {
+ if (this != &key_info) {
+ decltype(values_) new_values;
+ try {
+ for (unsigned int i = 0; i < key_info.values_.size(); ++i) {
+ auto new_value =
+ std::make_unique<unsigned char[]>(key_info.values_size_[i]);
+ std::copy(key_info.values_[i].get(),
+ key_info.values_[i].get() + key_info.values_size_[i],
+ new_value.get());
+ new_values.push_back(std::move(new_value));
+ }
+ } catch (const std::bad_alloc& e) {
+ THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
+ }
+
+ type_ = key_info.type_;
+ key_ = key_info.key_;
+ values_size_ = key_info.values_size_;
+ uvalues_size_ = key_info.uvalues_size_;
+ values_ = std::move(new_values);
+ }
+
+ return *this;
+}
+
+KeyInfo::KeyInfo(KeyInfo&& key_info) noexcept {
+ type_ = key_info.type_;
+ key_info.type_ = 0;
+ key_ = std::move(key_info.key_);
+ values_ = std::move(key_info.values_);
+ values_size_ = std::move(key_info.values_size_);
+ uvalues_size_ = std::move(key_info.uvalues_size_);
+}
+
+KeyInfo& KeyInfo::operator=(KeyInfo&& key_info) noexcept {
+ if (this != &key_info) {
+ type_ = key_info.type_;
+ key_info.type_ = 0;
+ key_ = std::move(key_info.key_);
+ values_ = std::move(key_info.values_);
+ values_size_ = std::move(key_info.values_size_);
+ uvalues_size_ = std::move(key_info.uvalues_size_);
+ }
+ return *this;
+}
+
+bool KeyInfo::operator==(const KeyInfo& key_info) {
+ if (this == &key_info)
+ return true;
+
+ if (type_ != key_info.type_)
+ return false;
+
+ if (key_ != key_info.key_)
+ return false;
+
+ if (values_.size() != key_info.values_.size())
+ return false;
+
+ for (unsigned int i = 0; i < values_.size(); ++i) {
+ if (values_size_[i] != key_info.values_size_[i])
+ return false;
+
+ int ret = std::memcmp(values_[i].get(), key_info.values_[i].get(),
+ values_size_[i]);
+ if (ret != 0)
+ return false;
+ }
+
+ return true;
+}
+
+int KeyInfo::GetType() const {
+ return type_;
+}
+
+bool KeyInfo::IsArray() const {
+ if (type_ & BUNDLE_TYPE_ARRAY)
+ return true;
+
+ return false;
+}
+
+const std::string& KeyInfo::GetKey() {
+ return key_;
+}
+
+const std::vector<std::unique_ptr<unsigned char[]>>& KeyInfo::GetValues() {
+ return values_;
+}
+
+const std::vector<std::size_t>& KeyInfo::GetValuesSize() {
+ return values_size_;
+}
+
+const std::vector<unsigned int>& KeyInfo::GetUValuesSize() {
+ return uvalues_size_;
+}
+
+int KeyInfo::SetValue(const std::vector<unsigned char>& value) {
+ try {
+ auto new_value = std::make_unique<unsigned char[]>(value.size());
+ std::copy(value.begin(), value.end(), new_value.get());
+ values_.emplace_back(std::move(new_value));
+ } catch (const std::bad_alloc& e) {
+ return BUNDLE_ERROR_OUT_OF_MEMORY;
+ }
+
+ values_size_.push_back(value.size());
+ uvalues_size_.push_back(static_cast<unsigned int>(value.size()));
+ return BUNDLE_ERROR_NONE;
+}
+
+int KeyInfo::SetValues(const std::vector<std::vector<unsigned char>>& values) {
+ try {
+ for (unsigned int i = 0; i < values.size(); ++i) {
+ auto new_value = std::make_unique<unsigned char[]>(values[i].size());
+ std::copy(values[i].begin(), values[i].end(), new_value.get());
+ values_.push_back(std::move(new_value));
+ values_size_.push_back(values[i].size());
+ uvalues_size_.push_back(values[i].size());
+ }
+ } catch (const std::bad_alloc& e) {
+ return BUNDLE_ERROR_OUT_OF_MEMORY;
+ }
+
+ return BUNDLE_ERROR_NONE;
+}
+
+std::vector<unsigned char> KeyInfo::Encode() {
+ std::size_t encoded_size = GetEncodedSize();
+ if (encoded_size == 0)
+ return {};
+
+ std::vector<unsigned char> bytes;
+
+ // total size
+ unsigned char* p = reinterpret_cast<unsigned char*>(&encoded_size);
+ bytes.insert(bytes.end(), p, p + sizeof(encoded_size));
+
+ // type
+ p = reinterpret_cast<unsigned char*>(&type_);
+ bytes.insert(bytes.end(), p, p + sizeof(type_));
+
+ // key size
+ std::size_t key_length = key_.length() + 1;
+ p = reinterpret_cast<unsigned char*>(&key_length);
+ bytes.insert(bytes.end(), p, p + sizeof(key_length));
+
+ // key
+ bytes.insert(bytes.end(), key_.begin(), key_.end() + 1);
+
+ if (type_ & BUNDLE_TYPE_ARRAY) {
+ // values size
+ std::size_t values_size = values_.size();
+ p = reinterpret_cast<unsigned char*>(&values_size);
+ bytes.insert(bytes.end(), p, p + sizeof(values_size));
+ }
+
+ // values
+ for (unsigned int i = 0; i < values_.size(); i++) {
+ std::size_t value_size = values_size_[i];
+ p = reinterpret_cast<unsigned char*>(&value_size);
+ bytes.insert(bytes.end(), p, p + sizeof(value_size));
+
+ bytes.insert(bytes.end(), values_[i].get(), values_[i].get() + value_size);
+ }
+
+ return bytes;
+}
+
+std::size_t KeyInfo::GetEncodedSize() {
+ // total size
+ std::size_t encoded_size = sizeof(std::size_t);
+
+ // type
+ encoded_size += sizeof(int);
+
+ // key size
+ encoded_size += sizeof(std::size_t);
+
+ // key
+ if ((encoded_size + key_.length() + 1) < encoded_size)
+ return 0;
+
+ encoded_size += key_.length() + 1;
+
+ if (type_ & BUNDLE_TYPE_ARRAY) {
+ // values size
+ if ((encoded_size + sizeof(std::size_t)) < encoded_size)
+ return 0;
+
+ encoded_size += sizeof(std::size_t);
+ }
+
+ // values
+ std::size_t values_size = 0;
+ for (unsigned int i = 0; i < values_.size(); ++i) {
+ // value size
+ if ((values_size + sizeof(std::size_t)) < values_size)
+ return 0;
+
+ values_size += sizeof(std::size_t);
+
+ // value
+ if ((values_size + values_size_[i]) < values_size)
+ return 0;
+
+ values_size += values_size_[i];
+ }
+
+ if ((encoded_size + values_size) < encoded_size)
+ return 0;
+
+ encoded_size += values_size;
+
+ return encoded_size;
+}
+
+int KeyInfo::Decode(const std::vector<unsigned char>& bytes) {
+ unsigned int reader = 0;
+
+ // total size
+ std::size_t total_size = 0;
+ if ((reader + sizeof(total_size)) > bytes.size())
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ unsigned char* p = reinterpret_cast<unsigned char*>(&total_size);
+ std::copy(&bytes[reader], &bytes[reader] + sizeof(total_size), p);
+ reader += sizeof(total_size);
+
+ // type
+ if ((reader + sizeof(type_)) > bytes.size())
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ p = reinterpret_cast<unsigned char*>(&type_);
+ std::copy(&bytes[reader], &bytes[reader] + sizeof(type_), p);
+ reader += sizeof(type_);
+
+ // key size
+ std::size_t key_size = 0;
+
+ if ((reader + sizeof(key_size)) > bytes.size())
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ p = reinterpret_cast<unsigned char*>(&key_size);
+ std::copy(&bytes[reader], &bytes[reader] + sizeof(key_size), p);
+ reader += sizeof(key_size);
+
+ if ((reader + key_size) > bytes.size())
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ // key
+ std::vector<unsigned char> key(&bytes[reader], &bytes[reader] + key_size);
+ p = reinterpret_cast<unsigned char*>(&key[0]);
+ key_ = std::string(reinterpret_cast<char*>(p));
+ reader += key_size;
+
+ std::size_t values_size = 0;
+ if (type_ & BUNDLE_TYPE_ARRAY) {
+ // values size
+ if ((reader + sizeof(values_size)) > bytes.size())
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ p = reinterpret_cast<unsigned char*>(&values_size);
+ std::copy(&bytes[reader], &bytes[reader] + sizeof(values_size), p);
+ reader += sizeof(values_size);
+ } else {
+ values_size = 1;
+ }
+
+ // values
+ for (std::size_t i = 0; i < values_size; ++i) {
+ // value_size
+ std::size_t value_size = 0;
+ if ((reader + sizeof(value_size)) > bytes.size())
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ p = reinterpret_cast<unsigned char*>(&value_size);
+ std::copy(&bytes[reader], &bytes[reader] + sizeof(value_size), p);
+ reader += sizeof(value_size);
+
+ // value
+ if ((reader + value_size) > bytes.size())
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ try {
+ auto new_value = std::make_unique<unsigned char[]>(value_size);
+ std::copy(&bytes[reader], &bytes[reader] + value_size, new_value.get());
+ reader += value_size;
+ values_.push_back(std::move(new_value));
+ } catch (const std::bad_alloc& e) {
+ return BUNDLE_ERROR_OUT_OF_MEMORY;
+ }
+ values_size_.push_back(value_size);
+ uvalues_size_.push_back(static_cast<unsigned int>(value_size));
+ }
+
+ return BUNDLE_ERROR_NONE;
+}
+
+int KeyInfo::SetValue(int index, const std::vector<unsigned char>& value) {
+ if (index > GetSize() || index < 0)
+ return BUNDLE_ERROR_ARRAY_INDEX_OUT_OF_BOUNDS;
+
+ if (!IsArray())
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ try {
+ auto new_value = std::make_unique<unsigned char[]>(value.size());
+ if (value.size() != 0)
+ std::copy(value.begin(), value.end(), new_value.get());
+
+ values_[index] = std::move(new_value);
+ } catch (const std::bad_alloc& e) {
+ return BUNDLE_ERROR_OUT_OF_MEMORY;
+ }
+
+ values_size_[index] = value.size();
+ uvalues_size_[index] = static_cast<unsigned int>(value.size());
+ return BUNDLE_ERROR_NONE;
+}
+
+int KeyInfo::GetSize() const {
+ return values_.size();
+}
+
+} // namespace internal
+} // namespace tizen_base
--- /dev/null
+/*
+ * Copyright (c) 2020 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 KEY_INFO_INTERNAL_H_
+#define KEY_INFO_INTERNAL_H_
+
+#include <string>
+#include <vector>
+#include <memory>
+
+namespace tizen_base {
+namespace internal {
+
+class KeyInfo {
+ public:
+ KeyInfo(int type, std::string key,
+ std::vector<unsigned char> value);
+ KeyInfo(int type, std::string key,
+ std::vector<std::vector<unsigned char>> values);
+ explicit KeyInfo(std::vector<unsigned char> encoded_bytes);
+ virtual ~KeyInfo() = default;
+
+ KeyInfo(const KeyInfo& key_info);
+ KeyInfo& operator = (const KeyInfo& key_info);
+ KeyInfo(KeyInfo&& key_info) noexcept;
+ KeyInfo& operator = (KeyInfo&& key_info) noexcept;
+
+ bool operator == (const KeyInfo& key_info);
+
+ int GetType() const;
+ bool IsArray() const;
+ const std::string& GetKey();
+ const std::vector<std::unique_ptr<unsigned char[]>>& GetValues();
+ const std::vector<std::size_t>& GetValuesSize();
+ const std::vector<unsigned int>& GetUValuesSize();
+ std::vector<unsigned char> Encode();
+
+ int SetValue(int index, const std::vector<unsigned char>& value);
+ int GetSize() const;
+
+ private:
+ std::size_t GetEncodedSize();
+ int SetValuesSize();
+ int SetValue(const std::vector<unsigned char>& value);
+ int SetValues(const std::vector<std::vector<unsigned char>>& values);
+ int Decode(const std::vector<unsigned char>& bytes);
+
+ private:
+ int type_;
+ std::string key_;
+ std::vector<std::unique_ptr<unsigned char[]>> values_;
+ std::vector<std::size_t> values_size_;
+ std::vector<unsigned int> uvalues_size_;
+};
+
+} // namespace internal
+} // namespace tizen_base
+
+#endif // KEY_INFO_INTERNAL_H_
--- /dev/null
+/*
+ * Copyright (c) 2020 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 LOG_PRIVATE_H_
+#define LOG_PRIVATE_H_
+
+#include <dlog.h>
+
+#undef LOG_TAG
+#define LOG_TAG "BUNDLE"
+
+#undef _E
+#define _E LOGE
+
+#undef _W
+#define _W LOGW
+
+#undef _I
+#define _I LOGI
+
+#undef _D
+#define _D LOGD
+
+#endif // LOG_PRIVATE_H_
--- /dev/null
+/*
+ * Copyright (c) 2020 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 <tizen.h>
+#include <glib.h>
+
+#include <stdexcept>
+
+#include "include/bundle.h"
+#include "include/bundle_internal.h"
+
+#include "bundle-internal.h"
+#include "exception-internal.h"
+#include "export-api-internal.h"
+#include "json-internal.h"
+
+using namespace tizen_base::internal;
+
+extern "C" EXPORT_API bundle* bundle_create(void) {
+ auto* h = new (std::nothrow) Bundle();
+ if (h == nullptr) {
+ set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
+ return nullptr;
+ }
+
+ set_last_result(BUNDLE_ERROR_NONE);
+ return reinterpret_cast<bundle*>(h);
+}
+
+extern "C" EXPORT_API int bundle_free(bundle* b) {
+ if (b == nullptr)
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ auto* h = reinterpret_cast<Bundle*>(b);
+ delete h;
+ return BUNDLE_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int bundle_add_str(bundle* b,
+ const char* key, const char* str) {
+ if (b == nullptr || key == nullptr || strlen(key) == 0 || str == nullptr)
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ auto* h = reinterpret_cast<Bundle*>(b);
+ std::vector<unsigned char> value(str, str + (strlen(str) + 1));
+
+ KeyInfo* key_info;
+ try {
+ key_info = new KeyInfo(BUNDLE_TYPE_STR, key, std::move(value));
+ } catch (const Exception& e) {
+ return e.GetErrorCode();
+ } catch (const std::bad_alloc& ba) {
+ return BUNDLE_ERROR_OUT_OF_MEMORY;
+ }
+
+ try {
+ h->Add(std::shared_ptr<KeyInfo>(key_info));
+ } catch (const Exception& e) {
+ return e.GetErrorCode();
+ }
+
+ return BUNDLE_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int bundle_get_str(bundle* b,
+ const char* key, char** str) {
+ if (b == nullptr || key == nullptr)
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ auto* h = reinterpret_cast<Bundle*>(b);
+ std::shared_ptr<KeyInfo> key_info;
+ try {
+ key_info = h->Get(key);
+ } catch (const Exception& e) {
+ return e.GetErrorCode();
+ }
+
+ if (key_info->GetType() != BUNDLE_TYPE_STR)
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ if (str) {
+ auto& values = key_info->GetValues();
+ auto& value = const_cast<std::unique_ptr<unsigned char[]>&>(values[0]);
+ *str = reinterpret_cast<char*>(&value[0]);
+ }
+
+ return BUNDLE_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int bundle_add(bundle* b, const char* key,
+ const char* val) {
+ return bundle_add_str(b, key, val);
+}
+
+extern "C" EXPORT_API int bundle_del(bundle* b, const char* key) {
+ if (b == nullptr || key == nullptr || strlen(key) == 0)
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ auto* h = reinterpret_cast<Bundle*>(b);
+ try {
+ h->Remove(key);
+ } catch (const Exception& e) {
+ return e.GetErrorCode();
+ }
+
+ return BUNDLE_ERROR_NONE;
+}
+
+extern "C" EXPORT_API const char* bundle_get_val(bundle* b, const char* key) {
+ char* val = nullptr;
+ int ret = bundle_get_str(b, key, &val);
+ set_last_result(ret);
+ return val;
+}
+
+extern "C" EXPORT_API int bundle_get_count(bundle* b) {
+ if (b == nullptr)
+ return 0;
+
+ auto* h = reinterpret_cast<Bundle*>(b);
+ set_last_result(BUNDLE_ERROR_NONE);
+ return h->GetSize();
+}
+
+extern "C" EXPORT_API void bundle_iterate(bundle* b,
+ bundle_iterate_cb_t callback, void* user_data) {
+ if (b == nullptr || callback == nullptr) {
+ set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ auto* h = reinterpret_cast<Bundle*>(b);
+ for (const auto& [key, key_info] : h->GetMap()) {
+ auto& values = key_info->GetValues();
+ auto& value = const_cast<std::unique_ptr<unsigned char[]>&>(values[0]);
+ auto* val = reinterpret_cast<char*>(&value[0]);
+ callback(key_info->GetKey().c_str(), val, user_data);
+ }
+
+ set_last_result(BUNDLE_ERROR_NONE);
+}
+
+extern "C" EXPORT_API void bundle_foreach(bundle* b,
+ bundle_iterator_t callback, void* user_data) {
+ if (b == nullptr || callback == nullptr) {
+ set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ auto* h = reinterpret_cast<Bundle*>(b);
+ auto it = h->GetMap().begin();
+ while (it != h->GetMap().end()) {
+ auto& key_info = it->second;
+ ++it;
+ callback(key_info->GetKey().c_str(), key_info->GetType(),
+ reinterpret_cast<bundle_keyval_t*>(key_info.get()), user_data);
+ }
+
+ set_last_result(BUNDLE_ERROR_NONE);
+}
+
+extern "C" EXPORT_API int bundle_keyval_get_type(bundle_keyval_t* kv) {
+ if (kv == nullptr) {
+ set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
+ return -1;
+ }
+
+ auto* key_info = reinterpret_cast<KeyInfo*>(kv);
+ set_last_result(BUNDLE_ERROR_NONE);
+ return key_info->GetType();
+}
+
+extern "C" EXPORT_API int bundle_keyval_type_is_array(bundle_keyval_t* kv) {
+ int type = bundle_keyval_get_type(kv);
+ if (type == -1)
+ return -1;
+
+ set_last_result(BUNDLE_ERROR_NONE);
+ if (type & BUNDLE_TYPE_ARRAY)
+ return 1;
+
+ return 0;
+}
+
+extern "C" EXPORT_API int bundle_keyval_type_is_measurable(
+ bundle_keyval_t* kv) {
+ int type = bundle_keyval_get_type(kv);
+ if (type == -1)
+ return -1;
+
+ set_last_result(BUNDLE_ERROR_NONE);
+ if (type & BUNDLE_TYPE_MEASURABLE)
+ return 1;
+
+ return 0;
+}
+
+extern "C" EXPORT_API int bundle_keyval_get_basic_val(bundle_keyval_t* kv,
+ void** val, size_t* size) {
+ if (kv == nullptr)
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ auto* key_info = reinterpret_cast<KeyInfo*>(kv);
+ if (key_info->IsArray())
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ if (val) {
+ auto& values = key_info->GetValues();
+ auto& value = const_cast<std::unique_ptr<unsigned char[]>&>(values[0]);
+ *val = reinterpret_cast<void*>(&value[0]);
+ }
+
+ if (size) {
+ auto& values_size = key_info->GetValuesSize();
+ *size = reinterpret_cast<size_t>(values_size[0]);
+ }
+
+ return BUNDLE_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int bundle_keyval_get_array_val(bundle_keyval_t* kv,
+ void*** array_val, unsigned int* array_len, size_t** array_item_size) {
+ if (kv == nullptr)
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ auto* key_info = reinterpret_cast<KeyInfo*>(kv);
+ if (!key_info->IsArray())
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ auto& values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
+ key_info->GetValues());
+
+ if (array_val)
+ *array_val = reinterpret_cast<void**>(&values[0]);
+
+ if (array_len)
+ *array_len = static_cast<unsigned int>(values.size());
+
+ if (array_item_size) {
+ auto& values_size = const_cast<std::vector<std::size_t>&>(
+ key_info->GetValuesSize());
+ *array_item_size = reinterpret_cast<size_t*>(&values_size[0]);
+ }
+
+ return BUNDLE_ERROR_NONE;
+}
+
+extern "C" EXPORT_API bundle_keyval_t* bundle_keyval_dup(
+ const bundle_keyval_t* kv) {
+ if (kv == nullptr) {
+ set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
+ return nullptr;
+ }
+
+ auto* keyval = const_cast<bundle_keyval_t*>(kv);
+ auto* key_info = reinterpret_cast<KeyInfo*>(keyval);
+
+ KeyInfo* k;
+ try {
+ k = new KeyInfo(*key_info);
+ } catch (const Exception& e) {
+ set_last_result(e.GetErrorCode());
+ return nullptr;
+ } catch (const std::bad_alloc& ba) {
+ set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
+ return nullptr;
+ }
+
+ set_last_result(BUNDLE_ERROR_NONE);
+ return reinterpret_cast<bundle_keyval_t*>(k);
+}
+
+extern "C" EXPORT_API int bundle_keyval_free(bundle_keyval_t* kv) {
+ if (kv == nullptr)
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ auto* key_info = reinterpret_cast<KeyInfo*>(kv);
+ delete key_info;
+ return BUNDLE_ERROR_NONE;
+}
+
+extern "C" EXPORT_API bundle* bundle_dup(bundle* b_from) {
+ if (b_from == nullptr) {
+ set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
+ return nullptr;
+ }
+
+ Bundle* b;
+ try {
+ auto* h = reinterpret_cast<Bundle*>(b_from);
+ b = new Bundle(*h);
+ } catch (const Exception& e) {
+ set_last_result(e.GetErrorCode());
+ return nullptr;
+ } catch (const std::bad_alloc& e) {
+ set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
+ return nullptr;
+ }
+
+ set_last_result(BUNDLE_ERROR_NONE);
+ return reinterpret_cast<bundle*>(b);
+}
+
+extern "C" EXPORT_API int bundle_encode(bundle *b, bundle_raw** raw, int* len) {
+ if (b == nullptr || raw == nullptr || len == nullptr)
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ auto* h = reinterpret_cast<Bundle*>(b);
+ try {
+ *raw = reinterpret_cast<bundle_raw*>(h->Encode());
+ } catch (const Exception& e) {
+ *raw = nullptr;
+ return e.GetErrorCode();
+ }
+
+ *len = strlen(reinterpret_cast<char*>(*raw));
+ return BUNDLE_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int bundle_free_encoded_rawdata(bundle_raw **r) {
+ if (r == nullptr || *r == nullptr)
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ free(*r);
+ *r = nullptr;
+ return BUNDLE_ERROR_NONE;
+}
+
+extern "C" EXPORT_API bundle* bundle_decode(const bundle_raw* r,
+ const int data_size) {
+ if (r == nullptr) {
+ set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
+ return nullptr;
+ }
+
+ Bundle* b = nullptr;
+ try {
+ auto* raw = const_cast<bundle_raw*>(r);
+ b = new Bundle(static_cast<unsigned char*>(raw), data_size);
+ } catch (const Exception& e) {
+ set_last_result(e.GetErrorCode());
+ return nullptr;
+ } catch (const std::bad_alloc& ba) {
+ set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
+ return nullptr;
+ }
+
+ set_last_result(BUNDLE_ERROR_NONE);
+ return reinterpret_cast<bundle*>(b);
+}
+
+extern "C" EXPORT_API int bundle_encode_raw(bundle* b, bundle_raw** r,
+ int* len) {
+ if (b == nullptr || r == nullptr || len == nullptr)
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ auto* h = reinterpret_cast<Bundle*>(b);
+ try {
+ *r = reinterpret_cast<bundle_raw*>(h->EncodeRaw(len));
+ } catch (const Exception& e) {
+ return e.GetErrorCode();
+ }
+ return BUNDLE_ERROR_NONE;
+}
+
+extern "C" EXPORT_API bundle* bundle_decode_raw(const bundle_raw* r,
+ const int data_size) {
+ if (r == nullptr) {
+ set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
+ return nullptr;
+ }
+
+ Bundle* b = nullptr;
+ try {
+ auto* raw = const_cast<bundle_raw*>(r);
+ b = new Bundle(static_cast<unsigned char*>(raw), data_size, false);
+ } catch (const Exception& e) {
+ set_last_result(e.GetErrorCode());
+ return nullptr;
+ } catch (const std::bad_alloc& ba) {
+ set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
+ return nullptr;
+ }
+
+ set_last_result(BUNDLE_ERROR_NONE);
+ return reinterpret_cast<bundle*>(b);
+}
+
+extern "C" EXPORT_API int bundle_get_type(bundle* b, const char* key) {
+ if (b == nullptr || key == nullptr) {
+ set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
+ return BUNDLE_TYPE_NONE;
+ }
+
+ auto* h = reinterpret_cast<Bundle*>(b);
+ std::shared_ptr<KeyInfo> key_info;
+ try {
+ key_info = h->Get(key);
+ } catch (const Exception& e) {
+ set_last_result(e.GetErrorCode());
+ return BUNDLE_TYPE_NONE;
+ }
+
+ set_last_result(BUNDLE_ERROR_NONE);
+ return key_info->GetType();
+}
+
+extern "C" EXPORT_API int bundle_add_str_array(bundle* b, const char* key,
+ const char** str_array, const int len) {
+ if (b == nullptr || key == nullptr || strlen(key) == 0)
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ auto* h = reinterpret_cast<Bundle*>(b);
+ std::vector<std::vector<unsigned char>> values(len);
+ if (str_array) {
+ for (int i = 0; i < len; ++i) {
+ std::vector<unsigned char> value(str_array[i],
+ str_array[i] + (strlen(str_array[i]) + 1));
+ values[i] = std::move(value);
+ }
+ }
+
+ try {
+ auto key_info = std::make_shared<KeyInfo>(
+ (BUNDLE_TYPE_STR_ARRAY | BUNDLE_TYPE_ARRAY), key, values);
+ h->Add(std::move(key_info));
+ } catch (const Exception& e) {
+ return e.GetErrorCode();
+ } catch (const std::bad_alloc& ba) {
+ return BUNDLE_ERROR_OUT_OF_MEMORY;
+ }
+
+ return BUNDLE_ERROR_NONE;
+}
+
+extern "C" EXPORT_API const char** bundle_get_str_array(bundle* b,
+ const char* key, int* len) {
+ if (b == nullptr || key == nullptr) {
+ set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
+ return nullptr;
+ }
+
+ auto* h = reinterpret_cast<Bundle*>(b);
+ std::shared_ptr<KeyInfo> key_info;
+ try {
+ key_info = h->Get(key);
+ } catch (const Exception& e) {
+ set_last_result(e.GetErrorCode());
+ return nullptr;
+ }
+
+ if (key_info->GetType() != BUNDLE_TYPE_STR_ARRAY) {
+ set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
+ return nullptr;
+ }
+
+ set_last_result(BUNDLE_ERROR_NONE);
+
+ auto& raw_values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
+ key_info->GetValues());
+
+ if (len)
+ *len = static_cast<int>(raw_values.size());
+
+ if (raw_values.size() == 0)
+ return nullptr;
+
+ auto** values = reinterpret_cast<unsigned char**>(&raw_values[0]);
+ return const_cast<const char**>(reinterpret_cast<char**>(values));
+}
+
+extern "C" EXPORT_API int bundle_add_byte(bundle* b, const char* key,
+ const void* bytes, const size_t size) {
+ if (b == nullptr || key == nullptr || strlen(key) == 0)
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ auto* h = reinterpret_cast<Bundle*>(b);
+ auto* p = reinterpret_cast<const unsigned char*>(bytes);
+ std::vector<unsigned char> value;
+ if (bytes)
+ value.insert(value.end(), p, p + size);
+
+ KeyInfo* key_info;
+ try {
+ key_info = new KeyInfo(BUNDLE_TYPE_BYTE, key, std::move(value));
+ } catch (const Exception& e) {
+ return e.GetErrorCode();
+ } catch (const std::bad_alloc& ba) {
+ return BUNDLE_ERROR_OUT_OF_MEMORY;
+ }
+
+ try {
+ h->Add(std::shared_ptr<KeyInfo>(key_info));
+ } catch (const Exception& e) {
+ return e.GetErrorCode();
+ }
+
+ return BUNDLE_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int bundle_get_byte(bundle* b, const char* key,
+ void** bytes, size_t* size) {
+ if (b == nullptr || key == nullptr)
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ auto* h = reinterpret_cast<Bundle*>(b);
+ std::shared_ptr<KeyInfo> key_info;
+ try {
+ key_info = h->Get(key);
+ } catch (const Exception& e) {
+ return e.GetErrorCode();
+ }
+
+ if (key_info->GetType() != BUNDLE_TYPE_BYTE)
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ if (bytes) {
+ auto& values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
+ key_info->GetValues());
+ if (values.size() == 0) {
+ *bytes = nullptr;
+ } else {
+ auto& value = values[0];
+ *bytes = reinterpret_cast<void*>(&value[0]);
+ }
+ }
+
+ if (size) {
+ auto& values_size = key_info->GetValuesSize();
+ *size = reinterpret_cast<size_t>(values_size[0]);
+ }
+
+ return BUNDLE_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int bundle_export_to_argv(bundle* b, char*** argv) {
+ if (b == nullptr || argv == nullptr) {
+ set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
+ return -1;
+ }
+
+ auto* h = reinterpret_cast<Bundle*>(b);
+ std::vector<std::string> exported_vt;
+ try {
+ exported_vt = h->Export();
+ } catch (const Exception& e) {
+ set_last_result(e.GetErrorCode());
+ return -1;
+ }
+
+ int argc = exported_vt.size();
+ auto** exported_argv = reinterpret_cast<char**>(
+ calloc(argc + 1, sizeof(char*)));
+ if (exported_argv == nullptr) {
+ set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
+ return -1;
+ }
+
+ exported_argv[1] = const_cast<char*>(TAG_IMPORT_EXPORT_CHECK);
+ for (unsigned int idx = 2; idx < exported_vt.size(); idx += 2) {
+ exported_argv[idx] = strdup(exported_vt[idx].c_str());
+ if (exported_argv[idx] == nullptr) {
+ set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
+ bundle_free_exported_argv(idx + 1, &exported_argv);
+ return -1;
+ }
+
+ exported_argv[idx + 1] = strdup(exported_vt[idx + 1].c_str());
+ if (exported_argv[idx + 1] == nullptr) {
+ set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
+ bundle_free_exported_argv(idx + 2, &exported_argv);
+ return -1;
+ }
+ }
+
+ *argv = exported_argv;
+ set_last_result(BUNDLE_ERROR_NONE);
+ return argc;
+}
+
+extern "C" EXPORT_API int bundle_free_exported_argv(int argc, char*** argv) {
+ if (argc < 2 || !argv || !*argv)
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ for (int i = 2; i < argc; i++)
+ std::free((*argv)[i]);
+
+ std::free(*argv);
+ *argv = nullptr;
+
+ return BUNDLE_ERROR_NONE;
+}
+
+extern "C" EXPORT_API bundle* bundle_import_from_argv(int argc, char** argv) {
+ if (argv == nullptr) {
+ set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
+ return nullptr;
+ }
+
+ Bundle* b = nullptr;
+ try {
+ b = new (std::nothrow) Bundle(argc, argv);
+ } catch (const Exception& e) {
+ set_last_result(e.GetErrorCode());
+ return nullptr;
+ }
+
+ set_last_result(BUNDLE_ERROR_NONE);
+ return reinterpret_cast<bundle*>(b);
+}
+
+extern "C" EXPORT_API int bundle_compare(bundle* b1, bundle* b2) {
+ if (b1 == nullptr || b2 == nullptr)
+ return -1;
+
+ auto* h1 = reinterpret_cast<Bundle*>(b1);
+ auto* h2 = reinterpret_cast<Bundle*>(b2);
+ if (*h1 == *h2)
+ return 0;
+
+ return 1;
+}
+
+extern "C" EXPORT_API int bundle_set_str_array_element(bundle* b,
+ const char* key, const unsigned int idx, const char* val) {
+ if (b == nullptr || key == nullptr || val == nullptr)
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ auto len = strlen(val) + 1;
+ auto* p = reinterpret_cast<unsigned char*>(const_cast<char*>(val));
+ std::vector<unsigned char> value(p, p + len);
+
+ auto* h = reinterpret_cast<Bundle*>(b);
+ try {
+ h->Set(key, idx, std::move(value));
+ } catch (const Exception& e) {
+ return e.GetErrorCode();
+ }
+
+ return BUNDLE_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int bundle_add_byte_array(bundle* b,
+ const char* key, const unsigned int len) {
+ return bundle_init_byte_array(b, key, len);
+}
+
+extern "C" EXPORT_API int bundle_init_byte_array(bundle* b,
+ const char* key, const unsigned int len) {
+ if (b == nullptr || key == nullptr || strlen(key) == 0)
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ auto* h = reinterpret_cast<Bundle*>(b);
+
+ KeyInfo* key_info;
+ try {
+ std::vector<std::vector<unsigned char>> values(len);
+ key_info = new KeyInfo(Bundle::Type::ByteArray, key, std::move(values));
+ } catch (const Exception& e) {
+ return e.GetErrorCode();
+ } catch (const std::bad_alloc& ba) {
+ return BUNDLE_ERROR_OUT_OF_MEMORY;
+ } catch (const std::length_error&) {
+ return BUNDLE_ERROR_OUT_OF_MEMORY;
+ }
+
+ try {
+ h->Add(std::shared_ptr<KeyInfo>(key_info));
+ } catch (const Exception& e) {
+ return e.GetErrorCode();
+ }
+
+ return BUNDLE_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int bundle_get_byte_array(bundle* b,
+ const char* key, void*** bytes_array, unsigned int* len,
+ unsigned int** array_element_size) {
+ if (b == nullptr || key == nullptr)
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ auto* h = reinterpret_cast<Bundle*>(b);
+ std::shared_ptr<KeyInfo> key_info;
+ try {
+ key_info = h->Get(key);
+ } catch (const Exception& e) {
+ return e.GetErrorCode();
+ }
+
+ if (key_info->GetType() != BUNDLE_TYPE_BYTE_ARRAY)
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ auto& raw_values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
+ key_info->GetValues());
+
+ if (bytes_array) {
+ auto** values = reinterpret_cast<unsigned char**>(&raw_values[0]);
+ *bytes_array = reinterpret_cast<void**>(values);
+ }
+
+ if (len)
+ *len = static_cast<unsigned int>(raw_values.size());
+
+ if (array_element_size) {
+ auto& raw_values_size = const_cast<std::vector<unsigned int>&>(
+ key_info->GetUValuesSize());
+ *array_element_size = reinterpret_cast<unsigned int*>(&raw_values_size[0]);
+ }
+
+ return BUNDLE_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int bundle_set_byte_array_element(bundle* b,
+ const char* key, const unsigned int idx,
+ const void* bytes, const size_t size) {
+ if (b == nullptr || key == nullptr || size <= 0)
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ std::vector<unsigned char> value;
+ if (bytes) {
+ auto* p = reinterpret_cast<unsigned char*>(const_cast<void*>(bytes));
+ value.insert(value.end(), p, p + size);
+ }
+
+ auto* h = reinterpret_cast<Bundle*>(b);
+ try {
+ h->Set(key, idx, std::move(value));
+ } catch (const Exception& e) {
+ return e.GetErrorCode();
+ }
+
+ return BUNDLE_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int bundle_to_json(bundle* b, char** json) {
+ if (b == nullptr || json == nullptr)
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ auto* h = reinterpret_cast<Bundle*>(b);
+ Json js(h);
+ try {
+ *json = strdup(js.ToString().c_str());
+ } catch (const Exception& e) {
+ return e.GetErrorCode();
+ }
+
+ return BUNDLE_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int bundle_from_json(const char* json, bundle** b) {
+ if (json == nullptr || b == nullptr)
+ return BUNDLE_ERROR_INVALID_PARAMETER;
+
+ Json js(json);
+ try {
+ *b = reinterpret_cast<bundle*>(js.ToBundle());
+ } catch (const Exception& e) {
+ return e.GetErrorCode();
+ }
+
+ return BUNDLE_ERROR_NONE;
+}
+++ /dev/null
-/*
- * Copyright (c) 2019 - 2020 Samsung Electronics Co., Ltd.
- *
- * 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 <memory>
-#include <stdexcept>
-
-#include "bundle_cpp.h"
-#include "bundle_cpp_implementation.h"
-#include "bundle_internal.h"
-#include "log-private.h"
-
-namespace tizen_base {
-Bundle::Impl::Impl(Bundle* parent, bool copy, bool own)
- : copy_(copy), own_(own), parent_(parent) {
-}
-
-Bundle::Impl::Impl(Bundle* parent) : parent_(parent) {
-}
-
-Bundle::Impl::~Impl() = default;
-
-Bundle::Bundle()
- : impl_(new Impl(this)) {
- impl_->handle_ = bundle_create();
- if (impl_->handle_ == nullptr)
- throw std::bad_alloc();
-}
-
-Bundle::Bundle(std::initializer_list<
- std::pair<std::string, std::string>> key_values)
- : impl_(new Impl(this)) {
- impl_->handle_ = bundle_create();
- if (impl_->handle_ == nullptr)
- throw std::bad_alloc();
- for (auto& i : key_values)
- Add(i.first, i.second);
-}
-
-Bundle::Bundle(BundleRaw raw, bool base64)
- : impl_(new Impl(this)) {
- if (base64)
- impl_->handle_ = bundle_decode(raw.first.get(), raw.second);
- else
- impl_->handle_ = bundle_decode_raw(raw.first.get(), raw.second);
- if (impl_->handle_ == nullptr)
- throw std::bad_alloc();
-}
-
-Bundle::Bundle(const std::string& raw)
- : impl_(new Impl(this)) {
- impl_->handle_ = bundle_decode(reinterpret_cast<const bundle_raw*>(
- raw.c_str()), raw.length());
- if (impl_->handle_ == nullptr)
- throw std::bad_alloc();
-}
-
-Bundle::Bundle(bundle* b, bool copy, bool own)
- : impl_(new Impl(this, copy, own)) {
- if (b == nullptr)
- throw std::invalid_argument("b cannot be null");
-
- if (!impl_->copy_) {
- impl_->handle_ = b;
- } else {
- impl_->handle_ = bundle_dup(b);
- if (impl_->handle_ == nullptr)
- throw std::bad_alloc();
- }
-}
-
-Bundle::~Bundle() {
- if (impl_ && impl_->handle_ && (impl_->own_ || impl_->copy_))
- bundle_free(impl_->handle_);
-}
-
-Bundle::Bundle(const Bundle& b)
- : impl_(new Impl(this)) {
- impl_->handle_ = bundle_dup(b.impl_->handle_);
- if (impl_->handle_ == nullptr)
- throw std::bad_alloc();
-}
-
-Bundle::KeyInfo::KeyInfo(const bundle_keyval_t* handle, std::string name,
- bool own)
- : impl_(new Impl(this, handle, std::move(name), own)) {
-}
-
-Bundle::KeyInfo::~KeyInfo() {
- if (impl_ && impl_->handle_ && impl_->own_)
- bundle_keyval_free(const_cast<bundle_keyval_t*>(impl_->handle_));
-}
-
-Bundle::KeyInfo::Impl::~Impl() = default;
-
-Bundle::KeyInfo::Impl::Impl(Bundle::KeyInfo* parent,
- const bundle_keyval_t* handle,
- std::string name,
- bool own)
- : handle_(handle), name_(name), parent_(parent), own_(own) {
-}
-
-Bundle::KeyInfo::Impl::Impl(Bundle::KeyInfo* parent) : parent_(parent) {
-}
-
-Bundle::KeyInfo::KeyInfo(const KeyInfo& k)
- : impl_(new Impl(this)) {
- impl_->handle_ = bundle_keyval_dup(k.impl_->handle_);
- impl_->name_ = k.impl_->name_;
- impl_->own_ = true;
- if (impl_->handle_ == nullptr)
- throw std::bad_alloc();
-}
-
-Bundle::KeyInfo& Bundle::KeyInfo::operator = (const Bundle::KeyInfo& k) {
- if (this != &k) {
- if (impl_->handle_ && impl_->own_)
- bundle_keyval_free(const_cast<bundle_keyval_t*>(impl_->handle_));
-
- impl_->handle_ = bundle_keyval_dup(k.impl_->handle_);
- impl_->name_ = k.impl_->name_;
- if (impl_->handle_ == nullptr)
- throw std::bad_alloc();
-
- impl_->own_ = true;
- }
- return *this;
-}
-
-Bundle::KeyInfo::KeyInfo(Bundle::KeyInfo&& k) noexcept {
- impl_ = std::move(k.impl_);
- impl_->parent_ = this;
-}
-
-Bundle::KeyInfo& Bundle::KeyInfo::operator = (Bundle::KeyInfo&& k) noexcept {
- if (this != &k) {
- if (impl_->handle_ && impl_->own_)
- bundle_keyval_free(const_cast<bundle_keyval_t*>(impl_->handle_));
-
- impl_->handle_ = k.impl_->handle_;
- impl_->name_ = k.impl_->name_;
- impl_->own_ = k.impl_->own_;
- k.impl_->handle_ = nullptr;
- k.impl_->name_ = "";
- k.impl_->own_ = false;
- }
- return *this;
-}
-
-bundle_type Bundle::KeyInfo::GetType() const {
- return static_cast<bundle_type>(
- bundle_keyval_get_type(const_cast<bundle_keyval_t*>(impl_->handle_)));
-}
-
-bool Bundle::KeyInfo::IsArray() const {
- return bundle_keyval_type_is_array(const_cast<bundle_keyval_t*>(
- impl_->handle_));
-}
-
-const std::string& Bundle::KeyInfo::GetName() const {
- return impl_->name_;
-}
-
-Bundle& Bundle::operator = (const Bundle& b) {
- if (this != &b) {
- if (impl_->handle_ && (impl_->own_ || impl_->copy_))
- bundle_free(impl_->handle_);
-
- impl_->handle_ = bundle_dup(b.impl_->handle_);
- if (impl_->handle_ == nullptr)
- throw std::bad_alloc();
-
- impl_->own_ = true;
- impl_->copy_ = true;
- }
- return *this;
-}
-
-Bundle::Bundle(Bundle&& b) noexcept {
- impl_ = std::move(b.impl_);
- impl_->parent_ = this;
- b.impl_.reset(new Impl(&b));
- b.impl_->handle_ = bundle_create();
-}
-
-Bundle& Bundle::operator = (Bundle&& b) noexcept {
- if (this != &b) {
- if (impl_->handle_ && (impl_->own_ || impl_->copy_))
- bundle_free(impl_->handle_);
-
- impl_->handle_ = b.impl_->handle_;
- b.impl_->handle_ = nullptr;
- impl_->own_ = b.impl_->own_;
- b.impl_->own_ = false;
- impl_->copy_ = b.impl_->copy_;
- b.impl_->copy_ = false;
- }
- return *this;
-}
-
-bool Bundle::IsEmpty() const noexcept {
- return (bundle_get_count(impl_->handle_) == 0) ? true : false;
-}
-
-std::vector<Bundle::KeyInfo> Bundle::GetKeys() {
- std::vector<Bundle::KeyInfo> v;
-
- bundle_foreach(impl_->handle_, [](const char *key, const int type,
- const bundle_keyval_t *kv, void *user_data) {
- auto* v = static_cast<std::vector<KeyInfo>*>(user_data);
- v->emplace_back(kv, key, false);
- }, &v);
-
- return v;
-}
-
-int Bundle::Add(const std::string& key, const std::string& val) {
- int ret = bundle_add_str(impl_->handle_, key.c_str(), val.c_str());
- if (ret != BUNDLE_ERROR_NONE)
- LOGE("Add fail key(%s), val(%s), ret(%d)", key.c_str(), val.c_str(), ret);
- return ret;
-}
-
-int Bundle::Add(const std::string& key, const std::vector<std::string>& val) {
- std::vector<const char*> v;
- for (auto& i : val) {
- v.push_back(i.c_str());
- }
-
- int ret = bundle_add_str_array(
- impl_->handle_, key.c_str(), v.data(), v.size());
- if (ret != BUNDLE_ERROR_NONE)
- LOGE("Add fail key(%s), ret(%d)", key.c_str(), ret);
-
- return ret;
-}
-
-int Bundle::Add(const std::string& key, const std::vector<unsigned char>& val) {
- int ret = bundle_add_byte(impl_->handle_, key.c_str(), val.data(), val.size());
- if (ret != BUNDLE_ERROR_NONE)
- LOGE("Add fail key(%s), ret(%d)", key.c_str(), ret);
- return ret;
-}
-
-int Bundle::Delete(const std::string& key) {
- return bundle_del(impl_->handle_, key.c_str());
-}
-
-std::string Bundle::GetString(const std::string& key) const {
- char* str = nullptr;
- bundle_get_str(impl_->handle_, key.c_str(), &str);
-
- if (!str)
- return "";
-
- return std::string(str);
-}
-
-std::vector<std::string> Bundle::GetStringArray(const std::string& key) const {
- std::vector<std::string> v;
-
- const char** str_array = nullptr;
- int len = 0;
-
- str_array = bundle_get_str_array(impl_->handle_, key.c_str(), &len);
-
- for (int i = 0; i < len; i++) {
- v.emplace_back(str_array[i]);
- }
-
- return v;
-}
-
-std::vector<unsigned char> Bundle::GetByte(const std::string& key) const {
- size_t size;
- unsigned char* bytes = nullptr;
- int ret = bundle_get_byte(impl_->handle_, key.c_str(),
- reinterpret_cast<void**>(&bytes), &size);
- if (ret != BUNDLE_ERROR_NONE) {
- LOGE("bundle_get_byte() is failed");
- return {};
- }
-
- return std::vector<unsigned char>(bytes, bytes + size);
-}
-
-Bundle::BundleRaw Bundle::ToRaw(bool base64) {
- bundle_raw* raw = nullptr;
- int len = 0;
- int ret;
- if (base64)
- ret = bundle_encode(impl_->handle_, &raw, &len);
- else
- ret = bundle_encode_raw(impl_->handle_, &raw, &len);
- if (raw == nullptr) {
- LOGE("Fail to encode data (%d)", ret);
- throw std::bad_alloc();
- }
-
- return BundleRaw(
- std::unique_ptr<bundle_raw, decltype(std::free)*>(raw, std::free), len);
-}
-
-int Bundle::GetCount() const {
- return bundle_get_count(impl_->handle_);
-}
-
-bundle_type Bundle::GetType(const std::string& key) const {
- return static_cast<bundle_type>(bundle_get_type(impl_->handle_, key.c_str()));
-}
-
-bundle* Bundle::GetHandle() const {
- return impl_->handle_;
-}
-
-bundle* Bundle::Detach() {
- auto* h = impl_->handle_;
- impl_->handle_ = nullptr;
- return h;
-}
-
-std::vector<std::string> Bundle::Export() const {
- char** argv = nullptr;
- int argc = bundle_export_to_argv(impl_->handle_, &argv);
- if (argc < 0) {
- LOGE("bundle_export_to_argv() is failed");
- return {};
- }
-
- std::vector<std::string> args(1);
- for (int i = 1; i < argc; ++i)
- args.push_back(argv[i]);
-
- bundle_free_exported_argv(argc, &argv);
- return args;
-}
-
-} // namespace tizen_base
+++ /dev/null
-/*
- * Copyright (c) 2019 - 2020 Samsung Electronics Co., Ltd.
- *
- * 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 BUNDLE_CPP_IMPLEMENTATION_H_
-#define BUNDLE_CPP_IMPLEMENTATION_H_
-
-#include <string>
-#include <memory>
-#include <list>
-
-#include "include/bundle_cpp.h"
-
-namespace tizen_base {
-
-class Bundle::KeyInfo::Impl {
- public:
- virtual ~Impl();
-
- private:
- Impl(Bundle::KeyInfo* parent, const bundle_keyval_t* handle,
- std::string name, bool own);
- explicit Impl(Bundle::KeyInfo* parent);
-
- private:
- friend class Bundle::KeyInfo;
-
- private:
- const bundle_keyval_t* handle_ = nullptr;
- std::string name_;
- Bundle::KeyInfo* parent_;
- bool own_ = false;
-};
-
-class Bundle::Impl {
- public:
- virtual ~Impl();
-
- private:
- explicit Impl(Bundle* parent);
- Impl(Bundle* parent, bool copy, bool own);
-
- private:
- friend class Bundle;
-
- bundle* handle_ = nullptr;
- bool copy_ = true;
- bool own_ = true;
- Bundle* parent_ = nullptr;
-};
-
-} // namespace tizen_base
-
-#endif // BUNDLE_CPP_IMPLEMENTATION_H_
+++ /dev/null
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
- *
- * 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 EXCEPTION_INTERNAL_H_
-#define EXCEPTION_INTERNAL_H_
-
-#include <string>
-#include <exception>
-
-#include "log-private.h"
-
-#define THROW(error_code) throw Exception(error_code)
-
-namespace tizen_base {
-namespace internal {
-
-class Exception : public std::exception {
- public:
- explicit Exception(int error_code, std::string file = __FILE__,
- int line = __LINE__ ) {
- error_code_ = error_code;
- message_ = file.substr(file.find_last_of("/") + 1) + ":"
- + std::to_string(line) + " code:" + std::to_string(error_code_);
- }
-
- virtual ~Exception() {}
-
- virtual const char *what(void) const noexcept {
- return message_.c_str();
- }
-
- int GetErrorCode() const {
- return error_code_;
- }
-
- private:
- int error_code_;
- std::string message_;
-};
-
-} // namespace internal
-} // namespace tizen_base
-
-#endif // EXCEPTION_INTERNAL_H_
+++ /dev/null
-/*
- * Copyright (c) 2020 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 EXPORT_API_INTERNAL_H_
-#define EXPORT_API_INTERNAL_H_
-
-#ifndef EXPORT_API
-#define EXPORT_API __attribute__((visibility("default")))
-#endif
-
-#endif // EXPORT_API_INTERNAL_H_
+++ /dev/null
-/*
- * Copyright (c) 2020 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 "exception-internal.h"
-#include "json-internal.h"
-
-namespace tizen_base {
-namespace internal {
-
-Json::Json(std::string json) : json_(std::move(json)) {
-}
-
-Json::Json(Bundle* b) : b_(b) {
-}
-
-Bundle* Json::ToBundle() {
- if (json_.empty())
- return nullptr;
-
- JsonParser* parser = json_parser_new();
- if (parser == nullptr)
- THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
-
- std::unique_ptr<JsonParser, decltype(g_object_unref)*> parser_ptr(parser,
- g_object_unref);
-
- GError* error = nullptr;
- json_parser_load_from_data(parser, json_.c_str(), json_.length(), &error);
- if (error) {
- g_error_free(error);
- THROW(BUNDLE_ERROR_INVALID_PARAMETER);
- }
-
- JsonNode* root = json_parser_get_root(parser);
- if (root == nullptr)
- THROW(BUNDLE_ERROR_INVALID_PARAMETER);
-
- JsonObject* root_obj = json_node_get_object(root);
- if (root_obj == nullptr)
- THROW(BUNDLE_ERROR_INVALID_PARAMETER);
-
- Bundle* b = new (std::nothrow) Bundle();
- if (b == nullptr)
- THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
-
- json_object_foreach_member(root_obj, OnJsonObjectMember, b);
-
- return b;
-}
-
-std::string Json::ToString() {
- if (b_ == nullptr)
- THROW(BUNDLE_ERROR_INVALID_PARAMETER);
-
- JsonObject* object = json_object_new();
- if (object == nullptr)
- THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
-
- std::unique_ptr<JsonObject, decltype(json_object_unref)*> object_ptr(object,
- json_object_unref);
-
- for (const auto& kv : b_->GetMap()) {
- auto& key_info = kv.second;
- if (key_info->GetType() == Bundle::Type::StringArray) {
- JsonArray* json_arr = json_array_new();
- if (json_arr == nullptr)
- THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
-
- for (const auto& v : key_info->GetValues()) {
- json_array_add_string_element(json_arr,
- const_cast<const char*>(reinterpret_cast<char*>(v.get())));
- }
-
- json_object_set_array_member(object, key_info->GetKey().c_str(),
- json_arr);
- } else {
- json_object_set_string_member(object, key_info->GetKey().c_str(),
- const_cast<const char*>(
- reinterpret_cast<char*>(
- key_info->GetValues()[0].get())));
- }
- }
-
- JsonNode* node = json_node_new(JSON_NODE_OBJECT);
- if (node == nullptr)
- THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
-
- std::unique_ptr<JsonNode, decltype(json_node_free)*> node_ptr(node,
- json_node_free);
-
- json_node_set_object(node, object);
-
- JsonGenerator* generator = json_generator_new();
- if (generator == nullptr)
- THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
-
- std::unique_ptr<JsonGenerator, decltype(g_object_unref)*> generator_ptr(
- generator, g_object_unref);
-
- json_generator_set_root(generator, node);
- gsize length = 0;
- gchar* json = json_generator_to_data(generator, &length);
- if (json == nullptr)
- THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
-
- std::unique_ptr<gchar, decltype(g_free)*> json_auto(json, g_free);
- json_ = json;
- return json_;
-}
-
-void Json::OnJsonObjectMember(JsonObject* object, const char* key,
- JsonNode* node, gpointer user_data) {
- auto* b = static_cast<Bundle*>(user_data);
- KeyInfo* key_info;
- JsonNodeType node_type = JSON_NODE_TYPE(node);
- if (node_type == JSON_NODE_ARRAY) {
- JsonArray* json_arr = json_node_get_array(node);
- if (json_arr == nullptr)
- return;
-
- std::vector<std::vector<unsigned char>> values;
- guint len = json_array_get_length(json_arr);
- for (guint i = 0; i < len; ++i) {
- auto* val = json_array_get_string_element(json_arr, i);
- if (val == nullptr)
- val = "";
-
- auto* p = reinterpret_cast<unsigned char*>(const_cast<char*>(val));
- std::vector<unsigned char> value(p, p + (strlen(val) + 1));
- values.push_back(std::move(value));
- }
-
- try {
- key_info = new KeyInfo(Bundle::Type::StringArray, key, std::move(values));
- } catch (const Exception& e) {
- _E("Error(%d)", e.GetErrorCode());
- return;
- } catch (const std::bad_alloc& ba) {
- _E("bad alloc exception");
- return;
- }
- } else {
- auto* val = json_node_get_string(node);
- if (val == nullptr)
- val = "";
-
- auto* p = reinterpret_cast<unsigned char*>(const_cast<char*>(val));
- std::vector<unsigned char> value(p, p + (strlen(val) + 1));
-
- try {
- key_info = new KeyInfo(Bundle::Type::String, key, std::move(value));
- } catch (const Exception& e) {
- _E("Error(%d)", e.GetErrorCode());
- return;
- } catch (const std::bad_alloc& ba) {
- _E("bad alloc exception");
- return;
- }
- }
-
- try {
- b->Add(std::shared_ptr<KeyInfo>(key_info));
- } catch (const Exception& e) {
- _W("Add() is failed. error(%d)", e.GetErrorCode());
- return;
- }
-}
-
-} // namespace internal
-} // namespace tizen_base
+++ /dev/null
-/*
- * Copyright (c) 2020 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 JSON_INTERNAL_H_
-#define JSON_INTERNAL_H_
-
-#include <glib.h>
-#include <json-glib/json-glib.h>
-
-#include <memory>
-#include <string>
-
-#include "bundle-internal.h"
-
-namespace tizen_base {
-namespace internal {
-
-class Json {
- public:
- explicit Json(std::string json);
- explicit Json(Bundle* b);
- virtual ~Json() = default;
-
- Bundle* ToBundle();
- std::string ToString();
-
- private:
- static void OnJsonObjectMember(JsonObject* object, const char* key,
- JsonNode* node, gpointer user_data);
-
- private:
- Bundle* b_ = nullptr;
- std::string json_;
-};
-
-} // namespace internal
-} // namespace tizen_base
-
-#endif // JSON_INTERNAL_H_
+++ /dev/null
-/*
- * Copyright (c) 2020 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 <algorithm>
-#include <cstring>
-#include <utility>
-
-#include "include/bundle.h"
-
-#include "exception-internal.h"
-#include "key-info-internal.h"
-
-namespace tizen_base {
-namespace internal {
-
-KeyInfo::KeyInfo(int type, std::string key, std::vector<unsigned char> value)
- : type_(type), key_(std::move(key)) {
- int ret = SetValue(value);
- if (ret != BUNDLE_ERROR_NONE)
- THROW(ret);
-}
-
-KeyInfo::KeyInfo(int type, std::string key,
- std::vector<std::vector<unsigned char>> values)
- : type_(type), key_(std::move(key)) {
- int ret = SetValues(values);
- if (ret != BUNDLE_ERROR_NONE)
- THROW(ret);
-}
-
-KeyInfo::KeyInfo(std::vector<unsigned char> encoded_bytes) {
- int ret = Decode(encoded_bytes);
- if (ret != BUNDLE_ERROR_NONE)
- THROW(ret);
-}
-
-KeyInfo::KeyInfo(const KeyInfo& key_info) {
- values_.reserve(key_info.values_.size());
- try {
- for (unsigned int i = 0; i < key_info.values_.size(); ++i) {
- auto new_value =
- std::make_unique<unsigned char[]>(key_info.values_size_[i]);
- std::copy(key_info.values_[i].get(),
- key_info.values_[i].get() + key_info.values_size_[i],
- new_value.get());
- values_.push_back(std::move(new_value));
- }
- } catch (const std::bad_alloc& e) {
- THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
- }
-
- type_ = key_info.type_;
- key_ = key_info.key_;
- values_size_ = key_info.values_size_;
- uvalues_size_ = key_info.uvalues_size_;
-}
-
-KeyInfo& KeyInfo::operator=(const KeyInfo& key_info) {
- if (this != &key_info) {
- decltype(values_) new_values;
- try {
- for (unsigned int i = 0; i < key_info.values_.size(); ++i) {
- auto new_value =
- std::make_unique<unsigned char[]>(key_info.values_size_[i]);
- std::copy(key_info.values_[i].get(),
- key_info.values_[i].get() + key_info.values_size_[i],
- new_value.get());
- new_values.push_back(std::move(new_value));
- }
- } catch (const std::bad_alloc& e) {
- THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
- }
-
- type_ = key_info.type_;
- key_ = key_info.key_;
- values_size_ = key_info.values_size_;
- uvalues_size_ = key_info.uvalues_size_;
- values_ = std::move(new_values);
- }
-
- return *this;
-}
-
-KeyInfo::KeyInfo(KeyInfo&& key_info) noexcept {
- type_ = key_info.type_;
- key_info.type_ = 0;
- key_ = std::move(key_info.key_);
- values_ = std::move(key_info.values_);
- values_size_ = std::move(key_info.values_size_);
- uvalues_size_ = std::move(key_info.uvalues_size_);
-}
-
-KeyInfo& KeyInfo::operator=(KeyInfo&& key_info) noexcept {
- if (this != &key_info) {
- type_ = key_info.type_;
- key_info.type_ = 0;
- key_ = std::move(key_info.key_);
- values_ = std::move(key_info.values_);
- values_size_ = std::move(key_info.values_size_);
- uvalues_size_ = std::move(key_info.uvalues_size_);
- }
- return *this;
-}
-
-bool KeyInfo::operator==(const KeyInfo& key_info) {
- if (this == &key_info)
- return true;
-
- if (type_ != key_info.type_)
- return false;
-
- if (key_ != key_info.key_)
- return false;
-
- if (values_.size() != key_info.values_.size())
- return false;
-
- for (unsigned int i = 0; i < values_.size(); ++i) {
- if (values_size_[i] != key_info.values_size_[i])
- return false;
-
- int ret = std::memcmp(values_[i].get(), key_info.values_[i].get(),
- values_size_[i]);
- if (ret != 0)
- return false;
- }
-
- return true;
-}
-
-int KeyInfo::GetType() const {
- return type_;
-}
-
-bool KeyInfo::IsArray() const {
- if (type_ & BUNDLE_TYPE_ARRAY)
- return true;
-
- return false;
-}
-
-const std::string& KeyInfo::GetKey() {
- return key_;
-}
-
-const std::vector<std::unique_ptr<unsigned char[]>>& KeyInfo::GetValues() {
- return values_;
-}
-
-const std::vector<std::size_t>& KeyInfo::GetValuesSize() {
- return values_size_;
-}
-
-const std::vector<unsigned int>& KeyInfo::GetUValuesSize() {
- return uvalues_size_;
-}
-
-int KeyInfo::SetValue(const std::vector<unsigned char>& value) {
- try {
- auto new_value = std::make_unique<unsigned char[]>(value.size());
- std::copy(value.begin(), value.end(), new_value.get());
- values_.emplace_back(std::move(new_value));
- } catch (const std::bad_alloc& e) {
- return BUNDLE_ERROR_OUT_OF_MEMORY;
- }
-
- values_size_.push_back(value.size());
- uvalues_size_.push_back(static_cast<unsigned int>(value.size()));
- return BUNDLE_ERROR_NONE;
-}
-
-int KeyInfo::SetValues(const std::vector<std::vector<unsigned char>>& values) {
- try {
- for (unsigned int i = 0; i < values.size(); ++i) {
- auto new_value = std::make_unique<unsigned char[]>(values[i].size());
- std::copy(values[i].begin(), values[i].end(), new_value.get());
- values_.push_back(std::move(new_value));
- values_size_.push_back(values[i].size());
- uvalues_size_.push_back(values[i].size());
- }
- } catch (const std::bad_alloc& e) {
- return BUNDLE_ERROR_OUT_OF_MEMORY;
- }
-
- return BUNDLE_ERROR_NONE;
-}
-
-std::vector<unsigned char> KeyInfo::Encode() {
- std::size_t encoded_size = GetEncodedSize();
- if (encoded_size == 0)
- return {};
-
- std::vector<unsigned char> bytes;
-
- // total size
- unsigned char* p = reinterpret_cast<unsigned char*>(&encoded_size);
- bytes.insert(bytes.end(), p, p + sizeof(encoded_size));
-
- // type
- p = reinterpret_cast<unsigned char*>(&type_);
- bytes.insert(bytes.end(), p, p + sizeof(type_));
-
- // key size
- std::size_t key_length = key_.length() + 1;
- p = reinterpret_cast<unsigned char*>(&key_length);
- bytes.insert(bytes.end(), p, p + sizeof(key_length));
-
- // key
- bytes.insert(bytes.end(), key_.begin(), key_.end() + 1);
-
- if (type_ & BUNDLE_TYPE_ARRAY) {
- // values size
- std::size_t values_size = values_.size();
- p = reinterpret_cast<unsigned char*>(&values_size);
- bytes.insert(bytes.end(), p, p + sizeof(values_size));
- }
-
- // values
- for (unsigned int i = 0; i < values_.size(); i++) {
- std::size_t value_size = values_size_[i];
- p = reinterpret_cast<unsigned char*>(&value_size);
- bytes.insert(bytes.end(), p, p + sizeof(value_size));
-
- bytes.insert(bytes.end(), values_[i].get(), values_[i].get() + value_size);
- }
-
- return bytes;
-}
-
-std::size_t KeyInfo::GetEncodedSize() {
- // total size
- std::size_t encoded_size = sizeof(std::size_t);
-
- // type
- encoded_size += sizeof(int);
-
- // key size
- encoded_size += sizeof(std::size_t);
-
- // key
- if ((encoded_size + key_.length() + 1) < encoded_size)
- return 0;
-
- encoded_size += key_.length() + 1;
-
- if (type_ & BUNDLE_TYPE_ARRAY) {
- // values size
- if ((encoded_size + sizeof(std::size_t)) < encoded_size)
- return 0;
-
- encoded_size += sizeof(std::size_t);
- }
-
- // values
- std::size_t values_size = 0;
- for (unsigned int i = 0; i < values_.size(); ++i) {
- // value size
- if ((values_size + sizeof(std::size_t)) < values_size)
- return 0;
-
- values_size += sizeof(std::size_t);
-
- // value
- if ((values_size + values_size_[i]) < values_size)
- return 0;
-
- values_size += values_size_[i];
- }
-
- if ((encoded_size + values_size) < encoded_size)
- return 0;
-
- encoded_size += values_size;
-
- return encoded_size;
-}
-
-int KeyInfo::Decode(const std::vector<unsigned char>& bytes) {
- unsigned int reader = 0;
-
- // total size
- std::size_t total_size = 0;
- if ((reader + sizeof(total_size)) > bytes.size())
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- unsigned char* p = reinterpret_cast<unsigned char*>(&total_size);
- std::copy(&bytes[reader], &bytes[reader] + sizeof(total_size), p);
- reader += sizeof(total_size);
-
- // type
- if ((reader + sizeof(type_)) > bytes.size())
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- p = reinterpret_cast<unsigned char*>(&type_);
- std::copy(&bytes[reader], &bytes[reader] + sizeof(type_), p);
- reader += sizeof(type_);
-
- // key size
- std::size_t key_size = 0;
-
- if ((reader + sizeof(key_size)) > bytes.size())
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- p = reinterpret_cast<unsigned char*>(&key_size);
- std::copy(&bytes[reader], &bytes[reader] + sizeof(key_size), p);
- reader += sizeof(key_size);
-
- if ((reader + key_size) > bytes.size())
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- // key
- std::vector<unsigned char> key(&bytes[reader], &bytes[reader] + key_size);
- p = reinterpret_cast<unsigned char*>(&key[0]);
- key_ = std::string(reinterpret_cast<char*>(p));
- reader += key_size;
-
- std::size_t values_size = 0;
- if (type_ & BUNDLE_TYPE_ARRAY) {
- // values size
- if ((reader + sizeof(values_size)) > bytes.size())
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- p = reinterpret_cast<unsigned char*>(&values_size);
- std::copy(&bytes[reader], &bytes[reader] + sizeof(values_size), p);
- reader += sizeof(values_size);
- } else {
- values_size = 1;
- }
-
- // values
- for (std::size_t i = 0; i < values_size; ++i) {
- // value_size
- std::size_t value_size = 0;
- if ((reader + sizeof(value_size)) > bytes.size())
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- p = reinterpret_cast<unsigned char*>(&value_size);
- std::copy(&bytes[reader], &bytes[reader] + sizeof(value_size), p);
- reader += sizeof(value_size);
-
- // value
- if ((reader + value_size) > bytes.size())
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- try {
- auto new_value = std::make_unique<unsigned char[]>(value_size);
- std::copy(&bytes[reader], &bytes[reader] + value_size, new_value.get());
- reader += value_size;
- values_.push_back(std::move(new_value));
- } catch (const std::bad_alloc& e) {
- return BUNDLE_ERROR_OUT_OF_MEMORY;
- }
- values_size_.push_back(value_size);
- uvalues_size_.push_back(static_cast<unsigned int>(value_size));
- }
-
- return BUNDLE_ERROR_NONE;
-}
-
-int KeyInfo::SetValue(int index, const std::vector<unsigned char>& value) {
- if (index > GetSize() || index < 0)
- return BUNDLE_ERROR_ARRAY_INDEX_OUT_OF_BOUNDS;
-
- if (!IsArray())
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- try {
- auto new_value = std::make_unique<unsigned char[]>(value.size());
- if (value.size() != 0)
- std::copy(value.begin(), value.end(), new_value.get());
-
- values_[index] = std::move(new_value);
- } catch (const std::bad_alloc& e) {
- return BUNDLE_ERROR_OUT_OF_MEMORY;
- }
-
- values_size_[index] = value.size();
- uvalues_size_[index] = static_cast<unsigned int>(value.size());
- return BUNDLE_ERROR_NONE;
-}
-
-int KeyInfo::GetSize() const {
- return values_.size();
-}
-
-} // namespace internal
-} // namespace tizen_base
+++ /dev/null
-/*
- * Copyright (c) 2020 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 KEY_INFO_INTERNAL_H_
-#define KEY_INFO_INTERNAL_H_
-
-#include <string>
-#include <vector>
-#include <memory>
-
-namespace tizen_base {
-namespace internal {
-
-class KeyInfo {
- public:
- KeyInfo(int type, std::string key,
- std::vector<unsigned char> value);
- KeyInfo(int type, std::string key,
- std::vector<std::vector<unsigned char>> values);
- explicit KeyInfo(std::vector<unsigned char> encoded_bytes);
- virtual ~KeyInfo() = default;
-
- KeyInfo(const KeyInfo& key_info);
- KeyInfo& operator = (const KeyInfo& key_info);
- KeyInfo(KeyInfo&& key_info) noexcept;
- KeyInfo& operator = (KeyInfo&& key_info) noexcept;
-
- bool operator == (const KeyInfo& key_info);
-
- int GetType() const;
- bool IsArray() const;
- const std::string& GetKey();
- const std::vector<std::unique_ptr<unsigned char[]>>& GetValues();
- const std::vector<std::size_t>& GetValuesSize();
- const std::vector<unsigned int>& GetUValuesSize();
- std::vector<unsigned char> Encode();
-
- int SetValue(int index, const std::vector<unsigned char>& value);
- int GetSize() const;
-
- private:
- std::size_t GetEncodedSize();
- int SetValuesSize();
- int SetValue(const std::vector<unsigned char>& value);
- int SetValues(const std::vector<std::vector<unsigned char>>& values);
- int Decode(const std::vector<unsigned char>& bytes);
-
- private:
- int type_;
- std::string key_;
- std::vector<std::unique_ptr<unsigned char[]>> values_;
- std::vector<std::size_t> values_size_;
- std::vector<unsigned int> uvalues_size_;
-};
-
-} // namespace internal
-} // namespace tizen_base
-
-#endif // KEY_INFO_INTERNAL_H_
+++ /dev/null
-/*
- * Copyright (c) 2020 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 LOG_PRIVATE_H_
-#define LOG_PRIVATE_H_
-
-#include <dlog.h>
-
-#undef LOG_TAG
-#define LOG_TAG "BUNDLE"
-
-#undef _E
-#define _E LOGE
-
-#undef _W
-#define _W LOGW
-
-#undef _I
-#define _I LOGI
-
-#undef _D
-#define _D LOGD
-
-#endif // LOG_PRIVATE_H_
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} PARCEL_SRCS)
+
+ADD_LIBRARY(${TARGET_PARCEL} SHARED ${PARCEL_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_PARCEL} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/api
+ ${CMAKE_CURRENT_SOURCE_DIR}/../)
+
+SET_TARGET_PROPERTIES(${TARGET_PARCEL} PROPERTIES SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(${TARGET_PARCEL} PROPERTIES VERSION ${FULLVER})
+
+APPLY_PKG_CONFIG(${TARGET_PARCEL} PUBLIC
+ CAPI_BASE_COMMON_DEPS
+ DLOG_DEPS
+ GLIB_DEPS
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_PARCEL} PUBLIC ${TARGET_BUNDLE})
+
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/parcel.pc.in
+ ${CMAKE_CURRENT_SOURCE_DIR}/parcel.pc @ONLY)
+
+INSTALL(TARGETS ${TARGET_PARCEL} DESTINATION ${LIB_INSTALL_DIR})
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/parcel.pc
+ DESTINATION ${LIB_INSTALL_DIR}/pkgconfig/)
+
+INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ DESTINATION include/parcel/
+ FILES_MATCHING
+ PATTERN "*.hh"
+ PATTERN "*_private.hh" EXCLUDE
+ PATTERN "*_implementation.hh" EXCLUDE)
+
+ INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/api
+ DESTINATION include/parcel/
+ FILES_MATCHING
+ PATTERN "*.h")
--- /dev/null
+/*
+ * Copyright (c) 2020 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 __PARCEL_H__
+#define __PARCEL_H__
+
+#include <stdint.h>
+#include <stddef.h>
+#include <tizen.h>
+
+/**
+ * @addtogroup CORE_LIB_PARCEL_MODULE
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief The parcel handle.
+ * @since_tizen 6.5
+ */
+typedef void *parcel_h;
+
+/**
+ * @brief The interface for converting data to/from a parcel.
+ * @since_tizen 6.5
+ */
+typedef struct {
+ void (*to)(parcel_h parcel, void *data);
+ void (*from)(parcel_h parcel, void *data);
+} parcelable_t;
+
+/**
+ * @brief Enumeration for error codes for a parcel.
+ * @since_tizen 6.5
+ */
+typedef enum {
+ PARCEL_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
+ PARCEL_ERROR_ILLEGAL_BYTE_SEQ = TIZEN_ERROR_ILLEGAL_BYTE_SEQ, /**< Illegal byte sequence */
+ PARCEL_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
+ PARCEL_ERROR_NO_DATA = TIZEN_ERROR_NO_DATA, /**< No data available */
+ PARCEL_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */
+} parcel_error_e;
+
+/**
+ * @brief Creates a parcel handle.
+ * @since_tizen 6.5
+ * @remarks You MUST release @a parcel using parcel_destroy().
+ * @param[out] parcel The parcel handle that is newly created
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PARCEL_ERROR_OUT_OF_MEMORY Out of memory
+ * @see parcel_destroy()
+ */
+int parcel_create(parcel_h *parcel);
+
+/**
+ * @brief Destroys a parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER
+ * @see parcel_create()
+ */
+int parcel_destroy(parcel_h parcel);
+
+/**
+ * @brief Creates and returns a copy of the given parcel handle.
+ * @since_tizen 6.5
+ * @remarks A newly created parcel should be destroyed by calling the parcel_destroy() if it is no longer needed.
+ * @param[in] parcel The parcel handle
+ * @param[out] If successful, a newly created parcel handle will be returned
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see parcel_destroy()
+ */
+int parcel_clone(parcel_h parcel, parcel_h *clone);
+
+/**
+ * @brief Writes bytes to the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[in] buf The array buffer to write
+ * @param[in] size The size of bytes to write
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see parcel_burst_read()
+ */
+int parcel_burst_write(parcel_h parcel, const void *buf, uint32_t size);
+
+/**
+ * @brief Reads bytes from the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[out] buf The array buffer to read
+ * @param[in] size The size of bytes to read
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PARCEL_ERROR_NO_DATA No data available
+ * @retval #PARCEL_ERROR_ILLEGAL_BYTE_SEQ Illegal byte sequence
+ * @see parcel_burst_write()
+ */
+int parcel_burst_read(parcel_h parcel, void *buf, uint32_t size);
+
+/**
+ * @brief Writes a boolean value into the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[in] val The boolean value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see parcel_read_bool()
+ */
+int parcel_write_bool(parcel_h parcel, bool val);
+
+/**
+ * @brief Writes a byte value into the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[in] val The byte value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see parcel_read_uint8()
+ */
+int parcel_write_byte(parcel_h parcel, char val);
+
+/**
+ * @brief Writes an unsigned short value into the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[in] val The unsigned short value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see parcel_read_uint16()
+ */
+int parcel_write_uint16(parcel_h parcel, uint16_t val);
+
+/**
+ * @brief Writes an unsigned integer value into the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[in] val The unsigned integer value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see parcel_read_uint32()
+ */
+int parcel_write_uint32(parcel_h parcel, uint32_t val);
+
+/**
+ * @brief Writes an unsigned long long integer value into the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[in] val The unsigned long long interger value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see parcel_read_uint64()
+ */
+int parcel_write_uint64(parcel_h parcel, uint64_t val);
+
+/**
+ * @brief Writes a signed short value into the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[in] val The signed short value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see parcel_read_int16()
+ */
+int parcel_write_int16(parcel_h parcel, int16_t val);
+
+/**
+ * @brief Writes a signed integer value into the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[in] val The signed integer value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see parcel_read_int32()
+ */
+int parcel_write_int32(parcel_h parcel, int32_t val);
+
+/**
+ * @brief Writes a signed long long integer value into the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[in] val The signedi long long integer value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see parcel_read_int64()
+ */
+int parcel_write_int64(parcel_h parcel, int64_t val);
+
+/**
+ * @brief Writes a floating point value into the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[in] val The floating point value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see parcel_read_float()
+ */
+int parcel_write_float(parcel_h parcel, float val);
+
+/**
+ * @brief Writes a double precision floating point value into the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[in] val The double precision floating point value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCLE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see parcel_read_double()
+ */
+int parcel_write_double(parcel_h parcel, double val);
+
+/**
+ * @brief Writes a string data into the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[in] str The string data
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see parcel_read_string()
+ */
+int parcel_write_string(parcel_h parcel, const char *str);
+
+/**
+ * @brief Reads a boolean value from the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[out] val The boolean value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PARCEL_ERROR_NO_DATA No data available
+ * @retval #PARCEL_ERROR_ILLEGAL_BYTE_SEQ Illegal byte sequence
+ * @see parcel_write_bool()
+ */
+int parcel_read_bool(parcel_h parcel, bool *val);
+
+/**
+ * @brief Reads a byte value from the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[out] val The byte value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PARCEL_ERROR_NO_DATA No data available
+ * @retval #PARCEL_ERROR_ILLEGAL_BYTE_SEQ Illegal byte sequence
+ * @see parcel_write_uint8()
+ */
+int parcel_read_byte(parcel_h parcel, char *val);
+
+/**
+ * @brief Reads an unsigned short value from the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[out] val The unsigned short value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PARCEL_ERROR_NO_DATA No data available
+ * @retval #PARCEL_ERROR_ILLEGAL_BYTE_SEQ Illegal byte sequence
+ * @see parcel_write_uint16()
+ */
+int parcel_read_uint16(parcel_h parcel, uint16_t *val);
+
+/**
+ * @brief Reads an unsigned integer value from the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[out] val The unsigned integer value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PARCEL_ERROR_NO_DATA No data available
+ * @retval #PARCEL_ERROR_ILLEGAL_BYTE_SEQ Illegal byte sequence
+ * @see parcel_write_uint32()
+ */
+int parcel_read_uint32(parcel_h parcel, uint32_t *val);
+
+/**
+ * @brief Reads an unsigned long long integer value from the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[out] val The unsigned long long integer value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PARCEL_ERROR_NO_DATA No data available
+ * @retval #PARCEL_ERROR_ILLEGAL_BYTE_SEQ Illegal byte sequence
+ * @see parcel_write_uint64()
+ */
+int parcel_read_uint64(parcel_h parcel, uint64_t *val);
+
+/**
+ * @brief Reads a signed short value from the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[out] val The signed short value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PARCEL_ERROR_NO_DATA No data available
+ * @retval #PARCEL_ERROR_ILLEGAL_BYTE_SEQ Illegal byte sequence
+ * @see parcel_write_int16()
+ */
+int parcel_read_int16(parcel_h parcel, int16_t *val);
+
+/**
+ * @brief Reads a signed integer value from the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[out] val The signed integer value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PARCEL_ERROR_NO_DATA No data available
+ * @retval #PARCEL_ERROR_ILLEGAL_BYTE_SEQ Illegal byte sequence
+ * @see parcel_write_int32()
+ */
+int parcel_read_int32(parcel_h parcel, int32_t *val);
+
+/**
+ * @brief Reads a signed long long integer value from the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[out] val The signed long long integer value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PARCEL_ERROR_NO_DATA No data available
+ * @retval #PARCEL_ERROR_ILLEGAL_BYTE_SEQ Illegal byte sequence
+ * @see parcel_write_int64()
+ */
+int parcel_read_int64(parcel_h parcel, int64_t *val);
+
+/**
+ * @brief Reads a floating point value from the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[out] val The floating point value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PARCEL_ERROR_NO_DATA No data available
+ * @retval #PARCEL_ERROR_ILLEGAL_BYTE_SEQ Illegal byte sequence
+ * @see parcel_write_uint8()
+ */
+int parcel_read_float(parcel_h parcel, float *val);
+
+/**
+ * @brief Reads a double precision floating point value from the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[out] val The double precision floating point value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PARCEL_ERROR_NO_DATA No data available
+ * @retval #PARCEL_ERROR_ILLEGAL_BYTE_SEQ Illegal byte sequence
+ * @see parcel_write_uint8()
+ */
+int parcel_read_double(parcel_h parcel, double *val);
+
+/**
+ * @brief Reads a string data from the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[out] str The string data
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PARCEL_ERROR_NO_DATA No data available
+ * @retval #PARCEL_ERROR_ILLEGAL_BYTE_SEQ Illegal byte sequence
+ * @retval #PARCEL_ERROR_OUT_OF_MEMORY Out of memory
+ * @see parcel_write_uint8()
+ */
+int parcel_read_string(parcel_h parcel, char **str);
+
+/**
+ * @brief Resets the reader pointer of the parcel handle to the start.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int parcel_reset_reader(parcel_h parcel);
+
+/**
+ * @brief Clears the data of the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int parcel_clear(parcel_h parcel);
+
+/**
+ * @brief Resets the data of the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[in] buf The array buffer to write
+ * @param[in] size The size of bytes to write
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int parcel_reset(parcel_h parcel, const void *buf, uint32_t size);
+
+/**
+ * @brief Writes the data using @a parcelable to the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[in] parcelable The interface to write the data into the parcel handle
+ * @param[in] data The user data which writes into the parcel handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see parcel_read()
+ */
+int parcel_write(parcel_h parcel, parcelable_t *parcelable, void *data);
+
+/**
+ * @brief Reads the data using @a parcelable from the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[in] parcelable The interface to read the data from the parcel handle
+ * @param[in] data The user data which reads from the parcel handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see parcel_write()
+ */
+int parcel_read(parcel_h parcel, parcelable_t *parcelable, void *data);
+
+/**
+ * @brief Gets the raw data of the parcel handle.
+ * @since_tizen 6.5
+ * @remarks You MUST NOT release @a raw using free(). It's managed by platform.
+ * @param[in] parcel The parcel handle
+ * @param[out] raw The raw data
+ * @param[out] size The size of the raw data
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int parcel_get_raw(parcel_h parcel, void **raw, uint32_t *size);
+
+/**
+ * @brief Sets byte order of the parcel handle.
+ * @since_tizen 6.5
+ * @remarks The platform byte order is little-endian.
+ * The network byte order is defined to always be big-endian.
+ * If you want to change byte order of the raw data of the parcel handle,
+ * you set byte order of the parcel handle using the function.
+ * @param[in] parcel The parcel handle
+ * @param[in] big_endian @ true, if byte order of the parcel is big-endian
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int parcel_set_byte_order(parcel_h parcle, bool big_endian);
+
+/**
+ * @brief Gets the size of the data capacity of the parcel handle.
+ * @since_tizen 7.0
+ * @param[in] parcel The parcel handle
+ * @param[out] size The size of the data capacity
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int parcel_get_data_capacity(parcel_h parcel, size_t *size);
+
+/**
+ * @brief Sets the size of the data capacity of the parcel handle.
+ * @since_tizen 7.0
+ * @remarks The raw data will be reallocated using the given size.
+ * @param[in] parcel The parcel handle
+ * @param[in] size The size of the data capacity
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #PARCEL_ERROR_NONE Successful
+ * @retval #PARCEL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PARCEL_ERROR_OUT_OF_MEMORY
+ */
+int parcel_set_data_capacity(parcel_h parcel, size_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}
+ */
+
+#endif /* __PARCEL_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2020 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 PARCEL_COMMON_HH_
+#define PARCEL_COMMON_HH_
+
+#undef EXPORT
+#define EXPORT __attribute__((visibility("default")))
+
+#endif // PARCEL_COMMON_HH_
--- /dev/null
+/*
+ * Copyright (c) 2020 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 PARCEL_LOG_PRIVATE_HH_
+#define PARCEL_LOG_PRIVATE_HH_
+
+#include <dlog.h>
+
+#undef LOG_TAG
+#define LOG_TAG "PARCEL"
+
+#undef _E
+#define _E LOGE
+
+#undef _W
+#define _W LOGW
+
+#undef _I
+#define _I LOGI
+
+#undef _D
+#define _D LOGD
+
+#endif // PARCEL_LOG_PRIVATE_HH_
--- /dev/null
+/*
+ * Copyright (c) 2020 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 <glib.h>
+
+#include <exception>
+#include <mutex>
+
+#include "parcel/common.hh"
+#include "parcel/log_private.hh"
+#include "parcel/parcel.hh"
+#include "parcel/parcel_implementation.hh"
+#include "parcel/parcelable.hh"
+
+namespace tizen_base {
+namespace {
+
+constexpr const size_t kDataCapacity = 1024;
+
+} // namespace
+
+Parcel::Impl::Impl(Parcel* parent, size_t data_capacity, uint8_t* data)
+ : parent_(parent), data_capacity_(data_capacity), data_(data) {
+ if (data_ != nullptr)
+ data_size_ = data_capacity_;
+ else
+ data_ = static_cast<uint8_t*>(malloc(data_capacity_));
+}
+
+Parcel::Impl::~Impl() {
+ free(data_);
+}
+
+void Parcel::Impl::Write(const void* buf, uint32_t size) {
+ if (data_size_ + size > data_capacity_) {
+ size_t new_size = (data_capacity_ + size) * 3 / 2;
+ uint8_t* data = static_cast<uint8_t*>(realloc(data_, new_size));
+ if (data == nullptr)
+ throw std::bad_alloc();
+
+ data_ = data;
+ data_capacity_ = new_size;
+ }
+
+ memcpy(data_ + data_size_, buf, size);
+ data_size_ += size;
+}
+
+int Parcel::Impl::Read(void* buf, uint32_t size) {
+ if (data_size_ == 0)
+ return TIZEN_ERROR_NO_DATA;
+
+ if (reader_ + size > data_size_)
+ return TIZEN_ERROR_ILLEGAL_BYTE_SEQ;
+
+ memcpy(buf, data_ + reader_, size);
+ reader_ += size;
+ set_last_result(TIZEN_ERROR_NONE);
+ return TIZEN_ERROR_NONE;
+}
+
+void Parcel::Impl::ResetReader() {
+ reader_ = 0;
+}
+
+void Parcel::Impl::Clear() {
+ data_size_ = 0;
+ reader_ = 0;
+}
+
+void Parcel::Impl::Reset(const void* buf, uint32_t size) {
+ Clear();
+ Write(buf, size);
+}
+
+bool Parcel::Impl::IsEmpty() {
+ return data_size_ == 0;
+}
+
+void Parcel::Impl::WriteSize(uint32_t size) {
+ if (IsBigEndian())
+ size = GUINT32_TO_BE(size);
+
+ Write<uint32_t>(size);
+}
+
+template <typename T>
+void Parcel::Impl::Write(T d) {
+ if (data_size_ + sizeof(T) > data_capacity_) {
+ size_t new_size = (data_capacity_ + sizeof(T)) * 3 / 2;
+ uint8_t* data = static_cast<uint8_t*>(realloc(data_, new_size));
+ if (data == nullptr)
+ throw std::bad_alloc();
+
+ data_ = data;
+ data_capacity_ = new_size;
+ }
+
+ auto* p = reinterpret_cast<uint8_t*>(&d);
+ memcpy(data_ + data_size_, p, sizeof(T));
+ data_size_ += sizeof(T);
+}
+
+int Parcel::Impl::ReadSize(uint32_t* size) {
+ if (data_size_ == 0)
+ return TIZEN_ERROR_NO_DATA;
+
+ int ret = Read<uint32_t>(size);
+ if (ret != TIZEN_ERROR_NONE)
+ return ret;
+
+ if (IsBigEndian())
+ *size = GUINT32_FROM_BE(*size);
+
+ return TIZEN_ERROR_NONE;
+}
+
+template <typename T>
+int Parcel::Impl::Read(T* d) {
+ uint32_t size = static_cast<uint32_t>(sizeof(T));
+ if (reader_ + size > data_size_)
+ return TIZEN_ERROR_ILLEGAL_BYTE_SEQ;
+
+ auto* p = reinterpret_cast<uint8_t*>(d);
+ memcpy(p, data_ + reader_, size);
+ reader_ += size;
+ return TIZEN_ERROR_NONE;
+}
+
+void Parcel::Impl::SetByteOrder(bool big_endian) {
+ big_endian_ = big_endian;
+}
+
+bool Parcel::Impl::IsBigEndian() const {
+ return big_endian_;
+}
+
+uint8_t* Parcel::Impl::GetData() const {
+ return data_;
+}
+
+size_t Parcel::Impl::GetDataSize() const {
+ return data_size_;
+}
+
+size_t Parcel::Impl::GetDataCapacity() const {
+ return data_capacity_;
+}
+
+void Parcel::Impl::SetDataCapacity(size_t size) {
+ uint8_t* data = static_cast<uint8_t*>(realloc(data_, size));
+ if (data == nullptr)
+ throw std::bad_alloc();
+
+ data_ = data;
+ data_capacity_ = size;
+}
+
+uint8_t* Parcel::Impl::Detach(size_t* size) {
+ uint8_t* data = data_;
+ *size = data_size_;
+ data_ = nullptr;
+ data_capacity_ = 0;
+ data_size_ = 0;
+ reader_= 0;
+ return data;
+}
+
+uint32_t Parcel::Impl::GetReader() const {
+ return reader_;
+}
+
+std::vector<uint8_t> Parcel::Impl::ToRaw() {
+ return std::vector<uint8_t>(data_, data_ + data_size_);
+}
+
+Parcel::Parcel()
+ : impl_(new Impl(this, kDataCapacity, nullptr)) {
+ if (impl_->data_ == nullptr)
+ throw std::bad_alloc();
+}
+
+Parcel::Parcel(const void* buf, uint32_t size, bool copy)
+ : impl_(new Impl(this, size,
+ copy ? nullptr : static_cast<uint8_t*>(const_cast<void*>(buf)))) {
+ if (impl_->data_ == nullptr)
+ throw std::bad_alloc();
+
+ if (copy)
+ impl_->Write(buf, size);
+}
+
+Parcel::~Parcel() {};
+
+Parcel::Parcel(const Parcel& p)
+ : impl_(new Impl(this, kDataCapacity)) {
+ impl_->big_endian_ = p.impl_->big_endian_;
+ impl_->data_capacity_ = p.impl_->data_capacity_;
+ impl_->data_size_ = p.impl_->data_size_;
+
+ uint8_t* data = static_cast<uint8_t*>(
+ realloc(impl_->data_, impl_->data_capacity_));
+ if (data == nullptr)
+ throw std::bad_alloc();
+
+ impl_->data_ = data;
+ memcpy(impl_->data_, p.impl_->data_, impl_->data_size_);
+
+ impl_->reader_ = p.impl_->reader_;
+}
+
+Parcel& Parcel::operator = (const Parcel& p) {
+ if (this != &p) {
+ impl_->big_endian_ = p.impl_->big_endian_;
+ impl_->data_capacity_ = p.impl_->data_capacity_;
+ impl_->data_size_ = p.impl_->data_size_;
+
+ uint8_t* data = static_cast<uint8_t*>(
+ realloc(impl_->data_, impl_->data_capacity_));
+ if (data == nullptr)
+ throw std::bad_alloc();
+
+ impl_->data_ = data;
+ memcpy(impl_->data_, p.impl_->data_, impl_->data_size_);
+
+ impl_->reader_ = p.impl_->reader_;
+ }
+ return *this;
+}
+
+Parcel::Parcel(Parcel&& p) noexcept
+ : impl_(new Impl(this, kDataCapacity)) {
+ impl_->big_endian_ = p.impl_->big_endian_;
+
+ impl_->data_size_ = p.impl_->data_size_;
+ p.impl_->data_size_ = 0;
+
+ uint8_t* data = impl_->data_;
+ size_t data_capacity = impl_->data_capacity_;
+
+ impl_->data_ = p.impl_->data_;
+ impl_->data_capacity_ = p.impl_->data_capacity_;
+
+ p.impl_->data_ = data;
+ p.impl_->data_capacity_ = data_capacity;
+
+ impl_->reader_ = p.impl_->reader_;
+ p.impl_->reader_ = 0;
+}
+
+Parcel& Parcel::operator = (Parcel&& p) noexcept {
+ if (this != &p) {
+ impl_->big_endian_ = p.impl_->big_endian_;
+
+ impl_->data_size_ = p.impl_->data_size_;
+ p.impl_->data_size_ = 0;
+
+ uint8_t* data = impl_->data_;
+ size_t data_capacity = impl_->data_capacity_;
+
+ impl_->data_ = p.impl_->data_;
+ impl_->data_capacity_ = p.impl_->data_capacity_;
+
+ p.impl_->data_ = data;
+ p.impl_->data_capacity_ = data_capacity;
+
+ impl_->reader_ = p.impl_->reader_;
+ p.impl_->reader_ = 0;
+ }
+ return *this;
+}
+
+bool Parcel::IsEmpty() const noexcept {
+ return impl_->IsEmpty();
+}
+
+void Parcel::Write(const void* buf, uint32_t size) {
+ impl_->Write(buf, size);
+}
+
+int Parcel::Read(void* buf, uint32_t size) {
+ return impl_->Read(buf, size);
+}
+
+void Parcel::WriteBool(bool val) {
+ impl_->Write<bool>(val);
+}
+
+void Parcel::WriteByte(char val) {
+ impl_->Write<char>(val);
+}
+
+void Parcel::WriteUInt16(uint16_t val) {
+ if (impl_->IsBigEndian())
+ val = GUINT16_TO_BE(val);
+
+ impl_->Write<uint16_t>(val);
+}
+
+void Parcel::WriteUInt32(uint32_t val) {
+ if (impl_->IsBigEndian())
+ val = GUINT32_TO_BE(val);
+
+ impl_->Write<uint32_t>(val);
+}
+
+void Parcel::WriteUInt64(uint64_t val) {
+ if (impl_->IsBigEndian())
+ val = GUINT64_TO_BE(val);
+
+ impl_->Write<uint64_t>(val);
+}
+
+void Parcel::WriteInt16(int16_t val) {
+ if (impl_->IsBigEndian())
+ val = GINT16_TO_BE(val);
+
+ impl_->Write<int16_t>(val);
+}
+
+void Parcel::WriteInt32(int32_t val) {
+ if (impl_->IsBigEndian())
+ val = GINT32_TO_BE(val);
+
+ impl_->Write<int32_t>(val);
+}
+
+void Parcel::WriteInt64(int64_t val) {
+ if (impl_->IsBigEndian())
+ val = GINT64_TO_BE(val);
+
+ impl_->Write<int64_t>(val);
+}
+
+void Parcel::WriteFloat(float val) {
+ if (impl_->IsBigEndian())
+ val = static_cast<float>(GINT32_TO_BE(val));
+
+ impl_->Write<float>(val);
+}
+
+void Parcel::WriteDouble(double val) {
+ if (impl_->IsBigEndian())
+ val = static_cast<double>(GINT64_TO_BE(val));
+
+ impl_->Write<double>(val);
+}
+
+void Parcel::WriteString(const std::string& str) {
+ impl_->WriteSize(str.length() + 1);
+ impl_->Write(str.c_str(), str.length() + 1);
+}
+
+void Parcel::WriteCString(const char* str) {
+ impl_->WriteSize(strlen(str) + 1);
+ impl_->Write(str, strlen(str) + 1);
+}
+
+int Parcel::ReadBool(bool* val) {
+ return impl_->Read<bool>(val);
+}
+
+int Parcel::ReadByte(char* val) {
+ return impl_->Read<char>(val);
+}
+
+int Parcel::ReadUInt16(uint16_t* val) {
+ int ret = impl_->Read<uint16_t>(val);
+ if (impl_->IsBigEndian())
+ *val = GUINT16_FROM_BE(*val);
+
+ return ret;
+}
+
+int Parcel::ReadUInt32(uint32_t* val) {
+ int ret = impl_->Read<uint32_t>(val);
+ if (impl_->IsBigEndian())
+ *val = GUINT32_FROM_BE(*val);
+
+ return ret;
+}
+
+int Parcel::ReadUInt64(uint64_t* val) {
+ int ret = impl_->Read<uint64_t>(val);
+ if (impl_->IsBigEndian())
+ *val = GUINT64_FROM_BE(*val);
+
+ return ret;
+}
+
+int Parcel::ReadInt16(int16_t* val) {
+ int ret = impl_->Read<int16_t>(val);
+ if (impl_->IsBigEndian())
+ *val = GINT16_FROM_BE(*val);
+
+ return ret;
+}
+
+int Parcel::ReadInt32(int32_t* val) {
+ int ret = impl_->Read<int32_t>(val);
+ if (impl_->IsBigEndian())
+ *val = GINT32_FROM_BE(*val);
+
+ return ret;
+}
+
+int Parcel::ReadInt64(int64_t* val) {
+ int ret = impl_->Read<int64_t>(val);
+ if (impl_->IsBigEndian())
+ *val = GINT64_FROM_BE(*val);
+
+ return ret;
+}
+
+int Parcel::ReadFloat(float* val) {
+ int ret = impl_->Read<float>(val);
+ if (impl_->IsBigEndian())
+ *val = static_cast<float>(GINT32_FROM_BE(*val));
+
+ return ret;
+}
+
+int Parcel::ReadDouble(double* val) {
+ int ret = impl_->Read<double>(val);
+ if (impl_->IsBigEndian())
+ *val = static_cast<double>(GINT64_FROM_BE(*val));
+
+ return ret;
+}
+
+std::string Parcel::ReadString() {
+ uint32_t len = 0;
+ int ret = impl_->ReadSize(&len);
+ if (ret != TIZEN_ERROR_NONE) {
+ set_last_result(ret);
+ return {};
+ }
+
+ char* str = new (std::nothrow) char[len];
+ if (str == nullptr) {
+ set_last_result(TIZEN_ERROR_OUT_OF_MEMORY);
+ return {};
+ }
+
+ auto ptr = std::unique_ptr<char[]>(str);
+ ret = impl_->Read(str, len);
+ if (ret != TIZEN_ERROR_NONE) {
+ set_last_result(ret);
+ return {};
+ }
+
+ set_last_result(TIZEN_ERROR_NONE);
+ return std::string(str);
+}
+
+int Parcel::ReadCString(char** str) {
+ uint32_t len = 0;
+ int ret = impl_->ReadSize(&len);
+ if (ret != TIZEN_ERROR_NONE)
+ return ret;
+
+ char* val = static_cast<char*>(calloc(len, sizeof(char)));
+ if (val == nullptr)
+ return TIZEN_ERROR_OUT_OF_MEMORY;
+
+ ret = impl_->Read(val, len);
+ if (ret != TIZEN_ERROR_NONE) {
+ free(val);
+ return ret;
+ }
+
+ *str = val;
+ return TIZEN_ERROR_NONE;
+}
+
+void Parcel::ResetReader() {
+ impl_->ResetReader();
+}
+
+void Parcel::Clear() {
+ impl_->Clear();
+}
+
+void Parcel::Reset(const void* buf, uint32_t size) {
+ impl_->Reset(buf, size);
+}
+
+void Parcel::WriteParcelable(const Parcelable& parcelable) {
+ parcelable.WriteToParcel(this);
+}
+
+int Parcel::ReadParcelable(Parcelable* parcelable) {
+ parcelable->ReadFromParcel(this);
+ return TIZEN_ERROR_NONE;
+}
+
+void Parcel::SetByteOrder(bool big_endian) {
+ impl_->SetByteOrder(big_endian);
+}
+
+uint8_t* Parcel::GetData() const {
+ return impl_->GetData();
+}
+
+size_t Parcel::GetDataSize() const {
+ return impl_->GetDataSize();
+}
+
+size_t Parcel::GetDataCapacity() const {
+ return impl_->GetDataCapacity();
+}
+
+void Parcel::SetDataCapacity(size_t size) {
+ impl_->SetDataCapacity(size);
+}
+
+uint8_t* Parcel::Detach(size_t* size) {
+ return impl_->Detach(size);
+}
+
+uint32_t Parcel::GetReader() const {
+ return impl_->GetReader();
+}
+
+std::vector<uint8_t> Parcel::ToRaw() {
+ return impl_->ToRaw();
+}
+
+} // namespace tizen_base
--- /dev/null
+/*
+ * Copyright (c) 2020 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 PARCEL_PARCEL_HH_
+#define PARCEL_PARCEL_HH_
+
+/**
+ * @addtogroup CORE_LIB_PARCEL_MODULE
+ * @{
+ */
+
+#include <tizen.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "parcel/common.hh"
+#include "parcel/parcelable.hh"
+
+namespace tizen_base {
+
+/**
+ * @brief The class for Parcel API.
+ * @since_tizen 6.5
+ */
+class EXPORT Parcel final {
+ public:
+ /**
+ * @brief Enumeration for parcel error.
+ * @since_tizen 6.5
+ */
+ enum Error {
+ None = TIZEN_ERROR_NONE, /**< Successful */
+ IllegalByteSeq = TIZEN_ERROR_ILLEGAL_BYTE_SEQ, /**< Illegal byte sequence */
+ InvalidParameter = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
+ NoData = TIZEN_ERROR_NO_DATA, /**< No data available */
+ OutOfMemory = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */
+ };
+
+ /**
+ * @brief Constructor.
+ * @since_tizen 6.5
+ */
+ Parcel();
+
+ /**
+ * @brief Constructor
+ * @since_tizen 6.5
+ * @param[in] buf The bytes to write
+ * @param[in] size the size of bytes to write
+ * @param[in] copy If @c is true, this object copies bytes.
+ * If @c is false, this object takes ownership of @buf.
+ */
+ Parcel(const void* buf, uint32_t size, bool copy = true);
+
+ /**
+ * @brief Destructor
+ * @since_tizen 6.5
+ */
+ ~Parcel();
+
+ /**
+ * @brief Copy-constructor.
+ * @since_tizen 6.5
+ * @param[in] p The object to copy
+ */
+ Parcel(const Parcel& p);
+
+ /**
+ * @brief Assignment.
+ * @since_tizen 6.5
+ * @param[in] b The object to copy
+ */
+ Parcel& operator = (const Parcel& p);
+
+ /**
+ * @brief Move-constructor.
+ * @since_tizen 6.5
+ * @param[in] p The object to move
+ */
+ Parcel(Parcel&& p) noexcept;
+
+ /**
+ * @brief Assignment.
+ * @since_tizen 6.5
+ * @param[in] p The object to move
+ */
+ Parcel& operator = (Parcel&& p) noexcept;
+
+ /**
+ * @brief Checks the parcel is empty or not.
+ * @since_tizen 6.5
+ * @return true if the parcel is empty
+ */
+ bool IsEmpty() const noexcept;
+
+ /**
+ * @brief Writes bytes into the parcel.
+ * @since_tizen 6.5
+ * @param[in] buf The bytes to write
+ * @param[in] size The size of bytes to write
+ */
+ void Write(const void* buf, uint32_t size);
+
+ /**
+ * @brief Reads bytes from the parcel.
+ * @since_tizen 6.5
+ * @param[out] buf The bytes to read
+ * @param[in] size The size of bytes to read
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ */
+ int Read(void* buf, uint32_t size);
+
+ /**
+ * @brief Writes a boolean value into the parcel.
+ * @since_tizen 6.5
+ * @param[in] val The boolean value
+ */
+ void WriteBool(bool val);
+
+ /**
+ * @brief Writes a byte value into the parcel.
+ * @since_tizen 6.5
+ * @param[in] val The unsigned byte value
+ */
+ void WriteByte(char byte);
+
+ /**
+ * @brief Writes an unsigned short value into the parcel.
+ * @since_tizen 6.5
+ * @param[in] val The unsigned short value
+ */
+ void WriteUInt16(uint16_t val);
+
+ /**
+ * @brief Writes an unsigned integer value into the parcel.
+ * @since_tizen 6.5
+ * @param[in] val The unsigned integer value
+ */
+ void WriteUInt32(uint32_t val);
+
+ /**
+ * @brief Writes an unsigned long long integer into the parcel.
+ * @since_tizen 6.5
+ * @param[in] val The unsigned long long integer value
+ */
+ void WriteUInt64(uint64_t val);
+
+ /**
+ * @brief Writes a signed short value into the parcel.
+ * @since_tizen 6.5
+ * @param[in] val The signed short value
+ */
+ void WriteInt16(int16_t val);
+
+ /**
+ * @brief Writes a signed integer value into the parcel.
+ * @since_tizen 6.5
+ * @param[in] val The signed integer value
+ */
+ void WriteInt32(int32_t val);
+
+ /**
+ * @brief Writes a signed long long integer value into the parcel.
+ * @since_tizen 6.5
+ * @param[in] val The signed long long integer value
+ */
+ void WriteInt64(int64_t val);
+
+ /**
+ * @brief Writes a floating point value into the parcel.
+ * @since_tizen 6.5
+ * @param[in] val The floating point value
+ */
+ void WriteFloat(float val);
+
+ /**
+ * @brief Writes a double precision floating point value into the parcel.
+ * @since_tizen 6.5
+ * @param[in] val The double precision floating point value
+ */
+ void WriteDouble(double val);
+
+ /**
+ * @brief Writes a string data into the parcel.
+ * @since_tizen 6.5
+ * @param[in] str The string data
+ */
+ void WriteString(const std::string& str);
+
+ /**
+ * @brief Writes a string data into the parcel.
+ * @since_tizen 6.5
+ * @param[in] str The string data
+ */
+ void WriteCString(const char* str);
+
+ /**
+ * @brief Reads a boolean value from the parcel.
+ * @since_tizen 6.5
+ * @param[out] val The boolean value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ */
+ int ReadBool(bool* val);
+
+ /**
+ * @brief Reads a byte value from the parcel.
+ * @since_tizen 6.5
+ * @param[out] val The unsigned byte value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ */
+ int ReadByte(char* val);
+
+ /**
+ * @breif Reads an unsigned short value from the parcel.
+ * @since_tizen 6.5
+ * @param[out] val The unsigned short value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ */
+ int ReadUInt16(uint16_t* val);
+
+ /**
+ * @brief Reads an unsigned integer value from the parcel.
+ * @since_tizen 6.5
+ * @param[out] val The unsigned integer value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ */
+ int ReadUInt32(uint32_t* val);
+
+ /**
+ * @brief Reads an unsigned long long integer value from the parcel.
+ * @since_tizen 6.5
+ * @param[out] val The unsigned long long integer value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ */
+ int ReadUInt64(uint64_t* val);
+
+ /**
+ * @brief Reads a signed byte value from the parcel.
+ * @since_tizen 6.5
+ * @param[out] val The signed byte value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ */
+ int ReadInt8(int8_t* val);
+
+ /**
+ * @brief Reads a signed short value from the parcel.
+ * @since_tizen 6.5
+ * @param[out] val The signed short value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ */
+ int ReadInt16(int16_t* val);
+
+ /**
+ * @brief Reads a signed integer value from the parcel.
+ * @since_tizen 6.5
+ * @param[out] val The signed integer value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ */
+ int ReadInt32(int32_t* val);
+
+ /**
+ * @brief Reads a signed long long integer value from the parcel.
+ * @since_tizen 6.5
+ * @param[out] val The signed long long integer value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ */
+ int ReadInt64(int64_t* val);
+
+ /**
+ * @brief Reads a floating point value from the parcel.
+ * @since_tizen 6.5
+ * @param[out] val The floating point value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ */
+ int ReadFloat(float* val);
+
+ /**
+ * @brief Reads a double precision floating point value from the parcel.
+ * @since_tizen 6.5
+ * @param[out] val The double precision floating point value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ */
+ int ReadDouble(double* val);
+
+ /**
+ * @brief Reads a string data from the parcel.
+ * @since_tizen 6.5
+ * @return The string data
+ * @remarks Before using the returned value, you should check the result using get_last_result().
+ * @see get_last_result()
+ */
+ std::string ReadString();
+
+ /**
+ * @brief Reads a string data from the parcel.
+ * @since_tizen 6.5
+ * @remarks You should release @a str using free().
+ * @param[out] str The string data
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ */
+ int ReadCString(char** str);
+
+ /**
+ * @brief Resets the reader pointer of the parcel to the start.
+ * @since_tizen 6.5
+ */
+ void ResetReader();
+
+ /**
+ * @brief Clears the data of the parcel.
+ * @since_tizen 6.5
+ */
+ void Clear();
+
+ /**
+ * @brief Resets the parcel.
+ * @since_tizen 6.5
+ * @param[in] buf The bytes to write
+ * @param[in] size The size of bytes to write
+ */
+ void Reset(const void* buf, uint32_t size);
+
+ /**
+ * @brief Writes the data using @a parcelable into the parcel.
+ * @since_tizen 6.5
+ * @param[in] parcelable The interface to write the data into the parcel
+ */
+ void WriteParcelable(const Parcelable& parcelable);
+
+ /**
+ * @brief Reads the data using @a parcelable from the parcel.
+ * @since_tizen 6.5
+ * @param[out] parcelable The interface to get data from the parcel
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ */
+ int ReadParcelable(Parcelable* parcelable);
+
+ /**
+ * @brief Sets byte order of the parcel.
+ * @since_tizen 6.5
+ * @param[in] big_endian @c true, if byte order of the parcel is big-endian
+ */
+ void SetByteOrder(bool big_endian);
+
+ /**
+ * @brief Gets the raw data of the parcel.
+ * @since_tizen 7.0
+ * @return The raw data
+ */
+ uint8_t* GetData() const;
+
+ /**
+ * @breif Gets the size of the raw data of the parcel.
+ * @since_tizen 7.0
+ * @return The size of the raw data
+ */
+ size_t GetDataSize() const;
+
+ /**
+ * @brief Gets the size of the data capacity of the parcel.
+ * @since_tizen 7.0
+ * @return The size of the data capacity
+ */
+ size_t GetDataCapacity() const;
+
+ /**
+ * @breif Sets the size of the data capacity of the parcel.
+ * @since_tizen 7.0
+ * @param[in] size The size of the data capcity
+ */
+ void SetDataCapacity(size_t size);
+
+ /**
+ * @brief Detaches the raw data from the parcel.
+ * @since_tizen 7.0
+ * @param[out] size The size of the raw data
+ * @return The raw data
+ */
+ uint8_t* Detach(size_t* size);
+
+ /**
+ * @brief Gets the position of the reader of the parcel.
+ * @since_tizen 7.0
+ * @return The position of the reader
+ */
+ uint32_t GetReader() const;
+
+ /**
+ * @brief Converts the raw data of the parcel to the vector.
+ * @since_tizen 7.0
+ * @return The vector of the raw data
+ */
+ std::vector<uint8_t> ToRaw();
+
+ private:
+ class Impl;
+ std::unique_ptr<Impl> impl_;
+};
+
+} // naemspace tizen_base
+
+/**
+ * @}
+ */
+
+#endif // PARCEL_PARCEL_HH_
--- /dev/null
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=${prefix}
+libdir=@LIB_INSTALL_DIR@
+includedir=${prefix}/include
+
+Name: parcel
+Description: Parcel library
+Version: @VERSION@
+Requires: capi-base-common
+Libs: -L${libdir} -lparcel
+Cflags: -I${includedir} -I${includedir}/parcel
+cppflags: -I${includedir} -I${includedir}/parcel
--- /dev/null
+/*
+ * Copyright (c) 2020 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 PARCEL_PARCEL_IMPLEMENTATION_HH_
+#define PARCEL_PARCEL_IMPLEMENTATION_HH_
+
+#include <string>
+#include <vector>
+
+#include "parcel/parcel.hh"
+#include "parcel/parcelable.hh"
+
+namespace tizen_base {
+
+class Parcel::Impl {
+ public:
+ virtual ~Impl();
+
+ void Write(const void* buf, uint32_t size);
+ int Read(void* buf, uint32_t size);
+ void ResetReader();
+ void Clear();
+ void Reset(const void* buf, uint32_t size);
+ bool IsEmpty();
+ void WriteSize(uint32_t size);
+ int ReadSize(uint32_t* size);
+
+ template <typename T>
+ void Write(T d);
+ template <typename T>
+ int Read(T* d);
+
+ void SetByteOrder(bool big_endian);
+ bool IsBigEndian() const;
+ uint8_t* GetData() const;
+ size_t GetDataSize() const;
+ size_t GetDataCapacity() const;
+ void SetDataCapacity(size_t size);
+ uint8_t* Detach(size_t* size);
+ uint32_t GetReader() const;
+ std::vector<uint8_t> ToRaw();
+
+ private:
+ friend class Parcel;
+ explicit Impl(Parcel* parent, size_t data_capacity, uint8_t* data = nullptr);
+
+ private:
+ Parcel* parent_;
+ size_t data_capacity_;
+ bool big_endian_ = false;
+ size_t data_size_ = 0;
+ uint8_t* data_ = nullptr;
+ uint32_t reader_ = 0;
+};
+
+} // naemspace tizen_base
+
+#endif // PARCEL_PARCEL_IMPLEMENTATION_HH_
--- /dev/null
+/*
+ * Copyright (c) 2020 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 PARCEL_PARCELABLE_HH_
+#define PARCEL_PARCELABLE_HH_
+
+/**
+ * @addtogroup CORE_LIB_PARCEL_MODULE
+ * @{
+ */
+
+#include "parcel/common.hh"
+
+namespace tizen_base {
+
+class Parcel;
+
+/**
+ * @brief The Parcelable interface.
+ * @since_tizen 6.5
+ */
+class EXPORT Parcelable {
+ public:
+ /**
+ * @brief Constructor.
+ * @since_tizen 6.5
+ */
+ Parcelable() = default;
+
+ /**
+ * @brief Copy constructor.
+ * @since_tizen 6.5
+ */
+ Parcelable(const Parcelable&) = default;
+
+ /**
+ * @brief Destructor.
+ * @since_tizen 6.5
+ */
+ virtual ~Parcelable() = default;
+
+ /**
+ * @brief Writes the data into the parcel.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel object
+ */
+ virtual void WriteToParcel(Parcel* parcel) const = 0;
+
+ /**
+ * @brief Reads the data from the parcel.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel object
+ */
+ virtual void ReadFromParcel(Parcel* parcel) = 0;
+};
+
+} // naemspace tizen_base
+
+/**
+ * @}
+ */
+
+#endif // PARCEL_PARCELABLE_HH_
--- /dev/null
+/*
+ * Copyright (c) 2020 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 "parcel/api/parcel.h"
+
+#include <exception>
+
+#include "parcel/common.hh"
+#include "parcel/log_private.hh"
+#include "parcel/parcel.hh"
+#include "parcel/parcelable.hh"
+
+using namespace tizen_base;
+
+extern "C" EXPORT int parcel_create(parcel_h *parcel) {
+ if (parcel == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = new (std::nothrow) Parcel();
+ if (h == nullptr) {
+ _E("Out of memory");
+ return PARCEL_ERROR_OUT_OF_MEMORY;
+ }
+
+ *parcel = static_cast<parcel_h>(h);
+ return PARCEL_ERROR_NONE;
+}
+
+extern "C" EXPORT int parcel_destroy(parcel_h parcel) {
+ if (parcel == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ delete h;
+ return PARCEL_ERROR_NONE;
+}
+
+extern "C" EXPORT int parcel_clone(parcel_h parcel, parcel_h* clone) {
+ if (parcel == nullptr || clone == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ auto* c = new (std::nothrow) Parcel(*h);
+ if (c == nullptr) {
+ _E("Out of memory");
+ return PARCEL_ERROR_OUT_OF_MEMORY;
+ }
+
+ *clone = static_cast<parcel_h>(c);
+ return PARCEL_ERROR_NONE;
+}
+
+extern "C" EXPORT int parcel_burst_write(parcel_h parcel, const void *buf,
+ uint32_t size) {
+ if (parcel == nullptr || buf == nullptr || size == 0) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ h->Write(buf, size);
+ return PARCEL_ERROR_NONE;
+}
+
+extern "C" EXPORT int parcel_burst_read(parcel_h parcel, void *buf,
+ uint32_t size) {
+ if (parcel == nullptr || buf == nullptr || size == 0) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ h->Read(buf, size);
+ return PARCEL_ERROR_NONE;
+}
+
+extern "C" EXPORT int parcel_write_bool(parcel_h parcel, bool val) {
+ if (parcel == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ h->WriteBool(val);
+ return PARCEL_ERROR_NONE;
+}
+
+extern "C" EXPORT int parcel_write_byte(parcel_h parcel, char val) {
+ if (parcel == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ h->WriteByte(val);
+ return PARCEL_ERROR_NONE;
+}
+
+extern "C" EXPORT int parcel_write_uint16(parcel_h parcel, uint16_t val) {
+ if (parcel == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ h->WriteUInt16(val);
+ return PARCEL_ERROR_NONE;
+}
+
+extern "C" EXPORT int parcel_write_uint32(parcel_h parcel, uint32_t val) {
+ if (parcel == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ h->WriteUInt32(val);
+ return PARCEL_ERROR_NONE;
+}
+
+extern "C" EXPORT int parcel_write_uint64(parcel_h parcel, uint64_t val) {
+ if (parcel == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ h->WriteUInt64(val);
+ return PARCEL_ERROR_NONE;
+}
+
+extern "C" EXPORT int parcel_write_int16(parcel_h parcel, int16_t val) {
+ if (parcel == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ h->WriteInt16(val);
+ return PARCEL_ERROR_NONE;
+}
+
+extern "C" EXPORT int parcel_write_int32(parcel_h parcel, int32_t val) {
+ if (parcel == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ h->WriteInt32(val);
+ return PARCEL_ERROR_NONE;
+}
+
+extern "C" EXPORT int parcel_write_int64(parcel_h parcel, int64_t val) {
+ if (parcel == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ h->WriteInt64(val);
+ return PARCEL_ERROR_NONE;
+}
+
+extern "C" EXPORT int parcel_write_float(parcel_h parcel, float val) {
+ if (parcel == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ h->WriteFloat(val);
+ return PARCEL_ERROR_NONE;
+}
+
+extern "C" EXPORT int parcel_write_double(parcel_h parcel, double val) {
+ if (parcel == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ h->WriteDouble(val);
+ return PARCEL_ERROR_NONE;
+}
+
+extern "C" EXPORT int parcel_write_string(parcel_h parcel, const char* str) {
+ if (parcel == nullptr || str == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ h->WriteCString(str);
+ return PARCEL_ERROR_NONE;
+}
+
+extern "C" EXPORT int parcel_read_bool(parcel_h parcel, bool* val) {
+ if (parcel == nullptr || val == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ return h->ReadBool(val);
+}
+
+extern "C" EXPORT int parcel_read_byte(parcel_h parcel, char* val) {
+ if (parcel == nullptr || val == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ return h->ReadByte(val);
+}
+
+extern "C" EXPORT int parcel_read_uint16(parcel_h parcel, uint16_t* val) {
+ if (parcel == nullptr || val == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ return h->ReadUInt16(val);
+}
+
+extern "C" EXPORT int parcel_read_uint32(parcel_h parcel, uint32_t* val) {
+ if (parcel == nullptr || val == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ return h->ReadUInt32(val);
+}
+
+extern "C" EXPORT int parcel_read_uint64(parcel_h parcel, uint64_t* val) {
+ if (parcel == nullptr || val == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ return h->ReadUInt64(val);
+}
+
+extern "C" EXPORT int parcel_read_int16(parcel_h parcel, int16_t* val) {
+ if (parcel == nullptr || val == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ return h->ReadInt16(val);
+}
+
+extern "C" EXPORT int parcel_read_int32(parcel_h parcel, int32_t* val) {
+ if (parcel == nullptr || val == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ return h->ReadInt32(val);
+}
+
+extern "C" EXPORT int parcel_read_int64(parcel_h parcel, int64_t* val) {
+ if (parcel == nullptr || val == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ return h->ReadInt64(val);
+}
+
+extern "C" EXPORT int parcel_read_float(parcel_h parcel, float* val) {
+ if (parcel == nullptr || val == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ return h->ReadFloat(val);
+}
+
+extern "C" EXPORT int parcel_read_double(parcel_h parcel, double* val) {
+ if (parcel == nullptr || val == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ return h->ReadDouble(val);
+}
+
+extern "C" EXPORT int parcel_read_string(parcel_h parcel, char** str) {
+ if (parcel == nullptr || str == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ return h->ReadCString(str);
+}
+
+extern "C" EXPORT int parcel_reset_reader(parcel_h parcel) {
+ if (parcel == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ h->ResetReader();
+ return PARCEL_ERROR_NONE;
+}
+
+extern "C" EXPORT int parcel_clear(parcel_h parcel) {
+ if (parcel == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ h->Clear();
+ return PARCEL_ERROR_NONE;
+}
+
+extern "C" EXPORT int parcel_reset(parcel_h parcel, const void* buf,
+ uint32_t size) {
+ if (parcel == nullptr || buf == nullptr || size == 0) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ h->Reset(buf, size);
+ return PARCEL_ERROR_NONE;
+}
+
+extern "C" EXPORT int parcel_write(parcel_h parcel, parcelable_t* parcelable,
+ void* data) {
+ if (parcel == nullptr || parcelable == nullptr || parcelable->to == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ parcelable->to(parcel, data);
+ return PARCEL_ERROR_NONE;
+}
+
+extern "C" EXPORT int parcel_read(parcel_h parcel, parcelable_t* parcelable,
+ void* data) {
+ if (parcel == nullptr || parcelable == nullptr ||
+ parcelable->from == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ parcelable->from(parcel, data);
+ return PARCEL_ERROR_NONE;
+}
+
+extern "C" EXPORT int parcel_get_raw(parcel_h parcel, void** raw,
+ uint32_t* size) {
+ if (parcel == nullptr || raw == nullptr || size == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ *raw = reinterpret_cast<void*>(h->GetData());
+ *size = static_cast<uint32_t>(h->GetDataSize() & UINT32_MAX);
+ return PARCEL_ERROR_NONE;
+}
+
+extern "C" EXPORT int parcel_set_byte_order(parcel_h parcel,
+ bool big_endian) {
+ if (parcel == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ h->SetByteOrder(big_endian);
+ return PARCEL_ERROR_NONE;
+}
+
+extern "C" EXPORT int parcel_get_data_capacity(parcel_h parcel,
+ size_t* size) {
+ if (parcel == nullptr || size == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ *size = h->GetDataCapacity();
+ return PARCEL_ERROR_NONE;
+}
+
+extern "C" EXPORT int parcel_set_data_capacity(parcel_h parcel,
+ size_t size) {
+ if (parcel == nullptr || size == 0) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ try {
+ h->SetDataCapacity(size);
+ } catch (const std::bad_alloc& e) {
+ _E("Exception occurs. error(%s)", e.what());
+ return PARCEL_ERROR_OUT_OF_MEMORY;
+ }
+
+ return PARCEL_ERROR_NONE;
+}
+++ /dev/null
-/*
- * Copyright (c) 2020 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 <tizen.h>
-#include <glib.h>
-
-#include <stdexcept>
-
-#include "include/bundle.h"
-#include "include/bundle_internal.h"
-
-#include "bundle-internal.h"
-#include "exception-internal.h"
-#include "export-api-internal.h"
-#include "json-internal.h"
-
-using namespace tizen_base::internal;
-
-extern "C" EXPORT_API bundle* bundle_create(void) {
- auto* h = new (std::nothrow) Bundle();
- if (h == nullptr) {
- set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
- return nullptr;
- }
-
- set_last_result(BUNDLE_ERROR_NONE);
- return reinterpret_cast<bundle*>(h);
-}
-
-extern "C" EXPORT_API int bundle_free(bundle* b) {
- if (b == nullptr)
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- auto* h = reinterpret_cast<Bundle*>(b);
- delete h;
- return BUNDLE_ERROR_NONE;
-}
-
-extern "C" EXPORT_API int bundle_add_str(bundle* b,
- const char* key, const char* str) {
- if (b == nullptr || key == nullptr || strlen(key) == 0 || str == nullptr)
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- auto* h = reinterpret_cast<Bundle*>(b);
- std::vector<unsigned char> value(str, str + (strlen(str) + 1));
-
- KeyInfo* key_info;
- try {
- key_info = new KeyInfo(BUNDLE_TYPE_STR, key, std::move(value));
- } catch (const Exception& e) {
- return e.GetErrorCode();
- } catch (const std::bad_alloc& ba) {
- return BUNDLE_ERROR_OUT_OF_MEMORY;
- }
-
- try {
- h->Add(std::shared_ptr<KeyInfo>(key_info));
- } catch (const Exception& e) {
- return e.GetErrorCode();
- }
-
- return BUNDLE_ERROR_NONE;
-}
-
-extern "C" EXPORT_API int bundle_get_str(bundle* b,
- const char* key, char** str) {
- if (b == nullptr || key == nullptr)
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- auto* h = reinterpret_cast<Bundle*>(b);
- std::shared_ptr<KeyInfo> key_info;
- try {
- key_info = h->Get(key);
- } catch (const Exception& e) {
- return e.GetErrorCode();
- }
-
- if (key_info->GetType() != BUNDLE_TYPE_STR)
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- if (str) {
- auto& values = key_info->GetValues();
- auto& value = const_cast<std::unique_ptr<unsigned char[]>&>(values[0]);
- *str = reinterpret_cast<char*>(&value[0]);
- }
-
- return BUNDLE_ERROR_NONE;
-}
-
-extern "C" EXPORT_API int bundle_add(bundle* b, const char* key,
- const char* val) {
- return bundle_add_str(b, key, val);
-}
-
-extern "C" EXPORT_API int bundle_del(bundle* b, const char* key) {
- if (b == nullptr || key == nullptr || strlen(key) == 0)
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- auto* h = reinterpret_cast<Bundle*>(b);
- try {
- h->Remove(key);
- } catch (const Exception& e) {
- return e.GetErrorCode();
- }
-
- return BUNDLE_ERROR_NONE;
-}
-
-extern "C" EXPORT_API const char* bundle_get_val(bundle* b, const char* key) {
- char* val = nullptr;
- int ret = bundle_get_str(b, key, &val);
- set_last_result(ret);
- return val;
-}
-
-extern "C" EXPORT_API int bundle_get_count(bundle* b) {
- if (b == nullptr)
- return 0;
-
- auto* h = reinterpret_cast<Bundle*>(b);
- set_last_result(BUNDLE_ERROR_NONE);
- return h->GetSize();
-}
-
-extern "C" EXPORT_API void bundle_iterate(bundle* b,
- bundle_iterate_cb_t callback, void* user_data) {
- if (b == nullptr || callback == nullptr) {
- set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
- return;
- }
-
- auto* h = reinterpret_cast<Bundle*>(b);
- for (const auto& [key, key_info] : h->GetMap()) {
- auto& values = key_info->GetValues();
- auto& value = const_cast<std::unique_ptr<unsigned char[]>&>(values[0]);
- auto* val = reinterpret_cast<char*>(&value[0]);
- callback(key_info->GetKey().c_str(), val, user_data);
- }
-
- set_last_result(BUNDLE_ERROR_NONE);
-}
-
-extern "C" EXPORT_API void bundle_foreach(bundle* b,
- bundle_iterator_t callback, void* user_data) {
- if (b == nullptr || callback == nullptr) {
- set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
- return;
- }
-
- auto* h = reinterpret_cast<Bundle*>(b);
- auto it = h->GetMap().begin();
- while (it != h->GetMap().end()) {
- auto& key_info = it->second;
- ++it;
- callback(key_info->GetKey().c_str(), key_info->GetType(),
- reinterpret_cast<bundle_keyval_t*>(key_info.get()), user_data);
- }
-
- set_last_result(BUNDLE_ERROR_NONE);
-}
-
-extern "C" EXPORT_API int bundle_keyval_get_type(bundle_keyval_t* kv) {
- if (kv == nullptr) {
- set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
- return -1;
- }
-
- auto* key_info = reinterpret_cast<KeyInfo*>(kv);
- set_last_result(BUNDLE_ERROR_NONE);
- return key_info->GetType();
-}
-
-extern "C" EXPORT_API int bundle_keyval_type_is_array(bundle_keyval_t* kv) {
- int type = bundle_keyval_get_type(kv);
- if (type == -1)
- return -1;
-
- set_last_result(BUNDLE_ERROR_NONE);
- if (type & BUNDLE_TYPE_ARRAY)
- return 1;
-
- return 0;
-}
-
-extern "C" EXPORT_API int bundle_keyval_type_is_measurable(
- bundle_keyval_t* kv) {
- int type = bundle_keyval_get_type(kv);
- if (type == -1)
- return -1;
-
- set_last_result(BUNDLE_ERROR_NONE);
- if (type & BUNDLE_TYPE_MEASURABLE)
- return 1;
-
- return 0;
-}
-
-extern "C" EXPORT_API int bundle_keyval_get_basic_val(bundle_keyval_t* kv,
- void** val, size_t* size) {
- if (kv == nullptr)
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- auto* key_info = reinterpret_cast<KeyInfo*>(kv);
- if (key_info->IsArray())
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- if (val) {
- auto& values = key_info->GetValues();
- auto& value = const_cast<std::unique_ptr<unsigned char[]>&>(values[0]);
- *val = reinterpret_cast<void*>(&value[0]);
- }
-
- if (size) {
- auto& values_size = key_info->GetValuesSize();
- *size = reinterpret_cast<size_t>(values_size[0]);
- }
-
- return BUNDLE_ERROR_NONE;
-}
-
-extern "C" EXPORT_API int bundle_keyval_get_array_val(bundle_keyval_t* kv,
- void*** array_val, unsigned int* array_len, size_t** array_item_size) {
- if (kv == nullptr)
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- auto* key_info = reinterpret_cast<KeyInfo*>(kv);
- if (!key_info->IsArray())
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- auto& values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
- key_info->GetValues());
-
- if (array_val)
- *array_val = reinterpret_cast<void**>(&values[0]);
-
- if (array_len)
- *array_len = static_cast<unsigned int>(values.size());
-
- if (array_item_size) {
- auto& values_size = const_cast<std::vector<std::size_t>&>(
- key_info->GetValuesSize());
- *array_item_size = reinterpret_cast<size_t*>(&values_size[0]);
- }
-
- return BUNDLE_ERROR_NONE;
-}
-
-extern "C" EXPORT_API bundle_keyval_t* bundle_keyval_dup(
- const bundle_keyval_t* kv) {
- if (kv == nullptr) {
- set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
- return nullptr;
- }
-
- auto* keyval = const_cast<bundle_keyval_t*>(kv);
- auto* key_info = reinterpret_cast<KeyInfo*>(keyval);
-
- KeyInfo* k;
- try {
- k = new KeyInfo(*key_info);
- } catch (const Exception& e) {
- set_last_result(e.GetErrorCode());
- return nullptr;
- } catch (const std::bad_alloc& ba) {
- set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
- return nullptr;
- }
-
- set_last_result(BUNDLE_ERROR_NONE);
- return reinterpret_cast<bundle_keyval_t*>(k);
-}
-
-extern "C" EXPORT_API int bundle_keyval_free(bundle_keyval_t* kv) {
- if (kv == nullptr)
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- auto* key_info = reinterpret_cast<KeyInfo*>(kv);
- delete key_info;
- return BUNDLE_ERROR_NONE;
-}
-
-extern "C" EXPORT_API bundle* bundle_dup(bundle* b_from) {
- if (b_from == nullptr) {
- set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
- return nullptr;
- }
-
- Bundle* b;
- try {
- auto* h = reinterpret_cast<Bundle*>(b_from);
- b = new Bundle(*h);
- } catch (const Exception& e) {
- set_last_result(e.GetErrorCode());
- return nullptr;
- } catch (const std::bad_alloc& e) {
- set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
- return nullptr;
- }
-
- set_last_result(BUNDLE_ERROR_NONE);
- return reinterpret_cast<bundle*>(b);
-}
-
-extern "C" EXPORT_API int bundle_encode(bundle *b, bundle_raw** raw, int* len) {
- if (b == nullptr || raw == nullptr || len == nullptr)
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- auto* h = reinterpret_cast<Bundle*>(b);
- try {
- *raw = reinterpret_cast<bundle_raw*>(h->Encode());
- } catch (const Exception& e) {
- *raw = nullptr;
- return e.GetErrorCode();
- }
-
- *len = strlen(reinterpret_cast<char*>(*raw));
- return BUNDLE_ERROR_NONE;
-}
-
-extern "C" EXPORT_API int bundle_free_encoded_rawdata(bundle_raw **r) {
- if (r == nullptr || *r == nullptr)
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- free(*r);
- *r = nullptr;
- return BUNDLE_ERROR_NONE;
-}
-
-extern "C" EXPORT_API bundle* bundle_decode(const bundle_raw* r,
- const int data_size) {
- if (r == nullptr) {
- set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
- return nullptr;
- }
-
- Bundle* b = nullptr;
- try {
- auto* raw = const_cast<bundle_raw*>(r);
- b = new Bundle(static_cast<unsigned char*>(raw), data_size);
- } catch (const Exception& e) {
- set_last_result(e.GetErrorCode());
- return nullptr;
- } catch (const std::bad_alloc& ba) {
- set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
- return nullptr;
- }
-
- set_last_result(BUNDLE_ERROR_NONE);
- return reinterpret_cast<bundle*>(b);
-}
-
-extern "C" EXPORT_API int bundle_encode_raw(bundle* b, bundle_raw** r,
- int* len) {
- if (b == nullptr || r == nullptr || len == nullptr)
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- auto* h = reinterpret_cast<Bundle*>(b);
- try {
- *r = reinterpret_cast<bundle_raw*>(h->EncodeRaw(len));
- } catch (const Exception& e) {
- return e.GetErrorCode();
- }
- return BUNDLE_ERROR_NONE;
-}
-
-extern "C" EXPORT_API bundle* bundle_decode_raw(const bundle_raw* r,
- const int data_size) {
- if (r == nullptr) {
- set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
- return nullptr;
- }
-
- Bundle* b = nullptr;
- try {
- auto* raw = const_cast<bundle_raw*>(r);
- b = new Bundle(static_cast<unsigned char*>(raw), data_size, false);
- } catch (const Exception& e) {
- set_last_result(e.GetErrorCode());
- return nullptr;
- } catch (const std::bad_alloc& ba) {
- set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
- return nullptr;
- }
-
- set_last_result(BUNDLE_ERROR_NONE);
- return reinterpret_cast<bundle*>(b);
-}
-
-extern "C" EXPORT_API int bundle_get_type(bundle* b, const char* key) {
- if (b == nullptr || key == nullptr) {
- set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
- return BUNDLE_TYPE_NONE;
- }
-
- auto* h = reinterpret_cast<Bundle*>(b);
- std::shared_ptr<KeyInfo> key_info;
- try {
- key_info = h->Get(key);
- } catch (const Exception& e) {
- set_last_result(e.GetErrorCode());
- return BUNDLE_TYPE_NONE;
- }
-
- set_last_result(BUNDLE_ERROR_NONE);
- return key_info->GetType();
-}
-
-extern "C" EXPORT_API int bundle_add_str_array(bundle* b, const char* key,
- const char** str_array, const int len) {
- if (b == nullptr || key == nullptr || strlen(key) == 0)
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- auto* h = reinterpret_cast<Bundle*>(b);
- std::vector<std::vector<unsigned char>> values(len);
- if (str_array) {
- for (int i = 0; i < len; ++i) {
- std::vector<unsigned char> value(str_array[i],
- str_array[i] + (strlen(str_array[i]) + 1));
- values[i] = std::move(value);
- }
- }
-
- try {
- auto key_info = std::make_shared<KeyInfo>(
- (BUNDLE_TYPE_STR_ARRAY | BUNDLE_TYPE_ARRAY), key, values);
- h->Add(std::move(key_info));
- } catch (const Exception& e) {
- return e.GetErrorCode();
- } catch (const std::bad_alloc& ba) {
- return BUNDLE_ERROR_OUT_OF_MEMORY;
- }
-
- return BUNDLE_ERROR_NONE;
-}
-
-extern "C" EXPORT_API const char** bundle_get_str_array(bundle* b,
- const char* key, int* len) {
- if (b == nullptr || key == nullptr) {
- set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
- return nullptr;
- }
-
- auto* h = reinterpret_cast<Bundle*>(b);
- std::shared_ptr<KeyInfo> key_info;
- try {
- key_info = h->Get(key);
- } catch (const Exception& e) {
- set_last_result(e.GetErrorCode());
- return nullptr;
- }
-
- if (key_info->GetType() != BUNDLE_TYPE_STR_ARRAY) {
- set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
- return nullptr;
- }
-
- set_last_result(BUNDLE_ERROR_NONE);
-
- auto& raw_values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
- key_info->GetValues());
-
- if (len)
- *len = static_cast<int>(raw_values.size());
-
- if (raw_values.size() == 0)
- return nullptr;
-
- auto** values = reinterpret_cast<unsigned char**>(&raw_values[0]);
- return const_cast<const char**>(reinterpret_cast<char**>(values));
-}
-
-extern "C" EXPORT_API int bundle_add_byte(bundle* b, const char* key,
- const void* bytes, const size_t size) {
- if (b == nullptr || key == nullptr || strlen(key) == 0)
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- auto* h = reinterpret_cast<Bundle*>(b);
- auto* p = reinterpret_cast<const unsigned char*>(bytes);
- std::vector<unsigned char> value;
- if (bytes)
- value.insert(value.end(), p, p + size);
-
- KeyInfo* key_info;
- try {
- key_info = new KeyInfo(BUNDLE_TYPE_BYTE, key, std::move(value));
- } catch (const Exception& e) {
- return e.GetErrorCode();
- } catch (const std::bad_alloc& ba) {
- return BUNDLE_ERROR_OUT_OF_MEMORY;
- }
-
- try {
- h->Add(std::shared_ptr<KeyInfo>(key_info));
- } catch (const Exception& e) {
- return e.GetErrorCode();
- }
-
- return BUNDLE_ERROR_NONE;
-}
-
-extern "C" EXPORT_API int bundle_get_byte(bundle* b, const char* key,
- void** bytes, size_t* size) {
- if (b == nullptr || key == nullptr)
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- auto* h = reinterpret_cast<Bundle*>(b);
- std::shared_ptr<KeyInfo> key_info;
- try {
- key_info = h->Get(key);
- } catch (const Exception& e) {
- return e.GetErrorCode();
- }
-
- if (key_info->GetType() != BUNDLE_TYPE_BYTE)
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- if (bytes) {
- auto& values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
- key_info->GetValues());
- if (values.size() == 0) {
- *bytes = nullptr;
- } else {
- auto& value = values[0];
- *bytes = reinterpret_cast<void*>(&value[0]);
- }
- }
-
- if (size) {
- auto& values_size = key_info->GetValuesSize();
- *size = reinterpret_cast<size_t>(values_size[0]);
- }
-
- return BUNDLE_ERROR_NONE;
-}
-
-extern "C" EXPORT_API int bundle_export_to_argv(bundle* b, char*** argv) {
- if (b == nullptr || argv == nullptr) {
- set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
- return -1;
- }
-
- auto* h = reinterpret_cast<Bundle*>(b);
- std::vector<std::string> exported_vt;
- try {
- exported_vt = h->Export();
- } catch (const Exception& e) {
- set_last_result(e.GetErrorCode());
- return -1;
- }
-
- int argc = exported_vt.size();
- auto** exported_argv = reinterpret_cast<char**>(
- calloc(argc + 1, sizeof(char*)));
- if (exported_argv == nullptr) {
- set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
- return -1;
- }
-
- exported_argv[1] = const_cast<char*>(TAG_IMPORT_EXPORT_CHECK);
- for (unsigned int idx = 2; idx < exported_vt.size(); idx += 2) {
- exported_argv[idx] = strdup(exported_vt[idx].c_str());
- if (exported_argv[idx] == nullptr) {
- set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
- bundle_free_exported_argv(idx + 1, &exported_argv);
- return -1;
- }
-
- exported_argv[idx + 1] = strdup(exported_vt[idx + 1].c_str());
- if (exported_argv[idx + 1] == nullptr) {
- set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
- bundle_free_exported_argv(idx + 2, &exported_argv);
- return -1;
- }
- }
-
- *argv = exported_argv;
- set_last_result(BUNDLE_ERROR_NONE);
- return argc;
-}
-
-extern "C" EXPORT_API int bundle_free_exported_argv(int argc, char*** argv) {
- if (argc < 2 || !argv || !*argv)
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- for (int i = 2; i < argc; i++)
- std::free((*argv)[i]);
-
- std::free(*argv);
- *argv = nullptr;
-
- return BUNDLE_ERROR_NONE;
-}
-
-extern "C" EXPORT_API bundle* bundle_import_from_argv(int argc, char** argv) {
- if (argv == nullptr) {
- set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
- return nullptr;
- }
-
- Bundle* b = nullptr;
- try {
- b = new (std::nothrow) Bundle(argc, argv);
- } catch (const Exception& e) {
- set_last_result(e.GetErrorCode());
- return nullptr;
- }
-
- set_last_result(BUNDLE_ERROR_NONE);
- return reinterpret_cast<bundle*>(b);
-}
-
-extern "C" EXPORT_API int bundle_compare(bundle* b1, bundle* b2) {
- if (b1 == nullptr || b2 == nullptr)
- return -1;
-
- auto* h1 = reinterpret_cast<Bundle*>(b1);
- auto* h2 = reinterpret_cast<Bundle*>(b2);
- if (*h1 == *h2)
- return 0;
-
- return 1;
-}
-
-extern "C" EXPORT_API int bundle_set_str_array_element(bundle* b,
- const char* key, const unsigned int idx, const char* val) {
- if (b == nullptr || key == nullptr || val == nullptr)
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- auto len = strlen(val) + 1;
- auto* p = reinterpret_cast<unsigned char*>(const_cast<char*>(val));
- std::vector<unsigned char> value(p, p + len);
-
- auto* h = reinterpret_cast<Bundle*>(b);
- try {
- h->Set(key, idx, std::move(value));
- } catch (const Exception& e) {
- return e.GetErrorCode();
- }
-
- return BUNDLE_ERROR_NONE;
-}
-
-extern "C" EXPORT_API int bundle_add_byte_array(bundle* b,
- const char* key, const unsigned int len) {
- return bundle_init_byte_array(b, key, len);
-}
-
-extern "C" EXPORT_API int bundle_init_byte_array(bundle* b,
- const char* key, const unsigned int len) {
- if (b == nullptr || key == nullptr || strlen(key) == 0)
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- auto* h = reinterpret_cast<Bundle*>(b);
-
- KeyInfo* key_info;
- try {
- std::vector<std::vector<unsigned char>> values(len);
- key_info = new KeyInfo(Bundle::Type::ByteArray, key, std::move(values));
- } catch (const Exception& e) {
- return e.GetErrorCode();
- } catch (const std::bad_alloc& ba) {
- return BUNDLE_ERROR_OUT_OF_MEMORY;
- } catch (const std::length_error&) {
- return BUNDLE_ERROR_OUT_OF_MEMORY;
- }
-
- try {
- h->Add(std::shared_ptr<KeyInfo>(key_info));
- } catch (const Exception& e) {
- return e.GetErrorCode();
- }
-
- return BUNDLE_ERROR_NONE;
-}
-
-extern "C" EXPORT_API int bundle_get_byte_array(bundle* b,
- const char* key, void*** bytes_array, unsigned int* len,
- unsigned int** array_element_size) {
- if (b == nullptr || key == nullptr)
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- auto* h = reinterpret_cast<Bundle*>(b);
- std::shared_ptr<KeyInfo> key_info;
- try {
- key_info = h->Get(key);
- } catch (const Exception& e) {
- return e.GetErrorCode();
- }
-
- if (key_info->GetType() != BUNDLE_TYPE_BYTE_ARRAY)
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- auto& raw_values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
- key_info->GetValues());
-
- if (bytes_array) {
- auto** values = reinterpret_cast<unsigned char**>(&raw_values[0]);
- *bytes_array = reinterpret_cast<void**>(values);
- }
-
- if (len)
- *len = static_cast<unsigned int>(raw_values.size());
-
- if (array_element_size) {
- auto& raw_values_size = const_cast<std::vector<unsigned int>&>(
- key_info->GetUValuesSize());
- *array_element_size = reinterpret_cast<unsigned int*>(&raw_values_size[0]);
- }
-
- return BUNDLE_ERROR_NONE;
-}
-
-extern "C" EXPORT_API int bundle_set_byte_array_element(bundle* b,
- const char* key, const unsigned int idx,
- const void* bytes, const size_t size) {
- if (b == nullptr || key == nullptr || size <= 0)
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- std::vector<unsigned char> value;
- if (bytes) {
- auto* p = reinterpret_cast<unsigned char*>(const_cast<void*>(bytes));
- value.insert(value.end(), p, p + size);
- }
-
- auto* h = reinterpret_cast<Bundle*>(b);
- try {
- h->Set(key, idx, std::move(value));
- } catch (const Exception& e) {
- return e.GetErrorCode();
- }
-
- return BUNDLE_ERROR_NONE;
-}
-
-extern "C" EXPORT_API int bundle_to_json(bundle* b, char** json) {
- if (b == nullptr || json == nullptr)
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- auto* h = reinterpret_cast<Bundle*>(b);
- Json js(h);
- try {
- *json = strdup(js.ToString().c_str());
- } catch (const Exception& e) {
- return e.GetErrorCode();
- }
-
- return BUNDLE_ERROR_NONE;
-}
-
-extern "C" EXPORT_API int bundle_from_json(const char* json, bundle** b) {
- if (json == nullptr || b == nullptr)
- return BUNDLE_ERROR_INVALID_PARAMETER;
-
- Json js(json);
- try {
- *b = reinterpret_cast<bundle*>(js.ToBundle());
- } catch (const Exception& e) {
- return e.GetErrorCode();
- }
-
- return BUNDLE_ERROR_NONE;
-}
--- /dev/null
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/tizen-database.pc.in
+ ${CMAKE_BINARY_DIR}/tizen-database.pc @ONLY)
+
+INSTALL(FILES ${CMAKE_BINARY_DIR}/tizen-database.pc
+ DESTINATION ${LIB_INSTALL_DIR}/pkgconfig/)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/database.hpp
+ DESTINATION include/tizen-database)
--- /dev/null
+# TizenDatabase
+Wrapper class for sqlite3
+
+## Source
+See database.hpp
+
+## Require
+sqlite3, C++17
+
+## How to use?
+Add 'BuildRequires: pkgconfig(tizen-database)' in your .spec file.
+
+## Cookbook
+
+### Auto close
+- It was implemented by RAII idiom. Database is automatically closed when it exits the scope.
+```cpp
+void test() {
+ tizen_base::Database db("test.db", SQLITE_OPEN_READWRITE);
+ ...
+}
+```
+
+### Binding
+- Bind() method supports various data type such as std::string, int, double and std::vector<unsigned char>.
+
+```cpp
+ tizen_base::Database db("test.db", SQLITE_OPEN_READWRITE);
+ auto q = tizen_base::Database::Sql(
+ "INSERT INTO TestTable(name, num, val, data) VALUES (?, ?, ?, ?);")
+ .Bind("gogo")
+ .Bind(1234)
+ .Bind(9.216)
+ .Bind( std::vector<unsigned char> {'9', '2', '1', '6' } );
+```
+
+- Bind() method also supports named tag using ':'.
+```cpp
+ tizen_base::Database db("test.db", SQLITE_OPEN_READWRITE);
+ auto q = tizen_base::Database::Sql("INSERT INTO TestTable(name, num, val, data) VALUES (:name, :num, :val, :data);")
+ .Bind(":name", "gogo")
+ .Bind(":num", 1234)
+ .Bind(":val", 9.216)
+ .Bind(":data", std::vector<unsigned char> {'9', '2', '1', '6' });
+```
+
+### Null-type binding
+- Null-type binding is supported using 'std::nullopt'.
+
+```cpp
+ tizen_base::Database db("test.db", SQLITE_OPEN_READWRITE);
+ auto q = tizen_base::Database::Sql(
+ "INSERT INTO TestTable(name, num, val, data) VALUES (?, ?, ?, ?);")
+ .Bind(std::nullopt)
+ .Bind(1234)
+ .Bind(9.216)
+ .Bind(std::nullopt);
+```
+- To get nullable object, you can use 'std::optional<>'.
+```cpp
+ for (const auto& i : r) {
+ std::optional<std::string> name = i.Get(0);
+ double val = static_cast<double>(i.Get(2));
+ std::optional<std::vector<unsigned char>> data = i.Get(3);
+ ...
+ }
+```
+
+### Structured binding declaration
+```cpp
+ auto [name, num, val, data] = i.Get<_, _, _, _>();
+```
+- Structured binding declaration can be used to unpack the record.
+
+```cpp
+ for (const auto& i : db.Exec({ "SELECT name, num, val, data FROM TestTable;" })) {
+ auto [name, num, val, data] = i.Get<_, _, _, _>();
+ std::cout << static_cast<std::string>(name) << std::endl;
+ }
+```
+
+### Range-based for loop
+- class 'Result' is iterable.
+
+```cpp
+ tizen_base::Database::Result r =
+ db.Exec({ "SELECT name, num, val, data FROM TestTable;" });
+ for (const auto& i : r) {
+ ...
+ }
+```
+
+### 'bool' type and 'int' type conversion operator
+- 'bool' type operator is supported to check errors.
+- 'int' type operator is supported to get error number.
+```cpp
+ auto r = db.Exec(q);
+ if (!r) {
+ std::cout << "error code:" << static_cast<int>(r) << std::endl;
+ }
+```
+
+### 'const char*' type conversion operator
+- 'const char*' type operator is supported to get error string
+```cpp
+ auto r = db.Exec(q);
+ if (!r) {
+ std::cout << "error message:" << static_cast<const char*>(r) << std::endl;
+ }
+```
+
+### Extract values from query results
+- There are many conversion operators to get the value.
+```cpp
+ for (const auto& i : db.Exec({ "SELECT name, num, val, data FROM TestTable;" })) {
+ auto name = static_cast<std::string>(i.Get(0));
+ auto num = static_cast<int>(i.Get(1));
+ auto val = static_cast<double>(i.Get(2));
+ auto data = static_cast<std::vector<unsigned char>>(i.Get(3));
+ }
+```
+
+### ToList(), ToVector() methods
+- Once you provide function operator in your classes, you can call the methods.
+- The class or struct should be movable.
+```cpp
+ struct MyRec {
+ std::string Id;
+ int Val;
+
+ // It should be implemented to map data set
+ void operator () (const tizen_base::Database::Result::Record& rec) {
+ Id = static_cast<std::string>(rec.Get(0));
+ Val = static_cast<int>(rec.Get(1));
+ }
+ };
+
+ auto /*std::vector<MyRec>*/ table =
+ db.Exec({ "SELECT id, val FROM TestTable;" }).ToVector<MyRec>();
+```
+
+### Transaction guard
+```cpp
+void test() {
+ tizen_base::Database db("test.db", SQLITE_OPEN_READWRITE);
+ auto guard = db.CreateTransactionGuard();
+
+ auto r = db.Exec({ "INSERT INTO MyTable(name, id) VALUES('gogo', 1);" });
+ if (!r)
+ return; // Rollback
+
+ auto r2 = db.Exec({ "INSERT INTO MyTable(name, id) VALUES('gugu', 2);" });
+ if (!r2)
+ return; // Rollback
+
+ guard.Commit();
+}
+```
+
+### Busy handler
+```cpp
+void test() {
+ tizen_base::Database db("test.db", SQLITE_OPEN_READWRITE, [&](int count) {
+ // Busy handler
+ usleep(BUSY_WAITING_USEC);
+ if (count < 10)
+ return true;
+
+ return false;
+ });
+ ...
+}
+```
+
+### Samples
+```cpp
+void test() {
+ tizen_base::Database db("test.db", SQLITE_OPEN_READWRITE);
+ for (const auto& i : db.Exec({ "SELECT name, num, val, data FROM TestTable;" })) {
+ auto [name, num, val, data] = i.Get<_, _, _, _>();
+ std::cout << static_cast<std::string>(name) << std::endl;
+ }
+}
+```
+
+```cpp
+void test() {
+ tizen_base::Database db("test.db", SQLITE_OPEN_READWRITE);
+ auto q = tizen_base::Database::Sql("INSERT INTO TestTable(name, num, val, data) VALUES (?, ?, ?, ?);")
+ .Bind("gogo")
+ .Bind(1234)
+ .Bind(9.216)
+ .Bind( std::vector<unsigned char> {'9', '2', '1', '6' } );
+ auto r = db.Exec(q);
+ if (!r) {
+ std::cout << "insert failed:" << r << std::endl;
+ std::cout << "error code:" << static_cast<int>(r) << std::endl;
+ }
+}
+```
+
+```cpp
+void test() {
+ tizen_base::Database db("test.db", SQLITE_OPEN_READWRITE);
+ auto q = tizen_base::Database::Sql(
+ "INSERT INTO TestTable(name, num, val, data) VALUES (:name, :num, :val, :data);")
+ .Bind(":name", "gogo")
+ .Bind(":num", 1234)
+ .Bind(":val", 9.216)
+ .Bind(":data", std::vector<unsigned char> {'9', '2', '1', '6' });
+ auto r = db.Exec(q);
+ if (!r) {
+ std::cout << "insert failed:" << r << std::endl;
+ std::cout << "error code:" << static_cast<int>(r) << std::endl;
+ }
+}
+```
--- /dev/null
+/*
+ * Copyright (c) 2022 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_DATABASE_DATABASE_HPP_
+#define TIZEN_DATABASE_DATABASE_HPP_
+
+#include <sqlite3.h>
+
+#include <functional>
+#include <list>
+#include <map>
+#include <memory>
+#include <optional>
+#include <stdexcept>
+#include <string>
+#include <tuple>
+#include <utility>
+#include <variant>
+#include <vector>
+
+namespace tizen_base {
+
+template<std::size_t N>
+struct num {
+ static const constexpr auto value = N;
+};
+
+template <class F, std::size_t... Is>
+void for_(F func, std::index_sequence<Is...>) {
+ (func(num<Is>{}), ...);
+}
+
+template <std::size_t N, typename F>
+void for_(F func) {
+ for_(func, std::make_index_sequence<N>());
+}
+
+using DbType = std::optional<std::variant<int64_t, double, std::string,
+ std::vector<unsigned char>>>;
+
+class DbException : public std::runtime_error {
+ public:
+ explicit DbException(const std::string& msg, int code = SQLITE_ERROR)
+ : std::runtime_error(msg), code_(code) {
+ }
+
+ DbException(const std::string& msg, int code, const std::string& file,
+ int line) : std::runtime_error(msg), code_(code) {
+ msg_ = msg + " at " + file + ":" + std::to_string(line);
+ }
+
+ int code() const {
+ return code_;
+ }
+
+ const char* msg() const {
+ if (msg_.empty())
+ return what();
+ return msg_.c_str();
+ }
+
+ private:
+ int code_;
+ std::string msg_;
+};
+
+class AutoDbType {
+ public:
+ AutoDbType() = default;
+ explicit AutoDbType(DbType db_type, int real_type)
+ : db_type_(db_type), real_type_(real_type) {}
+
+ int GetType() const {
+ return real_type_;
+ }
+
+ explicit operator int () {
+ if (!db_type_)
+ throw DbException("invalid type conversion from nullopt to int");
+ if (real_type_ != SQLITE_INTEGER)
+ throw DbException("invalid type conversion to int");
+
+ return std::get<int64_t>(*db_type_);
+ }
+
+ explicit operator int64_t () {
+ if (!db_type_)
+ throw DbException("invalid type conversion from nullopt to int64_t");
+ if (real_type_ != SQLITE_INTEGER)
+ throw DbException("invalid type conversion to int64_t");
+
+ return std::get<int64_t>(*db_type_);
+ }
+
+ explicit operator std::string () {
+ if (!db_type_) {
+ throw DbException(
+ "invalid type conversion from nullopt to string");
+ }
+
+ if (real_type_ != SQLITE_TEXT)
+ throw DbException("invalid type conversion to string");
+
+ return std::get<std::string>(*db_type_);
+ }
+
+ explicit operator double () {
+ if (!db_type_) {
+ throw DbException(
+ "invalid type conversion from nullopt to double");
+ }
+
+ if (real_type_ != SQLITE_FLOAT)
+ throw DbException("invalid type conversion to double");
+
+ return std::get<double>(*db_type_);
+ }
+
+ explicit operator std::vector<unsigned char> () {
+ if (!db_type_) {
+ throw DbException(
+ "invalid type conversion from nullopt to std::vector<unsigned char>");
+ }
+
+ if (real_type_ != SQLITE_BLOB)
+ throw DbException("invalid type conversion to std::vector<unsigned char>");
+
+ return std::get<std::vector<unsigned char>>(*db_type_);
+ }
+
+ operator std::optional<int> () {
+ if (!db_type_)
+ return std::nullopt;
+ if (real_type_ != SQLITE_INTEGER)
+ throw DbException("invalid type conversion to int");
+
+ return std::get<int64_t>(*db_type_);
+ }
+
+ operator std::optional<int64_t> () {
+ if (!db_type_)
+ return std::nullopt;
+ if (real_type_ != SQLITE_INTEGER)
+ throw DbException("invalid type conversion to int64_t");
+
+ return std::get<int64_t>(*db_type_);
+ }
+
+ operator std::optional<std::string> () {
+ if (!db_type_)
+ return std::nullopt;
+ if (real_type_ != SQLITE_TEXT)
+ throw DbException("invalid type conversion to string");
+
+ return std::get<std::string>(*db_type_);
+ }
+
+ operator std::optional<double> () {
+ if (!db_type_)
+ return std::nullopt;
+ if (real_type_ != SQLITE_FLOAT)
+ throw DbException("invalid type conversion to double");
+
+ return std::get<double>(*db_type_);
+ }
+
+ operator std::optional<std::vector<unsigned char>> () {
+ if (!db_type_)
+ return std::nullopt;
+ if (real_type_ != SQLITE_BLOB)
+ throw DbException("invalid type conversion to std::vector<unsigned char>");
+
+ return std::get<std::vector<unsigned char>>(*db_type_);
+ }
+
+ private:
+ DbType db_type_;
+ int real_type_ = SQLITE_NULL;
+};
+
+using _ = AutoDbType;
+
+class Database {
+ public:
+ class TransactionGuard {
+ public:
+ TransactionGuard(const TransactionGuard&) = delete;
+ TransactionGuard& operator = (const TransactionGuard&) = delete;
+
+ TransactionGuard(TransactionGuard&& t) noexcept {
+ db_ = std::move(t.db_);
+ }
+
+ TransactionGuard& operator = (TransactionGuard&& t) noexcept {
+ if (this != &t) {
+ if (!db_.expired())
+ sqlite3_exec(db_.lock().get(), "ROLLBACK", nullptr, nullptr, nullptr);
+ db_ = std::move(t.db_);
+ }
+
+ return *this;
+ }
+
+ explicit TransactionGuard(const std::shared_ptr<sqlite3>& db)
+ : db_(db) {
+ int r = sqlite3_exec(db_.lock().get(), "BEGIN DEFERRED",
+ nullptr, nullptr, nullptr);
+ if (r != SQLITE_OK) {
+ throw DbException("begin transaction failed", r);
+ }
+ }
+
+ ~TransactionGuard() {
+ if (!db_.expired())
+ sqlite3_exec(db_.lock().get(), "ROLLBACK", nullptr, nullptr, nullptr);
+ }
+
+ int Commit() {
+ if (db_.expired())
+ return SQLITE_OK;
+
+ auto db = db_.lock();
+ int ret = sqlite3_exec(db.get(), "COMMIT", nullptr, nullptr, nullptr);
+ if (ret != SQLITE_OK) {
+ sqlite3_exec(db.get(), "ROLLBACK", nullptr, nullptr, nullptr);
+ }
+
+ return ret;
+ }
+
+ private:
+ std::weak_ptr<sqlite3> db_;
+ };
+
+ class Sql {
+ public:
+ Sql(std::string query) : query_(std::move(query)) {}
+
+ Sql& Bind(const char* val) {
+ if (val == nullptr) {
+ bindings_.push_back(DbType(std::nullopt));
+ } else {
+ std::string str = val;
+ if (empty_string_as_null_ && str.empty())
+ bindings_.push_back(DbType(std::nullopt));
+ else
+ bindings_.push_back(DbType(std::move(str)));
+ }
+ return *this;
+ }
+
+ Sql& Bind(std::string val) {
+ if (empty_string_as_null_ && val.empty())
+ bindings_.push_back(DbType(std::nullopt));
+ else
+ bindings_.push_back(DbType(std::move(val)));
+ return *this;
+ }
+
+ Sql& Bind(int val) {
+ bindings_.push_back(DbType(static_cast<int64_t>(val)));
+ return *this;
+ }
+
+ Sql& Bind(int64_t val) {
+ bindings_.push_back(DbType(val));
+ return *this;
+ }
+
+ Sql& Bind(double val) {
+ bindings_.push_back(DbType(val));
+ return *this;
+ }
+
+ Sql& Bind(std::vector<unsigned char> val) {
+ if (empty_vector_as_null_ && val.empty())
+ bindings_.push_back(DbType(std::nullopt));
+ else
+ bindings_.push_back(DbType(std::move(val)));
+ return *this;
+ }
+
+ Sql& Bind(const std::nullopt_t val) {
+ bindings_.push_back(DbType(val));
+ return *this;
+ }
+
+ Sql& Bind(int pos, const char* val) {
+ if (val == nullptr) {
+ binding_map_[pos] = DbType(std::nullopt);
+ } else {
+ std::string str = val;
+ if (empty_string_as_null_ && str.empty())
+ binding_map_[pos] = DbType(std::nullopt);
+ else
+ binding_map_[pos] = DbType(std::move(str));
+ }
+ return *this;
+ }
+
+ Sql& Bind(int pos, std::string val) {
+ if (empty_string_as_null_ && val.empty())
+ binding_map_[pos] = DbType(std::nullopt);
+ else
+ binding_map_[pos] = DbType(std::move(val));
+ return *this;
+ }
+
+ Sql& Bind(int pos, int val) {
+ binding_map_[pos] = DbType(static_cast<int64_t>(val));
+ return *this;
+ }
+
+ Sql& Bind(int pos, int64_t val) {
+ binding_map_[pos] = DbType(val);
+ return *this;
+ }
+
+ Sql& Bind(int pos, double val) {
+ binding_map_[pos] = DbType(val);
+ return *this;
+ }
+
+ Sql& Bind(int pos, std::vector<unsigned char> val) {
+ if (empty_vector_as_null_ && val.empty())
+ binding_map_[pos] = DbType(std::nullopt);
+ else
+ binding_map_[pos] = DbType(std::move(val));
+ return *this;
+ }
+
+ Sql& Bind(int pos, const std::nullopt_t& val) {
+ binding_map_[pos] = DbType(val);
+ return *this;
+ }
+
+ Sql& Bind(std::string name, const char* val) {
+ if (val == nullptr) {
+ binding_name_map_[std::move(name)] = DbType(std::nullopt);
+ } else {
+ std::string str = val;
+ if (empty_string_as_null_ && str.empty())
+ binding_name_map_[std::move(name)] = DbType(std::nullopt);
+ else
+ binding_name_map_[std::move(name)] = DbType(std::move(str));
+ }
+ return *this;
+ }
+
+ Sql& Bind(std::string name, std::string val) {
+ if (empty_string_as_null_ && val.empty())
+ binding_name_map_[std::move(name)] = DbType(std::nullopt);
+ else
+ binding_name_map_[std::move(name)] = DbType(std::move(val));
+ return *this;
+ }
+
+ Sql& Bind(std::string name, int val) {
+ binding_name_map_[std::move(name)] = DbType(static_cast<int64_t>(val));
+ return *this;
+ }
+
+ Sql& Bind(std::string name, int64_t val) {
+ binding_name_map_[std::move(name)] = DbType(val);
+ return *this;
+ }
+
+ Sql& Bind(std::string name, double val) {
+ binding_name_map_[std::move(name)] = DbType(val);
+ return *this;
+ }
+
+ Sql& Bind(std::string name, std::vector<unsigned char> val) {
+ if (empty_vector_as_null_ && val.empty())
+ binding_name_map_[std::move(name)] = DbType(std::nullopt);
+ else
+ binding_name_map_[std::move(name)] = DbType(std::move(val));
+ return *this;
+ }
+
+ Sql& Bind(std::string name, const std::nullopt_t& val) {
+ binding_name_map_[std::move(name)] = DbType(val);
+ return *this;
+ }
+
+ const std::vector<DbType>& GetBindings() const {
+ return bindings_;
+ }
+
+ const std::map<int, DbType>& GetBindingMap() const {
+ return binding_map_;
+ }
+
+ const std::map<std::string, DbType>& GetBindingNameMap() const {
+ return binding_name_map_;
+ }
+
+ const std::string& GetQuery() const {
+ return query_;
+ }
+
+ Sql& SetEmptyStringAsNull(bool as_null) {
+ empty_string_as_null_ = as_null;
+ return *this;
+ }
+
+ Sql& SetEmptyVectorAsNull(bool as_null) {
+ empty_vector_as_null_ = as_null;
+ return *this;
+ }
+
+ Sql& Reset() {
+ bindings_.clear();
+ binding_map_.clear();
+ binding_name_map_.clear();
+ empty_string_as_null_ = false;
+ empty_vector_as_null_ = false;
+ return *this;
+ }
+
+ private:
+ std::string query_;
+ std::vector<DbType> bindings_;
+ std::map<int, DbType> binding_map_;
+ std::map<std::string, DbType> binding_name_map_;
+ bool empty_string_as_null_ = false;
+ bool empty_vector_as_null_ = false;
+ };
+
+ class Result {
+ public:
+ Result() = default;
+ ~Result() {
+ if (stmt_)
+ sqlite3_finalize(stmt_);
+ }
+
+ Result(const Result&) = delete;
+ Result& operator = (const Result&) = delete;
+
+ Result(Result&& r) noexcept {
+ stmt_ = r.stmt_;
+ r.stmt_ = nullptr;
+ query_ = std::move(r.query_);
+ is_done_ = r.is_done_;
+ }
+
+ Result& operator = (Result&& r) noexcept {
+ if (this != &r) {
+ if (stmt_)
+ sqlite3_finalize(stmt_);
+ stmt_ = r.stmt_;
+ r.stmt_ = nullptr;
+ query_ = std::move(r.query_);
+ is_done_ = r.is_done_;
+ }
+
+ return *this;
+ }
+
+ class Record {
+ public:
+ explicit Record(const sqlite3_stmt* stmt) : stmt_(stmt) {}
+
+ std::optional<std::string> GetString(int pos) const {
+ sqlite3_stmt* stmt = const_cast<sqlite3_stmt*>(stmt_);
+ const char* text = reinterpret_cast<const char*>(
+ sqlite3_column_text(stmt, pos));
+ if (!text)
+ return std::nullopt;
+
+ return text;
+ }
+
+ AutoDbType Get(int pos) const {
+ sqlite3_stmt* stmt = const_cast<sqlite3_stmt*>(stmt_);
+ int type = sqlite3_column_type(stmt, pos);
+
+ DbType dbt;
+ if (type == SQLITE_TEXT) {
+ dbt = DbType(reinterpret_cast<const char*>(
+ sqlite3_column_text(stmt, pos)));
+ } else if (type == SQLITE_INTEGER) {
+ dbt = DbType(static_cast<int64_t>(sqlite3_column_int64(stmt, pos)));
+ } else if (type == SQLITE_FLOAT) {
+ dbt = DbType(sqlite3_column_double(stmt, pos));
+ } else if (type == SQLITE_BLOB) {
+ const unsigned char* val = reinterpret_cast<const unsigned char*>(
+ sqlite3_column_blob(stmt, pos));
+ int len = sqlite3_column_bytes(stmt, pos);
+
+ if (!val || len < 0) {
+ throw DbException("invalid blob");;
+ } else {
+ dbt = DbType(std::vector<unsigned char>(val, val + len));
+ }
+ } else if (type == SQLITE_NULL) {
+ dbt = DbType(std::nullopt);
+ } else {
+ throw DbException("invalid column type", type);
+ }
+
+ return AutoDbType(dbt, type);
+ }
+
+ template <typename ...Types>
+ auto Get() const {
+ std::tuple<Types...> t;
+ int pos = 0;
+ for_<std::tuple_size_v<std::tuple<Types...>>>([&] (auto i) {
+ std::get<i.value>(t) = Get(pos++);
+ });
+
+ return t;
+ }
+
+ private:
+ const sqlite3_stmt* stmt_;
+ };
+
+ class Iterator {
+ public:
+ explicit Iterator(sqlite3_stmt* stmt) : stmt_(stmt) {}
+
+ Record operator*() { return Record(stmt_); }
+
+ bool operator != (const Iterator& rhs) const {
+ return stmt_ != rhs.stmt_;
+ }
+
+ void operator ++() {
+ int r = sqlite3_step(stmt_);
+ if (r != SQLITE_ROW)
+ stmt_ = nullptr;
+ }
+
+ private:
+ sqlite3_stmt* stmt_ = nullptr;
+ };
+
+ Iterator begin() const {
+ if (is_done_)
+ return Iterator(nullptr);
+ return Iterator(stmt_);
+ }
+
+ Iterator end() const {
+ return Iterator(nullptr);
+ }
+
+ operator bool() const {
+ if (stmt_ == nullptr)
+ return false;
+ return true;
+ }
+
+ explicit operator int() const {
+ auto db = db_.lock();
+ if (db == nullptr)
+ return SQLITE_ERROR;
+ return sqlite3_errcode(db.get());
+ }
+
+ explicit operator const char*() const {
+ auto db = db_.lock();
+ if (db == nullptr)
+ return "";
+ return sqlite3_errmsg(db.get());
+ }
+
+ template <class T>
+ std::vector<T> ToVector() {
+ if (stmt_ == nullptr)
+ return {};
+
+ std::vector<T> vec;
+ for (const auto& rec : *this) {
+ T t;
+ t(rec);
+ vec.push_back(std::move(t));
+ }
+
+ return vec;
+ }
+
+ template <class T>
+ std::list<T> ToList() {
+ if (stmt_ == nullptr)
+ return {};
+
+ std::list<T> l;
+ for (const auto& rec : *this) {
+ T t;
+ t(rec);
+ l.push_back(std::move(t));
+ }
+
+ return l;
+ }
+
+ template <class T>
+ std::optional<T> GetFirst() {
+ if (stmt_ == nullptr)
+ return std::nullopt;
+ for (const auto& rec : *this) {
+ T t;
+ t(rec);
+ return t;
+ }
+
+ return std::nullopt;
+ }
+
+ std::optional<Record> GetFirstRecord() {
+ if (stmt_ == nullptr)
+ return std::nullopt;
+ for (const auto& rec : *this) {
+ return rec;
+ }
+
+ return std::nullopt;
+ }
+
+ sqlite3_stmt* GetRaw() const {
+ return stmt_;
+ }
+
+ const std::string& GetQuery() const {
+ return query_;
+ }
+
+ void SetDone(bool is_done) {
+ is_done_ = is_done;
+ }
+
+ size_t GetColumnCount() const {
+ return sqlite3_column_count(stmt_);
+ }
+
+ private:
+ friend class Database;
+ Result(sqlite3_stmt* stmt, const std::shared_ptr<sqlite3>& db, std::string query, bool is_done)
+ : stmt_(stmt), db_(db), query_(std::move(query)), is_done_(is_done) {}
+
+ sqlite3_stmt* stmt_ = nullptr;
+ std::weak_ptr<sqlite3> db_;
+ std::string query_;
+ bool is_done_ = false;
+ };
+
+ Database(std::string db_path, int flags) {
+ sqlite3* raw_db = nullptr;
+ int r = sqlite3_open_v2(db_path.c_str(), &raw_db, flags, nullptr);
+ if (r != SQLITE_OK)
+ throw DbException("open failed", r);
+
+ db_.reset(raw_db, sqlite3_close_v2);
+ }
+
+ Database(std::string db_path, int flags,
+ std::function<bool(int)> busy_handler) {
+ sqlite3* raw_db = nullptr;
+ int r = sqlite3_open_v2(db_path.c_str(), &raw_db, flags, nullptr);
+ if (r != SQLITE_OK)
+ throw DbException("sqlite3_open_v2() failed", r);
+
+ db_.reset(raw_db, sqlite3_close_v2);
+ busy_handler_ = std::move(busy_handler);
+ r = sqlite3_busy_handler(db_.get(), [](void* data, int count) {
+ Database* pDb = static_cast<Database*>(data);
+ if (pDb->busy_handler_ && pDb->busy_handler_(count))
+ return 1;
+ return 0;
+ }, this);
+
+ if (r != SQLITE_OK)
+ throw DbException("sqlite3_busy_handler() failed", r);
+ }
+
+ ~Database() = default;
+ Database() = default;
+ Database(const Database&) = delete;
+ Database& operator = (const Database&) = delete;
+
+ Database(Database&& db) noexcept {
+ db_ = std::move(db.db_);
+ busy_handler_ = std::move(db.busy_handler_);
+ db.db_ = nullptr;
+ db.busy_handler_ = nullptr;
+
+ sqlite3_busy_handler(db_.get(), [](void* data, int count) {
+ Database* pDb = static_cast<Database*>(data);
+ if (pDb->busy_handler_ && pDb->busy_handler_(count))
+ return 1;
+ return 0;
+ }, this);
+ }
+
+ explicit operator bool() const {
+ if (db_ == nullptr)
+ return false;
+ return true;
+ }
+
+ Database& operator = (Database&& db) noexcept {
+ if (this != &db) {
+ db_ = std::move(db.db_);
+ busy_handler_ = std::move(db.busy_handler_);
+ db.db_ = nullptr;
+ db.busy_handler_ = nullptr;
+ sqlite3_busy_handler(db_.get(), [](void* data, int count) {
+ Database* pDb = static_cast<Database*>(data);
+ if (pDb->busy_handler_ && pDb->busy_handler_(count))
+ return 1;
+ return 0;
+ }, this);
+ }
+
+ return *this;
+ }
+
+ TransactionGuard CreateTransactionGuard() const {
+ return TransactionGuard(db_);
+ }
+
+ Result Prepare(const Sql& sql) const {
+ if (!db_)
+ throw DbException("Not opened");
+
+ sqlite3_stmt* stmt = nullptr;
+ int r = sqlite3_prepare_v2(db_.get(), sql.GetQuery().c_str(),
+ -1, &stmt, nullptr);
+ if (r != SQLITE_OK)
+ return { nullptr, db_, "", true };
+ return { stmt, db_, sql.GetQuery(), false };
+ }
+
+ Result Exec(const Sql& sql) const {
+ if (!db_)
+ throw DbException("Not opened");
+
+ sqlite3_stmt* stmt = nullptr;
+ int r = sqlite3_prepare_v2(db_.get(), sql.GetQuery().c_str(),
+ -1, &stmt, nullptr);
+ if (r != SQLITE_OK) {
+ return { nullptr, db_, "", true };
+ }
+
+ std::unique_ptr<sqlite3_stmt, decltype(sqlite3_finalize)*> stmt_auto(stmt,
+ sqlite3_finalize);
+ int pos = 1;
+ for (const auto& i : sql.GetBindings()) {
+ Bind(pos++, i, stmt);
+ }
+
+ for (const auto& i : sql.GetBindingMap()) {
+ Bind(i.first, i.second, stmt);
+ }
+
+ for (const auto& i : sql.GetBindingNameMap()) {
+ int pos = sqlite3_bind_parameter_index(stmt, i.first.c_str());
+ if (pos == 0)
+ throw DbException("Invalid binding");
+ Bind(pos, i.second, stmt);
+ }
+
+ r = sqlite3_step(stmt);
+ if (r != SQLITE_ROW && r != SQLITE_DONE) {
+ return { nullptr, db_, "", true };
+ }
+
+ return { stmt_auto.release(), db_, sql.GetQuery(),
+ r == SQLITE_DONE ? true : false };
+ }
+
+ bool Exec(const Sql& sql, Result& previous_stmt) const {
+ if (sql.GetQuery() != previous_stmt.GetQuery())
+ throw DbException("Query is different");
+
+ sqlite3_stmt* stmt = previous_stmt.GetRaw();
+ if (!stmt)
+ return false;
+
+ int r = sqlite3_reset(stmt);
+ if (r != SQLITE_ROW && r != SQLITE_DONE && r != SQLITE_OK)
+ return false;
+
+ int pos = 1;
+ for (const auto& i : sql.GetBindings()) {
+ Bind(pos++, i, stmt);
+ }
+
+ for (const auto& i : sql.GetBindingMap()) {
+ Bind(i.first, i.second, stmt);
+ }
+
+ for (const auto& i : sql.GetBindingNameMap()) {
+ int pos = sqlite3_bind_parameter_index(stmt, i.first.c_str());
+ if (pos == 0)
+ throw DbException("Invalid binding");
+ Bind(pos, i.second, stmt);
+ }
+
+ r = sqlite3_step(stmt);
+ if (r != SQLITE_ROW && r != SQLITE_DONE)
+ return false;
+
+ previous_stmt.SetDone(r == SQLITE_DONE ? true : false);
+ return true;
+ }
+
+ void OneStepExec(const Sql& sql) const {
+ char* errmsg = nullptr;
+ int ret = sqlite3_exec(db_.get(), sql.GetQuery().c_str(), nullptr, nullptr,
+ &errmsg);
+ if (ret != SQLITE_OK) {
+ std::unique_ptr<char, decltype(sqlite3_free)*> errmsg_auto(
+ errmsg, sqlite3_free);
+ throw DbException(errmsg);
+ }
+ }
+
+ sqlite3* GetRaw() const {
+ if (!db_)
+ throw DbException("Not opened");
+ return db_.get();
+ }
+
+ private:
+ void Bind(int pos, const DbType& type, sqlite3_stmt* stmt) const {
+ int r;
+ if (!type) {
+ r = sqlite3_bind_null(stmt, pos);
+ if (r != SQLITE_OK) {
+ throw DbException("Invalid binding", r);
+ }
+
+ return;
+ }
+
+ if (const std::string* pstr = std::get_if<std::string>(&(*type))) {
+ r = sqlite3_bind_text(stmt, pos, (*pstr).c_str(), -1,
+ SQLITE_TRANSIENT);
+ } else if (const int64_t* pint = std::get_if<int64_t>(&(*type))) {
+ r = sqlite3_bind_int64(stmt, pos, (*pint));
+ } else if (const double* pdouble = std::get_if<double>(&(*type))) {
+ r = sqlite3_bind_double(stmt, pos, (*pdouble));
+ } else if (const std::vector<unsigned char>* pvector =
+ std::get_if<std::vector<unsigned char>>(&(*type))) {
+ r = sqlite3_bind_blob(stmt, pos, (*pvector).data(),
+ (*pvector).size(), nullptr);
+ } else {
+ r = -1;
+ }
+
+ if (r != SQLITE_OK) {
+ throw DbException("Invalid binding");
+ }
+ }
+
+ private:
+ std::shared_ptr<sqlite3> db_ = nullptr;
+ std::function<bool(int)> busy_handler_;
+};
+
+} // namespace tizen_base
+
+#endif // TIZEN_DATABASE_DATABASE_HPP_
--- /dev/null
+# Wrapper class for sqlite3
+
+prefix=@PREFIX@
+includedir=${prefix}/include
+
+Name: tizen-database
+Description: Wrapper class for sqlite3
+Version: @VERSION@
+Requires: sqlite3
+Cflags: -I${includedir} -I${includedir}/tizen-database
+cppflags: -I${includedir} -I${includedir}/tizen-database
--- /dev/null
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/tizen-shared-queue.pc.in
+ ${CMAKE_BINARY_DIR}/tizen-shared-queue.pc @ONLY)
+
+INSTALL(FILES ${CMAKE_BINARY_DIR}/tizen-shared-queue.pc
+ DESTINATION ${LIB_INSTALL_DIR}/pkgconfig/)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/shared-queue.hpp
+ DESTINATION include/tizen-shared-queue)
--- /dev/null
+/*
+ * Copyright (c) 2023 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_SHARED_QUEUE_SHARED_QUEUE_HPP_
+#define TIZEN_SHARED_QUEUE_SHARED_QUEUE_HPP_
+
+#include <condition_variable>
+#include <memory>
+#include <mutex>
+#include <queue>
+#include <thread>
+#include <utility>
+
+namespace tizen_base {
+
+template <class T>
+class SharedQueue {
+ public:
+ SharedQueue() = default;
+ virtual ~SharedQueue() = default;
+
+ void Push(T item) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ queue_.push(item);
+ cond_var_.notify_one();
+ }
+
+ bool TryAndPop(T& item) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ if (queue_.empty())
+ return false;
+
+ item = queue_.front();
+ queue_.pop();
+ return true;
+ }
+
+ T WaitAndPop() {
+ std::unique_lock<std::mutex> lock(mutex_);
+ while (queue_.empty())
+ cond_var_.wait(lock);
+
+ auto item = std::move(queue_.front());
+ queue_.pop();
+ return item;
+ }
+
+ bool WaitAndPopFor(T& item, int timeout) {
+ std::unique_lock<std::mutex> lock(mutex_);
+ if (!queue_.empty()) {
+ item = queue_.front();
+ queue_.pop();
+ return true;
+ }
+
+ std::chrono::milliseconds duration(timeout);
+ if (cond_var_.wait_for(lock, duration) == std::cv_status::timeout)
+ return false;
+
+ item = queue_.front();
+ queue_.pop();
+ return true;
+ }
+
+ bool IsEmpty() const {
+ std::lock_guard<std::mutex> lock(mutex_);
+ return queue_.empty();
+ }
+
+ unsigned int Size() const {
+ std::lock_guard<std::mutex> lock(mutex_);
+ return queue_.size();
+ }
+
+ private:
+ std::queue<T> queue_;
+ mutable std::mutex mutex_;
+ std::condition_variable cond_var_;
+};
+
+} // namespace tizen_base
+
+#endif // TIZEN_SHARED_QUEUE_SHARED_QUEUE_HPP_
--- /dev/null
+# Wrapper class for sqlite3
+
+prefix=@PREFIX@
+includedir=${prefix}/include
+
+Name: tizen-shared-queue
+Description: shared queue class for active object pattern
+Version: @VERSION@
+Requires:
+Cflags: -I${includedir} -I${includedir}/tizen-shared-queue
+cppflags: -I${includedir} -I${includedir}/tizen-shared-queue
ADD_SUBDIRECTORY(parcel_unittests)
ADD_SUBDIRECTORY(tizen-database_unittests)
ADD_SUBDIRECTORY(tizen-shared-queue_unittests)
+
+ADD_DEPENDENCIES(${TARGET_BUNDLE_UNITTESTS} ${TARGET_BUNDLE})
+ADD_DEPENDENCIES(${TARGET_PARCEL_UNITTESTS} ${TARGET_PARCEL})
-CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
-PROJECT(bundle_unittests C CXX)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src BUNDLE_UNITTESTS_SRCS)
-INCLUDE(FindPkgConfig)
-PKG_CHECK_MODULES(bundle_unittests REQUIRED
- dlog
- gmock
- glib-2.0
- json-glib-1.0
- capi-base-common
-)
-
-FOREACH(flag ${bundle_unittests_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall -Werror -Winline")
-
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -std=c++17")
-SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
+ADD_EXECUTABLE(${TARGET_BUNDLE_UNITTESTS} ${BUNDLE_UNITTESTS_SRCS})
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../)
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../)
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../src)
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../include)
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../bundle)
-
-AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src UNITTESTS_SOURCES)
-AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../src BUNDLE_SOURCES)
+TARGET_INCLUDE_DIRECTORIES(${TARGET_BUNDLE_UNITTESTS} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../bundle/include
+)
-ADD_EXECUTABLE(${PROJECT_NAME}
- ${BUNDLE_SOURCES}
- ${UNITTESTS_SOURCES}
+APPLY_PKG_CONFIG(${TARGET_BUNDLE_UNITTESTS} PUBLIC
+ GMOCK_DEPS
+ DLOG_DEPS
+ GLIB_DEPS
)
-SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${bundle_unittests_LDFLAGS})
+TARGET_LINK_LIBRARIES(${TARGET_BUNDLE_UNITTESTS} PRIVATE ${TARGET_BUNDLE})
-INSTALL(TARGETS ${PROJECT_NAME} DESTINATION /usr/bin/)
+INSTALL(TARGETS ${TARGET_BUNDLE_UNITTESTS} DESTINATION bin)
-CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
-PROJECT(parcel_unittests C CXX)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} PARCEL_UNITTESTS_SRCS)
-INCLUDE(FindPkgConfig)
-PKG_CHECK_MODULES(parcel_unittests REQUIRED
- capi-base-common
- dlog
- glib-2.0
- gmock
- json-glib-1.0
-)
-
-FOREACH(flag ${parcel_unittests_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall -Werror -Winline")
-
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -std=c++17")
-SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
+ADD_EXECUTABLE(${TARGET_PARCEL_UNITTESTS} ${PARCEL_UNITTESTS_SRCS})
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../)
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../)
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../src)
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../include)
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../parcel)
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../parcel/api)
-
-AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/ UNITTESTS_SOURCES)
-AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../src BUNDLE_SOURCES)
-AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../parcel PARCEL_SOURCES)
+TARGET_INCLUDE_DIRECTORIES(${TARGET_PARCEL_UNITTESTS} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../src
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../src/parcel
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../src/parcel/api
+)
-ADD_EXECUTABLE(${PROJECT_NAME}
- ${BUNDLE_SOURCES}
- ${PARCEL_SOURCES}
- ${UNITTESTS_SOURCES}
+APPLY_PKG_CONFIG(${TARGET_PARCEL_UNITTESTS} PUBLIC
+ GMOCK_DEPS
)
-SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${parcel_unittests_LDFLAGS})
+TARGET_LINK_LIBRARIES(${TARGET_PARCEL_UNITTESTS} PRIVATE ${TARGET_PARCEL})
-INSTALL(TARGETS ${PROJECT_NAME} DESTINATION /usr/bin/)
+INSTALL(TARGETS ${TARGET_PARCEL_UNITTESTS} DESTINATION bin)
-CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
-PROJECT(tizen-database_unittests CXX)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src TIZEN_DATABASE_UNITTESTS_SRCS)
-INCLUDE(FindPkgConfig)
-PKG_CHECK_MODULES(tizen-database_unittests REQUIRED
- gmock
- sqlite3
-)
-
-SET(EXTRA_CFLAGS "")
-FOREACH(flag ${database_unittests_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall -Werror")
-
-SET(CMAKE_CXX_FLAGS "${EXTRA_CFLAGS} -std=c++17")
-SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
+ADD_EXECUTABLE(${TARGET_TIZEN_DATABASE_UNITTESTS}
+ ${TIZEN_DATABASE_UNITTESTS_SRCS})
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../)
-AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src UNITTESTS_SOURCES)
+TARGET_INCLUDE_DIRECTORIES(${TARGET_TIZEN_DATABASE_UNITTESTS} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../src
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../src/tizen-database
+)
-ADD_EXECUTABLE(${PROJECT_NAME}
- ${UNITTESTS_SOURCES}
+APPLY_PKG_CONFIG(${TARGET_TIZEN_DATABASE_UNITTESTS} PUBLIC
+ GMOCK_DEPS
+ SQLITE3_DEPS
)
-SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${tizen-database_unittests_LDFLAGS})
-INSTALL(TARGETS ${PROJECT_NAME} DESTINATION /usr/bin/)
\ No newline at end of file
+#TARGET_LINK_LIBRARIES(${TARGET_TIZEN_DATABASE_UNITTESTS} PRIVATE
+# ${TARGET_TIZEN_DATABASE})
+
+INSTALL(TARGETS ${TARGET_TIZEN_DATABASE_UNITTESTS} DESTINATION bin)
-CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
-PROJECT(tizen-shared-queue_unittests CXX)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}
+ TIZEN_SHARED_QUEUE_UNITTESTS_SRCS)
-INCLUDE(FindPkgConfig)
-PKG_CHECK_MODULES(tizen-shared-queue_unittests REQUIRED gmock)
+ADD_EXECUTABLE(${TARGET_TIZEN_SHARED_QUEUE_UNITTESTS}
+ ${TIZEN_SHARED_QUEUE_UNITTESTS_SRCS})
-SET(EXTRA_CFLAGS "")
-FOREACH(flag ${tizen-shared-queue_unittests_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall -Werror")
+TARGET_INCLUDE_DIRECTORIES(${TARGET_TIZEN_SHARED_QUEUE_UNITTESTS} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../src
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../src/tizen-shared-queue
+)
-SET(CMAKE_CXX_FLAGS "${EXTRA_CFLAGS} -std=c++17")
-SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
+APPLY_PKG_CONFIG(${TARGET_TIZEN_SHARED_QUEUE_UNITTESTS} PUBLIC
+ GMOCK_DEPS
+)
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../)
-AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} UNITTESTS_SOURCES)
+#TARGET_LINK_LIBRARIES(${TARGET_TIZEN_SHARED_QUEUE_UNITTESTS}
+# PRIVATE ${TARGET_TIZEN_SHARED_QUEUE})
-ADD_EXECUTABLE(${PROJECT_NAME} ${UNITTESTS_SOURCES})
-
-SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS
- "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${tizen-shared-queue_unittests_LDFLAGS})
-INSTALL(TARGETS ${PROJECT_NAME} DESTINATION /usr/bin/)
+INSTALL(TARGETS ${TARGET_TIZEN_SHARED_QUEUE_UNITTESTS} DESTINATION bin)
+++ /dev/null
-### Make pkgconfig file
-SET(PREFIX ${CMAKE_INSTALL_PREFIX})
-CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/tizen-database.pc.in
- ${CMAKE_BINARY_DIR}/tizen-database.pc @ONLY)
-
-### Install
-INSTALL(FILES ${CMAKE_BINARY_DIR}/tizen-database.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig/)
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/database.hpp
- DESTINATION include/tizen-database)
+++ /dev/null
-# TizenDatabase
-Wrapper class for sqlite3
-
-## Source
-See database.hpp
-
-## Require
-sqlite3, C++17
-
-## How to use?
-Add 'BuildRequires: pkgconfig(tizen-database)' in your .spec file.
-
-## Cookbook
-
-### Auto close
-- It was implemented by RAII idiom. Database is automatically closed when it exits the scope.
-```cpp
-void test() {
- tizen_base::Database db("test.db", SQLITE_OPEN_READWRITE);
- ...
-}
-```
-
-### Binding
-- Bind() method supports various data type such as std::string, int, double and std::vector<unsigned char>.
-
-```cpp
- tizen_base::Database db("test.db", SQLITE_OPEN_READWRITE);
- auto q = tizen_base::Database::Sql(
- "INSERT INTO TestTable(name, num, val, data) VALUES (?, ?, ?, ?);")
- .Bind("gogo")
- .Bind(1234)
- .Bind(9.216)
- .Bind( std::vector<unsigned char> {'9', '2', '1', '6' } );
-```
-
-- Bind() method also supports named tag using ':'.
-```cpp
- tizen_base::Database db("test.db", SQLITE_OPEN_READWRITE);
- auto q = tizen_base::Database::Sql("INSERT INTO TestTable(name, num, val, data) VALUES (:name, :num, :val, :data);")
- .Bind(":name", "gogo")
- .Bind(":num", 1234)
- .Bind(":val", 9.216)
- .Bind(":data", std::vector<unsigned char> {'9', '2', '1', '6' });
-```
-
-### Null-type binding
-- Null-type binding is supported using 'std::nullopt'.
-
-```cpp
- tizen_base::Database db("test.db", SQLITE_OPEN_READWRITE);
- auto q = tizen_base::Database::Sql(
- "INSERT INTO TestTable(name, num, val, data) VALUES (?, ?, ?, ?);")
- .Bind(std::nullopt)
- .Bind(1234)
- .Bind(9.216)
- .Bind(std::nullopt);
-```
-- To get nullable object, you can use 'std::optional<>'.
-```cpp
- for (const auto& i : r) {
- std::optional<std::string> name = i.Get(0);
- double val = static_cast<double>(i.Get(2));
- std::optional<std::vector<unsigned char>> data = i.Get(3);
- ...
- }
-```
-
-### Structured binding declaration
-```cpp
- auto [name, num, val, data] = i.Get<_, _, _, _>();
-```
-- Structured binding declaration can be used to unpack the record.
-
-```cpp
- for (const auto& i : db.Exec({ "SELECT name, num, val, data FROM TestTable;" })) {
- auto [name, num, val, data] = i.Get<_, _, _, _>();
- std::cout << static_cast<std::string>(name) << std::endl;
- }
-```
-
-### Range-based for loop
-- class 'Result' is iterable.
-
-```cpp
- tizen_base::Database::Result r =
- db.Exec({ "SELECT name, num, val, data FROM TestTable;" });
- for (const auto& i : r) {
- ...
- }
-```
-
-### 'bool' type and 'int' type conversion operator
-- 'bool' type operator is supported to check errors.
-- 'int' type operator is supported to get error number.
-```cpp
- auto r = db.Exec(q);
- if (!r) {
- std::cout << "error code:" << static_cast<int>(r) << std::endl;
- }
-```
-
-### 'const char*' type conversion operator
-- 'const char*' type operator is supported to get error string
-```cpp
- auto r = db.Exec(q);
- if (!r) {
- std::cout << "error message:" << static_cast<const char*>(r) << std::endl;
- }
-```
-
-### Extract values from query results
-- There are many conversion operators to get the value.
-```cpp
- for (const auto& i : db.Exec({ "SELECT name, num, val, data FROM TestTable;" })) {
- auto name = static_cast<std::string>(i.Get(0));
- auto num = static_cast<int>(i.Get(1));
- auto val = static_cast<double>(i.Get(2));
- auto data = static_cast<std::vector<unsigned char>>(i.Get(3));
- }
-```
-
-### ToList(), ToVector() methods
-- Once you provide function operator in your classes, you can call the methods.
-- The class or struct should be movable.
-```cpp
- struct MyRec {
- std::string Id;
- int Val;
-
- // It should be implemented to map data set
- void operator () (const tizen_base::Database::Result::Record& rec) {
- Id = static_cast<std::string>(rec.Get(0));
- Val = static_cast<int>(rec.Get(1));
- }
- };
-
- auto /*std::vector<MyRec>*/ table =
- db.Exec({ "SELECT id, val FROM TestTable;" }).ToVector<MyRec>();
-```
-
-### Transaction guard
-```cpp
-void test() {
- tizen_base::Database db("test.db", SQLITE_OPEN_READWRITE);
- auto guard = db.CreateTransactionGuard();
-
- auto r = db.Exec({ "INSERT INTO MyTable(name, id) VALUES('gogo', 1);" });
- if (!r)
- return; // Rollback
-
- auto r2 = db.Exec({ "INSERT INTO MyTable(name, id) VALUES('gugu', 2);" });
- if (!r2)
- return; // Rollback
-
- guard.Commit();
-}
-```
-
-### Busy handler
-```cpp
-void test() {
- tizen_base::Database db("test.db", SQLITE_OPEN_READWRITE, [&](int count) {
- // Busy handler
- usleep(BUSY_WAITING_USEC);
- if (count < 10)
- return true;
-
- return false;
- });
- ...
-}
-```
-
-### Samples
-```cpp
-void test() {
- tizen_base::Database db("test.db", SQLITE_OPEN_READWRITE);
- for (const auto& i : db.Exec({ "SELECT name, num, val, data FROM TestTable;" })) {
- auto [name, num, val, data] = i.Get<_, _, _, _>();
- std::cout << static_cast<std::string>(name) << std::endl;
- }
-}
-```
-
-```cpp
-void test() {
- tizen_base::Database db("test.db", SQLITE_OPEN_READWRITE);
- auto q = tizen_base::Database::Sql("INSERT INTO TestTable(name, num, val, data) VALUES (?, ?, ?, ?);")
- .Bind("gogo")
- .Bind(1234)
- .Bind(9.216)
- .Bind( std::vector<unsigned char> {'9', '2', '1', '6' } );
- auto r = db.Exec(q);
- if (!r) {
- std::cout << "insert failed:" << r << std::endl;
- std::cout << "error code:" << static_cast<int>(r) << std::endl;
- }
-}
-```
-
-```cpp
-void test() {
- tizen_base::Database db("test.db", SQLITE_OPEN_READWRITE);
- auto q = tizen_base::Database::Sql(
- "INSERT INTO TestTable(name, num, val, data) VALUES (:name, :num, :val, :data);")
- .Bind(":name", "gogo")
- .Bind(":num", 1234)
- .Bind(":val", 9.216)
- .Bind(":data", std::vector<unsigned char> {'9', '2', '1', '6' });
- auto r = db.Exec(q);
- if (!r) {
- std::cout << "insert failed:" << r << std::endl;
- std::cout << "error code:" << static_cast<int>(r) << std::endl;
- }
-}
-```
+++ /dev/null
-/*
- * Copyright (c) 2022 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_DATABASE_DATABASE_HPP_
-#define TIZEN_DATABASE_DATABASE_HPP_
-
-#include <sqlite3.h>
-
-#include <functional>
-#include <list>
-#include <map>
-#include <memory>
-#include <optional>
-#include <stdexcept>
-#include <string>
-#include <tuple>
-#include <utility>
-#include <variant>
-#include <vector>
-
-namespace tizen_base {
-
-template<std::size_t N>
-struct num {
- static const constexpr auto value = N;
-};
-
-template <class F, std::size_t... Is>
-void for_(F func, std::index_sequence<Is...>) {
- (func(num<Is>{}), ...);
-}
-
-template <std::size_t N, typename F>
-void for_(F func) {
- for_(func, std::make_index_sequence<N>());
-}
-
-using DbType = std::optional<std::variant<int64_t, double, std::string,
- std::vector<unsigned char>>>;
-
-class DbException : public std::runtime_error {
- public:
- explicit DbException(const std::string& msg, int code = SQLITE_ERROR)
- : std::runtime_error(msg), code_(code) {
- }
-
- DbException(const std::string& msg, int code, const std::string& file,
- int line) : std::runtime_error(msg), code_(code) {
- msg_ = msg + " at " + file + ":" + std::to_string(line);
- }
-
- int code() const {
- return code_;
- }
-
- const char* msg() const {
- if (msg_.empty())
- return what();
- return msg_.c_str();
- }
-
- private:
- int code_;
- std::string msg_;
-};
-
-class AutoDbType {
- public:
- AutoDbType() = default;
- explicit AutoDbType(DbType db_type, int real_type)
- : db_type_(db_type), real_type_(real_type) {}
-
- int GetType() const {
- return real_type_;
- }
-
- explicit operator int () {
- if (!db_type_)
- throw DbException("invalid type conversion from nullopt to int");
- if (real_type_ != SQLITE_INTEGER)
- throw DbException("invalid type conversion to int");
-
- return std::get<int64_t>(*db_type_);
- }
-
- explicit operator int64_t () {
- if (!db_type_)
- throw DbException("invalid type conversion from nullopt to int64_t");
- if (real_type_ != SQLITE_INTEGER)
- throw DbException("invalid type conversion to int64_t");
-
- return std::get<int64_t>(*db_type_);
- }
-
- explicit operator std::string () {
- if (!db_type_) {
- throw DbException(
- "invalid type conversion from nullopt to string");
- }
-
- if (real_type_ != SQLITE_TEXT)
- throw DbException("invalid type conversion to string");
-
- return std::get<std::string>(*db_type_);
- }
-
- explicit operator double () {
- if (!db_type_) {
- throw DbException(
- "invalid type conversion from nullopt to double");
- }
-
- if (real_type_ != SQLITE_FLOAT)
- throw DbException("invalid type conversion to double");
-
- return std::get<double>(*db_type_);
- }
-
- explicit operator std::vector<unsigned char> () {
- if (!db_type_) {
- throw DbException(
- "invalid type conversion from nullopt to std::vector<unsigned char>");
- }
-
- if (real_type_ != SQLITE_BLOB)
- throw DbException("invalid type conversion to std::vector<unsigned char>");
-
- return std::get<std::vector<unsigned char>>(*db_type_);
- }
-
- operator std::optional<int> () {
- if (!db_type_)
- return std::nullopt;
- if (real_type_ != SQLITE_INTEGER)
- throw DbException("invalid type conversion to int");
-
- return std::get<int64_t>(*db_type_);
- }
-
- operator std::optional<int64_t> () {
- if (!db_type_)
- return std::nullopt;
- if (real_type_ != SQLITE_INTEGER)
- throw DbException("invalid type conversion to int64_t");
-
- return std::get<int64_t>(*db_type_);
- }
-
- operator std::optional<std::string> () {
- if (!db_type_)
- return std::nullopt;
- if (real_type_ != SQLITE_TEXT)
- throw DbException("invalid type conversion to string");
-
- return std::get<std::string>(*db_type_);
- }
-
- operator std::optional<double> () {
- if (!db_type_)
- return std::nullopt;
- if (real_type_ != SQLITE_FLOAT)
- throw DbException("invalid type conversion to double");
-
- return std::get<double>(*db_type_);
- }
-
- operator std::optional<std::vector<unsigned char>> () {
- if (!db_type_)
- return std::nullopt;
- if (real_type_ != SQLITE_BLOB)
- throw DbException("invalid type conversion to std::vector<unsigned char>");
-
- return std::get<std::vector<unsigned char>>(*db_type_);
- }
-
- private:
- DbType db_type_;
- int real_type_ = SQLITE_NULL;
-};
-
-using _ = AutoDbType;
-
-class Database {
- public:
- class TransactionGuard {
- public:
- TransactionGuard(const TransactionGuard&) = delete;
- TransactionGuard& operator = (const TransactionGuard&) = delete;
-
- TransactionGuard(TransactionGuard&& t) noexcept {
- db_ = std::move(t.db_);
- }
-
- TransactionGuard& operator = (TransactionGuard&& t) noexcept {
- if (this != &t) {
- if (!db_.expired())
- sqlite3_exec(db_.lock().get(), "ROLLBACK", nullptr, nullptr, nullptr);
- db_ = std::move(t.db_);
- }
-
- return *this;
- }
-
- explicit TransactionGuard(const std::shared_ptr<sqlite3>& db)
- : db_(db) {
- int r = sqlite3_exec(db_.lock().get(), "BEGIN DEFERRED",
- nullptr, nullptr, nullptr);
- if (r != SQLITE_OK) {
- throw DbException("begin transaction failed", r);
- }
- }
-
- ~TransactionGuard() {
- if (!db_.expired())
- sqlite3_exec(db_.lock().get(), "ROLLBACK", nullptr, nullptr, nullptr);
- }
-
- int Commit() {
- if (db_.expired())
- return SQLITE_OK;
-
- auto db = db_.lock();
- int ret = sqlite3_exec(db.get(), "COMMIT", nullptr, nullptr, nullptr);
- if (ret != SQLITE_OK) {
- sqlite3_exec(db.get(), "ROLLBACK", nullptr, nullptr, nullptr);
- }
-
- return ret;
- }
-
- private:
- std::weak_ptr<sqlite3> db_;
- };
-
- class Sql {
- public:
- Sql(std::string query) : query_(std::move(query)) {}
-
- Sql& Bind(const char* val) {
- if (val == nullptr) {
- bindings_.push_back(DbType(std::nullopt));
- } else {
- std::string str = val;
- if (empty_string_as_null_ && str.empty())
- bindings_.push_back(DbType(std::nullopt));
- else
- bindings_.push_back(DbType(std::move(str)));
- }
- return *this;
- }
-
- Sql& Bind(std::string val) {
- if (empty_string_as_null_ && val.empty())
- bindings_.push_back(DbType(std::nullopt));
- else
- bindings_.push_back(DbType(std::move(val)));
- return *this;
- }
-
- Sql& Bind(int val) {
- bindings_.push_back(DbType(static_cast<int64_t>(val)));
- return *this;
- }
-
- Sql& Bind(int64_t val) {
- bindings_.push_back(DbType(val));
- return *this;
- }
-
- Sql& Bind(double val) {
- bindings_.push_back(DbType(val));
- return *this;
- }
-
- Sql& Bind(std::vector<unsigned char> val) {
- if (empty_vector_as_null_ && val.empty())
- bindings_.push_back(DbType(std::nullopt));
- else
- bindings_.push_back(DbType(std::move(val)));
- return *this;
- }
-
- Sql& Bind(const std::nullopt_t val) {
- bindings_.push_back(DbType(val));
- return *this;
- }
-
- Sql& Bind(int pos, const char* val) {
- if (val == nullptr) {
- binding_map_[pos] = DbType(std::nullopt);
- } else {
- std::string str = val;
- if (empty_string_as_null_ && str.empty())
- binding_map_[pos] = DbType(std::nullopt);
- else
- binding_map_[pos] = DbType(std::move(str));
- }
- return *this;
- }
-
- Sql& Bind(int pos, std::string val) {
- if (empty_string_as_null_ && val.empty())
- binding_map_[pos] = DbType(std::nullopt);
- else
- binding_map_[pos] = DbType(std::move(val));
- return *this;
- }
-
- Sql& Bind(int pos, int val) {
- binding_map_[pos] = DbType(static_cast<int64_t>(val));
- return *this;
- }
-
- Sql& Bind(int pos, int64_t val) {
- binding_map_[pos] = DbType(val);
- return *this;
- }
-
- Sql& Bind(int pos, double val) {
- binding_map_[pos] = DbType(val);
- return *this;
- }
-
- Sql& Bind(int pos, std::vector<unsigned char> val) {
- if (empty_vector_as_null_ && val.empty())
- binding_map_[pos] = DbType(std::nullopt);
- else
- binding_map_[pos] = DbType(std::move(val));
- return *this;
- }
-
- Sql& Bind(int pos, const std::nullopt_t& val) {
- binding_map_[pos] = DbType(val);
- return *this;
- }
-
- Sql& Bind(std::string name, const char* val) {
- if (val == nullptr) {
- binding_name_map_[std::move(name)] = DbType(std::nullopt);
- } else {
- std::string str = val;
- if (empty_string_as_null_ && str.empty())
- binding_name_map_[std::move(name)] = DbType(std::nullopt);
- else
- binding_name_map_[std::move(name)] = DbType(std::move(str));
- }
- return *this;
- }
-
- Sql& Bind(std::string name, std::string val) {
- if (empty_string_as_null_ && val.empty())
- binding_name_map_[std::move(name)] = DbType(std::nullopt);
- else
- binding_name_map_[std::move(name)] = DbType(std::move(val));
- return *this;
- }
-
- Sql& Bind(std::string name, int val) {
- binding_name_map_[std::move(name)] = DbType(static_cast<int64_t>(val));
- return *this;
- }
-
- Sql& Bind(std::string name, int64_t val) {
- binding_name_map_[std::move(name)] = DbType(val);
- return *this;
- }
-
- Sql& Bind(std::string name, double val) {
- binding_name_map_[std::move(name)] = DbType(val);
- return *this;
- }
-
- Sql& Bind(std::string name, std::vector<unsigned char> val) {
- if (empty_vector_as_null_ && val.empty())
- binding_name_map_[std::move(name)] = DbType(std::nullopt);
- else
- binding_name_map_[std::move(name)] = DbType(std::move(val));
- return *this;
- }
-
- Sql& Bind(std::string name, const std::nullopt_t& val) {
- binding_name_map_[std::move(name)] = DbType(val);
- return *this;
- }
-
- const std::vector<DbType>& GetBindings() const {
- return bindings_;
- }
-
- const std::map<int, DbType>& GetBindingMap() const {
- return binding_map_;
- }
-
- const std::map<std::string, DbType>& GetBindingNameMap() const {
- return binding_name_map_;
- }
-
- const std::string& GetQuery() const {
- return query_;
- }
-
- Sql& SetEmptyStringAsNull(bool as_null) {
- empty_string_as_null_ = as_null;
- return *this;
- }
-
- Sql& SetEmptyVectorAsNull(bool as_null) {
- empty_vector_as_null_ = as_null;
- return *this;
- }
-
- Sql& Reset() {
- bindings_.clear();
- binding_map_.clear();
- binding_name_map_.clear();
- empty_string_as_null_ = false;
- empty_vector_as_null_ = false;
- return *this;
- }
-
- private:
- std::string query_;
- std::vector<DbType> bindings_;
- std::map<int, DbType> binding_map_;
- std::map<std::string, DbType> binding_name_map_;
- bool empty_string_as_null_ = false;
- bool empty_vector_as_null_ = false;
- };
-
- class Result {
- public:
- Result() = default;
- ~Result() {
- if (stmt_)
- sqlite3_finalize(stmt_);
- }
-
- Result(const Result&) = delete;
- Result& operator = (const Result&) = delete;
-
- Result(Result&& r) noexcept {
- stmt_ = r.stmt_;
- r.stmt_ = nullptr;
- query_ = std::move(r.query_);
- is_done_ = r.is_done_;
- }
-
- Result& operator = (Result&& r) noexcept {
- if (this != &r) {
- if (stmt_)
- sqlite3_finalize(stmt_);
- stmt_ = r.stmt_;
- r.stmt_ = nullptr;
- query_ = std::move(r.query_);
- is_done_ = r.is_done_;
- }
-
- return *this;
- }
-
- class Record {
- public:
- explicit Record(const sqlite3_stmt* stmt) : stmt_(stmt) {}
-
- std::optional<std::string> GetString(int pos) const {
- sqlite3_stmt* stmt = const_cast<sqlite3_stmt*>(stmt_);
- const char* text = reinterpret_cast<const char*>(
- sqlite3_column_text(stmt, pos));
- if (!text)
- return std::nullopt;
-
- return text;
- }
-
- AutoDbType Get(int pos) const {
- sqlite3_stmt* stmt = const_cast<sqlite3_stmt*>(stmt_);
- int type = sqlite3_column_type(stmt, pos);
-
- DbType dbt;
- if (type == SQLITE_TEXT) {
- dbt = DbType(reinterpret_cast<const char*>(
- sqlite3_column_text(stmt, pos)));
- } else if (type == SQLITE_INTEGER) {
- dbt = DbType(static_cast<int64_t>(sqlite3_column_int64(stmt, pos)));
- } else if (type == SQLITE_FLOAT) {
- dbt = DbType(sqlite3_column_double(stmt, pos));
- } else if (type == SQLITE_BLOB) {
- const unsigned char* val = reinterpret_cast<const unsigned char*>(
- sqlite3_column_blob(stmt, pos));
- int len = sqlite3_column_bytes(stmt, pos);
-
- if (!val || len < 0) {
- throw DbException("invalid blob");;
- } else {
- dbt = DbType(std::vector<unsigned char>(val, val + len));
- }
- } else if (type == SQLITE_NULL) {
- dbt = DbType(std::nullopt);
- } else {
- throw DbException("invalid column type", type);
- }
-
- return AutoDbType(dbt, type);
- }
-
- template <typename ...Types>
- auto Get() const {
- std::tuple<Types...> t;
- int pos = 0;
- for_<std::tuple_size_v<std::tuple<Types...>>>([&] (auto i) {
- std::get<i.value>(t) = Get(pos++);
- });
-
- return t;
- }
-
- private:
- const sqlite3_stmt* stmt_;
- };
-
- class Iterator {
- public:
- explicit Iterator(sqlite3_stmt* stmt) : stmt_(stmt) {}
-
- Record operator*() { return Record(stmt_); }
-
- bool operator != (const Iterator& rhs) const {
- return stmt_ != rhs.stmt_;
- }
-
- void operator ++() {
- int r = sqlite3_step(stmt_);
- if (r != SQLITE_ROW)
- stmt_ = nullptr;
- }
-
- private:
- sqlite3_stmt* stmt_ = nullptr;
- };
-
- Iterator begin() const {
- if (is_done_)
- return Iterator(nullptr);
- return Iterator(stmt_);
- }
-
- Iterator end() const {
- return Iterator(nullptr);
- }
-
- operator bool() const {
- if (stmt_ == nullptr)
- return false;
- return true;
- }
-
- explicit operator int() const {
- auto db = db_.lock();
- if (db == nullptr)
- return SQLITE_ERROR;
- return sqlite3_errcode(db.get());
- }
-
- explicit operator const char*() const {
- auto db = db_.lock();
- if (db == nullptr)
- return "";
- return sqlite3_errmsg(db.get());
- }
-
- template <class T>
- std::vector<T> ToVector() {
- if (stmt_ == nullptr)
- return {};
-
- std::vector<T> vec;
- for (const auto& rec : *this) {
- T t;
- t(rec);
- vec.push_back(std::move(t));
- }
-
- return vec;
- }
-
- template <class T>
- std::list<T> ToList() {
- if (stmt_ == nullptr)
- return {};
-
- std::list<T> l;
- for (const auto& rec : *this) {
- T t;
- t(rec);
- l.push_back(std::move(t));
- }
-
- return l;
- }
-
- template <class T>
- std::optional<T> GetFirst() {
- if (stmt_ == nullptr)
- return std::nullopt;
- for (const auto& rec : *this) {
- T t;
- t(rec);
- return t;
- }
-
- return std::nullopt;
- }
-
- std::optional<Record> GetFirstRecord() {
- if (stmt_ == nullptr)
- return std::nullopt;
- for (const auto& rec : *this) {
- return rec;
- }
-
- return std::nullopt;
- }
-
- sqlite3_stmt* GetRaw() const {
- return stmt_;
- }
-
- const std::string& GetQuery() const {
- return query_;
- }
-
- void SetDone(bool is_done) {
- is_done_ = is_done;
- }
-
- size_t GetColumnCount() const {
- return sqlite3_column_count(stmt_);
- }
-
- private:
- friend class Database;
- Result(sqlite3_stmt* stmt, const std::shared_ptr<sqlite3>& db, std::string query, bool is_done)
- : stmt_(stmt), db_(db), query_(std::move(query)), is_done_(is_done) {}
-
- sqlite3_stmt* stmt_ = nullptr;
- std::weak_ptr<sqlite3> db_;
- std::string query_;
- bool is_done_ = false;
- };
-
- Database(std::string db_path, int flags) {
- sqlite3* raw_db = nullptr;
- int r = sqlite3_open_v2(db_path.c_str(), &raw_db, flags, nullptr);
- if (r != SQLITE_OK)
- throw DbException("open failed", r);
-
- db_.reset(raw_db, sqlite3_close_v2);
- }
-
- Database(std::string db_path, int flags,
- std::function<bool(int)> busy_handler) {
- sqlite3* raw_db = nullptr;
- int r = sqlite3_open_v2(db_path.c_str(), &raw_db, flags, nullptr);
- if (r != SQLITE_OK)
- throw DbException("sqlite3_open_v2() failed", r);
-
- db_.reset(raw_db, sqlite3_close_v2);
- busy_handler_ = std::move(busy_handler);
- r = sqlite3_busy_handler(db_.get(), [](void* data, int count) {
- Database* pDb = static_cast<Database*>(data);
- if (pDb->busy_handler_ && pDb->busy_handler_(count))
- return 1;
- return 0;
- }, this);
-
- if (r != SQLITE_OK)
- throw DbException("sqlite3_busy_handler() failed", r);
- }
-
- ~Database() = default;
- Database() = default;
- Database(const Database&) = delete;
- Database& operator = (const Database&) = delete;
-
- Database(Database&& db) noexcept {
- db_ = std::move(db.db_);
- busy_handler_ = std::move(db.busy_handler_);
- db.db_ = nullptr;
- db.busy_handler_ = nullptr;
-
- sqlite3_busy_handler(db_.get(), [](void* data, int count) {
- Database* pDb = static_cast<Database*>(data);
- if (pDb->busy_handler_ && pDb->busy_handler_(count))
- return 1;
- return 0;
- }, this);
- }
-
- explicit operator bool() const {
- if (db_ == nullptr)
- return false;
- return true;
- }
-
- Database& operator = (Database&& db) noexcept {
- if (this != &db) {
- db_ = std::move(db.db_);
- busy_handler_ = std::move(db.busy_handler_);
- db.db_ = nullptr;
- db.busy_handler_ = nullptr;
- sqlite3_busy_handler(db_.get(), [](void* data, int count) {
- Database* pDb = static_cast<Database*>(data);
- if (pDb->busy_handler_ && pDb->busy_handler_(count))
- return 1;
- return 0;
- }, this);
- }
-
- return *this;
- }
-
- TransactionGuard CreateTransactionGuard() const {
- return TransactionGuard(db_);
- }
-
- Result Prepare(const Sql& sql) const {
- if (!db_)
- throw DbException("Not opened");
-
- sqlite3_stmt* stmt = nullptr;
- int r = sqlite3_prepare_v2(db_.get(), sql.GetQuery().c_str(),
- -1, &stmt, nullptr);
- if (r != SQLITE_OK)
- return { nullptr, db_, "", true };
- return { stmt, db_, sql.GetQuery(), false };
- }
-
- Result Exec(const Sql& sql) const {
- if (!db_)
- throw DbException("Not opened");
-
- sqlite3_stmt* stmt = nullptr;
- int r = sqlite3_prepare_v2(db_.get(), sql.GetQuery().c_str(),
- -1, &stmt, nullptr);
- if (r != SQLITE_OK) {
- return { nullptr, db_, "", true };
- }
-
- std::unique_ptr<sqlite3_stmt, decltype(sqlite3_finalize)*> stmt_auto(stmt,
- sqlite3_finalize);
- int pos = 1;
- for (const auto& i : sql.GetBindings()) {
- Bind(pos++, i, stmt);
- }
-
- for (const auto& i : sql.GetBindingMap()) {
- Bind(i.first, i.second, stmt);
- }
-
- for (const auto& i : sql.GetBindingNameMap()) {
- int pos = sqlite3_bind_parameter_index(stmt, i.first.c_str());
- if (pos == 0)
- throw DbException("Invalid binding");
- Bind(pos, i.second, stmt);
- }
-
- r = sqlite3_step(stmt);
- if (r != SQLITE_ROW && r != SQLITE_DONE) {
- return { nullptr, db_, "", true };
- }
-
- return { stmt_auto.release(), db_, sql.GetQuery(),
- r == SQLITE_DONE ? true : false };
- }
-
- bool Exec(const Sql& sql, Result& previous_stmt) const {
- if (sql.GetQuery() != previous_stmt.GetQuery())
- throw DbException("Query is different");
-
- sqlite3_stmt* stmt = previous_stmt.GetRaw();
- if (!stmt)
- return false;
-
- int r = sqlite3_reset(stmt);
- if (r != SQLITE_ROW && r != SQLITE_DONE && r != SQLITE_OK)
- return false;
-
- int pos = 1;
- for (const auto& i : sql.GetBindings()) {
- Bind(pos++, i, stmt);
- }
-
- for (const auto& i : sql.GetBindingMap()) {
- Bind(i.first, i.second, stmt);
- }
-
- for (const auto& i : sql.GetBindingNameMap()) {
- int pos = sqlite3_bind_parameter_index(stmt, i.first.c_str());
- if (pos == 0)
- throw DbException("Invalid binding");
- Bind(pos, i.second, stmt);
- }
-
- r = sqlite3_step(stmt);
- if (r != SQLITE_ROW && r != SQLITE_DONE)
- return false;
-
- previous_stmt.SetDone(r == SQLITE_DONE ? true : false);
- return true;
- }
-
- void OneStepExec(const Sql& sql) const {
- char* errmsg = nullptr;
- int ret = sqlite3_exec(db_.get(), sql.GetQuery().c_str(), nullptr, nullptr,
- &errmsg);
- if (ret != SQLITE_OK) {
- std::unique_ptr<char, decltype(sqlite3_free)*> errmsg_auto(
- errmsg, sqlite3_free);
- throw DbException(errmsg);
- }
- }
-
- sqlite3* GetRaw() const {
- if (!db_)
- throw DbException("Not opened");
- return db_.get();
- }
-
- private:
- void Bind(int pos, const DbType& type, sqlite3_stmt* stmt) const {
- int r;
- if (!type) {
- r = sqlite3_bind_null(stmt, pos);
- if (r != SQLITE_OK) {
- throw DbException("Invalid binding", r);
- }
-
- return;
- }
-
- if (const std::string* pstr = std::get_if<std::string>(&(*type))) {
- r = sqlite3_bind_text(stmt, pos, (*pstr).c_str(), -1,
- SQLITE_TRANSIENT);
- } else if (const int64_t* pint = std::get_if<int64_t>(&(*type))) {
- r = sqlite3_bind_int64(stmt, pos, (*pint));
- } else if (const double* pdouble = std::get_if<double>(&(*type))) {
- r = sqlite3_bind_double(stmt, pos, (*pdouble));
- } else if (const std::vector<unsigned char>* pvector =
- std::get_if<std::vector<unsigned char>>(&(*type))) {
- r = sqlite3_bind_blob(stmt, pos, (*pvector).data(),
- (*pvector).size(), nullptr);
- } else {
- r = -1;
- }
-
- if (r != SQLITE_OK) {
- throw DbException("Invalid binding");
- }
- }
-
- private:
- std::shared_ptr<sqlite3> db_ = nullptr;
- std::function<bool(int)> busy_handler_;
-};
-
-} // namespace tizen_base
-
-#endif // TIZEN_DATABASE_DATABASE_HPP_
+++ /dev/null
-# Wrapper class for sqlite3
-
-prefix=@PREFIX@
-includedir=${prefix}/include
-
-Name: tizen-database
-Description: Wrapper class for sqlite3
-Version: @VERSION@
-Requires: sqlite3
-Cflags: -I${includedir} -I${includedir}/tizen-database
-cppflags: -I${includedir} -I${includedir}/tizen-database
+++ /dev/null
-### Make pkgconfig file
-SET(PREFIX ${CMAKE_INSTALL_PREFIX})
-CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/tizen-shared-queue.pc.in
- ${CMAKE_BINARY_DIR}/tizen-shared-queue.pc @ONLY)
-
-### Install
-INSTALL(FILES ${CMAKE_BINARY_DIR}/tizen-shared-queue.pc
- DESTINATION ${LIB_INSTALL_DIR}/pkgconfig/)
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/shared-queue.hpp
- DESTINATION include/tizen-shared-queue)
+++ /dev/null
-/*
- * Copyright (c) 2023 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_SHARED_QUEUE_SHARED_QUEUE_HPP_
-#define TIZEN_SHARED_QUEUE_SHARED_QUEUE_HPP_
-
-#include <condition_variable>
-#include <memory>
-#include <mutex>
-#include <queue>
-#include <thread>
-#include <utility>
-
-namespace tizen_base {
-
-template <class T>
-class SharedQueue {
- public:
- SharedQueue() = default;
- virtual ~SharedQueue() = default;
-
- void Push(T item) {
- std::lock_guard<std::mutex> lock(mutex_);
- queue_.push(item);
- cond_var_.notify_one();
- }
-
- bool TryAndPop(T& item) {
- std::lock_guard<std::mutex> lock(mutex_);
- if (queue_.empty())
- return false;
-
- item = queue_.front();
- queue_.pop();
- return true;
- }
-
- T WaitAndPop() {
- std::unique_lock<std::mutex> lock(mutex_);
- while (queue_.empty())
- cond_var_.wait(lock);
-
- auto item = std::move(queue_.front());
- queue_.pop();
- return item;
- }
-
- bool WaitAndPopFor(T& item, int timeout) {
- std::unique_lock<std::mutex> lock(mutex_);
- if (!queue_.empty()) {
- item = queue_.front();
- queue_.pop();
- return true;
- }
-
- std::chrono::milliseconds duration(timeout);
- if (cond_var_.wait_for(lock, duration) == std::cv_status::timeout)
- return false;
-
- item = queue_.front();
- queue_.pop();
- return true;
- }
-
- bool IsEmpty() const {
- std::lock_guard<std::mutex> lock(mutex_);
- return queue_.empty();
- }
-
- unsigned int Size() const {
- std::lock_guard<std::mutex> lock(mutex_);
- return queue_.size();
- }
-
- private:
- std::queue<T> queue_;
- mutable std::mutex mutex_;
- std::condition_variable cond_var_;
-};
-
-} // namespace tizen_base
-
-#endif // TIZEN_SHARED_QUEUE_SHARED_QUEUE_HPP_
+++ /dev/null
-# Wrapper class for sqlite3
-
-prefix=@PREFIX@
-includedir=${prefix}/include
-
-Name: tizen-shared-queue
-Description: shared queue class for active object pattern
-Version: @VERSION@
-Requires:
-Cflags: -I${includedir} -I${includedir}/tizen-shared-queue
-cppflags: -I${includedir} -I${includedir}/tizen-shared-queue