--- /dev/null
+Junghoon Park <jh9216.park@samsung.com>
PATTERN "*_private.h" EXCLUDE
PATTERN "${INC_DIR}/*.h"
)
+
+IF(NOT DEFINED MINIMUM_BUILD)
+ENABLE_TESTING()
+SET(UNITTESTS unittests)
+ADD_TEST(NAME ${UNITTESTS} COMMAND ${UNITTESTS}
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/unit_tests)
+
+ADD_SUBDIRECTORY(unit_tests)
+ENDIF(NOT DEFINED MINIMUM_BUILD)
#include <tizen.h>
+#include <app_control_uri.h>
+
#ifdef __cplusplus
extern "C" {
#endif
*/
#define APP_CONTROL_OPERATION_PRIVACY_SETTING_GUIDE "http://tizen.org/appcontrol/operation/guide_privacy_setting"
+/**
+ * @brief Definition for the application control operation: Sends URI.
+ * @details Input: URI, this is a mandatory field.\n
+ * Input: APP_CONTROL_DATA_URI_FRAGMENT in extra is the fragment of the URI. \n
+ * Input: APP_CONTROL_DATA_URI_PATH in extra is the path of the URI. \n
+ * Output: Nothing\n
+ * @since_tizen 5.5
+ */
+#define APP_CONTROL_OPERATION_INTENT "http://tizen.org/appcontrol/operation/intent"
+
/**
* @brief Definition for the app_control data: Feature of function name.
* @since_tizen @if WEARABLE 5.0 @endif
*/
#define APP_CONTROL_DATA_WIDGET_APP_ID "http://tizen.org/appcontrol/data/widget_app_id"
+/**
+ * @brief Definition for the fragment data of a URI.
+ * @since_tizen 5.5
+ */
+#define APP_CONTROL_DATA_URI_FRAGMENT "http://tizen.org/appcontrol/data/uri/fragment"
+
+/**
+ * @brief Definition for the path data of a URI.
+ * @since_tizen 5.5
+ */
+#define APP_CONTROL_DATA_URI_PATH "http://tizen.org/appcontrol/data/uri/path"
/**
* @brief Called when the reply of the launch request is delivered.
app_control_launch_mode_e mode, int extra_data_count, ...);
+/**
+ * @brief Creates an app_control handle from an app_control_uri handle.
+ *
+ * @since_tizen 5.5
+ * @remarks The @a app_control must be released using app_control_destroy().
+ *
+ * @param[out] app_control The app_control handle to be newly created on success
+ * @param[in] uri The URI handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #APP_CONTROL_ERROR_NONE Successful
+ * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @see app_control_destroy()
+ */
+int app_control_create_from_uri_handle(app_control_h *app_control,
+ app_control_uri_h uri);
+
+
/**
* @brief Destroys the app_control handle and releases all its resources.
*
int app_control_get_uri(app_control_h app_control, char **uri);
+/**
+ * @brief Sets the URI by the app_control_uri handle.
+ *
+ * @since_tizen 5.5
+ * @param[in] app_control The app_control handle
+ * @param[in] uri The URI handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #APP_CONTROL_ERROR_NONE Successful
+ * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see app_control_set_uri()
+ */
+int app_control_set_uri_by_handle(app_control_h app_control,
+ app_control_uri_h uri);
+
+
/**
* @brief Sets the explicit MIME type of the data.
*
--- /dev/null
+/*
+ * Copyright (c) 2019 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_APPFW_APP_CONTROL_URI_INCLUDE_H__
+#define __TIZEN_APPFW_APP_CONTROL_URI_INCLUDE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+#include <tizen_error.h>
+
+/**
+ * @addtogroup CAPI_APP_CONTROL_URI_MODULE
+ * @{
+ */
+
+/**
+ * @brief Enumeration for error codes of the App Control URI submodule.
+ * @since_tizen 5.5
+ */
+typedef enum {
+ APP_CONTROL_URI_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
+ APP_CONTROL_URI_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR, /**< Internal I/O error */
+ APP_CONTROL_URI_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */
+ APP_CONTROL_URI_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
+} app_control_uri_error_e;
+
+/**
+ * @brief The URI builder handle.
+ * @since_tizen 5.5
+ */
+typedef void *app_control_uri_builder_h;
+
+/**
+ * @brief The URI handle.
+ * @since_tizen 5.5
+ */
+typedef void *app_control_uri_h;
+
+/**
+ * @brief The query component handle of the URI.
+ * @since_tizen 5.5
+ */
+typedef const void *app_control_uri_query_h;
+
+/**
+ * @brief Creates a URI builder handle.
+ * @since_tizen 5.5
+ *
+ * @remarks The @a handle should be released using app_control_uri_builder_destroy().
+ *
+ * @param[out] handle The URI builder handle
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #APP_CONTROL_URI_ERROR_NONE Successful
+ * @retval #APP_CONTROL_URI_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #APP_CONTROL_URI_ERROR_OUT_OF_MEMORY Out of memory
+ * @see app_control_uri_builder_destroy()
+ */
+int app_control_uri_builder_create(app_control_uri_builder_h *handle);
+
+/**
+ * @brief Sets the scheme component.
+ * @since_tizen 5.5
+ *
+ * @param[in] handle The URI builder handle
+ * @param[in] scheme The scheme component
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #APP_CONTROL_URI_ERROR_NONE Successful
+ * @retval #APP_CONTROL_URI_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int app_control_uri_builder_set_scheme(app_control_uri_builder_h handle,
+ const char *scheme);
+
+/**
+ * @brief Sets the authority component.
+ * @since_tizen 5.5
+ *
+ * @param[in] handle The URI builder handle
+ * @param[in] auth The authority component
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #APP_CONTROL_URI_ERROR_NONE Successful
+ * @retval #APP_CONTROL_URI_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int app_control_uri_builder_set_authority(app_control_uri_builder_h handle,
+ const char *auth);
+
+/**
+ * @brief Sets the path component.
+ * @details If the path was already set, it will be replaced with @a path.
+ * @since_tizen 5.5
+ *
+ * @param[in] handle The URI builder handle
+ * @param[in] path The path component
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #APP_CONTROL_URI_ERROR_NONE Successful
+ * @retval #APP_CONTROL_URI_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int app_control_uri_builder_set_path(app_control_uri_builder_h handle,
+ const char *path);
+
+/**
+ * @brief Adds the path component.
+ * @details Builder appends @a path component to the path. If @a path doesn't
+ * start with a '/', builder will prepend the given path with a '/'.
+ * @since_tizen 5.5
+ *
+ * @param[in] handle The URI builder handle
+ * @param[in] path The path component
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #APP_CONTROL_URI_ERROR_NONE Successful
+ * @retval #APP_CONTROL_URI_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int app_control_uri_builder_add_path(app_control_uri_builder_h handle,
+ const char *path);
+
+/**
+ * @brief Sets the fragment identifier component.
+ * @since_tizen 5.5
+ *
+ * @param[in] handle The URI builder handle
+ * @param[in] fragment The fragment identifier component
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #APP_CONTROL_URI_ERROR_NONE Successful
+ * @retval #APP_CONTROL_URI_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int app_control_uri_builder_set_fragment(app_control_uri_builder_h handle,
+ const char *fragment);
+
+/**
+ * @brief Adds the key-value pair attribute of the query component.
+ * @since_tizen 5.5
+ *
+ * @param[in] handle The URI builder handle
+ * @param[in] key The name of the query component key-value pairs
+ * @param[in] val The value associated with the given key
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #APP_CONTROL_URI_ERROR_NONE Successful
+ * @retval #APP_CONTROL_URI_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int app_control_uri_builder_add_query(app_control_uri_builder_h handle,
+ const char *key, const char *val);
+
+/**
+ * @brief Creates a URI handle with the attributes set by calling URI builder functions.
+ * @since_tizen 5.5
+ *
+ * @remarks The @a app_control_uri should be released using app_control_uri_destroy().
+ *
+ * @param[in] builder The URI builder handle
+ * @param[out] app_control_uri The URI handle
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #APP_CONTROL_URI_ERROR_NONE Successful
+ * @retval #APP_CONTROL_URI_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #APP_CONTROL_URI_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int app_control_uri_builder_build(app_control_uri_builder_h builder,
+ app_control_uri_h* app_control_uri);
+
+/**
+ * @brief Destroys the URI builder handle.
+ * @since_tizen 5.5
+ *
+ * @param[in] handle The URI builder handle
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #APP_CONTROL_URI_ERROR_NONE Successful
+ * @retval #APP_CONTROL_URI_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int app_control_uri_builder_destroy(app_control_uri_builder_h handle);
+
+/**
+ * @brief Creates a URI handle from an encoded URI string.
+ * @since_tizen 5.5
+ *
+ * @remarks The @a handle should be released using app_control_uri_destroy().
+ *
+ * @param[in] encoded_app_control_uri The encoded URI string
+ * @param[out] handle The URI handle
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #APP_CONTROL_URI_ERROR_NONE Successful
+ * @retval #APP_CONTROL_URI_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #APP_CONTROL_URI_ERROR_OUT_OF_MEMORY Out of memory
+ * @see app_control_uri_encode()
+ */
+int app_control_uri_create(const char *encoded_app_control_uri,
+ app_control_uri_h *handle);
+
+/**
+ * @brief Destroys the URI handle.
+ * @since_tizen 5.5
+ *
+ * @param[in] handle The URI handle
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #APP_CONTROL_URI_ERROR_NONE Successful
+ * @retval #APP_CONTROL_URI_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int app_control_uri_destroy(app_control_uri_h handle);
+
+/**
+ * @brief Encodes the URI handle to string. The string is RFC 3986-compliant.
+ * @since_tizen 5.5
+ *
+ * @remarks The @a encoded_app_control_uri URI string should be released using free().
+ *
+ * @param[in] handle The URI handle
+ * @param[out] encoded_app_control_uri The encoded URI string
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #APP_CONTROL_URI_ERROR_NONE Successfully
+ * @retval #APP_CONTROL_URI_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #APP_CONTROL_URI_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int app_control_uri_encode(app_control_uri_h handle,
+ char **encoded_app_control_uri);
+
+/**
+ * @brief Gets the scheme component from a URI handle.
+ * @since_tizen 5.5
+ *
+ * @remarks The @a scheme must not be released. The platform will release it
+ * when the App Control URI object containing it is released.
+ *
+ * @param[in] handle The URI handle
+ * @param[out] scheme The scheme component
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #APP_CONTROL_URI_ERROR_NONE Successfully
+ * @retval #APP_CONTROL_URI_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int app_control_uri_get_scheme(app_control_uri_h handle, const char **scheme);
+
+/**
+ * @brief Gets the authority component from a URI handle.
+ * @since_tizen 5.5
+ *
+ * @remarks The @a authority must not be released. The platform will release it
+ * when the App Control URI object containing it is released.
+ *
+ * @param[in] handle The URI handle
+ * @param[out] auth The authority component
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #APP_CONTROL_URI_ERROR_NONE Successfully
+ * @retval #APP_CONTROL_URI_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int app_control_uri_get_authority(app_control_uri_h handle, const char **auth);
+
+/**
+ * @brief Gets the path component from a URI handle.
+ * @since_tizen 5.5
+ *
+ * @remarks The @a path must not be released. The platform will release it
+ * when the App Control URI object containing it is released.
+ *
+ * @param[in] handle The URI handle
+ * @param[out] path The path component
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #APP_CONTROL_URI_ERROR_NONE Successfully
+ * @retval #APP_CONTROL_URI_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int app_control_uri_get_path(app_control_uri_h handle, const char **path);
+
+/**
+ * @brief Gets the fragment identifier component from a URI handle.
+ * @since_tizen 5.5
+ *
+ * @remarks The @a fragment must not be released. The platform will release it
+ * when the App Control URI object containing it is released.
+ *
+ * @param[in] handle The URI handle
+ * @param[out] fragment The fragment identifier component
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #APP_CONTROL_URI_ERROR_NONE Successfully
+ * @retval #APP_CONTROL_URI_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int app_control_uri_get_fragment(app_control_uri_h handle,
+ const char **fragment);
+
+/**
+ * @brief Gets the handle of the query component from a URI handle.
+ * @since_tizen 5.5
+ *
+ * @remarks The @a query_handle will be released by the platform when
+ * the App Control URI object which contains the query is released.
+ *
+ * @param[in] handle The URI handle
+ * @param[out] query_handle The query component handle of the URI
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #APP_CONTROL_URI_ERROR_NONE Successfully
+ * @retval #APP_CONTROL_URI_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int app_control_uri_get_query(app_control_uri_h handle,
+ app_control_uri_query_h *query_handle);
+
+/**
+ * @brief Gets the host subcomponent from a URI handle.
+ * @since_tizen 5.5
+ *
+ * @remarks The @a host must not be released. The platform will release it
+ * when the App Control URI object containing it is released.
+ *
+ * @param[in] handle The URI handle
+ * @param[out] host The host subcomponent of authority
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #APP_CONTROL_URI_ERROR_NONE Successfully
+ * @retval #APP_CONTROL_URI_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int app_control_uri_get_host(app_control_uri_h handle, const char **host);
+
+/**
+ * @brief Gets the port subcomponent from a URI handle.
+ * @since_tizen 5.5
+ *
+ * @remarks The @a port must not be released. The platform will release it
+ * when the App Control URI object containing it is released.
+ *
+ * @param[in] handle The URI handle
+ * @param[out] port The port subcomponent of authority
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #APP_CONTROL_URI_ERROR_NONE Successfully
+ * @retval #APP_CONTROL_URI_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int app_control_uri_get_port(app_control_uri_h handle, const char **port);
+
+/**
+ * @brief Gets the user subcomponent from a URI handle.
+ * @since_tizen 5.5
+ *
+ * @remarks The @a user must not be released. The platform will release it
+ * when the App Control URI object containing it is released.
+ *
+ * @param[in] handle The URI handle
+ * @param[out] user The user subcomponent of authority
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #APP_CONTROL_URI_ERROR_NONE Successfully
+ * @retval #APP_CONTROL_URI_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int app_control_uri_get_user(app_control_uri_h handle, const char **user);
+
+/**
+ * @brief Called to retrieve key-value pair attributes contained in the query component.
+ * @since_tizen 5.5
+ *
+ * @param[in] key The name of the query component key-value pairs
+ * @param[in] val The value associated with the given key
+ * @param[in] user_data The user data passed from the foreach function
+ *
+ * @return @c true to continue with the next iteration of the loop,
+ * otherwise @c false to break out of the loop
+ * @see app_control_uri_query_foreach()
+ */
+typedef bool (*app_control_uri_query_foreach_cb)(const char *key,
+ const char *val, void *user_data);
+
+/**
+ * @brief Retrieves key-value pair attributes in the query component.
+ * @since_tizen 5.5
+ *
+ * @param[in] handle The query component handle of the URI
+ * @param[in] callback The iteration callback function
+ * @param[in] user_data The user data to be passed the callback function
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #APP_CONTROL_URI_ERROR_NONE Successful
+ * @retval #APP_CONTROL_URI_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int app_control_uri_query_foreach(app_control_uri_query_h handle,
+ app_control_uri_query_foreach_cb callback, void *user_data);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_APPFW_APP_CONTROL_URI_INCLUDE_H__ */
Name: capi-appfw-app-control
Summary: App control API
-Version: 0.10.1
+Version: 0.11.0
Release: 0
Group: System/API
License: Apache-2.0
BuildRequires: pkgconfig(capi-base-common)
BuildRequires: pkgconfig(appcore-common)
Recommends: amd-mod-share
+BuildRequires: pkgconfig(gmock)
+%if 0%{?gcov:1}
+BuildRequires: lcov
+BuildRequires: zip
+%endif
+
%description
An Application Control library in Tizen C API
%description devel
An Application Control library in Tizen C API (Development) package.
+
+#################################################
+# unittests
+#################################################
+%package -n unittests
+Summary: GTest for uri
+Group: Development/Libraries
+Requires: %{name}
+
+%description -n unittests
+GTest for app_control
+
+#################################################
+# gcov
+#################################################
+%if 0%{?gcov:1}
+%package gcov
+Summary: app_control(gcov)
+Group: Application Framework/Testing
+
+%description gcov
+app_control gcov objects
+%endif
+
%prep
%setup -q
cp %{SOURCE1001} .
%build
+%if 0%{?gcov:1}
+export CFLAGS+=" -fprofile-arcs -ftest-coverage"
+export CXXFLAGS+=" -fprofile-arcs -ftest-coverage"
+export FFLAGS+=" -fprofile-arcs -ftest-coverage"
+export LDFLAGS+=" -lgcov"
+%endif
+
MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
%cmake . -DFULLVER=%{version} -DMAJORVER=${MAJORVER}
-%__make %{?jobs:-j%jobs}
+%__make %{?_smp_mflags}
+
+%if 0%{?gcov:1}
+mkdir -p gcov-obj
+find . -name '*.gcno' -exec cp '{}' gcov-obj ';'
+%endif
%install
rm -rf %{buildroot}
%make_install
+%if 0%{?gcov:1}
+mkdir -p %{buildroot}%{_datadir}/gcov/obj
+install -m 0644 gcov-obj/* %{buildroot}%{_datadir}/gcov/obj
+%endif
+
+%check
+ctest --output-on-failure %{?_smp_mflags}
+%if 0%{?gcov:1}
+lcov -c --ignore-errors graph --no-external -q -d . -o app_control.info
+genhtml app_control.info -o app_control.out
+zip -r app_control.zip app_control.out
+install -m 0644 app_control.zip %{buildroot}%{_datadir}/gcov/app_control.zip
+%endif
+
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
+%post -n unittests
+%if 0%{?gcov:1}
+%{_bindir}/unittests
+%endif
+
%files
%manifest %{name}.manifest
%{_libdir}/libcapi-appfw-app-control.so.*
+%{_libdir}/libcapi-appfw-app-control-uri.so.*
%license LICENSE
%files devel
%manifest %{name}.manifest
%{_includedir}/appfw/app_control.h
%{_includedir}/appfw/app_control_internal.h
+%{_includedir}/appfw/app_control_uri.h
%{_libdir}/pkgconfig/capi-appfw-app-control.pc
%{_libdir}/libcapi-appfw-app-control.so
+%{_libdir}/libcapi-appfw-app-control-uri.so
+
+#################################################
+# unittests
+#################################################
+%files -n unittests
+%{_bindir}/unittests
+#################################################
+# uri-gcov
+#################################################
+%if 0%{?gcov:1}
+%files gcov
+%{_datadir}/gcov/*
+%endif
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
SET(fw_name "capi-appfw-app-control")
+SET(uri_fw_name "capi-appfw-app-control-uri")
PROJECT(${fw_name})
app_control.c
)
-TARGET_LINK_LIBRARIES(${fw_name} ${${fw_name}_LDFLAGS})
+TARGET_LINK_LIBRARIES(${fw_name} ${${fw_name}_LDFLAGS} ${uri_fw_name})
SET_TARGET_PROPERTIES(${fw_name}
PROPERTIES
PATTERN "${INC_DIR}/*.h"
)
+
SET(PC_NAME ${fw_name})
SET(PC_REQUIRED ${pc_requires})
-SET(PC_LDFLAGS -l${fw_name})
+SET(PC_LDFLAGS -l${fw_name} -l${uri_fw_name})
CONFIGURE_FILE(
${CMAKE_SOURCE_DIR}/${fw_name}.pc.in
@ONLY
)
INSTALL(FILES ${CMAKE_SOURCE_DIR}/${fw_name}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+
+ADD_SUBDIRECTORY(uri)
*/
+#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
return ret;
}
+static bool uri_query_cb(const char *key, const char *val, void *user_data)
+{
+ int ret;
+
+ app_control_h *app_control = (app_control_h *)user_data;
+
+ ret = app_control_add_extra_data(*app_control, key, val);
+ if (ret != APP_CONTROL_ERROR_NONE) {
+ LOGE("app_control_add_extra_data failed: %d[%s,%s]", ret, key, val);
+ return false;
+ }
+
+ return true;
+}
+
+int app_control_create_from_uri_handle(app_control_h *app_control,
+ app_control_uri_h uri)
+{
+ app_control_h tmp_control;
+ const char *scheme;
+ const char *auth;
+ const char *path;
+ const char *fragment;
+ app_control_uri_query_h query;
+ char *uri_str;
+ int uri_str_len = 0;
+ int ret;
+
+ if (app_control == NULL)
+ return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
+
+ ret = app_control_create_request(NULL, &tmp_control);
+ if (ret != APP_CONTROL_ERROR_NONE)
+ return ret;
+
+ ret = app_control_set_operation(tmp_control,
+ APP_CONTROL_OPERATION_INTENT);
+ if (ret != APP_CONTROL_ERROR_NONE) {
+ app_control_destroy(tmp_control);
+ return ret;
+ }
+
+ ret = app_control_uri_get_scheme(uri, &scheme);
+ if (ret != APP_CONTROL_ERROR_NONE) {
+ app_control_destroy(tmp_control);
+ return ret;
+ }
+
+ ret = app_control_uri_get_authority(uri, &auth);
+ if (ret != APP_CONTROL_ERROR_NONE) {
+ app_control_destroy(tmp_control);
+ return ret;
+ }
+
+ ret = app_control_uri_get_path(uri, &path);
+ if (ret != APP_CONTROL_ERROR_NONE) {
+ app_control_destroy(tmp_control);
+ return ret;
+ }
+
+ ret = app_control_uri_get_fragment(uri, &fragment);
+ if (ret != APP_CONTROL_ERROR_NONE) {
+ app_control_destroy(tmp_control);
+ return ret;
+ }
+
+ ret = app_control_add_extra_data(tmp_control,
+ APP_CONTROL_DATA_URI_PATH, path);
+ if (ret != APP_CONTROL_ERROR_NONE) {
+ app_control_destroy(tmp_control);
+ return ret;
+ }
+
+ ret = app_control_add_extra_data(tmp_control,
+ APP_CONTROL_DATA_URI_FRAGMENT, fragment);
+ if (ret != APP_CONTROL_ERROR_NONE) {
+ app_control_destroy(tmp_control);
+ return ret;
+ }
+
+ ret = app_control_uri_get_query(uri, &query);
+ if (ret != APP_CONTROL_ERROR_NONE) {
+ app_control_destroy(tmp_control);
+ return ret;
+ }
+
+ ret = app_control_uri_query_foreach(query, uri_query_cb,
+ &tmp_control);
+ if (ret != APP_CONTROL_ERROR_NONE) {
+ app_control_destroy(tmp_control);
+ return ret;
+ }
+
+ uri_str_len = strlen(scheme) + strlen(auth) + 2;
+ uri_str = malloc(sizeof(char) * uri_str_len);
+ if (uri_str == NULL) {
+ app_control_destroy(tmp_control);
+ free(uri_str);
+ return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
+ }
+
+ snprintf(uri_str, uri_str_len, "%s:%s", scheme, auth);
+ if (aul_svc_set_uri(tmp_control->data, uri_str) != 0) {
+ app_control_destroy(tmp_control);
+ free(uri_str);
+ return app_control_error(APP_CONTROL_ERROR_IO_ERROR, __FUNCTION__, "invalid URI");
+ }
+
+ free(uri_str);
+
+ *app_control = tmp_control;
+
+ return APP_CONTROL_ERROR_NONE;
+}
+
int app_control_create_event(bundle *data, struct app_control_s **app_control)
{
struct app_control_s *app_control_event;
return APP_CONTROL_ERROR_NONE;
}
+int app_control_set_uri_by_handle(app_control_h app_control, app_control_uri_h uri)
+{
+ const char *scheme;
+ const char *auth;
+ char *uri_str;
+ int uri_str_len = 0;
+
+ if (app_control_validate(app_control))
+ return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
+
+ if (app_control_uri_get_scheme(uri, &scheme))
+ return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
+
+ if (app_control_uri_get_authority(uri, &auth))
+ return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
+
+ uri_str_len = strlen(scheme) + strlen(auth) + 2;
+ uri_str = malloc(sizeof(char) * uri_str_len);
+ if (uri_str == NULL)
+ return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
+
+ snprintf(uri_str, uri_str_len, "%s:%s", scheme, auth);
+ if (aul_svc_set_uri(app_control->data, uri_str) != 0) {
+ free(uri_str);
+ return app_control_error(APP_CONTROL_ERROR_IO_ERROR, __FUNCTION__, "invalid URI");
+ }
+
+ free(uri_str);
+ return APP_CONTROL_ERROR_NONE;
+}
+
int app_control_set_mime(app_control_h app_control, const char *mime)
{
if (app_control_validate(app_control))
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+PROJECT(capi-appfw-app-control-uri C CXX)
+
+IF("${FULLVER}" STREQUAL "")
+ MESSAGE(FATAL_ERROR "VERSION is not defined")
+ENDIF()
+STRING(REGEX MATCH "^[0-9]+" VERSION_MAJOR ${FULLVER})
+IF("${VERSION_MAJOR}" STREQUAL "")
+ MESSAGE(FATAL_ERROR "can't get VERSION_MAJOR")
+ENDIF()
+
+### Required packages
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED glib-2.0 dlog)
+FOREACH(flag ${pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fvisibility=hidden -flto")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -fvisibility=hidden -flto")
+
+### Local include directories
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/src/uri)
+
+### Build
+AUX_SOURCE_DIRECTORY(${CMAKE_SOURCE_DIR}/src/uri SRCS)
+ADD_LIBRARY(capi-appfw-app-control-uri SHARED ${SRCS})
+SET_TARGET_PROPERTIES(capi-appfw-app-control-uri PROPERTIES SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(capi-appfw-app-control-uri PROPERTIES VERSION "${FULLVER}")
+MESSAGE(STATUS "Version from debian/changelog: ${FULLVER}, Major version: ${MAJORVER}")
+TARGET_LINK_LIBRARIES(capi-appfw-app-control-uri ${pkgs_LDFLAGS})
+
+INSTALL(TARGETS capi-appfw-app-control-uri DESTINATION ${LIB_INSTALL_DIR})
--- /dev/null
+/*
+ * Copyright (c) 2019 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 <cstring>
+
+#include "app_control_uri.h"
+#include "uri_internal.h"
+
+#undef URI_API
+#define URI_API extern "C" __attribute__((visibility("default")))
+
+using namespace appcontrol;
+
+URI_API int app_control_uri_builder_create(app_control_uri_builder_h* handle) {
+ if (handle == nullptr)
+ return APP_CONTROL_URI_ERROR_INVALID_PARAMETER;
+ Uri::Builder* builder = new (std::nothrow) Uri::Builder();
+ if (builder == nullptr)
+ return APP_CONTROL_URI_ERROR_OUT_OF_MEMORY;
+ *handle = static_cast<app_control_uri_builder_h>(builder);
+ return APP_CONTROL_URI_ERROR_NONE;
+}
+
+URI_API int app_control_uri_builder_set_scheme(app_control_uri_builder_h handle,
+ const char* scheme) {
+ if (handle == nullptr || scheme == nullptr)
+ return APP_CONTROL_URI_ERROR_INVALID_PARAMETER;
+ auto* builder = static_cast<Uri::Builder*>(handle);
+ builder->SetScheme(scheme);
+ return APP_CONTROL_URI_ERROR_NONE;
+}
+
+URI_API int app_control_uri_builder_set_authority(
+ app_control_uri_builder_h handle, const char* auth) {
+ if (handle == nullptr || auth == nullptr)
+ return APP_CONTROL_URI_ERROR_INVALID_PARAMETER;
+ auto* builder = static_cast<Uri::Builder*>(handle);
+ builder->SetAuthority(auth);
+ return APP_CONTROL_URI_ERROR_NONE;
+}
+
+URI_API int app_control_uri_builder_set_path(app_control_uri_builder_h handle,
+ const char* path) {
+ if (handle == nullptr || path == nullptr)
+ return APP_CONTROL_URI_ERROR_INVALID_PARAMETER;
+ auto* builder = static_cast<Uri::Builder*>(handle);
+ builder->SetPath(path);
+ return APP_CONTROL_URI_ERROR_NONE;
+}
+
+URI_API int app_control_uri_builder_add_path(app_control_uri_builder_h handle,
+ const char* path) {
+ if (handle == nullptr || path == nullptr)
+ return APP_CONTROL_URI_ERROR_INVALID_PARAMETER;
+ auto* builder = static_cast<Uri::Builder*>(handle);
+ builder->AddPath(path);
+ return APP_CONTROL_URI_ERROR_NONE;
+}
+
+URI_API int app_control_uri_builder_set_fragment(
+ app_control_uri_builder_h handle, const char* fragment) {
+ if (handle == nullptr || fragment == nullptr)
+ return APP_CONTROL_URI_ERROR_INVALID_PARAMETER;
+ auto* builder = static_cast<Uri::Builder*>(handle);
+ builder->SetFragment(fragment);
+ return APP_CONTROL_URI_ERROR_NONE;
+}
+
+URI_API int app_control_uri_builder_add_query(app_control_uri_builder_h handle,
+ const char* key, const char* val) {
+ if (handle == nullptr || key == nullptr || val == nullptr)
+ return APP_CONTROL_URI_ERROR_INVALID_PARAMETER;
+ auto* builder = static_cast<Uri::Builder*>(handle);
+ builder->AddQuery(key, val);
+ return APP_CONTROL_URI_ERROR_NONE;
+}
+
+URI_API int app_control_uri_builder_build(app_control_uri_builder_h builder,
+ app_control_uri_h* app_control_uri) {
+ if (builder == nullptr || app_control_uri == nullptr)
+ return APP_CONTROL_URI_ERROR_INVALID_PARAMETER;
+ auto* b = static_cast<Uri::Builder*>(builder);
+ auto* u = new (std::nothrow) Uri(b->Build());
+ if (u == nullptr)
+ return APP_CONTROL_URI_ERROR_OUT_OF_MEMORY;
+ *app_control_uri = static_cast<app_control_uri_h>(u);
+ return APP_CONTROL_URI_ERROR_NONE;
+}
+
+URI_API int app_control_uri_builder_destroy(app_control_uri_builder_h handle) {
+ if (handle == nullptr)
+ return APP_CONTROL_URI_ERROR_INVALID_PARAMETER;
+ auto* builder = static_cast<Uri::Builder*>(handle);
+ delete builder;
+ return APP_CONTROL_URI_ERROR_NONE;
+}
+
+URI_API int app_control_uri_create(const char* encoded_app_control_uri,
+ app_control_uri_h* handle) {
+ if (encoded_app_control_uri == nullptr || handle == nullptr)
+ return APP_CONTROL_URI_ERROR_INVALID_PARAMETER;
+ auto* u = new (std::nothrow) Uri(encoded_app_control_uri);
+ if (u == nullptr)
+ return APP_CONTROL_URI_ERROR_OUT_OF_MEMORY;
+ *handle = static_cast<app_control_uri_h>(u);
+ return APP_CONTROL_URI_ERROR_NONE;
+}
+
+URI_API int app_control_uri_destroy(app_control_uri_h handle) {
+ if (handle == nullptr)
+ return APP_CONTROL_URI_ERROR_INVALID_PARAMETER;
+ auto* app_control_uri = static_cast<Uri*>(handle);
+ delete app_control_uri;
+ return APP_CONTROL_URI_ERROR_NONE;
+}
+
+URI_API int app_control_uri_encode(app_control_uri_h handle,
+ char **encoded_app_control_uri) {
+ if (handle == nullptr)
+ return APP_CONTROL_URI_ERROR_INVALID_PARAMETER;
+ auto* app_control_uri = static_cast<Uri*>(handle);
+ *encoded_app_control_uri = strdup(app_control_uri->Encode().c_str());
+ if (*encoded_app_control_uri == nullptr)
+ return APP_CONTROL_URI_ERROR_OUT_OF_MEMORY;
+
+ return APP_CONTROL_URI_ERROR_NONE;
+}
+
+URI_API int app_control_uri_get_scheme(app_control_uri_h handle,
+ const char **scheme) {
+ if (handle == nullptr)
+ return APP_CONTROL_URI_ERROR_INVALID_PARAMETER;
+ auto* app_control_uri = static_cast<Uri*>(handle);
+ *scheme = app_control_uri->GetScheme().c_str();
+ return APP_CONTROL_URI_ERROR_NONE;
+}
+
+URI_API int app_control_uri_get_authority(app_control_uri_h handle,
+ const char **authority) {
+ if (handle == nullptr)
+ return APP_CONTROL_URI_ERROR_INVALID_PARAMETER;
+ auto* app_control_uri = static_cast<Uri*>(handle);
+ *authority = app_control_uri->GetAuthority().c_str();
+ return APP_CONTROL_URI_ERROR_NONE;
+}
+
+URI_API int app_control_uri_get_path(app_control_uri_h handle,
+ const char **path) {
+ if (handle == nullptr)
+ return APP_CONTROL_URI_ERROR_INVALID_PARAMETER;
+ auto* app_control_uri = static_cast<Uri*>(handle);
+ *path = app_control_uri->GetPath().c_str();
+ return APP_CONTROL_URI_ERROR_NONE;
+}
+
+URI_API int app_control_uri_get_fragment(app_control_uri_h handle,
+ const char **fragment) {
+ if (handle == nullptr)
+ return APP_CONTROL_URI_ERROR_INVALID_PARAMETER;
+ auto* app_control_uri = static_cast<Uri*>(handle);
+ *fragment = app_control_uri->GetFragment().c_str();
+ return APP_CONTROL_URI_ERROR_NONE;
+}
+
+URI_API int app_control_uri_get_query(app_control_uri_h handle,
+ app_control_uri_query_h* query_handle) {
+ if (handle == nullptr || query_handle == nullptr)
+ return APP_CONTROL_URI_ERROR_INVALID_PARAMETER;
+ auto* app_control_uri = static_cast<Uri*>(handle);
+ const auto& ql = app_control_uri->GetQuery();
+ *query_handle = static_cast<app_control_uri_query_h>(&ql);
+ return APP_CONTROL_URI_ERROR_NONE;
+}
+
+URI_API int app_control_uri_get_host(app_control_uri_h handle,
+ const char **host) {
+ if (handle == nullptr)
+ return APP_CONTROL_URI_ERROR_INVALID_PARAMETER;
+ auto* app_control_uri = static_cast<Uri*>(handle);
+ *host = app_control_uri->GetHost().c_str();
+ return APP_CONTROL_URI_ERROR_NONE;
+}
+
+URI_API int app_control_uri_get_port(app_control_uri_h handle,
+ const char **port) {
+ if (handle == nullptr)
+ return APP_CONTROL_URI_ERROR_INVALID_PARAMETER;
+ auto* app_control_uri = static_cast<Uri*>(handle);
+ *port = app_control_uri->GetPort().c_str();
+ return APP_CONTROL_URI_ERROR_NONE;
+}
+
+URI_API int app_control_uri_get_user(app_control_uri_h handle,
+ const char **user) {
+ if (handle == nullptr)
+ return APP_CONTROL_URI_ERROR_INVALID_PARAMETER;
+ auto* app_control_uri = static_cast<Uri*>(handle);
+ *user = app_control_uri->GetUser().c_str();
+ return APP_CONTROL_URI_ERROR_NONE;
+}
+
+URI_API int app_control_uri_query_foreach(app_control_uri_query_h handle,
+ app_control_uri_query_foreach_cb callback,
+ void* data) {
+ if (handle == nullptr || callback == nullptr)
+ return APP_CONTROL_URI_ERROR_INVALID_PARAMETER;
+
+ const auto* ql = static_cast<const std::list<std::pair<std::string,
+ std::string>>*>(handle);
+ for (auto& i : *ql) {
+ if (!callback(i.first.c_str(), i.second.c_str(), data))
+ break;
+ }
+ return APP_CONTROL_URI_ERROR_NONE;
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 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 <glib/gi18n.h>
+
+#include <memory>
+
+#include "uri_internal.h"
+
+namespace appcontrol {
+
+Uri::Builder& Uri::Builder::SetScheme(std::string scheme) {
+ scheme_ = std::move(scheme);
+ return *this;
+}
+
+Uri::Builder& Uri::Builder::SetAuthority(std::string auth) {
+ auth_ = std::move(auth);
+ return *this;
+}
+
+Uri::Builder& Uri::Builder::SetPath(std::string path) {
+ path_ = std::move(path);
+ return *this;
+}
+
+Uri::Builder& Uri::Builder::AddPath(std::string path) {
+ if (path[0] != '/')
+ path_ += "/";
+ path_ += path;
+ return *this;
+}
+
+Uri::Builder& Uri::Builder::SetFragment(std::string fragment) {
+ fragment_ = std::move(fragment);
+ return *this;
+}
+
+Uri::Builder& Uri::Builder::AddQuery(std::string key, std::string val) {
+ query_list_.emplace_back(std::move(key), std::move(val));
+ return *this;
+}
+
+Uri Uri::Builder::Build() {
+ return Uri(std::move(scheme_), std::move(auth_), std::move(path_),
+ std::move(query_list_), std::move(fragment_));
+}
+
+Uri::Uri(std::string encoded_uri) {
+ std::unique_ptr<char, decltype(std::free)*> d_uri(
+ g_uri_unescape_string(encoded_uri.c_str(), NULL), std::free);
+ std::string uri(d_uri.get());
+ Parse(uri);
+}
+
+Uri::Uri(std::string scheme, std::string auth, std::string path,
+ std::list<std::pair<std::string, std::string>> query,
+ std::string fragment) :
+ scheme_(std::move(scheme)), auth_(std::move(auth)), path_(std::move(path)),
+ fragment_(std::move(fragment)), query_list_(std::move(query)) {
+ ParseAuthoritySubcomponent(auth_);
+}
+
+const std::string& Uri::GetScheme() const {
+ return scheme_;
+}
+
+const std::string& Uri::GetAuthority() const {
+ return auth_;
+}
+
+const std::string& Uri::GetPath() const {
+ return path_;
+}
+
+const std::string& Uri::GetFragment() const {
+ return fragment_;
+}
+
+const std::list<std::pair<std::string, std::string>>& Uri::GetQuery() const {
+ return query_list_;
+}
+
+const std::string& Uri::GetHost() const {
+ return host_;
+}
+
+const std::string& Uri::GetPort() const {
+ return port_;
+}
+
+const std::string& Uri::GetUser() const {
+ return user_;
+}
+
+std::string Uri::Encode() const {
+ std::unique_ptr<char, decltype(std::free)*> e_scheme(
+ g_uri_escape_string(scheme_.c_str(), NULL, TRUE), std::free);
+ std::unique_ptr<char, decltype(std::free)*> e_auth(
+ g_uri_escape_string(auth_.c_str(), NULL, TRUE), std::free);
+ std::unique_ptr<char, decltype(std::free)*> e_path(
+ g_uri_escape_string(path_.c_str(), NULL, TRUE), std::free);
+ std::unique_ptr<char, decltype(std::free)*> e_fragment(
+ g_uri_escape_string(fragment_.c_str(), NULL, TRUE), std::free);
+
+ std::string ret = e_scheme.get();
+ ret += ":";
+ ret += e_auth.get();
+ ret += e_path.get();
+ bool first = true;
+
+ for (auto& i : query_list_) {
+ std::unique_ptr<char, decltype(std::free)*> key(
+ g_uri_escape_string(i.first.c_str(), NULL, TRUE), std::free);
+ std::unique_ptr<char, decltype(std::free)*> val(
+ g_uri_escape_string(i.second.c_str(), NULL, TRUE), std::free);
+ if (first) {
+ first = false;
+ ret += "?";
+ } else {
+ ret += "&";
+ }
+
+ ret += key.get();
+ ret += "=";
+ ret += val.get();
+ }
+
+ ret += "#";
+ ret += e_fragment.get();
+
+ return ret;
+}
+
+void Uri::Parse(const std::string& uri) {
+ std::size_t idx = 0;
+
+ ParseScheme(uri, idx);
+ ParseAuthority(uri, idx);
+ ParsePath(uri, idx);
+ ParseQuery(uri, idx);
+ ParseFragment(uri, idx);
+}
+
+void Uri::ParseScheme(const std::string& uri, std::size_t& idx) {
+ std::size_t found = uri.find(":");
+ if (found == std::string::npos)
+ return;
+
+ scheme_ = uri.substr(idx, found - idx);
+ idx = found + 1;
+}
+
+void Uri::ParseAuthority(const std::string& uri, std::size_t& idx) {
+ const std::string delim("//");
+ std::size_t found = uri.find(delim, idx);
+ if (found == std::string::npos)
+ return;
+
+ idx = found;
+ found = uri.find("/", idx + delim.length());
+ auth_ = uri.substr(idx, found - idx);
+ idx = found;
+
+ ParseAuthoritySubcomponent(auth_);
+}
+
+void Uri::ParsePath(const std::string& uri, std::size_t& idx) {
+ std::size_t found = uri.find("?", idx);
+ if (found == std::string::npos) {
+ found = uri.find("#", idx);
+ if (found == std::string::npos)
+ found = uri.length();
+ }
+
+ path_ = uri.substr(idx, found - idx);
+ idx = found;
+}
+
+void Uri::ParseQuery(const std::string& uri, std::size_t& idx) {
+ if (idx == uri.length())
+ return;
+
+ std::size_t found = uri.find("?", idx);
+ if (found == std::string::npos)
+ return;
+
+ idx = found;
+ found = uri.find("#", idx);
+ if (found == std::string::npos)
+ found = uri.length();
+
+ std::string query = uri.substr(idx, found - idx);
+ idx = found;
+
+ std::size_t i = query.find("?") + 1;
+ found = query.find("&");
+ while (found != std::string::npos) {
+ AddQuery(query.substr(i, found - i));
+ i = found + 1;
+ found = query.find("&", i);
+ }
+ AddQuery(query.substr(i, found - i));
+}
+
+void Uri::ParseFragment(const std::string& uri, std::size_t& idx) {
+ if (idx == uri.length())
+ return;
+
+ std::size_t found = uri.find("#", idx);
+ if (found == std::string::npos)
+ return;
+
+ idx = found + 1;
+ fragment_ = uri.substr(idx);
+}
+
+void Uri::ParseAuthoritySubcomponent(const std::string& auth) {
+ if (auth.empty())
+ return;
+
+ std::size_t idx = std::string("//").length();
+ std::size_t found = auth.find("@");
+ if (found != std::string::npos) {
+ user_ = auth.substr(idx, found - idx);
+ idx = found + 1;
+ }
+
+ found = auth.find_last_of(":");
+ if (found != std::string::npos && IsNumber(auth.substr(found + 1))) {
+ host_ = auth.substr(idx, found - idx);
+ port_ = auth.substr(found + 1);
+ } else {
+ host_ = auth.substr(idx);
+ }
+}
+
+void Uri::AddQuery(const std::string& query) {
+ std::size_t found = query.find("=");
+ if (found == std::string::npos)
+ return;
+
+ query_list_.emplace_back(query.substr(0, found), query.substr(found + 1));
+}
+
+bool Uri::IsNumber(const std::string& s) {
+ std::string::const_iterator iter = s.begin();
+ while (iter != s.end() && std::isdigit(*iter))
+ iter++;
+
+ return (!s.empty() && iter == s.end());
+}
+
+} // namespace appcontrol
--- /dev/null
+/*
+ * Copyright (c) 2019 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 URI_INTERNAL_H_
+#define URI_INTERNAL_H_
+
+#include <algorithm>
+#include <string>
+#include <list>
+#include <utility>
+
+namespace appcontrol {
+
+class Uri {
+ public:
+ class Builder {
+ public:
+ Builder& SetScheme(std::string scheme);
+ Builder& SetAuthority(std::string auth);
+ Builder& SetPath(std::string path);
+ Builder& AddPath(std::string path);
+ Builder& SetFragment(std::string fragment);
+ Builder& AddQuery(std::string key, std::string val);
+ Uri Build();
+
+ private:
+ std::string scheme_;
+ std::string auth_;
+ std::string path_;
+ std::string fragment_;
+ std::list<std::pair<std::string, std::string>> query_list_;
+ };
+
+ explicit Uri(std::string encoded_uri);
+ virtual ~Uri() {}
+
+ const std::string& GetScheme() const;
+ const std::string& GetAuthority() const;
+ const std::string& GetPath() const;
+ const std::string& GetFragment() const;
+ const std::list<std::pair<std::string, std::string>>& GetQuery() const;
+ const std::string& GetHost() const;
+ const std::string& GetPort() const;
+ const std::string& GetUser() const;
+ std::string Encode() const;
+
+ private:
+ Uri(std::string scheme, std::string auth, std::string path,
+ std::list<std::pair<std::string, std::string>> query,
+ std::string fragment);
+
+ bool IsNumber(const std::string& s);
+ void Parse(const std::string& uri);
+ void ParseScheme(const std::string& uri, std::size_t& idx);
+ void ParseAuthority(const std::string& uri, std::size_t& idx);
+ void ParsePath(const std::string& uri, std::size_t& idx);
+ void ParseQuery(const std::string& uri, std::size_t& idx);
+ void ParseFragment(const std::string& uri, std::size_t& idx);
+ void ParseAuthoritySubcomponent(const std::string& auth);
+ void AddQuery(const std::string& query);
+
+ private:
+ std::string scheme_;
+ std::string auth_;
+ std::string path_;
+ std::string fragment_;
+ std::list<std::pair<std::string, std::string>> query_list_;
+ std::string host_;
+ std::string port_;
+ std::string user_;
+};
+
+} // namespace appcontrol
+
+#endif // URI_INTERNAL_H_
--- /dev/null
+#!/bin/bash
+# Copyright (c) 2014 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.
+
+if [ ! `which cpplint.py` ]; then
+ echo -e "\nPlease make sure cpplint.py is in your PATH. It is part of depot_tools inside Chromium repository."
+ exit 1
+fi
+
+OLDPWD=$PWD
+BASE=`dirname $0`
+cd $BASE/..
+
+# filters
+FILTERS="-readability/streams,-build/c++11"
+
+cpplint.py --root=src --filter="$FILTERS" $(find . \( -name '*.h' -o -name '*.cc' \) )
+RET=$?
+
+JS_RET_VAL=$?
+cd $OLDPWD
+
+if [ "x$RET" == "x0" ]; then
+ exit 0
+else
+ exit 1
+fi
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+PROJECT(unittests CXX)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(unittests REQUIRED
+ glib-2.0
+ gmock
+ aul
+ appcore-common
+)
+
+FOREACH(flag ${unittests_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall -Werror -Winline")
+SET(CMAKE_C_FLAGS "${EXTRA_CFLAGS}")
+
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -std=c++11")
+SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
+SET(SOURCES
+ ${CMAKE_SOURCE_DIR}/src/app_control.c
+ ${CMAKE_SOURCE_DIR}/src/uri/uri_internal.cc
+ ${CMAKE_SOURCE_DIR}/src/uri/app_control_uri.cc)
+
+INCLUDE_DIRECTORIES(
+ ${CMAKE_CURRENT_SOURCE_DIR}/../include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../src/uri
+ )
+
+AUX_SOURCE_DIRECTORY(src TEST_SOURCES)
+ADD_EXECUTABLE(${PROJECT_NAME}
+ ${SOURCES}
+ ${TEST_SOURCES}
+)
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${unittests_LDFLAGS})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION /usr/bin)
--- /dev/null
+/*
+ * Copyright (c) 2019 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 <stdlib.h>
+#include <gtest/gtest.h>
+#include <app_control.h>
+#include <app_control_uri.h>
+
+#include <iostream>
+#include <memory>
+
+#include "uri_internal.h"
+
+// The source of the following example is "https://en.wikipedia.org/wiki/Uniform_Resource_Identifier"
+static const char EXAM_URI1[] = "https://john.doe@www.example.com:123";
+extern int gargc;
+extern char** gargv;
+
+class AppControlTest : public testing::Test {
+ public:
+ virtual ~AppControlTest() {
+ if (builder_ != nullptr)
+ app_control_uri_builder_destroy(builder_);
+ if (uri_ != nullptr)
+ app_control_uri_destroy(uri_);
+ }
+
+ virtual void SetUp() {
+ app_control_uri_builder_create(&builder_);
+ EXPECT_NE(builder_, nullptr);
+
+ app_control_uri_builder_set_scheme(builder_, "https");
+ app_control_uri_builder_set_authority(builder_,
+ "//john.doe@www.example.com:123");
+ app_control_uri_builder_set_path(builder_, "/forum/questions/");
+ app_control_uri_builder_set_fragment(builder_, "top");
+ app_control_uri_builder_add_query(builder_, "tag", "networking");
+ app_control_uri_builder_add_query(builder_, "order", "newest");
+
+ app_control_uri_builder_build(builder_, &uri_);
+ EXPECT_NE(uri_, nullptr);
+ }
+
+ virtual void TearDown() {
+ count_ = 0;
+
+ if (builder_ != nullptr) {
+ auto builder =
+ std::unique_ptr<void, decltype(app_control_uri_builder_destroy)*>(
+ builder_, app_control_uri_builder_destroy);
+ builder_ = nullptr;
+ }
+ if (uri_ != nullptr) {
+ auto uri = std::unique_ptr<void, decltype(app_control_uri_destroy)*>(uri_,
+ app_control_uri_destroy);
+ uri_ = nullptr;
+ }
+ }
+
+ app_control_uri_builder_h builder_;
+ app_control_uri_h uri_;
+ int count_ = 0;
+};
+
+/*
+ * @testcase app_control_create_from_uri_handle_p
+ * @description Creates a app_control handle from uri handle.
+ * @apicovered app_control_create_from_uri_handle
+ */
+TEST_F(AppControlTest, app_control_create_from_uri_handle_p) {
+ app_control_h app_control;
+ char *uri;
+ char *query_tag;
+ int r = app_control_create_from_uri_handle(&app_control, uri_);
+ EXPECT_EQ(r, APP_CONTROL_ERROR_NONE);
+
+ r = app_control_get_uri(app_control, &uri);
+ EXPECT_EQ(r, APP_CONTROL_ERROR_NONE);
+ EXPECT_STREQ(uri, EXAM_URI1);
+
+ r = app_control_get_extra_data(app_control, "tag", &query_tag);
+ EXPECT_EQ(r, APP_CONTROL_ERROR_NONE);
+ EXPECT_STREQ(query_tag, "networking");
+}
+
+/*
+ * @testcase app_control_set_uri_by_handle_p
+ * @description Sets uri data by uri handle.
+ * @apicovered app_control_set_uri_by_handle
+ */
+TEST_F(AppControlTest, app_control_set_uri_by_handle_p) {
+ app_control_h app_control;
+ char *uri;
+ int r = app_control_create(&app_control);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+
+ r = app_control_set_uri_by_handle(app_control, uri_);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+
+ r = app_control_get_uri(app_control, &uri);
+ EXPECT_EQ(r, APP_CONTROL_ERROR_NONE);
+ EXPECT_STREQ(uri, EXAM_URI1);
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 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 <gtest/gtest.h>
+
+int gargc;
+char** gargv;
+
+int main(int argc, char** argv) {
+ gargc = argc;
+ gargv = argv;
+
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 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 <stdlib.h>
+#include <gtest/gtest.h>
+#include <app_control_uri.h>
+
+#include <iostream>
+#include <memory>
+
+#include "uri_internal.h"
+
+// The source of the following example is "https://en.wikipedia.org/wiki/Uniform_Resource_Identifier"
+static const char EXAM_URI1[] = "https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top";
+static const char EXAM_URI2[] = "ldap://[2001:db8::7]/c=GB?objectClass?one";
+static const char EXAM_URI3[] = "mailto:John.Doe@example.com";
+static const char EXAM_URI4[] = "news:comp.infosystems.www.servers.unix";
+static const char EXAM_URI5[] = "tel:+1-816-555-1212";
+static const char EXAM_URI6[] = "telnet://192.0.2.16:80/";
+static const char EXAM_URI7[] = "urn:oasis:names:specification:docbook:dtd:xml:4.1.2";
+
+static const char ENCODED_URI1[] = "https:%2F%2Fjohn.doe%40www.example.com%3A123%2Fforum%2Fquestions%2F?tag=networking&order=newest#top";
+static const char ENCODED_URI2[] = "ldap:%2F%2F%5B2001%3Adb8%3A%3A7%5D%2Fc%3DGB?objectClass?one";
+static const char ENCODED_URI3[] = "mailto:John.Doe%40example.com";
+static const char ENCODED_URI4[] = "news:comp.infosystems.www.servers.unix";
+static const char ENCODED_URI5[] = "tel:%2B1-816-555-1212";
+static const char ENCODED_URI6[] = "telnet:%2F%2F192.0.2.16%3A80%2F";
+static const char ENCODED_URI7[] = "urn:oasis%3Anames%3Aspecification%3Adocbook%3Adtd%3Axml%3A4.1.2";
+
+extern int gargc;
+extern char** gargv;
+
+class UriTest : public testing::Test {
+ public:
+ virtual ~UriTest() {
+ if (builder_ != nullptr)
+ app_control_uri_builder_destroy(builder_);
+ if (uri_ != nullptr)
+ app_control_uri_destroy(uri_);
+ }
+
+ virtual void SetUp() {
+ std::string exam_uri[] = {
+ ENCODED_URI1,
+ ENCODED_URI2,
+ ENCODED_URI3,
+ ENCODED_URI4,
+ ENCODED_URI5,
+ ENCODED_URI6,
+ ENCODED_URI7,
+ };
+
+ for (int i = 0; i < 7; i++) {
+ uri_list_[i] =
+ std::unique_ptr<appcontrol::Uri>(new appcontrol::Uri(exam_uri[i]));
+ }
+
+ app_control_uri_builder_create(&builder_);
+ EXPECT_NE(builder_, nullptr);
+
+ app_control_uri_builder_set_scheme(builder_, "https");
+ app_control_uri_builder_set_authority(builder_,
+ "//john.doe@www.example.com:123");
+ app_control_uri_builder_set_path(builder_, "/forum/questions/");
+ app_control_uri_builder_set_fragment(builder_, "top");
+ app_control_uri_builder_add_query(builder_, "tag", "networking");
+ app_control_uri_builder_add_query(builder_, "order", "newest");
+
+ app_control_uri_builder_build(builder_, &uri_);
+ EXPECT_NE(uri_, nullptr);
+ }
+
+ virtual void TearDown() {
+ count_ = 0;
+
+ if (builder_ != nullptr) {
+ auto builder =
+ std::unique_ptr<void, decltype(app_control_uri_builder_destroy)*>(
+ builder_, app_control_uri_builder_destroy);
+ builder_ = nullptr;
+ }
+ if (uri_ != nullptr) {
+ auto uri = std::unique_ptr<void, decltype(app_control_uri_destroy)*>(uri_,
+ app_control_uri_destroy);
+ uri_ = nullptr;
+ }
+ }
+
+ std::unique_ptr<appcontrol::Uri> uri_list_[7];
+ app_control_uri_builder_h builder_;
+ app_control_uri_h uri_;
+ int count_ = 0;
+};
+
+/*
+ * @testcase Uri_Constructor
+ * @description Creates a Uri object.
+ * @apicovered appcontrol::Uri
+ */
+TEST_F(UriTest, Uri_Constructor) {
+ std::unique_ptr<appcontrol::Uri> uri = std::unique_ptr<appcontrol::Uri>(
+ new appcontrol::Uri(ENCODED_URI1));
+ EXPECT_NE(uri, nullptr);
+}
+
+/*
+ * @testcase Uri_GetScheme
+ * @description Gets a scheme component from a URI object.
+ * @apicovered appcontrol::Uri::GetScheme
+ */
+TEST_F(UriTest, Uri_GetScheme) {
+ std::string exam_scheme[] = {
+ "https",
+ "ldap",
+ "mailto",
+ "news",
+ "tel",
+ "telnet",
+ "urn",
+ };
+
+ for (int i = 0; i < 7; i++) {
+ EXPECT_EQ(uri_list_[i]->GetScheme(), exam_scheme[i]);
+ }
+}
+
+/*
+ * @testcase Uri_GetAuthority
+ * @description Gets an authority component from a URI object.
+ * @apicovered appcontrol::Uri::GetAuthority
+ */
+TEST_F(UriTest, Uri_GetAuthority) {
+ std::string exam_auth[] = {
+ "//john.doe@www.example.com:123",
+ "//[2001:db8::7]",
+ "",
+ "",
+ "",
+ "//192.0.2.16:80",
+ "",
+ };
+
+ for (int i = 0; i < 7; i++) {
+ EXPECT_EQ(uri_list_[i]->GetAuthority(), exam_auth[i]);
+ }
+}
+
+/*
+ * @testcase Uri_GetPath
+ * @description Gets a path component from a URI object.
+ * @apicovered appcontrol::Uri::GetPath
+ */
+TEST_F(UriTest, Uri_GetPath) {
+ std::string exam_path[] = {
+ "/forum/questions/",
+ "/c=GB",
+ "John.Doe@example.com",
+ "comp.infosystems.www.servers.unix",
+ "+1-816-555-1212",
+ "/",
+ "oasis:names:specification:docbook:dtd:xml:4.1.2",
+ };
+
+ for (int i = 0; i < 7; i++) {
+ EXPECT_EQ(uri_list_[i]->GetPath(), exam_path[i]);
+ }
+}
+
+/*
+ * @testcase Uri_GetFragment
+ * @description Gets a fragment component from a URI object.
+ * @apicovered appcontrol::Uri::GetFragment
+ */
+TEST_F(UriTest, Uri_GetFragment) {
+ std::string exam_fragment[] = {
+ "top",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ };
+
+ for (int i = 0; i < 7; i++) {
+ EXPECT_EQ(uri_list_[i]->GetFragment(), exam_fragment[i]);
+ }
+}
+
+/*
+ * @testcase Uri_GetHost
+ * @description Gets a host subcomponent from a URI object.
+ * @apicovered appcontrol::Uri::GetHost
+ */
+TEST_F(UriTest, Uri_GetHost) {
+ std::string exam_host[] = {
+ "www.example.com",
+ "[2001:db8::7]",
+ "",
+ "",
+ "",
+ "192.0.2.16",
+ "",
+ };
+
+ for (int i = 0; i < 7; i++) {
+ EXPECT_EQ(uri_list_[i]->GetHost(), exam_host[i]);
+ }
+}
+
+/*
+ * @testcase Uri_GetPort
+ * @description Gets a port subcomponent from a URI object.
+ * @apicovered appcontrol::Uri::GetPort
+ */
+TEST_F(UriTest, Uri_GetPort) {
+ std::string exam_port[] = {
+ "123",
+ "",
+ "",
+ "",
+ "",
+ "80",
+ "",
+ };
+
+ for (int i = 0; i < 7; i++) {
+ EXPECT_EQ(uri_list_[i]->GetPort(), exam_port[i]);
+ }
+}
+
+/*
+ * @testcase Uri_GetUser
+ * @description Gets a user subcomponent from a URI object.
+ * @apicovered appcontrol::Uri::GetUser
+ */
+TEST_F(UriTest, Uri_GetUser) {
+ std::string exam_user[] = {
+ "john.doe",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ };
+
+ for (int i = 0; i < 7; i++) {
+ EXPECT_EQ(uri_list_[i]->GetUser(), exam_user[i]);
+ }
+}
+
+/*
+ * @testcase Uri_GetQuery
+ * @description Gets a query component from a URI object.
+ * @apicovered appcontrol::Uri::GetQuery
+ */
+TEST_F(UriTest, Uri_GetQuery) {
+ int match_count = 0;
+ auto& query = uri_list_[0]->GetQuery();
+ for (auto& i : query) {
+ if (i.first == "tag" &&
+ i.second == "networking") {
+ match_count++;
+ } else if (i.first == "order" &&
+ i.second == "newest") {
+ match_count++;
+ }
+ }
+
+ EXPECT_EQ(match_count, 2);
+}
+
+/*
+ * @testcase Uri_Encode
+ * @description Encodes a URI object to string.
+ * @apicovered appcontrol::Uri::Encode
+ */
+TEST_F(UriTest, Uri_Encode) {
+ std::unique_ptr<appcontrol::Uri> uri = std::unique_ptr<appcontrol::Uri>(
+ new appcontrol::Uri(EXAM_URI1));
+ EXPECT_NE(uri, nullptr);
+ EXPECT_EQ(uri->Encode(), ENCODED_URI1);
+}
+
+/*
+ * @testcase Uri_Builder
+ * @description Builds a URI builder object to create a URI object.
+ * @apicovered appcontrol::Uri::Builder, appcontrol::Uri::Builder::SetScheme,
+ * appcontrol::Uri::Builder::SetAuthority, appcontrol::Uri::Builder::SetPath,
+ * appcontrol::Uri::Builder::AddQuery, appcontrol::Uri::Builder::SetFragment,
+ * appcontrol::Uri::Builder::Build
+ */
+TEST_F(UriTest, Uri_Builder) {
+ std::unique_ptr<appcontrol::Uri::Builder> builder(new appcontrol::Uri::Builder());
+ EXPECT_NE(builder, nullptr);
+ builder->SetScheme("https");
+ builder->SetAuthority("//john.doe@www.example.com:123");
+ builder->SetPath("/forum/questions/");
+ builder->AddQuery("tag", "networking");
+ builder->AddQuery("order", "newest");
+ builder->SetFragment("top");
+
+ appcontrol::Uri uri = builder->Build();
+ EXPECT_EQ(uri.Encode(), ENCODED_URI1);
+}
+
+/*
+ * @testcase app_control_uri_builder_create_p
+ * @description Creates a URI builder handle.
+ * @apicovered app_control_uri_builder_create
+ */
+TEST_F(UriTest, app_control_uri_builder_create_p) {
+ app_control_uri_builder_h builder = nullptr;
+ int r = app_control_uri_builder_create(&builder);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+ EXPECT_NE(builder, nullptr);
+ app_control_uri_builder_destroy(builder);
+}
+
+/*
+ * @testcase app_control_uri_builder_create_n
+ * @description Creates a URI builder handle.
+ * The function returns a negative error value.
+ * @apicovered app_control_uri_builder_create
+ */
+TEST_F(UriTest, app_control_uri_builder_create_n) {
+ int r = app_control_uri_builder_create(nullptr);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+}
+
+/*
+ * @testcase app_control_uri_builder_set_scheme_p
+ * @description Sets a scheme component to a URI builder handle.
+ * @apicovered app_control_uri_builder_set_scheme
+ */
+TEST_F(UriTest, app_control_uri_builder_set_scheme_p) {
+ int r = app_control_uri_builder_set_scheme(builder_, "https");
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+}
+
+/*
+ * @testcase app_control_uri_builder_set_scheme_n
+ * @description Sets a scheme component to a URI builder handle.
+ * The function returns a negative error value.
+ * @apicovered app_control_uri_builder_set_scheme
+ */
+TEST_F(UriTest, app_control_uri_builder_set_scheme_n) {
+ int r = app_control_uri_builder_set_scheme(builder_, nullptr);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+
+ r = app_control_uri_builder_set_scheme(nullptr, "https");
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+}
+
+/*
+ * @testcase app_control_uri_builder_set_authority_p
+ * @description Sets an authority component to a URI builder handle.
+ * @apicovered app_control_uri_builder_set_authority
+ */
+TEST_F(UriTest, app_control_uri_builder_set_authority_p) {
+ int r = app_control_uri_builder_set_authority(builder_,
+ "//john.doe@www.example.com:123");
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+}
+
+/*
+ * @testcase app_control_uri_builder_set_authority_n
+ * @description Sets an authority component to a URI builder handle.
+ * The function returns a negative error value.
+ * @apicovered app_control_uri_builder_set_authority
+ */
+TEST_F(UriTest, app_control_uri_builder_set_authority_n) {
+ int r = app_control_uri_builder_set_authority(builder_, nullptr);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+
+ r = app_control_uri_builder_set_authority(nullptr,
+ "//john.doe@www.example.com:123");
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+}
+
+/*
+ * @testcase app_control_uri_builder_set_path_p
+ * @description Sets a path component to a URI builder handle.
+ * @apicovered app_control_uri_builder_set_path
+ */
+TEST_F(UriTest, app_control_uri_builder_set_path_p) {
+ int r = app_control_uri_builder_set_path(builder_, "/forum/questions/");
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+}
+
+/*
+ * @testcase app_control_uri_builder_set_path_n
+ * @description Sets a path component to a URI builder handle.
+ * The function returns a negative error value.
+ * @apicovered app_control_uri_builder_set_path
+ */
+TEST_F(UriTest, app_control_uri_builder_set_path_n) {
+ int r = app_control_uri_builder_set_path(builder_, nullptr);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+
+ r = app_control_uri_builder_set_path(nullptr, "/forum/questions/");
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+}
+
+/*
+ * @testcase app_control_uri_builder_add_path_p
+ * @description Adds a path component on a URI builder handle.
+ * @apicovered app_control_uri_builder_add_path
+ */
+TEST_F(UriTest, app_control_uri_builder_add_path_p) {
+ int r = app_control_uri_builder_add_path(builder_, "/forum");
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+
+ r = app_control_uri_builder_add_path(builder_, "/questions/");
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+}
+
+/*
+ * @testcase app_control_uri_builder_add_path_n
+ * @description Adds a path component on a URI builder handle.
+ * The function returns a negative error value.
+ * @apicovered app_control_uri_builder_add_path
+ */
+TEST_F(UriTest, app_control_uri_builder_add_path_n) {
+ int r = app_control_uri_builder_add_path(builder_, nullptr);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+
+ r = app_control_uri_builder_add_path(nullptr, "/questions/");
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+}
+
+/*
+ * @testcase app_control_uri_builder_set_fragment_p
+ * @description Sets a fragment component to a URI builder handle.
+ * @apicovered app_control_uri_builder_set_fragment
+ */
+TEST_F(UriTest, app_control_uri_builder_set_fragment_p) {
+ int r = app_control_uri_builder_set_fragment(builder_, "top");
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+}
+
+/*
+ * @testcase app_control_uri_builder_set_fragment_n
+ * @description Sets a fragment component to a URI builder handle.
+ * The function returns a negative error value.
+ * @apicovered app_control_uri_builder_set_fragment
+ */
+TEST_F(UriTest, app_control_uri_builder_set_fragment_n) {
+ int r = app_control_uri_builder_set_fragment(builder_, nullptr);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+
+ r = app_control_uri_builder_set_fragment(nullptr, "top");
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+}
+
+/*
+ * @testcase app_control_uri_builder_add_query_p
+ * @description Adds a query component on a URI builder handle.
+ * @apicovered app_control_uri_builder_add_query
+ */
+TEST_F(UriTest, app_control_uri_builder_add_query_p) {
+ int r = app_control_uri_builder_add_query(builder_, "tag", "networking");
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+
+ r = app_control_uri_builder_add_query(builder_, "order", "newest");
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+}
+
+/*
+ * @testcase app_control_uri_builder_add_query_n
+ * @description Adds a query component on a URI builder handle.
+ * The function returns a negative error value.
+ * @apicovered app_control_uri_builder_add_query
+ */
+TEST_F(UriTest, app_control_uri_builder_add_query_n) {
+ int r = app_control_uri_builder_add_query(builder_, "tag", nullptr);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+
+ r = app_control_uri_builder_add_query(builder_, nullptr, "newest");
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+
+ r = app_control_uri_builder_add_query(nullptr, "tag", "newest");
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+}
+
+/*
+ * @testcase app_control_uri_builder_build_p
+ * @description Builds a URI builder handle to create a URI handle.
+ * @apicovered app_control_uri_builder_build
+ */
+TEST_F(UriTest, app_control_uri_builder_build_p) {
+ app_control_uri_h app_control_uri = nullptr;
+ int r = app_control_uri_builder_build(builder_, &app_control_uri);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+ EXPECT_NE(app_control_uri, nullptr);
+ app_control_uri_destroy(app_control_uri);
+}
+
+/*
+ * @testcase app_control_uri_builder_build_n
+ * @description Builds a URI builder handle to create a URI handle.
+ * The function returns a negative error value.
+ * @apicovered app_control_uri_builder_build
+ */
+TEST_F(UriTest, app_control_uri_builder_build_n) {
+ int r = app_control_uri_builder_build(builder_, nullptr);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+
+ app_control_uri_h app_control_uri = nullptr;
+ r = app_control_uri_builder_build(nullptr, &app_control_uri);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+}
+
+/*
+ * @testcase app_control_uri_builder_destroy_p
+ * @description Destroys a URI builder handle.
+ * @apicovered app_control_uri_builder_destroy
+ */
+TEST_F(UriTest, app_control_uri_builder_destroy_p) {
+ int r = app_control_uri_builder_destroy(builder_);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+ builder_ = nullptr;
+}
+
+/*
+ * @testcase app_control_uri_builder_destroy_n
+ * @description Destroys a URI builder handle.
+ * The function returns a negative error value.
+ * @apicovered app_control_uri_builder_destroy
+ */
+TEST_F(UriTest, app_control_uri_builder_destroy_n) {
+ int r = app_control_uri_builder_destroy(nullptr);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+}
+
+/*
+ * @testcase app_control_uri_create_p
+ * @description Creates a URI builder handle from an encoded URI string.
+ * @apicovered app_control_uri_create
+ */
+TEST_F(UriTest, app_control_uri_create_p) {
+ app_control_uri_h app_control_uri = nullptr;
+ const char *scheme;
+ const char *authority;
+ const char *path;
+ const char *fragment;
+ const char *host;
+ const char *port;
+ const char *user;
+ int r = app_control_uri_create(ENCODED_URI1, &app_control_uri);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+
+ auto handle = std::unique_ptr<void, decltype(app_control_uri_destroy)*>(
+ app_control_uri, app_control_uri_destroy);
+
+ r = app_control_uri_get_scheme(handle.get(), &scheme);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+ r = app_control_uri_get_authority(handle.get(), &authority);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+ r = app_control_uri_get_path(handle.get(), &path);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+ r = app_control_uri_get_fragment(handle.get(), &fragment);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+
+ EXPECT_EQ(std::string(scheme), "https");
+ EXPECT_EQ(std::string(authority), "//john.doe@www.example.com:123");
+ EXPECT_EQ(std::string(path), "/forum/questions/");
+ EXPECT_EQ(std::string(fragment), "top");
+
+ app_control_uri_query_h query = nullptr;
+ r = app_control_uri_get_query(handle.get(), &query);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+ EXPECT_NE(query, nullptr);
+
+ r = app_control_uri_get_host(handle.get(), &host);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+
+ r = app_control_uri_get_port(handle.get(), &port);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+
+ r = app_control_uri_get_user(handle.get(), &user);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+
+ EXPECT_EQ(std::string(host), "www.example.com");
+ EXPECT_EQ(std::string(port), "123");
+ EXPECT_EQ(std::string(user), "john.doe");
+}
+
+/*
+ * @testcase app_control_uri_create_n
+ * @description Creates a URI builder handle from an encoded URI string.
+ * The function returns a negative error value.
+ * @apicovered app_control_uri_create
+ */
+TEST_F(UriTest, app_control_uri_create_n) {
+ int r = app_control_uri_create(ENCODED_URI1, nullptr);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+
+ app_control_uri_h app_control_uri = nullptr;
+ r = app_control_uri_create(nullptr, &app_control_uri);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+}
+
+/*
+ * @testcase app_control_uri_destroy_p
+ * @description Destroys a URI handle.
+ * @apicovered app_control_uri_destroy
+ */
+TEST_F(UriTest, app_control_uri_destroy_p) {
+ int r = app_control_uri_destroy(uri_);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+ uri_ = nullptr;
+}
+
+/*
+ * @testcase app_control_uri_destroy_n
+ * @description Destroys a URI handle.
+ * The function returns a negative error value.
+ * @apicovered app_control_uri_destroy
+ */
+TEST_F(UriTest, app_control_uri_destroy_n) {
+ int r = app_control_uri_destroy(nullptr);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+}
+
+/*
+ * @testcase app_control_uri_encode_p
+ * @description Encodes a URI handle to string.
+ * @apicovered app_control_uri_encode
+ */
+TEST_F(UriTest, app_control_uri_encode_p) {
+ char *encoded_app_control_uri = nullptr;
+ int r = app_control_uri_encode(uri_, &encoded_app_control_uri);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+ EXPECT_EQ(std::string(encoded_app_control_uri), ENCODED_URI1);
+ if (encoded_app_control_uri)
+ free(encoded_app_control_uri);
+}
+
+/*
+ * @testcase app_control_uri_encode_n
+ * @description Encodes a URI handle to string.
+ * The function returns a nullptr.
+ * @apicovered app_control_uri_encode
+ */
+TEST_F(UriTest, app_control_uri_encode_n) {
+ char *encoded_app_control_uri;
+ int r = app_control_uri_encode(nullptr, &encoded_app_control_uri);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+}
+
+/*
+ * @testcase app_control_uri_get_scheme_p
+ * @description Gets a scheme component from a URI handle.
+ * @apicovered app_control_uri_get_scheme
+ */
+TEST_F(UriTest, app_control_uri_get_scheme_p) {
+ const char* scheme;
+ int r = app_control_uri_get_scheme(uri_, &scheme);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+ EXPECT_NE(scheme, nullptr);
+ EXPECT_EQ(std::string(scheme), "https");
+}
+
+/*
+ * @testcase app_control_uri_get_scheme_n
+ * @description Gets a scheme component from a URI handle.
+ * The function returns a nullptr.
+ * @apicovered app_control_uri_get_scheme
+ */
+TEST_F(UriTest, app_control_uri_get_scheme_n) {
+ const char* scheme;
+ int r = app_control_uri_get_scheme(nullptr, &scheme);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+}
+
+/*
+ * @testcase app_control_uri_get_authority_p
+ * @description Gets an authority component from a URI handle.
+ * @apicovered app_control_uri_get_authority
+ */
+TEST_F(UriTest, app_control_uri_get_authority_p) {
+ const char* auth;
+ int r = app_control_uri_get_authority(uri_, &auth);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+ EXPECT_NE(auth, nullptr);
+ EXPECT_EQ(std::string(auth), "//john.doe@www.example.com:123");
+}
+
+/*
+ * @testcase app_control_uri_get_authority_n
+ * @description Gets an authority component from a URI handle.
+ * The function returns a nullptr.
+ * @apicovered app_control_uri_get_authority
+ */
+TEST_F(UriTest, app_control_uri_get_authority_n) {
+ const char* auth;
+ int r = app_control_uri_get_authority(nullptr, &auth);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+}
+
+/*
+ * @testcase app_control_uri_get_path_p
+ * @description Gets a path component from a URI handle.
+ * @apicovered app_control_uri_get_path
+ */
+TEST_F(UriTest, app_control_uri_get_path_p) {
+ const char* path;
+ int r = app_control_uri_get_path(uri_, &path);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+ EXPECT_NE(path, nullptr);
+ EXPECT_EQ(std::string(path), "/forum/questions/");
+}
+
+/*
+ * @testcase app_control_uri_get_path_n
+ * @description Gets a path component from a URI handle.
+ * The function returns a nullptr.
+ * @apicovered app_control_uri_get_path
+ */
+TEST_F(UriTest, app_control_uri_get_path_n) {
+ const char* path;
+ int r = app_control_uri_get_path(nullptr, &path);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+}
+
+/*
+ * @testcase app_control_uri_get_fragment_p
+ * @description Gets a fragment component from a URI handle.
+ * @apicovered app_control_uri_get_fragment
+ */
+TEST_F(UriTest, app_control_uri_get_fragment_p) {
+ const char* fragment;
+ int r = app_control_uri_get_fragment(uri_, &fragment);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+ EXPECT_NE(fragment, nullptr);
+ EXPECT_EQ(std::string(fragment), "top");
+}
+
+/*
+ * @testcase app_control_uri_get_fragment_n
+ * @description Gets a fragment component from a URI handle.
+ * The function returns a nullptr.
+ * @apicovered app_control_uri_get_fragment
+ */
+TEST_F(UriTest, app_control_uri_get_fragment_n) {
+ const char* fragment;
+ int r = app_control_uri_get_fragment(nullptr, &fragment);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+}
+
+/*
+ * @testcase app_control_uri_get_query_p
+ * @description Gets a handle of the query component from a URI handle.
+ * @apicovered app_control_uri_get_query
+ */
+TEST_F(UriTest, app_control_uri_get_query_p) {
+ app_control_uri_query_h query = nullptr;
+ int r = app_control_uri_get_query(uri_, &query);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+ EXPECT_NE(query, nullptr);
+}
+
+/*
+ * @testcase app_control_uri_get_query_n
+ * @description Gets a handle of the query component from a URI handle.
+ * The function returns a negative error value.
+ * @apicovered app_control_uri_get_query
+ */
+TEST_F(UriTest, app_control_uri_get_query_n) {
+ int r = app_control_uri_get_query(uri_, nullptr);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+
+ app_control_uri_query_h query = nullptr;
+ r = app_control_uri_get_query(nullptr, &query);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+}
+
+/*
+ * @testcase app_control_uri_get_host_p
+ * @description Gets a host subcomponent from a URI handle.
+ * @apicovered app_control_uri_get_host
+ */
+TEST_F(UriTest, app_control_uri_get_host_p) {
+ const char* host;
+ int r = app_control_uri_get_host(uri_, &host);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+ EXPECT_NE(host, nullptr);
+ EXPECT_EQ(std::string(host), "www.example.com");
+}
+
+/*
+ * @testcase app_control_uri_get_host_n
+ * @description Gets a host subcomponent from a URI handle.
+ * The function returns a nullptr.
+ * @apicovered app_control_uri_get_host
+ */
+TEST_F(UriTest, app_control_uri_get_host_n) {
+ const char* host;
+ int r = app_control_uri_get_host(nullptr, &host);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+}
+
+/*
+ * @testcase app_control_uri_get_port_p
+ * @description Gets a port subcomponent from a URI handle.
+ * @apicovered app_control_uri_get_port
+ */
+TEST_F(UriTest, app_control_uri_get_port_p) {
+ const char* port;
+ int r = app_control_uri_get_port(uri_, &port);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+ EXPECT_NE(port, nullptr);
+ EXPECT_EQ(std::string(port), "123");
+}
+
+/*
+ * @testcase app_control_uri_get_port_n
+ * @description Gets a port subcomponent from a URI handle.
+ * The function returns a nullptr.
+ * @apicovered app_control_uri_get_port
+ */
+TEST_F(UriTest, app_control_uri_get_port_n) {
+ const char* port;
+ int r = app_control_uri_get_port(nullptr, &port);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+}
+
+/*
+ * @testcase app_control_uri_get_user_p
+ * @description Gets a user subcomponent from a URI handle.
+ * @apicovered app_control_uri_get_user
+ */
+TEST_F(UriTest, app_control_uri_get_user_p) {
+ const char* user;
+ int r = app_control_uri_get_user(uri_, &user);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+ EXPECT_NE(user, nullptr);
+ EXPECT_EQ(std::string(user), "john.doe");
+}
+
+/*
+ * @testcase app_control_uri_get_user_n
+ * @description Gets a user subcomponent from a URI handle.
+ * The function returns a nullptr.
+ * @apicovered app_control_uri_get_user
+ */
+TEST_F(UriTest, app_control_uri_get_user_n) {
+ const char* user;
+ int r = app_control_uri_get_user(nullptr, &user);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+}
+
+/*
+ * @testcase app_control_uri_query_foreach_p
+ * @description Retrieves the key-value pairs attributes in the query component.
+ * @apicovered app_control_uri_query_foreach
+ */
+TEST_F(UriTest, app_control_uri_query_foreach_p) {
+ // Pre-condition: Gets the query handle
+ app_control_uri_query_h query = nullptr;
+ int r = app_control_uri_get_query(uri_, &query);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+ EXPECT_NE(query, nullptr);
+
+ r = app_control_uri_query_foreach(query,
+ [](const char* key, const char* val, void* user_data) -> bool {
+ UriTest* p = static_cast<UriTest*>(user_data);
+ if (!strcmp(key, "tag") && !strcmp(val, "networking"))
+ p->count_++;
+ else if (!strcmp(key, "order") && !strcmp(val, "newest"))
+ p->count_++;
+ return true;
+ }, this);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+ EXPECT_EQ(count_, 2);
+}
+
+/*
+ * @testcase app_control_uri_query_foreach_n
+ * @description Retrieves the key-value pairs attributes in the query component.
+ * The function returns a negative error value.
+ * @apicovered app_control_uri_query_foreach
+ */
+TEST_F(UriTest, app_control_uri_query_foreach_n) {
+ // Pre-condition: Gets the query handle
+ app_control_uri_query_h query = nullptr;
+ int r = app_control_uri_get_query(uri_, &query);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_NONE);
+ EXPECT_NE(query, nullptr);
+
+ r = app_control_uri_query_foreach(query, nullptr, this);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+
+ r = app_control_uri_query_foreach(nullptr,
+ [](const char* key, const char* val, void* user_data) -> bool {
+ UriTest* p = static_cast<UriTest*>(user_data);
+ if (!strcmp(key, "tag") && !strcmp(val, "networking"))
+ p->count_++;
+ else if (!strcmp(key, "order") && !strcmp(val, "newest"))
+ p->count_++;
+ return true;
+ }, this);
+ EXPECT_EQ(r, APP_CONTROL_URI_ERROR_INVALID_PARAMETER);
+ EXPECT_EQ(count_, 0);
+}