This library is only for appfw internally.
Adds:
- parcel_create()
- parcel_destroy()
- parcel_clone()
- parcel_burst_write()
- parcel_burst_read()
- parcel_write_bool()
- parcel_write_byte()
- parcel_write_uint16()
- parcel_write_uint32()
- parcel_write_uint64()
- parcel_write_int16()
- parcel_write_int32()
- parcel_write_int64()
- parcel_write_float()
- parcel_write_double()
- parcel_write_string()
- parcel_write_bundle()
- parcel_read_bool()
- parcel_read_byte()
- parcel_read_uint16()
- parcel_read_uint32()
- parcel_read_uint64()
- parcel_read_int16()
- parcel_read_int32()
- parcel_read_int64()
- parcel_read_float()
- parcel_read_double()
- parcel_read_string()
- parcel_read_bundle()
- parcel_reset_reader()
- parcel_clear()
- parcel_reset()
- parcel_write()
- parcel_read()
- parcel_get_raw()
Change-Id: I322faee040ca95c4cb8e4b7356e33a9af5daeb8c
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ DESTINATION include/)
INSTALL(FILES ${CMAKE_BINARY_DIR}/bundle.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig/)
+ADD_SUBDIRECTORY(parcel)
+ADD_DEPENDENCIES(parcel bundle)
+
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}/unit_tests)
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests/bundle_unittests)
-ADD_SUBDIRECTORY(unit_tests)
+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)
+
+ADD_DEPENDENCIES(parcel_unittests parcel)
ENDIF(NOT DEFINED MINIMUM_BUILD)
License: Apache-2.0
Source0: bundle-%{version}.tar.gz
Source1001: bundle.manifest
+Source1002: parcel.manifest
BuildRequires: cmake
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(dlog)
Simple string key-val dictionary ADT gcov objects
%endif
+#################################################
+## parcel
+#################################################
+%package -n parcel
+Summary: Parcel Library
+Group: Development/Libraries
+
+%description -n parcel
+Parcel Library
+
+%package -n parcel-devel
+Summary: Parcel Library (devel)
+Group: Development/Libraries
+Requires: parcel = %{version}-%{release}
+
+%description -n parcel-devel
+Parcel Library (devel)
+
+#################################################
+# parcel-unittests
+#################################################
+%package -n parcel-unittests
+Summary: GTest for parcel
+Group: Development/Libraries
+
+%description -n parcel-unittests
+GTest for parcel
+
%prep
%setup -q -n %{name}-%{version}
cp %{SOURCE1001} .
+cp %{SOURCE1002} .
%build
%if 0%{?gcov:1}
%postun -p /sbin/ldconfig
+%post -n parcel
+/sbin/ldconfig
+
+%postun -n parcel
+/sbin/ldconfig
+
%post unittests
%if 0%{?gcov:1}
%{_bindir}/bundle_unittests
%files gcov
%{_datadir}/gcov/*
%endif
+
+#################################################
+# parcel
+#################################################
+%files -n parcel
+%manifest parcel.manifest
+%license LICENSE
+%{_libdir}/libparcel.so.*
+
+%files -n parcel-devel
+%manifest parcel.manifest
+%{_includedir}/*
+%{_libdir}/pkgconfig/parcel.pc
+%{_libdir}/libparcel.so
+
+%files -n parcel-unittests
+%{_bindir}/parcel_unittests
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+PROJECT(parcel C CXX)
+
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(pkgs REQUIRED dlog capi-base-common)
+
+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++14")
+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")
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} bundle)
+
+### 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 <bundle.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 Writes a bundle data into the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[in] b The bundle 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_bundle()
+ */
+int parcel_write_bundle(parcel_h parcel, bundle* b);
+
+/**
+ * @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 Reads a bundle data from the parcel handle.
+ * @since_tizen 6.5
+ * @param[in] parcel The parcel handle
+ * @param[out] val The bundle 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_bundle(parcel_h parcel, bundle **b);
+
+/**
+ * @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);
+
+#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 "include/bundle_cpp.h"
+#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 {
+
+Parcel::Impl::Impl(Parcel* parent) : parent_(parent) {
+}
+
+Parcel::Impl::~Impl() = default;
+
+void Parcel::Impl::Write(const void* buf, uint32_t size) {
+ auto* p = reinterpret_cast<const uint8_t*>(buf);
+ std::copy(p, p + size, std::back_inserter(data_));
+}
+
+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;
+
+ auto* p = reinterpret_cast<uint8_t*>(buf);
+ std::copy(&data_[reader_], &data_[reader_] + size, p);
+ reader_ += size;
+ set_last_result(TIZEN_ERROR_NONE);
+ return TIZEN_ERROR_NONE;
+}
+
+const std::vector<uint8_t>& Parcel::Impl::GetRaw() {
+ return data_;
+}
+
+void Parcel::Impl::ResetReader() {
+ reader_ = 0;
+}
+
+void Parcel::Impl::Clear() {
+ data_.clear();
+ 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) {
+ auto* p = reinterpret_cast<uint8_t*>(&size);
+ std::copy(p, p + sizeof(size), std::back_inserter(data_));
+}
+
+template <typename T>
+void Parcel::Impl::Write(T d) {
+ WriteSize(sizeof(T));
+ auto* p = reinterpret_cast<uint8_t*>(&d);
+ std::copy(p, p + sizeof(T), std::back_inserter(data_));
+}
+
+int Parcel::Impl::ReadSize(uint32_t* size) {
+ if (data_.size() == 0)
+ return TIZEN_ERROR_NO_DATA;
+
+ if (reader_ + sizeof(uint32_t) > data_.size())
+ return TIZEN_ERROR_ILLEGAL_BYTE_SEQ;
+
+ auto* p = reinterpret_cast<uint8_t*>(size);
+ std::copy(&data_[reader_], &data_[reader_] + sizeof(uint32_t), p);
+ reader_ += sizeof(uint32_t);
+ return TIZEN_ERROR_NONE;
+}
+
+template <typename T>
+int Parcel::Impl::Read(T* d) {
+ uint32_t size = 0;
+ int ret = ReadSize(&size);
+ if (ret != TIZEN_ERROR_NONE)
+ return ret;
+
+ if (size == 0 || size != sizeof(T))
+ return TIZEN_ERROR_ILLEGAL_BYTE_SEQ;
+
+ if (reader_ + size > data_.size())
+ return TIZEN_ERROR_ILLEGAL_BYTE_SEQ;
+
+ auto* p = reinterpret_cast<uint8_t*>(d);
+ std::copy(&data_[reader_], &data_[reader_] + size, p);
+ reader_ += size;
+ return TIZEN_ERROR_NONE;
+}
+
+Parcel::Parcel() : impl_(new Impl(this)) {
+}
+
+Parcel::Parcel(const void* buf, uint32_t size) : impl_(new Impl(this)) {
+ impl_->Write(buf, size);
+}
+
+Parcel::~Parcel() = default;
+
+Parcel::Parcel(const Parcel& p)
+ : impl_(new Impl(this)) {
+ std::copy(p.impl_->data_.begin(), p.impl_->data_.end(),
+ std::back_inserter(impl_->data_));
+ impl_->reader_ = p.impl_->reader_;
+}
+
+Parcel& Parcel::operator = (const Parcel& p) {
+ if (this != &p) {
+ std::copy(p.impl_->data_.begin(), p.impl_->data_.end(),
+ std::back_inserter(impl_->data_));
+ impl_->reader_ = p.impl_->reader_;
+ }
+ return *this;
+}
+
+Parcel::Parcel(Parcel&& p) noexcept {
+ impl_ = std::move(p.impl_);
+ impl_->parent_ = this;
+}
+
+Parcel& Parcel::operator = (Parcel&& p) noexcept {
+ if (this != &p) {
+ impl_->data_ = std::move(p.impl_->data_);
+ 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) {
+ impl_->Write<uint16_t>(val);
+}
+
+void Parcel::WriteUInt32(uint32_t val) {
+ impl_->Write<uint32_t>(val);
+}
+
+void Parcel::WriteUInt64(uint64_t val) {
+ impl_->Write<uint64_t>(val);
+}
+
+void Parcel::WriteInt16(int16_t val) {
+ impl_->Write<int16_t>(val);
+}
+
+void Parcel::WriteInt32(int32_t val) {
+ impl_->Write<int32_t>(val);
+}
+
+void Parcel::WriteInt64(int64_t val) {
+ impl_->Write<int64_t>(val);
+}
+
+void Parcel::WriteFloat(float val) {
+ impl_->Write<float>(val);
+}
+
+void Parcel::WriteDouble(double 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);
+}
+
+void Parcel::WriteCBundle(bundle* b) {
+ bundle_raw* raw = nullptr;
+ int len = 0;
+ bundle_encode(b, &raw, &len);
+ auto ptr = std::unique_ptr<bundle_raw, decltype(std::free)*>(raw, std::free);
+
+ auto* p = reinterpret_cast<void*>(raw);
+ impl_->WriteSize(len + 1);
+ impl_->Write(p, len + 1);
+}
+
+void Parcel::WriteBundle(const Bundle& b) {
+ auto raw = const_cast<Bundle&>(b).ToRaw();
+ auto* p = reinterpret_cast<void*>(raw.first.get());
+ impl_->WriteSize(raw.second + 1);
+ impl_->Write(p, raw.second + 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) {
+ return impl_->Read<uint16_t>(val);
+}
+
+int Parcel::ReadUInt32(uint32_t* val) {
+ return impl_->Read<uint32_t>(val);
+}
+
+int Parcel::ReadUInt64(uint64_t* val) {
+ return impl_->Read<uint64_t>(val);
+}
+
+int Parcel::ReadInt16(int16_t* val) {
+ return impl_->Read<int16_t>(val);
+}
+
+int Parcel::ReadInt32(int32_t* val) {
+ return impl_->Read<int32_t>(val);
+}
+
+int Parcel::ReadInt64(int64_t* val) {
+ return impl_->Read<int64_t>(val);
+}
+
+int Parcel::ReadFloat(float* val) {
+ return impl_->Read<float>(val);
+}
+
+int Parcel::ReadDouble(double* val) {
+ return impl_->Read<double>(val);
+}
+
+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;
+}
+
+int Parcel::ReadCBundle(bundle** b) {
+ uint32_t len = 0;
+ int ret = impl_->ReadSize(&len);
+ if (ret != TIZEN_ERROR_NONE)
+ return ret;
+
+ uint8_t* raw = new (std::nothrow) uint8_t [len];
+ if (raw == nullptr)
+ return TIZEN_ERROR_OUT_OF_MEMORY;
+
+ auto ptr = std::unique_ptr<uint8_t[]>(raw);
+ ret = impl_->Read(raw, len);
+ if (ret != TIZEN_ERROR_NONE)
+ return ret;
+
+ *b = bundle_decode(reinterpret_cast<bundle_raw*>(raw), len);
+ if (*b == nullptr)
+ return get_last_result();
+
+ return TIZEN_ERROR_NONE;
+}
+
+Bundle Parcel::ReadBundle() {
+ uint32_t len = 0;
+ int ret = impl_->ReadSize(&len);
+ if (ret != TIZEN_ERROR_NONE) {
+ set_last_result(ret);
+ return {};
+ }
+
+ uint8_t* raw = new (std::nothrow) uint8_t [len];
+ if (raw == nullptr) {
+ set_last_result(TIZEN_ERROR_OUT_OF_MEMORY);
+ return {};
+ }
+
+ auto ptr = std::unique_ptr<uint8_t[]>(raw);
+ ret = impl_->Read(raw, len);
+ if (ret != TIZEN_ERROR_NONE) {
+ set_last_result(ret);
+ return {};
+ }
+
+ bundle* b = bundle_decode(reinterpret_cast<bundle_raw*>(raw), len);
+ if (b == nullptr)
+ return {};
+
+ set_last_result(TIZEN_ERROR_NONE);
+ return Bundle(b, false, true);
+}
+
+const std::vector<uint8_t>& Parcel::GetRaw() {
+ return impl_->GetRaw();
+}
+
+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) {
+ impl_->Write<int32_t>(1);
+ parcelable.WriteToParcel(this);
+}
+
+int Parcel::ReadParcelable(Parcelable* parcelable) {
+ int32_t has_parcelable = 0;
+ int ret = impl_->Read<int32_t>(&has_parcelable);
+ if (ret != TIZEN_ERROR_NONE)
+ return ret;
+
+ if (has_parcelable != 1)
+ return TIZEN_ERROR_ILLEGAL_BYTE_SEQ;
+
+ parcelable->ReadFromParcel(this);
+ return TIZEN_ERROR_NONE;
+}
+
+} // naemspace 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 <bundle_cpp.h>
+#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
+ */
+ Parcel(const void* buf, uint32_t size);
+
+ /**
+ * @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 Writes a bundle data into the parcel.
+ * @since_tizen 6.5
+ * @param[in] b The bundle data
+ */
+ void WriteCBundle(bundle* b);
+
+ /**
+ * @brief Writes a bundle data into the parcel.
+ * @since_tizen 6.5
+ * @param[in] b The bundle data
+ */
+ void WriteBundle(const Bundle& b);
+
+ /**
+ * @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 Reads a bundle data from the parcel.
+ * @since_tizen 6.5
+ * @remarks You should release @a b using bundle_free().
+ * @param[out] b The bundle data
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ */
+ int ReadCBundle(bundle** b);
+
+ /**
+ * @brief Reads a bundle data from the parcel.
+ * @since_tizen 6.5
+ * @return The bundle data
+ * @remarks Before using the returned value, you should check the result using get_last_result().
+ * @see get_last_result();
+ */
+ Bundle ReadBundle();
+
+ /**
+ * @brief Gets the raw data of the parcel.
+ * @since_tizen 6.5
+ * @return The raw data
+ */
+ const std::vector<uint8_t>& GetRaw();
+
+ /**
+ * @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);
+
+ 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 -lbundle
+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);
+ const std::vector<uint8_t>& GetRaw();
+ 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);
+
+ private:
+ friend class Parcel;
+ explicit Impl(Parcel* parent);
+
+ private:
+ Parcel* parent_;
+ std::vector<uint8_t> data_;
+ uint64_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 "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_write_bundle(parcel_h parcel, bundle* b) {
+ if (parcel == nullptr || b == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ h->WriteCBundle(b);
+ 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_read_bundle(parcel_h parcel, bundle** b) {
+ if (parcel == nullptr || b == nullptr) {
+ _E("Invalid parameter");
+ return PARCEL_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* h = static_cast<Parcel*>(parcel);
+ return h->ReadCBundle(b);
+}
+
+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);
+ auto& raw_data = h->GetRaw();
+ *raw = reinterpret_cast<void*>(const_cast<uint8_t*>(&raw_data[0]));
+ *size = raw_data.size();
+ return PARCEL_ERROR_NONE;
+}
--- /dev/null
+ADD_SUBDIRECTORY(bundle_unittests)
+ADD_SUBDIRECTORY(parcel_unittests)
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}/../src)
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include)
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../bundle)
+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)
-AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../bundle BUNDLE_INTERNAL_SOURCES)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../src BUNDLE_SOURCES)
ADD_EXECUTABLE(${PROJECT_NAME}
${BUNDLE_SOURCES}
- ${BUNDLE_INTERNAL_SOURCES}
${UNITTESTS_SOURCES}
)
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+PROJECT(parcel_unittests C CXX)
+
+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++14")
+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}/../../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)
+
+ADD_EXECUTABLE(${PROJECT_NAME}
+ ${BUNDLE_SOURCES}
+ ${PARCEL_SOURCES}
+ ${UNITTESTS_SOURCES}
+)
+
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${parcel_unittests_LDFLAGS})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION /usr/bin/)
--- /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 <gtest/gtest.h>
+#include <gmock/gmock.h>
+
+#include <exception>
+
+int main(int argc, char** argv) {
+ try {
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+ } catch (std::exception const &e) {
+ std::cout << "test_main caught exception: " << e.what() << std::endl;
+ return -1;
+ }
+}
--- /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 <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <iostream>
+#include <stdexcept>
+#include <string>
+
+#include "parcel/api/parcel.h"
+
+class ParcelTest : public ::testing::Test {
+ public:
+ virtual void SetUp() {
+ parcel_create(&parcel_);
+ }
+
+ virtual void TearDown() {
+ if (parcel_)
+ parcel_destroy(parcel_);
+ }
+
+ parcel_h GetHandle() {
+ return parcel_;
+ }
+
+ void SetHandle(parcel_h* parcel) {
+ parcel_ = parcel;
+ }
+
+ private:
+ parcel_h parcel_ = nullptr;
+};
+
+TEST_F(ParcelTest, parcel_create_P) {
+ parcel_h parcel = nullptr;
+ int ret = parcel_create(&parcel);
+ auto ptr = std::unique_ptr<std::remove_pointer<parcel_h>::type,
+ decltype(parcel_destroy)*>(parcel, parcel_destroy);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_NE(parcel, nullptr);
+}
+
+TEST_F(ParcelTest, parcel_create_N) {
+ int ret = parcel_create(nullptr);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_destroy_P) {
+ int ret = parcel_destroy(GetHandle());
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ SetHandle(nullptr);
+}
+
+TEST_F(ParcelTest, parcel_destroy_N) {
+ int ret = parcel_destroy(nullptr);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_clone_P) {
+ parcel_h clone = nullptr;
+ int ret = parcel_clone(GetHandle(), &clone);
+ auto ptr = std::unique_ptr<std::remove_pointer<parcel_h>::type,
+ decltype(parcel_destroy)*>(clone, parcel_destroy);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_NE(clone, nullptr);
+}
+
+TEST_F(ParcelTest, parcel_clone_N) {
+ int ret = parcel_clone(nullptr, nullptr);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_burst_write_P) {
+ char buf[1024] = { 1, };
+ int ret = parcel_burst_write(GetHandle(), buf, sizeof(buf));
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ char read_buf[1024];
+ ret = parcel_burst_read(GetHandle(), read_buf, sizeof(read_buf));
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(read_buf[0], 1);
+}
+
+TEST_F(ParcelTest, parcel_burst_write_N) {
+ int ret = parcel_burst_write(nullptr, nullptr, 0);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_burst_read_P) {
+ char buf[1024] = { 2, };
+ int ret = parcel_burst_write(GetHandle(), buf, sizeof(buf));
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ char read_buf[1024];
+ ret = parcel_burst_read(GetHandle(), read_buf, sizeof(read_buf));
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(read_buf[0], 2);
+}
+
+TEST_F(ParcelTest, parcel_burst_read_N) {
+ int ret = parcel_burst_read(nullptr, nullptr, 0);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_write_bool_P) {
+ int ret = parcel_write_bool(GetHandle(), true);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ bool val = false;
+ ret = parcel_read_bool(GetHandle(), &val);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(val, true);
+}
+
+TEST_F(ParcelTest, parcel_write_bool_N) {
+ int ret = parcel_write_bool(nullptr, false);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_write_byte_P) {
+ int ret = parcel_write_byte(GetHandle(), 1);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ char val = 0;
+ ret = parcel_read_byte(GetHandle(), &val);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(val, 1);
+}
+
+TEST_F(ParcelTest, parcel_write_byte_N) {
+ int ret = parcel_write_byte(nullptr, 1);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_write_uint16_P) {
+ int ret = parcel_write_uint16(GetHandle(), 1);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ uint16_t val = 0;
+ ret = parcel_read_uint16(GetHandle(), &val);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(val, 1);
+}
+
+TEST_F(ParcelTest, parcel_write_uint16_N) {
+ int ret = parcel_write_uint16(nullptr, 1);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_write_uint32_P) {
+ int ret = parcel_write_uint32(GetHandle(), 1);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ uint32_t val = 0;
+ ret = parcel_read_uint32(GetHandle(), &val);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(val, 1);
+}
+
+TEST_F(ParcelTest, parcel_write_uint32_N) {
+ int ret = parcel_write_uint32(nullptr, 1);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_write_uint64_P) {
+ int ret = parcel_write_uint64(GetHandle(), 1);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ uint64_t val = 0;
+ ret = parcel_read_uint64(GetHandle(), &val);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(val, 1);
+}
+
+TEST_F(ParcelTest, parcel_write_uint64_N) {
+ int ret = parcel_write_uint64(nullptr, 1);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_write_int16_P) {
+ int ret = parcel_write_int16(GetHandle(), 1);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ int16_t val = 0;
+ ret = parcel_read_int16(GetHandle(), &val);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(val, 1);
+}
+
+TEST_F(ParcelTest, parcel_write_int16_N) {
+ int ret = parcel_write_int16(nullptr, 1);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_write_int32_P) {
+ int ret = parcel_write_int32(GetHandle(), 1);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ int32_t val = 0;
+ ret = parcel_read_int32(GetHandle(), &val);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(val, 1);
+}
+
+TEST_F(ParcelTest, parcel_write_int32_N) {
+ int ret = parcel_write_int32(nullptr, 1);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_write_int64_P) {
+ int ret = parcel_write_int64(GetHandle(), 1);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ int64_t val = 0;
+ ret = parcel_read_int64(GetHandle(), &val);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(val, 1);
+}
+
+TEST_F(ParcelTest, parcel_write_int64_N) {
+ int ret = parcel_write_int64(nullptr, 1);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_write_float_P) {
+ int ret = parcel_write_float(GetHandle(), 0.1f);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ float val = 0.0f;
+ ret = parcel_read_float(GetHandle(), &val);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(val, 0.1f);
+}
+
+TEST_F(ParcelTest, parcel_write_float_N) {
+ int ret = parcel_write_float(nullptr, 0.1f);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_write_double_P) {
+ int ret = parcel_write_double(GetHandle(), 0.1f);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ double val = 0.0f;
+ ret = parcel_read_double(GetHandle(), &val);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(val, 0.1f);
+}
+
+TEST_F(ParcelTest, parcel_write_double_N) {
+ int ret = parcel_write_double(nullptr, 0.1f);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_write_string_P) {
+ int ret = parcel_write_string(GetHandle(), "TestString");
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ char* str = nullptr;
+ ret = parcel_read_string(GetHandle(), &str);
+ ASSERT_NE(str, nullptr);
+ auto ptr = std::unique_ptr<char, decltype(std::free)*>(str, std::free);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(std::string(str), "TestString");
+}
+
+TEST_F(ParcelTest, parcel_write_string_N) {
+ int ret = parcel_write_string(nullptr, nullptr);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_write_bundle_P) {
+ bundle* b = bundle_create();
+ bundle_add_str(b, "Key", "Value");
+ int ret = parcel_write_bundle(GetHandle(), b);
+ bundle_free(b);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ b = nullptr;
+ ret = parcel_read_bundle(GetHandle(), &b);
+ ASSERT_NE(b, nullptr);
+ auto ptr = std::unique_ptr<std::remove_pointer<bundle>::type,
+ decltype(bundle_free)*>(b, bundle_free);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ char* str = nullptr;
+ bundle_get_str(b, "Key", &str);
+ ASSERT_EQ(std::string(str), "Value");
+}
+
+TEST_F(ParcelTest, parcel_write_bundle_N) {
+ int ret = parcel_write_bundle(nullptr, nullptr);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_read_bool_P) {
+ int ret = parcel_write_bool(GetHandle(), false);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ bool val = true;
+ ret = parcel_read_bool(GetHandle(), &val);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(val, false);
+}
+
+TEST_F(ParcelTest, parcel_read_bool_N) {
+ int ret = parcel_read_bool(nullptr, nullptr);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_read_byte_P) {
+ int ret = parcel_write_byte(GetHandle(), 2);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ char val = 0;
+ ret = parcel_read_byte(GetHandle(), &val);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(val, 2);
+}
+
+TEST_F(ParcelTest, parcel_read_byte_N) {
+ int ret = parcel_read_byte(nullptr, nullptr);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_read_uint16_P) {
+ int ret = parcel_write_uint16(GetHandle(), 2);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ uint16_t val = 0;
+ ret = parcel_read_uint16(GetHandle(), &val);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(val, 2);
+}
+
+TEST_F(ParcelTest, parcel_read_uint16_N) {
+ int ret = parcel_read_uint16(nullptr, nullptr);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_read_uint32_P) {
+ int ret = parcel_write_uint32(GetHandle(), 2);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ uint32_t val = 0;
+ ret = parcel_read_uint32(GetHandle(), &val);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(val, 2);
+}
+
+TEST_F(ParcelTest, parcel_read_uint32_N) {
+ int ret = parcel_read_uint32(nullptr, nullptr);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_read_uint64_P) {
+ int ret = parcel_write_uint64(GetHandle(), 2);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ uint64_t val = 0;
+ ret = parcel_read_uint64(GetHandle(), &val);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(val, 2);
+}
+
+TEST_F(ParcelTest, parcel_read_uint64_N) {
+ int ret = parcel_read_uint64(nullptr, nullptr);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_read_int16_P) {
+ int ret = parcel_write_int16(GetHandle(), 2);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ int16_t val = 0;
+ ret = parcel_read_int16(GetHandle(), &val);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(val, 2);
+}
+
+TEST_F(ParcelTest, parcel_read_int16_N) {
+ int ret = parcel_read_int16(nullptr, nullptr);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_read_int32_P) {
+ int ret = parcel_write_int32(GetHandle(), 2);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ int32_t val = 0;
+ ret = parcel_read_int32(GetHandle(), &val);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(val, 2);
+}
+
+TEST_F(ParcelTest, parcel_read_int32_N) {
+ int ret = parcel_read_int32(nullptr, nullptr);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_read_int64_P) {
+ int ret = parcel_write_int64(GetHandle(), 2);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ int64_t val = 0;
+ ret = parcel_read_int64(GetHandle(), &val);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(val, 2);
+}
+
+TEST_F(ParcelTest, parcel_read_int64_N) {
+ int ret = parcel_read_int64(nullptr, nullptr);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_read_float_P) {
+ int ret = parcel_write_float(GetHandle(), 0.2f);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ float val = 0.0f;
+ ret = parcel_read_float(GetHandle(), &val);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(val, 0.2f);
+}
+
+TEST_F(ParcelTest, parcel_read_float_N) {
+ int ret = parcel_read_float(nullptr, nullptr);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_read_double_P) {
+ int ret = parcel_write_double(GetHandle(), 0.2f);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ double val = 0.0f;
+ ret = parcel_read_double(GetHandle(), &val);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(val, 0.2f);
+}
+
+TEST_F(ParcelTest, parcel_read_double_N) {
+ int ret = parcel_read_double(nullptr, nullptr);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_read_string_P) {
+ int ret = parcel_write_string(GetHandle(), "ReadCString");
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ char* str = nullptr;
+ ret = parcel_read_string(GetHandle(), &str);
+ ASSERT_NE(str, nullptr);
+ auto ptr = std::unique_ptr<char, decltype(std::free)*>(str, std::free);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(std::string(str), "ReadCString");
+}
+
+TEST_F(ParcelTest, parcel_read_string_N) {
+ int ret = parcel_read_string(nullptr, nullptr);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_read_bundle_P) {
+ bundle* b = bundle_create();
+ bundle_add_str(b, "Key", "Value");
+ int ret = parcel_write_bundle(GetHandle(), b);
+ bundle_free(b);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ b = nullptr;
+ ret = parcel_read_bundle(GetHandle(), &b);
+ ASSERT_NE(b, nullptr);
+ auto ptr = std::unique_ptr<std::remove_pointer<bundle>::type,
+ decltype(bundle_free)*>(b, bundle_free);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ char* str = nullptr;
+ bundle_get_str(b, "Key", &str);
+ ASSERT_EQ(std::string(str), "Value");
+}
+
+TEST_F(ParcelTest, parcel_read_bundle_N) {
+ int ret = parcel_read_bundle(nullptr, nullptr);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_reset_reader_P) {
+ int ret = parcel_reset_reader(GetHandle());
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+}
+
+TEST_F(ParcelTest, parcel_reset_reader_N) {
+ int ret = parcel_reset_reader(nullptr);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_clear_P) {
+ int ret = parcel_clear(GetHandle());
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+}
+
+TEST_F(ParcelTest, parcel_clear_N) {
+ int ret = parcel_clear(nullptr);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_reset_P) {
+ char buf[1024] = { 128, };
+ int ret = parcel_reset(GetHandle(), buf, sizeof(buf));
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ char read_buf[1024] = { 0, };
+ ret = parcel_burst_read(GetHandle(), read_buf, sizeof(read_buf));
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(read_buf[0], buf[0]);
+}
+
+TEST_F(ParcelTest, parcel_reset_N) {
+ int ret = parcel_reset(nullptr, nullptr, 0);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+static void __write_to_parcel(parcel_h parcel, void* data) {
+ parcel_write_int32(parcel, 1);
+}
+
+static void __read_from_parcel(parcel_h parcel, void* data) {
+ int32_t* val = static_cast<int32_t*>(data);
+ parcel_read_int32(parcel, val);
+}
+
+TEST_F(ParcelTest, parcel_write_P) {
+ parcelable_t parcelable = {
+ .to = __write_to_parcel,
+ .from = __read_from_parcel
+ };
+ int ret = parcel_write(GetHandle(), &parcelable, nullptr);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ int32_t val = 0;
+ ret = parcel_read(GetHandle(), &parcelable, static_cast<void*>(&val));
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(val, 1);
+}
+
+TEST_F(ParcelTest, parcel_write_N) {
+ int ret = parcel_write(nullptr, nullptr, nullptr);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_read_P) {
+ parcelable_t parcelable = {
+ .to = __write_to_parcel,
+ .from = __read_from_parcel
+ };
+ int ret = parcel_write(GetHandle(), &parcelable, nullptr);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ int32_t val = 0;
+ ret = parcel_read(GetHandle(), &parcelable, static_cast<void*>(&val));
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_EQ(val, 1);
+}
+
+TEST_F(ParcelTest, parcel_read_N) {
+ int ret = parcel_read(nullptr, nullptr, nullptr);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(ParcelTest, parcel_get_raw_P) {
+ int ret = parcel_write_int32(GetHandle(), 1);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ uint8_t* raw = nullptr;
+ uint32_t size = 0;
+ ret = parcel_get_raw(GetHandle(), reinterpret_cast<void**>(&raw), &size);
+ ASSERT_EQ(ret, PARCEL_ERROR_NONE);
+ ASSERT_NE(raw, nullptr);
+ ASSERT_EQ(size, sizeof(uint32_t) + sizeof(int32_t));
+}
+
+TEST_F(ParcelTest, parcel_get_raw_N) {
+ int ret = parcel_get_raw(nullptr, nullptr, nullptr);
+ ASSERT_EQ(ret, PARCEL_ERROR_INVALID_PARAMETER);
+}
--- /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 <gtest/gtest.h>
+#include <gmock/gmock.h>
+#include <iostream>
+#include <stdexcept>
+
+#include "parcel/parcel.hh"
+
+using ::testing::AtLeast;
+using namespace tizen_base;
+
+class ParcelCppTest : public ::testing::Test {
+ public:
+ virtual void SetUp() {
+ }
+
+ virtual void TearDown() {
+ parcel_.Clear();
+ }
+
+ Parcel& GetHandle() {
+ return parcel_;
+ }
+
+ private:
+ Parcel parcel_;
+};
+
+class Student : public Parcelable {
+ public:
+ Student(std::string name, uint32_t age)
+ : name_(std::move(name)), age_(age) {
+ }
+
+ Student() = default;
+ virtual ~Student() = default;
+
+ const std::string& GetName() const {
+ return name_;
+ }
+
+ uint32_t GetAge() const {
+ return age_;
+ }
+
+ virtual void WriteToParcel(Parcel* parcel) const {
+ parcel->WriteString(name_);
+ parcel->WriteUInt32(age_);
+ }
+
+ virtual void ReadFromParcel(Parcel* parcel) {
+ name_ = parcel->ReadString();
+ parcel->ReadUInt32(&age_);
+ }
+
+ private:
+ std::string name_;
+ uint32_t age_;
+};
+
+TEST_F(ParcelCppTest, Ctor_AND_Dtor) {
+ Parcel parcel;
+}
+
+TEST_F(ParcelCppTest, Write_AND_Read) {
+ char buf[1024] = { 128, };
+ GetHandle().Write(buf, sizeof(buf));
+ char read_buf[1024] = { 0, };
+ int ret = GetHandle().Read(read_buf, sizeof(read_buf));
+ ASSERT_EQ(ret, Parcel::Error::None);
+ ASSERT_EQ(buf[0], read_buf[0]);
+}
+
+TEST_F(ParcelCppTest, WriteBool_AND_ReadBool) {
+ GetHandle().WriteBool(true);
+ bool val = false;
+ int ret = GetHandle().ReadBool(&val);
+ ASSERT_EQ(ret, Parcel::Error::None);
+ ASSERT_EQ(val, true);
+}
+
+TEST_F(ParcelCppTest, WriteByte_AND_ReadByte) {
+ GetHandle().WriteByte(1);
+ char val = 0;
+ int ret = GetHandle().ReadByte(&val);
+ ASSERT_EQ(ret, Parcel::Error::None);
+ ASSERT_EQ(val, 1);
+}
+
+TEST_F(ParcelCppTest, WriteUInt16_AND_ReadUInt16) {
+ GetHandle().WriteUInt16(1);
+ uint16_t val = 0;
+ int ret = GetHandle().ReadUInt16(&val);
+ ASSERT_EQ(ret, Parcel::Error::None);
+ ASSERT_EQ(val, 1);
+}
+
+TEST_F(ParcelCppTest, WriteUInt32_AND_ReadUInt32) {
+ GetHandle().WriteUInt32(1);
+ uint32_t val = 0;
+ int ret = GetHandle().ReadUInt32(&val);
+ ASSERT_EQ(ret, Parcel::Error::None);
+ ASSERT_EQ(val, 1);
+}
+
+TEST_F(ParcelCppTest, WriteUInt64_AND_ReadUInt64) {
+ GetHandle().WriteUInt64(1);
+ uint64_t val = 0;
+ int ret = GetHandle().ReadUInt64(&val);
+ ASSERT_EQ(ret, Parcel::Error::None);
+ ASSERT_EQ(val, 1);
+}
+
+TEST_F(ParcelCppTest, WriteInt16_AND_ReadInt16) {
+ GetHandle().WriteInt16(1);
+ int16_t val = 0;
+ int ret = GetHandle().ReadInt16(&val);
+ ASSERT_EQ(ret, Parcel::Error::None);
+ ASSERT_EQ(val, 1);
+}
+
+TEST_F(ParcelCppTest, WriteInt32_AND_ReadInt32) {
+ GetHandle().WriteInt32(1);
+ int32_t val = 0;
+ int ret = GetHandle().ReadInt32(&val);
+ ASSERT_EQ(ret, Parcel::Error::None);
+ ASSERT_EQ(val, 1);
+}
+
+TEST_F(ParcelCppTest, WriteInt64_AND_ReadInt64) {
+ GetHandle().WriteInt64(1);
+ int64_t val = 0;
+ int ret = GetHandle().ReadInt64(&val);
+ ASSERT_EQ(ret, Parcel::Error::None);
+ ASSERT_EQ(val, 1);
+}
+
+TEST_F(ParcelCppTest, WriteFloat_AND_ReadFloat) {
+ GetHandle().WriteFloat(0.1f);
+ float val = 0.0f;
+ int ret = GetHandle().ReadFloat(&val);
+ ASSERT_EQ(ret, Parcel::Error::None);
+ ASSERT_EQ(val, 0.1f);
+}
+
+TEST_F(ParcelCppTest, WriteDouble_AND_ReadDouble) {
+ GetHandle().WriteDouble(0.1f);
+ double val = 0.0f;
+ int ret = GetHandle().ReadDouble(&val);
+ ASSERT_EQ(ret, Parcel::Error::None);
+ ASSERT_EQ(val, 0.1f);
+}
+
+TEST_F(ParcelCppTest, WriteString_AND_ReadString) {
+ GetHandle().WriteString("TestString");
+ auto val = GetHandle().ReadString();
+ ASSERT_EQ(get_last_result(), Parcel::Error::None);
+ ASSERT_EQ(val, "TestString");
+}
+
+TEST_F(ParcelCppTest, WriteCString_AND_ReadCString) {
+ GetHandle().WriteCString("TestCString");
+ char* str = nullptr;
+ int ret = GetHandle().ReadCString(&str);
+ auto ptr = std::unique_ptr<char, decltype(std::free)*>(str, std::free);
+ ASSERT_EQ(ret, Parcel::Error::None);
+ ASSERT_NE(str, nullptr);
+ ASSERT_EQ(std::string(str), "TestCString");
+}
+
+TEST_F(ParcelCppTest, WriteCBundle_AND_ReadCBundle) {
+ bundle* b = bundle_create();
+ bundle_add_str(b, "Key", "Value");
+ GetHandle().WriteCBundle(b);
+ bundle_free(b);
+ bundle* val = nullptr;
+ int ret = GetHandle().ReadCBundle(&val);
+ auto ptr = std::unique_ptr<bundle, decltype(bundle_free)*>(val, bundle_free);
+ ASSERT_EQ(ret, Parcel::Error::None);
+ ASSERT_NE(val, nullptr);
+ char* str = nullptr;
+ bundle_get_str(b, "Key", &str);
+ ASSERT_EQ(std::string(str), "Value");
+}
+
+TEST_F(ParcelCppTest, WriteBundle_AND_ReadBundle) {
+ Bundle b;
+ b.Add("Key", "Value");
+ GetHandle().WriteBundle(b);
+ auto val = GetHandle().ReadBundle();
+ ASSERT_EQ(get_last_result(), Parcel::Error::None);
+ auto str = val.GetString("Key");
+ ASSERT_EQ(str, "Value");
+}
+
+TEST_F(ParcelCppTest, GetRaw) {
+ GetHandle().WriteInt32(0);
+ auto& raw = GetHandle().GetRaw();
+ ASSERT_EQ(raw.size(), sizeof(uint32_t) + sizeof(int32_t));
+}
+
+TEST_F(ParcelCppTest, ResetReader) {
+ GetHandle().WriteInt32(1);
+ GetHandle().WriteInt32(2);
+ int32_t val = 0;
+ int ret = GetHandle().ReadInt32(&val);
+ ASSERT_EQ(ret, Parcel::Error::None);
+ ASSERT_EQ(val, 1);
+ GetHandle().ResetReader();
+ val = 0;
+ ret = GetHandle().ReadInt32(&val);
+ ASSERT_EQ(ret, Parcel::Error::None);
+ ASSERT_EQ(val, 1);
+}
+
+TEST_F(ParcelCppTest, Clear) {
+ GetHandle().WriteInt32(1);
+ GetHandle().Clear();
+ int32_t val = 0;
+ int ret = GetHandle().ReadInt32(&val);
+ ASSERT_NE(ret, Parcel::Error::None);
+ ASSERT_NE(val, 1);
+}
+
+TEST_F(ParcelCppTest, Reset) {
+ GetHandle().WriteByte(1);
+ char buf[1024] = { 128, };
+ GetHandle().Reset(buf, sizeof(buf));
+ char read_buf[1024] = { 0, };
+ int ret = GetHandle().Read(read_buf, sizeof(read_buf));
+ ASSERT_EQ(ret, Parcel::Error::None);
+ ASSERT_EQ(buf[0], read_buf[0]);
+}
+
+TEST_F(ParcelCppTest, WriteParcelable_AND_ReadParcelable) {
+ Student s1("s1", 8);
+ GetHandle().WriteParcelable(s1);
+ Student s2;
+ GetHandle().ReadParcelable(&s2);
+ ASSERT_EQ(s1.GetName(), s2.GetName());
+ ASSERT_EQ(s1.GetAge(), s2.GetAge());
+}
+
+TEST_F(ParcelCppTest, IsEmpty) {
+ ASSERT_EQ(GetHandle().IsEmpty(), true);
+ GetHandle().WriteInt32(1);
+ ASSERT_EQ(GetHandle().IsEmpty(), false);
+}