From 85be84fb1e0ac98e2628b1efd29d59492d9bf1f8 Mon Sep 17 00:00:00 2001 From: Jaeyun Jung Date: Thu, 24 Jul 2025 18:09:59 +0900 Subject: [PATCH] [C-Api] function to iterate ml-information Add new function to iterate key-value pairs in ml-information. Signed-off-by: Jaeyun Jung --- c/src/ml-api-common.c | 60 ++++++++++++++++ c/src/ml-api-internal.h | 23 ++++++ tests/capi/unittest_capi_inference_single.cc | 74 ++++++++++++++++++++ 3 files changed, 157 insertions(+) diff --git a/c/src/ml-api-common.c b/c/src/ml-api-common.c index 32204220..81abde7c 100644 --- a/c/src/ml-api-common.c +++ b/c/src/ml-api-common.c @@ -59,6 +59,15 @@ typedef struct GSList *info; /**< The list of ml_info. */ } ml_info_list_s; +/** + * @brief Internal data structure for iterating ml-information. + */ +typedef struct +{ + ml_information_iterate_cb callback; + void *user_data; +} ml_info_iter_data_s; + /** * @brief Gets the version number of machine-learning API. */ @@ -1638,6 +1647,57 @@ _ml_information_set (ml_information_h information, const char *key, void *value, return _ml_info_set_value ((ml_info_s *) information, key, value, destroy); } +/** + * @brief Internal function to iterate ml-information. + */ +static void +_ml_information_iter_internal (gpointer key, gpointer value, gpointer user_data) +{ + ml_info_iter_data_s *iter = (ml_info_iter_data_s *) user_data; + ml_info_value_s *info_value = (ml_info_value_s *) value; + + iter->callback (key, info_value->value, iter->user_data); +} + +/** + * @brief Iterates the key and value of each pair in ml-information. + */ +int +ml_information_iterate (ml_information_h ml_info, + ml_information_iterate_cb cb, void *user_data) +{ + ml_info_s *_info; + ml_info_iter_data_s *iter; + + check_feature_state (ML_FEATURE); + + if (!_ml_info_is_valid (ml_info, ML_INFO_TYPE_INFORMATION)) { + _ml_error_report_return (ML_ERROR_INVALID_PARAMETER, + "The parameter, 'ml_info' is not a ml-information handle."); + } + + if (!cb) { + _ml_error_report_return (ML_ERROR_INVALID_PARAMETER, + "The parameter, 'cb' is NULL. It should be a valid function."); + } + + _info = (ml_info_s *) ml_info; + + iter = g_new0 (ml_info_iter_data_s, 1); + if (!iter) { + _ml_error_report_return (ML_ERROR_OUT_OF_MEMORY, + "Failed to allocate memory for the iteration. Out of memory?"); + } + + iter->callback = cb; + iter->user_data = user_data; + + g_hash_table_foreach (_info->table, _ml_information_iter_internal, iter); + g_free (iter); + + return ML_ERROR_NONE; +} + /** * @brief Frees the given handle of a ml_information. */ diff --git a/c/src/ml-api-internal.h b/c/src/ml-api-internal.h index bb376119..49c4916d 100644 --- a/c/src/ml-api-internal.h +++ b/c/src/ml-api-internal.h @@ -341,6 +341,29 @@ int _ml_information_create (ml_information_h *ml_info); */ int _ml_information_set (ml_information_h ml_info, const char *key, void *value, ml_data_destroy_cb destroy); +/** + * @brief Callback to iterate the key and value of each pair in ml-information. + * @since_tizen 10.0 + * @param[in] key The key in ml-information. + * @param[in] value The value of the key. + * @param[in] user_data Private data for the callback. + */ +typedef void (*ml_information_iterate_cb) (const char *key, const void *value, void *user_data); + +/** + * @brief Iterates the key and value of each pair in ml-information. + * @since_tizen 10.0 + * @param[in] ml_info The handle of ml-information. + * @param[in] cb The callback to call for each key/value pair. + * @param[in] user_data Private data for the callback. This value is passed to the callback when it's invoked. + * @return @c 0 on success. Otherwise a negative error value. + * @retval #ML_ERROR_NONE Successful. + * @retval #ML_ERROR_NOT_SUPPORTED Not supported. + * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid. + * @retval #ML_ERROR_OUT_OF_MEMORY Failed to allocate required memory. + */ +int ml_information_iterate (ml_information_h ml_info, ml_information_iterate_cb cb, void *user_data); + /** * @brief Creates an ml-information-list instance and returns the handle. */ diff --git a/tests/capi/unittest_capi_inference_single.cc b/tests/capi/unittest_capi_inference_single.cc index 84ad6d6d..c30f4b76 100644 --- a/tests/capi/unittest_capi_inference_single.cc +++ b/tests/capi/unittest_capi_inference_single.cc @@ -4418,6 +4418,80 @@ TEST (nnstreamer_capi_ml_option, fw_name_tensorflow_lite) } #endif +/** + * @brief Internal callback for iterating ml-information. + */ +static void +_test_ml_information_iter (const char *key, const void *value, void *user_data) +{ + gint *count = (gint *) user_data; + + if (((key && g_ascii_strcasecmp (key, "tkey1") == 0) + && (value && g_ascii_strcasecmp ((const char *) value, "tvalue1") == 0)) + || ((key && g_ascii_strcasecmp (key, "tkey2") == 0) + && (value && g_ascii_strcasecmp ((const char *) value, "tvalue2") == 0))) { + *count += 1; + } else { + *count = -1; + } +} + +/** + * @brief Test for iterating ml-information. + */ +TEST (nnstreamer_capi_ml_information, iterate) +{ + ml_information_h info; + int status; + gint *count = (gint *) g_malloc0 (sizeof (gint)); + + status = _ml_information_create (&info); + EXPECT_EQ (status, ML_ERROR_NONE); + + status = _ml_information_set (info, "tkey1", g_strdup ("tvalue1"), g_free); + EXPECT_EQ (status, ML_ERROR_NONE); + status = _ml_information_set (info, "tkey2", g_strdup ("tvalue2"), g_free); + EXPECT_EQ (status, ML_ERROR_NONE); + + status = ml_information_iterate (info, _test_ml_information_iter, count); + EXPECT_EQ (status, ML_ERROR_NONE); + + status = ml_information_destroy (info); + EXPECT_EQ (status, ML_ERROR_NONE); + + EXPECT_EQ (*count, 2); + g_free (count); +} + +/** + * @brief Test for iterating ml-information with invalid param. + */ +TEST (nnstreamer_capi_ml_information, iterateInvalidParam01_n) +{ + int status; + + status = ml_information_iterate (NULL, _test_ml_information_iter, NULL); + EXPECT_EQ (status, ML_ERROR_INVALID_PARAMETER); +} + +/** + * @brief Test for iterating ml-information with invalid param. + */ +TEST (nnstreamer_capi_ml_information, iterateInvalidParam02_n) +{ + ml_information_h info; + int status; + + status = _ml_information_create (&info); + EXPECT_EQ (status, ML_ERROR_NONE); + + status = ml_information_iterate (info, NULL, NULL); + EXPECT_EQ (status, ML_ERROR_INVALID_PARAMETER); + + status = ml_information_destroy (info); + EXPECT_EQ (status, ML_ERROR_NONE); +} + /** * @brief Test utility functions (private) * @details check sub-plugin type and name