Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions c/src/ml-api-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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.
*/
Expand Down
23 changes: 23 additions & 0 deletions c/src/ml-api-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
74 changes: 74 additions & 0 deletions tests/capi/unittest_capi_inference_single.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down