You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

260 lines
5.8 KiB

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