src/stringpair.c
author Volker Birk <vb@pep.foundation>
Tue, 27 Dec 2016 21:13:41 +0100
changeset 1513 e7f7e42385b5
parent 1286 278339f8066c
child 1559 c6506bc6a0df
permissions -rw-r--r--
adding license info to each file
     1 // This file is under GNU General Public License 3.0
     2 // see LICENSE.txt
     3 
     4 #include "pEp_internal.h"
     5 
     6 #include <stdlib.h>
     7 #include <assert.h>
     8 #include <string.h>
     9 
    10 #include "stringpair.h"
    11 
    12 DYNAMIC_API stringpair_t * new_stringpair(const char *key, const char *value)
    13 {
    14     stringpair_t *pair = NULL;
    15 
    16     // key and value should not be NULL, that's bad style (while legal)
    17 
    18     assert(key);
    19     assert(value);
    20 
    21     pair = calloc(1, sizeof(stringpair_t));
    22     assert(pair);
    23     if (pair == NULL)
    24         goto enomem;
    25 
    26     pair->key = key ? strdup(key) : strdup("");
    27     assert(pair->key);
    28     if (pair->key == NULL)
    29         goto enomem;
    30 
    31     pair->value = value ? strdup(value) : strdup("");
    32     assert(pair->value);
    33     if (pair->value == NULL)
    34         goto enomem;
    35 
    36     return pair;
    37 
    38 enomem:
    39     free_stringpair(pair);
    40     return NULL;
    41 }
    42 
    43 DYNAMIC_API void free_stringpair(stringpair_t * pair)
    44 {
    45     if (pair) {
    46         free(pair->key);
    47         free(pair->value);
    48         free(pair);
    49     }
    50 }
    51 
    52 DYNAMIC_API stringpair_t * stringpair_dup(const stringpair_t *src)
    53 {
    54     assert(src);
    55     if (src == NULL)
    56         return NULL;
    57     
    58     return new_stringpair(src->key, src->value);
    59 }
    60 
    61 DYNAMIC_API stringpair_list_t *new_stringpair_list(stringpair_t *value)
    62 {
    63     stringpair_list_t *result = calloc(1, sizeof(stringpair_list_t));
    64     assert(result);
    65 
    66     if (result && value)
    67         result->value = value;
    68     
    69     return result;
    70 }
    71 
    72 DYNAMIC_API stringpair_list_t *stringpair_list_dup(
    73         const stringpair_list_t *src
    74     )
    75 {
    76     assert(src);
    77     if (src == NULL)
    78         return NULL;
    79 
    80     stringpair_t* copy_pair = stringpair_dup(src->value);
    81     
    82     stringpair_list_t *dst = new_stringpair_list(copy_pair);
    83     if (dst == NULL)
    84         return NULL;
    85 
    86     stringpair_list_t* src_curr = src->next;
    87     stringpair_list_t** dst_curr_ptr = &dst->next;
    88 
    89     while (src_curr) {
    90         copy_pair = stringpair_dup(src_curr->value);
    91         if (copy_pair == NULL) {
    92             free_stringpair_list(dst);
    93             return NULL;
    94         }
    95         *dst_curr_ptr = new_stringpair_list(copy_pair);
    96         if (*dst_curr_ptr == NULL) {
    97             free_stringpair(copy_pair);
    98             free_stringpair_list(dst);
    99             return NULL;
   100         }
   101         src_curr = src_curr->next;
   102         dst_curr_ptr = &((*dst_curr_ptr)->next);
   103     }
   104 
   105     return dst;
   106     
   107 }
   108 
   109 DYNAMIC_API stringpair_list_t *stringpair_list_add(
   110         stringpair_list_t *stringpair_list,
   111         stringpair_t *value
   112     )
   113 {
   114     assert(value);
   115 
   116     // empty list (no nodes)
   117     if (stringpair_list == NULL)
   118         return new_stringpair_list(value);
   119 
   120     // empty list (one node, no value)
   121     if (stringpair_list->value == NULL) {
   122         if (stringpair_list->next)
   123             return NULL; // invalid list
   124             
   125         stringpair_list->value = value;
   126         assert(stringpair_list->value);
   127         
   128         if (stringpair_list->value == NULL)
   129             return NULL;
   130         
   131         return stringpair_list;
   132     }
   133     
   134     stringpair_list_t* list_curr = stringpair_list;
   135     
   136     while (list_curr->next)
   137         list_curr = list_curr->next;
   138      
   139     list_curr->next = new_stringpair_list(value);
   140 
   141     assert(list_curr->next);
   142     if (list_curr->next == NULL)
   143         return NULL;
   144 
   145     return list_curr->next;
   146     
   147 }
   148 
   149 DYNAMIC_API stringpair_list_t *stringpair_list_append(
   150         stringpair_list_t *stringpair_list,
   151         stringpair_list_t *second
   152     )
   153 {
   154     assert(stringpair_list);
   155     if (stringpair_list == NULL)
   156         return NULL;
   157 
   158     // second list is empty
   159     if (second == NULL || second->value == NULL)
   160         return stringpair_list;
   161 
   162     stringpair_list_t *_s = stringpair_list;
   163     stringpair_list_t *_s2;
   164     for (_s2 = second; _s2 != NULL; _s2 = _s2->next) {
   165         stringpair_t *_sp = stringpair_dup(_s2->value);
   166         if (_sp == NULL)
   167             return NULL;
   168         _s = stringpair_list_add(_s, _sp);
   169         if (_s == NULL){
   170             free_stringpair(_sp);
   171             return NULL;
   172         }
   173     }
   174     return _s;
   175 }
   176 
   177 DYNAMIC_API int stringpair_list_length(
   178         const stringpair_list_t *stringpair_list
   179     )
   180 {
   181     int len = 0;
   182 
   183     const stringpair_list_t *_sl;
   184     for (_sl = stringpair_list; _sl && _sl->value; _sl = _sl->next)
   185         len++;
   186 
   187     return len;
   188 }
   189 
   190 DYNAMIC_API void free_stringpair_list(stringpair_list_t *stringpair_list)
   191 {
   192     if (stringpair_list) {
   193         free_stringpair_list(stringpair_list->next);
   194         free_stringpair(stringpair_list->value);
   195         free(stringpair_list);
   196     }
   197 }
   198 
   199 DYNAMIC_API stringpair_list_t *stringpair_list_find(
   200         stringpair_list_t *stringpair_list,
   201         const char *key
   202     )
   203 {
   204     assert(key);
   205 
   206     stringpair_list_t *_l;
   207     for (_l = stringpair_list; _l; _l = _l->next) {
   208         if (strcoll(key, _l->value->key) == 0)
   209             return _l;
   210     }
   211 
   212     return NULL;
   213 }
   214