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