1/*** 2 This file is part of PulseAudio. 3 4 Copyright 2008 Colin Guthrie 5 Copyright 2007 Lennart Poettering 6 7 PulseAudio is free software; you can redistribute it and/or modify 8 it under the terms of the GNU Lesser General Public License as 9 published by the Free Software Foundation; either version 2.1 of the 10 License, or (at your option) any later version. 11 12 PulseAudio is distributed in the hope that it will be useful, but 13 WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 Lesser General Public License for more details. 16 17 You should have received a copy of the GNU Lesser General Public 18 License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. 19***/ 20 21#ifdef HAVE_CONFIG_H 22#include <config.h> 23#endif 24 25#include <string.h> 26 27#include <pulse/xmalloc.h> 28 29#include <pulsecore/hashmap.h> 30#include <pulsecore/strbuf.h> 31#include <pulsecore/core-util.h> 32 33#include "headerlist.h" 34 35struct header { 36 char *key; 37 void *value; 38 size_t nbytes; 39}; 40 41#define MAKE_HASHMAP(p) ((pa_hashmap*) (p)) 42#define MAKE_HEADERLIST(p) ((pa_headerlist*) (p)) 43 44static void header_free(struct header *hdr) { 45 pa_assert(hdr); 46 47 pa_xfree(hdr->key); 48 pa_xfree(hdr->value); 49 pa_xfree(hdr); 50} 51 52pa_headerlist* pa_headerlist_new(void) { 53 return MAKE_HEADERLIST(pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) header_free)); 54} 55 56void pa_headerlist_free(pa_headerlist* p) { 57 pa_hashmap_free(MAKE_HASHMAP(p)); 58} 59 60int pa_headerlist_puts(pa_headerlist *p, const char *key, const char *value) { 61 struct header *hdr; 62 bool add = false; 63 64 pa_assert(p); 65 pa_assert(key); 66 67 if (!(hdr = pa_hashmap_get(MAKE_HASHMAP(p), key))) { 68 hdr = pa_xnew(struct header, 1); 69 hdr->key = pa_xstrdup(key); 70 add = true; 71 } else 72 pa_xfree(hdr->value); 73 74 hdr->value = pa_xstrdup(value); 75 hdr->nbytes = strlen(value)+1; 76 77 if (add) 78 pa_hashmap_put(MAKE_HASHMAP(p), hdr->key, hdr); 79 80 return 0; 81} 82 83int pa_headerlist_putsappend(pa_headerlist *p, const char *key, const char *value) { 84 struct header *hdr; 85 bool add = false; 86 87 pa_assert(p); 88 pa_assert(key); 89 90 if (!(hdr = pa_hashmap_get(MAKE_HASHMAP(p), key))) { 91 hdr = pa_xnew(struct header, 1); 92 hdr->key = pa_xstrdup(key); 93 hdr->value = pa_xstrdup(value); 94 add = true; 95 } else { 96 void *newval = pa_sprintf_malloc("%s%s", (char*)hdr->value, value); 97 pa_xfree(hdr->value); 98 hdr->value = newval; 99 } 100 hdr->nbytes = strlen(hdr->value)+1; 101 102 if (add) 103 pa_hashmap_put(MAKE_HASHMAP(p), hdr->key, hdr); 104 105 return 0; 106} 107 108const char *pa_headerlist_gets(pa_headerlist *p, const char *key) { 109 struct header *hdr; 110 111 pa_assert(p); 112 pa_assert(key); 113 114 if (!(hdr = pa_hashmap_get(MAKE_HASHMAP(p), key))) 115 return NULL; 116 117 if (hdr->nbytes <= 0) 118 return NULL; 119 120 if (((char*) hdr->value)[hdr->nbytes-1] != 0) 121 return NULL; 122 123 if (strlen((char*) hdr->value) != hdr->nbytes-1) 124 return NULL; 125 126 return (char*) hdr->value; 127} 128 129int pa_headerlist_remove(pa_headerlist *p, const char *key) { 130 pa_assert(p); 131 pa_assert(key); 132 133 return pa_hashmap_remove_and_free(MAKE_HASHMAP(p), key); 134} 135 136const char *pa_headerlist_iterate(pa_headerlist *p, void **state) { 137 struct header *hdr; 138 139 if (!(hdr = pa_hashmap_iterate(MAKE_HASHMAP(p), state, NULL))) 140 return NULL; 141 142 return hdr->key; 143} 144 145char *pa_headerlist_to_string(pa_headerlist *p) { 146 const char *key; 147 void *state = NULL; 148 pa_strbuf *buf; 149 150 pa_assert(p); 151 152 buf = pa_strbuf_new(); 153 154 while ((key = pa_headerlist_iterate(p, &state))) { 155 156 const char *v; 157 158 if ((v = pa_headerlist_gets(p, key))) 159 pa_strbuf_printf(buf, "%s: %s\r\n", key, v); 160 } 161 162 return pa_strbuf_to_string_free(buf); 163} 164 165int pa_headerlist_contains(pa_headerlist *p, const char *key) { 166 pa_assert(p); 167 pa_assert(key); 168 169 if (!(pa_hashmap_get(MAKE_HASHMAP(p), key))) 170 return 0; 171 172 return 1; 173} 174