Merge commit 'flameeyes/libtool-2.2'
[platform/upstream/pulseaudio.git] / src / modules / rtp / headerlist.c
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, write to the Free Software
19   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20   USA.
21 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <string.h>
28
29 #include <pulse/xmalloc.h>
30
31 #include <pulsecore/hashmap.h>
32 #include <pulsecore/strbuf.h>
33 #include <pulsecore/core-util.h>
34
35 #include "headerlist.h"
36
37 struct header {
38     char *key;
39     void *value;
40     size_t nbytes;
41 };
42
43 #define MAKE_HASHMAP(p) ((pa_hashmap*) (p))
44 #define MAKE_HEADERLIST(p) ((pa_headerlist*) (p))
45
46 static void header_free(struct header *hdr) {
47     pa_assert(hdr);
48
49     pa_xfree(hdr->key);
50     pa_xfree(hdr->value);
51     pa_xfree(hdr);
52 }
53
54 pa_headerlist* pa_headerlist_new(void) {
55     return MAKE_HEADERLIST(pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func));
56 }
57
58 void pa_headerlist_free(pa_headerlist* p) {
59     struct header *hdr;
60
61     while ((hdr = pa_hashmap_steal_first(MAKE_HASHMAP(p))))
62         header_free(hdr);
63
64     pa_hashmap_free(MAKE_HASHMAP(p), NULL, NULL);
65 }
66
67 int pa_headerlist_puts(pa_headerlist *p, const char *key, const char *value) {
68     struct header *hdr;
69     pa_bool_t add = FALSE;
70
71     pa_assert(p);
72     pa_assert(key);
73
74     if (!(hdr = pa_hashmap_get(MAKE_HASHMAP(p), key))) {
75         hdr = pa_xnew(struct header, 1);
76         hdr->key = pa_xstrdup(key);
77         add = TRUE;
78     } else
79         pa_xfree(hdr->value);
80
81     hdr->value = pa_xstrdup(value);
82     hdr->nbytes = strlen(value)+1;
83
84     if (add)
85         pa_hashmap_put(MAKE_HASHMAP(p), hdr->key, hdr);
86
87     return 0;
88 }
89
90 int pa_headerlist_putsappend(pa_headerlist *p, const char *key, const char *value) {
91     struct header *hdr;
92     pa_bool_t add = FALSE;
93
94     pa_assert(p);
95     pa_assert(key);
96
97     if (!(hdr = pa_hashmap_get(MAKE_HASHMAP(p), key))) {
98         hdr = pa_xnew(struct header, 1);
99         hdr->key = pa_xstrdup(key);
100         hdr->value = pa_xstrdup(value);
101         add = TRUE;
102     } else {
103         void *newval = pa_sprintf_malloc("%s%s", (char*)hdr->value, value);
104         pa_xfree(hdr->value);
105         hdr->value = newval;
106     }
107     hdr->nbytes = strlen(hdr->value)+1;
108
109     if (add)
110         pa_hashmap_put(MAKE_HASHMAP(p), hdr->key, hdr);
111
112     return 0;
113 }
114
115 const char *pa_headerlist_gets(pa_headerlist *p, const char *key) {
116     struct header *hdr;
117
118     pa_assert(p);
119     pa_assert(key);
120
121     if (!(hdr = pa_hashmap_get(MAKE_HASHMAP(p), key)))
122         return NULL;
123
124     if (hdr->nbytes <= 0)
125         return NULL;
126
127     if (((char*) hdr->value)[hdr->nbytes-1] != 0)
128         return NULL;
129
130     if (strlen((char*) hdr->value) != hdr->nbytes-1)
131         return NULL;
132
133     return (char*) hdr->value;
134 }
135
136 int pa_headerlist_remove(pa_headerlist *p, const char *key) {
137     struct header *hdr;
138
139     pa_assert(p);
140     pa_assert(key);
141
142     if (!(hdr = pa_hashmap_remove(MAKE_HASHMAP(p), key)))
143         return -1;
144
145     header_free(hdr);
146     return 0;
147 }
148
149 const char *pa_headerlist_iterate(pa_headerlist *p, void **state) {
150     struct header *hdr;
151
152     if (!(hdr = pa_hashmap_iterate(MAKE_HASHMAP(p), state, NULL)))
153         return NULL;
154
155     return hdr->key;
156 }
157
158 char *pa_headerlist_to_string(pa_headerlist *p) {
159     const char *key;
160     void *state = NULL;
161     pa_strbuf *buf;
162
163     pa_assert(p);
164
165     buf = pa_strbuf_new();
166
167     while ((key = pa_headerlist_iterate(p, &state))) {
168
169         const char *v;
170
171         if ((v = pa_headerlist_gets(p, key)))
172             pa_strbuf_printf(buf, "%s: %s\r\n", key, v);
173     }
174
175     return pa_strbuf_tostring_free(buf);
176 }
177
178 int pa_headerlist_contains(pa_headerlist *p, const char *key) {
179     pa_assert(p);
180     pa_assert(key);
181
182     if (!(pa_hashmap_get(MAKE_HASHMAP(p), key)))
183         return 0;
184
185     return 1;
186 }