• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
35 struct 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 
header_free(struct header * hdr)44 static 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 
pa_headerlist_new(void)52 pa_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 
pa_headerlist_free(pa_headerlist * p)56 void pa_headerlist_free(pa_headerlist* p) {
57     pa_hashmap_free(MAKE_HASHMAP(p));
58 }
59 
pa_headerlist_puts(pa_headerlist * p,const char * key,const char * value)60 int 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 
pa_headerlist_putsappend(pa_headerlist * p,const char * key,const char * value)83 int 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 
pa_headerlist_gets(pa_headerlist * p,const char * key)108 const 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 
pa_headerlist_remove(pa_headerlist * p,const char * key)129 int 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 
pa_headerlist_iterate(pa_headerlist * p,void ** state)136 const 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 
pa_headerlist_to_string(pa_headerlist * p)145 char *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 
pa_headerlist_contains(pa_headerlist * p,const char * key)165 int 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