LCOV - code coverage report
Current view: top level - nnstreamer-edge-0.2.6/src/libnnstreamer-edge - nnstreamer-edge-metadata.c (source / functions) Coverage Total Hit
Test: NNStreamer-edge 0.2.6-1 nnstreamer/nnstreamer-edge#121619a22eefb07aef74ab765d1eb0ec59b1416e Lines: 90.8 % 153 139
Test Date: 2025-06-06 05:20:40 Functions: 100.0 % 10 10

            Line data    Source code
       1              : /* SPDX-License-Identifier: Apache-2.0 */
       2              : /**
       3              :  * Copyright (C) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
       4              :  *
       5              :  * @file   nnstreamer-edge-metadata.c
       6              :  * @date   6 April 2022
       7              :  * @brief  Util functions for metadata.
       8              :  * @see    https://github.com/nnstreamer/nnstreamer
       9              :  * @author Gichan Jang <gichan2.jang@samsung.com>
      10              :  * @bug    No known bugs except for NYI items
      11              :  */
      12              : 
      13              : #include "nnstreamer-edge-metadata.h"
      14              : #include "nnstreamer-edge-util.h"
      15              : 
      16              : /**
      17              :  * @brief Internal data structure for metadata.
      18              :  */
      19              : typedef struct _nns_edge_metadata_node_s nns_edge_metadata_node_s;
      20              : 
      21              : /**
      22              :  * @brief Internal data structure for metadata.
      23              :  */
      24              : struct _nns_edge_metadata_node_s
      25              : {
      26              :   char *key;
      27              :   char *value;
      28              :   nns_edge_metadata_node_s *next;
      29              : };
      30              : 
      31              : /**
      32              :  * @brief Internal data structure to handle metadata. This struct should be managed in the handle.
      33              :  */
      34              : typedef struct
      35              : {
      36              :   uint32_t list_len;
      37              :   nns_edge_metadata_node_s *list;
      38              : } nns_edge_metadata_s;
      39              : 
      40              : /**
      41              :  * @brief Internal function to find node in the list.
      42              :  */
      43              : static nns_edge_metadata_node_s *
      44          434 : nns_edge_metadata_find (nns_edge_metadata_s * meta, const char *key)
      45              : {
      46              :   nns_edge_metadata_node_s *node;
      47              : 
      48          434 :   if (!meta)
      49            1 :     return NULL;
      50              : 
      51          433 :   if (!STR_IS_VALID (key))
      52            2 :     return NULL;
      53              : 
      54          431 :   node = meta->list;
      55          763 :   while (node) {
      56          470 :     if (strcasecmp (key, node->key) == 0)
      57          138 :       return node;
      58              : 
      59          332 :     node = node->next;
      60              :   }
      61              : 
      62          293 :   return NULL;
      63              : }
      64              : 
      65              : /**
      66              :  * @brief Internal function to initialize metadata structure.
      67              :  */
      68              : static int
      69          303 : nns_edge_metadata_init (nns_edge_metadata_s * meta)
      70              : {
      71          303 :   if (!meta)
      72            0 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
      73              : 
      74          303 :   memset (meta, 0, sizeof (nns_edge_metadata_s));
      75          303 :   return NNS_EDGE_ERROR_NONE;
      76              : }
      77              : 
      78              : /**
      79              :  * @brief Internal function to free the list and items in metadata structure.
      80              :  */
      81              : static int
      82          335 : nns_edge_metadata_free (nns_edge_metadata_s * meta)
      83              : {
      84              :   nns_edge_metadata_node_s *node, *tmp;
      85              : 
      86          335 :   if (!meta)
      87            0 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
      88              : 
      89          335 :   node = meta->list;
      90          335 :   meta->list_len = 0;
      91          335 :   meta->list = NULL;
      92              : 
      93          627 :   while (node) {
      94          292 :     tmp = node->next;
      95              : 
      96          292 :     SAFE_FREE (node->key);
      97          292 :     SAFE_FREE (node->value);
      98          292 :     SAFE_FREE (node);
      99              : 
     100          292 :     node = tmp;
     101              :   }
     102              : 
     103          335 :   return NNS_EDGE_ERROR_NONE;
     104              : }
     105              : 
     106              : /**
     107              :  * @brief Internal function to create metadata.
     108              :  */
     109              : int
     110          225 : nns_edge_metadata_create (nns_edge_metadata_h * metadata_h)
     111              : {
     112              :   nns_edge_metadata_s *meta;
     113              : 
     114          225 :   if (!metadata_h)
     115            1 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     116              : 
     117          224 :   meta = calloc (1, sizeof (nns_edge_metadata_s));
     118          224 :   if (!meta)
     119            0 :     return NNS_EDGE_ERROR_OUT_OF_MEMORY;
     120              : 
     121          224 :   nns_edge_metadata_init (meta);
     122              : 
     123          224 :   *metadata_h = meta;
     124          224 :   return NNS_EDGE_ERROR_NONE;
     125              : }
     126              : 
     127              : /**
     128              :  * @brief Internal function to destroy metadata.
     129              :  */
     130              : int
     131          225 : nns_edge_metadata_destroy (nns_edge_metadata_h metadata_h)
     132              : {
     133              :   nns_edge_metadata_s *meta;
     134              : 
     135          225 :   meta = (nns_edge_metadata_s *) metadata_h;
     136              : 
     137          225 :   if (!meta)
     138            1 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     139              : 
     140          224 :   nns_edge_metadata_free (meta);
     141          224 :   SAFE_FREE (meta);
     142              : 
     143          224 :   return NNS_EDGE_ERROR_NONE;
     144              : }
     145              : 
     146              : /**
     147              :  * @brief Internal function to set the metadata.
     148              :  */
     149              : int
     150          339 : nns_edge_metadata_set (nns_edge_metadata_h metadata_h,
     151              :     const char *key, const char *value)
     152              : {
     153              :   nns_edge_metadata_s *meta;
     154              :   nns_edge_metadata_node_s *node;
     155              : 
     156          339 :   meta = (nns_edge_metadata_s *) metadata_h;
     157              : 
     158          339 :   if (!meta)
     159            1 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     160              : 
     161          338 :   if (!STR_IS_VALID (key))
     162            2 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     163              : 
     164          336 :   if (!STR_IS_VALID (value))
     165            3 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     166              : 
     167              :   /* Replace old value if key exists in the list. */
     168          333 :   node = nns_edge_metadata_find (meta, key);
     169          333 :   if (node) {
     170           41 :     char *val = nns_edge_strdup (value);
     171              : 
     172           41 :     if (!val)
     173            0 :       return NNS_EDGE_ERROR_OUT_OF_MEMORY;
     174              : 
     175           41 :     SAFE_FREE (node->value);
     176           41 :     node->value = val;
     177           41 :     return NNS_EDGE_ERROR_NONE;
     178              :   }
     179              : 
     180          292 :   node = calloc (1, sizeof (nns_edge_metadata_node_s));
     181          292 :   if (!node)
     182            0 :     return NNS_EDGE_ERROR_OUT_OF_MEMORY;
     183              : 
     184          292 :   node->key = nns_edge_strdup (key);
     185          292 :   node->value = nns_edge_strdup (value);
     186              : 
     187          292 :   if (!node->key || !node->value) {
     188            0 :     SAFE_FREE (node->key);
     189            0 :     SAFE_FREE (node->value);
     190            0 :     SAFE_FREE (node);
     191            0 :     return NNS_EDGE_ERROR_OUT_OF_MEMORY;
     192              :   }
     193              : 
     194              :   /* Prepend new node to the start of the list. */
     195          292 :   meta->list_len++;
     196          292 :   node->next = meta->list;
     197          292 :   meta->list = node;
     198              : 
     199          292 :   return NNS_EDGE_ERROR_NONE;
     200              : }
     201              : 
     202              : /**
     203              :  * @brief Internal function to get the metadata in the list. Caller should release the returned value using free().
     204              :  */
     205              : int
     206          102 : nns_edge_metadata_get (nns_edge_metadata_h metadata_h,
     207              :     const char *key, char **value)
     208              : {
     209              :   nns_edge_metadata_s *meta;
     210              :   nns_edge_metadata_node_s *node;
     211              : 
     212          102 :   meta = (nns_edge_metadata_s *) metadata_h;
     213              : 
     214          102 :   if (!value)
     215            1 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     216              : 
     217          101 :   node = nns_edge_metadata_find (meta, key);
     218          101 :   if (node) {
     219           97 :     *value = nns_edge_strdup (node->value);
     220           97 :     return (*value) ? NNS_EDGE_ERROR_NONE : NNS_EDGE_ERROR_OUT_OF_MEMORY;
     221              :   }
     222              : 
     223            4 :   return NNS_EDGE_ERROR_INVALID_PARAMETER;
     224              : }
     225              : 
     226              : /**
     227              :  * @brief Internal function to copy the metadata.
     228              :  */
     229              : int
     230           81 : nns_edge_metadata_copy (nns_edge_metadata_h dest_h, nns_edge_metadata_h src_h)
     231              : {
     232              :   nns_edge_metadata_s *dest, *src;
     233              :   nns_edge_metadata_s tmp;
     234              :   nns_edge_metadata_node_s *node;
     235              :   int ret;
     236              : 
     237           81 :   dest = (nns_edge_metadata_s *) dest_h;
     238           81 :   src = (nns_edge_metadata_s *) src_h;
     239              : 
     240           81 :   if (!dest || !src)
     241           81 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     242              : 
     243           79 :   nns_edge_metadata_init (&tmp);
     244              : 
     245           79 :   node = src->list;
     246          245 :   while (node) {
     247          166 :     ret = nns_edge_metadata_set (&tmp, node->key, node->value);
     248          166 :     if (ret != NNS_EDGE_ERROR_NONE) {
     249            0 :       nns_edge_metadata_free (&tmp);
     250            0 :       return ret;
     251              :     }
     252              : 
     253          166 :     node = node->next;
     254              :   }
     255              : 
     256              :   /* Replace dest when new metadata is successfully copied. */
     257           79 :   nns_edge_metadata_free (dest);
     258           79 :   *dest = tmp;
     259              : 
     260           79 :   return NNS_EDGE_ERROR_NONE;
     261              : }
     262              : 
     263              : /**
     264              :  * @brief Internal function to serialize the metadata. Caller should release the returned value using free().
     265              :  */
     266              : int
     267           51 : nns_edge_metadata_serialize (nns_edge_metadata_h metadata_h,
     268              :     void **data, nns_size_t * data_len)
     269              : {
     270              :   nns_edge_metadata_s *meta;
     271              :   nns_edge_metadata_node_s *node;
     272              :   char *serialized, *ptr;
     273              :   nns_size_t total, len;
     274              : 
     275           51 :   meta = (nns_edge_metadata_s *) metadata_h;
     276              : 
     277           51 :   if (!meta)
     278            1 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     279              : 
     280           50 :   if (!data || !data_len)
     281            5 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     282              : 
     283           45 :   *data = NULL;
     284           45 :   *data_len = 0U;
     285              : 
     286           45 :   if (meta->list_len == 0)
     287            5 :     return NNS_EDGE_ERROR_NONE;
     288              : 
     289              :   /* length, # of metadata */
     290           40 :   total = len = sizeof (uint32_t);
     291              : 
     292           40 :   node = meta->list;
     293          133 :   while (node) {
     294           93 :     total += (strlen (node->key) + strlen (node->value) + 2);
     295           93 :     node = node->next;
     296              :   }
     297              : 
     298           40 :   serialized = ptr = (char *) nns_edge_malloc (total);
     299           40 :   if (!serialized)
     300            0 :     return NNS_EDGE_ERROR_OUT_OF_MEMORY;
     301              : 
     302              :   /* length + list of key-value pair */
     303           40 :   ((uint32_t *) serialized)[0] = meta->list_len;
     304           40 :   ptr += len;
     305              : 
     306           40 :   node = meta->list;
     307          133 :   while (node) {
     308           93 :     len = strlen (node->key);
     309           93 :     memcpy (ptr, node->key, len);
     310           93 :     ptr[len] = '\0';
     311           93 :     ptr += (len + 1);
     312              : 
     313           93 :     len = strlen (node->value);
     314           93 :     memcpy (ptr, node->value, len);
     315           93 :     ptr[len] = '\0';
     316           93 :     ptr += (len + 1);
     317              : 
     318           93 :     node = node->next;
     319              :   }
     320              : 
     321           40 :   *data = serialized;
     322           40 :   *data_len = total;
     323              : 
     324           40 :   return NNS_EDGE_ERROR_NONE;
     325              : }
     326              : 
     327              : /**
     328              :  * @brief Internal function to deserialize memory into metadata.
     329              :  */
     330              : int
     331           47 : nns_edge_metadata_deserialize (nns_edge_metadata_h metadata_h,
     332              :     const void *data, const nns_size_t data_len)
     333              : {
     334              :   nns_edge_metadata_s *meta;
     335              :   char *key, *value;
     336              :   nns_size_t cur, total;
     337              :   int ret;
     338              : 
     339           47 :   meta = (nns_edge_metadata_s *) metadata_h;
     340              : 
     341           47 :   if (!meta)
     342            1 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     343              : 
     344           46 :   if (!data || data_len <= 0)
     345           14 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     346              : 
     347           32 :   nns_edge_metadata_free (meta);
     348              : 
     349              :   /* length + list of key-value pair */
     350           32 :   total = ((uint32_t *) data)[0];
     351              : 
     352           32 :   cur = sizeof (uint32_t);
     353          117 :   while (cur < data_len || meta->list_len < total) {
     354           85 :     key = (char *) data + cur;
     355           85 :     cur += (strlen (key) + 1);
     356              : 
     357           85 :     value = (char *) data + cur;
     358           85 :     cur += (strlen (value) + 1);
     359              : 
     360           85 :     ret = nns_edge_metadata_set (meta, key, value);
     361           85 :     if (ret != NNS_EDGE_ERROR_NONE) {
     362            0 :       nns_edge_metadata_free (meta);
     363            0 :       return ret;
     364              :     }
     365              :   }
     366              : 
     367           32 :   return NNS_EDGE_ERROR_NONE;
     368              : }
        

Generated by: LCOV version 2.0-1