]> code.delx.au - pulseaudio/blob - polyp/tagstruct.c
add support for module search path as command line argument
[pulseaudio] / polyp / tagstruct.c
1 /* $Id$ */
2
3 /***
4 This file is part of polypaudio.
5
6 polypaudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; either version 2 of the License,
9 or (at your option) any later version.
10
11 polypaudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with polypaudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdlib.h>
27 #include <string.h>
28 #include <netinet/in.h>
29 #include <assert.h>
30
31 #include "tagstruct.h"
32 #include "xmalloc.h"
33
34 enum tags {
35 TAG_STRING = 't',
36 TAG_U32 = 'L',
37 TAG_S32 = 'l',
38 TAG_U16 = 'S',
39 TAG_S16 = 's',
40 TAG_U8 = 'B',
41 TAG_S8 = 'b',
42 TAG_SAMPLE_SPEC = 'a',
43 TAG_ARBITRARY = 'x',
44 TAG_BOOLEAN_TRUE = '1',
45 TAG_BOOLEAN_FALSE = '0',
46 TAG_TIMEVAL = 'T',
47 };
48
49 struct pa_tagstruct {
50 uint8_t *data;
51 size_t length, allocated;
52 size_t rindex;
53
54 int dynamic;
55 };
56
57 struct pa_tagstruct *pa_tagstruct_new(const uint8_t* data, size_t length) {
58 struct pa_tagstruct*t;
59
60 assert(!data || (data && length));
61
62 t = pa_xmalloc(sizeof(struct pa_tagstruct));
63 t->data = (uint8_t*) data;
64 t->allocated = t->length = data ? length : 0;
65 t->rindex = 0;
66 t->dynamic = !data;
67 return t;
68 }
69
70 void pa_tagstruct_free(struct pa_tagstruct*t) {
71 assert(t);
72 if (t->dynamic)
73 pa_xfree(t->data);
74 pa_xfree(t);
75 }
76
77 uint8_t* pa_tagstruct_free_data(struct pa_tagstruct*t, size_t *l) {
78 uint8_t *p;
79 assert(t && t->dynamic && l);
80 p = t->data;
81 *l = t->length;
82 pa_xfree(t);
83 return p;
84 }
85
86 static void extend(struct pa_tagstruct*t, size_t l) {
87 assert(t && t->dynamic);
88
89 if (t->length+l <= t->allocated)
90 return;
91
92 t->data = pa_xrealloc(t->data, t->allocated = t->length+l+100);
93 }
94
95 void pa_tagstruct_puts(struct pa_tagstruct*t, const char *s) {
96 size_t l;
97 assert(t && s);
98 l = strlen(s)+2;
99 extend(t, l);
100 t->data[t->length] = TAG_STRING;
101 strcpy((char*) (t->data+t->length+1), s);
102 t->length += l;
103 }
104
105 void pa_tagstruct_putu32(struct pa_tagstruct*t, uint32_t i) {
106 assert(t);
107 extend(t, 5);
108 t->data[t->length] = TAG_U32;
109 *((uint32_t*) (t->data+t->length+1)) = htonl(i);
110 t->length += 5;
111 }
112
113 void pa_tagstruct_putu8(struct pa_tagstruct*t, uint8_t c) {
114 assert(t);
115 extend(t, 2);
116 t->data[t->length] = TAG_U8;
117 *(t->data+t->length+1) = c;
118 t->length += 2;
119 }
120
121 void pa_tagstruct_put_sample_spec(struct pa_tagstruct *t, const struct pa_sample_spec *ss) {
122 assert(t && ss);
123 extend(t, 7);
124 t->data[t->length] = TAG_SAMPLE_SPEC;
125 t->data[t->length+1] = (uint8_t) ss->format;
126 t->data[t->length+2] = ss->channels;
127 *(uint32_t*) (t->data+t->length+3) = htonl(ss->rate);
128 t->length += 7;
129 }
130
131 void pa_tagstruct_put_arbitrary(struct pa_tagstruct *t, const void *p, size_t length) {
132 assert(t && p);
133
134 extend(t, 5+length);
135 t->data[t->length] = TAG_ARBITRARY;
136 *((uint32_t*) (t->data+t->length+1)) = htonl(length);
137 if (length)
138 memcpy(t->data+t->length+5, p, length);
139 t->length += 5+length;
140 }
141
142 void pa_tagstruct_put_boolean(struct pa_tagstruct*t, int b) {
143 assert(t);
144 extend(t, 1);
145 t->data[t->length] = b ? TAG_BOOLEAN_TRUE : TAG_BOOLEAN_FALSE;
146 t->length += 1;
147 }
148
149 void pa_tagstruct_put_timeval(struct pa_tagstruct*t, const struct timeval *tv) {
150 assert(t);
151 extend(t, 9);
152 t->data[t->length] = TAG_TIMEVAL;
153 *((uint32_t*) (t->data+t->length+1)) = htonl(tv->tv_sec);
154 *((uint32_t*) (t->data+t->length+5)) = htonl(tv->tv_usec);
155 t->length += 9;
156 }
157
158 int pa_tagstruct_gets(struct pa_tagstruct*t, const char **s) {
159 int error = 0;
160 size_t n;
161 char *c;
162 assert(t && s);
163
164 if (t->rindex+2 > t->length)
165 return -1;
166
167 if (t->data[t->rindex] != TAG_STRING)
168 return -1;
169
170 error = 1;
171 for (n = 0, c = (char*) (t->data+t->rindex+1); t->rindex+1+n < t->length; n++, c++)
172 if (!*c) {
173 error = 0;
174 break;
175 }
176
177 if (error)
178 return -1;
179
180 *s = (char*) (t->data+t->rindex+1);
181
182 t->rindex += n+2;
183 return 0;
184 }
185
186 int pa_tagstruct_getu32(struct pa_tagstruct*t, uint32_t *i) {
187 assert(t && i);
188
189 if (t->rindex+5 > t->length)
190 return -1;
191
192 if (t->data[t->rindex] != TAG_U32)
193 return -1;
194
195 *i = ntohl(*((uint32_t*) (t->data+t->rindex+1)));
196 t->rindex += 5;
197 return 0;
198 }
199
200 int pa_tagstruct_getu8(struct pa_tagstruct*t, uint8_t *c) {
201 assert(t && c);
202
203 if (t->rindex+2 > t->length)
204 return -1;
205
206 if (t->data[t->rindex] != TAG_U8)
207 return -1;
208
209 *c = t->data[t->rindex+1];
210 t->rindex +=2;
211 return 0;
212 }
213
214 int pa_tagstruct_get_sample_spec(struct pa_tagstruct *t, struct pa_sample_spec *ss) {
215 assert(t && ss);
216
217 if (t->rindex+7 > t->length)
218 return -1;
219
220 if (t->data[t->rindex] != TAG_SAMPLE_SPEC)
221 return -1;
222
223 ss->format = t->data[t->rindex+1];
224 ss->channels = t->data[t->rindex+2];
225 ss->rate = ntohl(*(uint32_t*) (t->data+t->rindex+3));
226
227 t->rindex += 7;
228 return 0;
229 }
230
231 int pa_tagstruct_get_arbitrary(struct pa_tagstruct *t, const void **p, size_t length) {
232 assert(t && p);
233
234 if (t->rindex+5+length > t->length)
235 return -1;
236
237 if (t->data[t->rindex] != TAG_ARBITRARY)
238 return -1;
239
240 if (ntohl(*((uint32_t*) (t->data+t->rindex+1))) != length)
241 return -1;
242
243 *p = t->data+t->rindex+5;
244 t->rindex += 5+length;
245 return 0;
246 }
247
248 int pa_tagstruct_eof(struct pa_tagstruct*t) {
249 assert(t);
250 return t->rindex >= t->length;
251 }
252
253 const uint8_t* pa_tagstruct_data(struct pa_tagstruct*t, size_t *l) {
254 assert(t && t->dynamic && l);
255 *l = t->length;
256 return t->data;
257 }
258
259 int pa_tagstruct_get_boolean(struct pa_tagstruct*t, int *b) {
260 assert(t && b);
261
262 if (t->rindex+1 > t->length)
263 return -1;
264
265 if (t->data[t->rindex] == TAG_BOOLEAN_TRUE)
266 *b = 1;
267 else if (t->data[t->rindex] == TAG_BOOLEAN_FALSE)
268 *b = 0;
269 else
270 return -1;
271
272 t->rindex +=1;
273 return 0;
274 }
275
276 int pa_tagstruct_get_timeval(struct pa_tagstruct*t, struct timeval *tv) {
277
278 if (t->rindex+9 > t->length)
279 return -1;
280
281 if (t->data[t->rindex] != TAG_TIMEVAL)
282 return -1;
283
284 tv->tv_sec = ntohl(*((uint32_t*) (t->data+t->rindex+1)));
285 tv->tv_usec = ntohl(*((uint32_t*) (t->data+t->rindex+5)));
286 t->rindex += 9;
287 return 0;
288
289 }
290