Brought up to date
[swftools.git] / lib / q.c
bloba997fddab6a6e32bb0bba570cc217e074157d6a5
1 /* q.c
3 Part of the swftools package.
5 Copyright (c) 2001 Matthias Kramm <kramm@quiss.org>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <memory.h>
26 #include "q.h"
28 // ------------------------------- malloc, alloc routines ---------------------
30 #ifndef STRNDUP
31 char* strdup_n(const char*str, int size)
33 char*m = (char*)malloc(size+1);
34 memcpy(m, str, size);
35 m[size] = 0;
36 return m;
38 #endif
39 void* qmalloc_internal(int len)
41 void*val = malloc(len);
42 if(!val) {
43 printf("memory error! Couldn't reserve %d bytes\n", len);
44 fprintf(stderr, "memory error! Couldn't reserve %d bytes\n", len);
45 exit(1);
47 return val;
49 void* qrealloc_internal(void*old, int len)
51 void*val = realloc(old, len);
52 if(!val) {
53 printf("memory error! Couldn't reserve %d bytes\n", len);
54 fprintf(stderr, "memory error! Couldn't reserve %d bytes\n", len);
55 exit(1);
57 return val;
59 void qfree_internal(void*old)
61 free(old);
63 char*qstrdup(const char*string)
65 return strdup(string);
67 char*qstrndup(const char*string, int len)
69 return strdup_n(string, len);
72 // ------------------------------- mem_t --------------------------------------
74 void mem_init(mem_t*mem)
76 memset(mem, 0, sizeof(mem_t));
78 void mem_clear(mem_t*mem)
80 free(mem->buffer);mem->buffer = 0;
82 void mem_destroy(mem_t*mem)
84 mem_clear(mem);
85 free(mem);
87 static int mem_put_(mem_t*m,void*data, int length, int null)
89 int n = m->pos;
90 m->pos += length + (null?1:0);
91 if(m->pos > m->len)
93 //m->len += 1024>length?1024:(null?length*2:length);
95 m->len *= 2;
96 while(m->len < m->pos)
97 m->len += 64;
99 m->buffer = m->buffer?(char*)realloc(m->buffer,m->len):(char*)malloc(m->len);
101 memcpy(&m->buffer[n], data, length);
102 if(null)
103 m->buffer[n + length] = 0;
104 return n;
106 int mem_put(mem_t*m,void*data, int length)
108 return mem_put_(m, data, length, 0);
110 int mem_putstring(mem_t*m,string_t str)
112 return mem_put_(m, str.str, str.len, 1);
115 // ------------------------------- ringbuffer_t -------------------------------
117 typedef struct _ringbuffer_internal_t
119 unsigned char*buffer;
120 int readpos;
121 int writepos;
122 int buffersize;
123 } ringbuffer_internal_t;
125 void ringbuffer_init(ringbuffer_t*r)
127 ringbuffer_internal_t*i = (ringbuffer_internal_t*)malloc(sizeof(ringbuffer_internal_t));
128 memset(r, 0, sizeof(ringbuffer_t));
129 memset(i, 0, sizeof(ringbuffer_internal_t));
130 r->internal = i;
131 i->buffer = (unsigned char*)malloc(1024);
132 i->buffersize = 1024;
134 int ringbuffer_read(ringbuffer_t*r, void*buf, int len)
136 unsigned char* data = (unsigned char*)buf;
137 ringbuffer_internal_t*i = (ringbuffer_internal_t*)r->internal;
138 if(r->available < len)
139 len = r->available;
140 if(!len)
141 return 0;
142 if(i->readpos + len > i->buffersize) {
143 int read1 = i->buffersize-i->readpos;
144 memcpy(data, &i->buffer[i->readpos], read1);
145 memcpy(&data[read1], &i->buffer[0], len - read1);
146 i->readpos = len - read1;
147 } else {
148 memcpy(data, &i->buffer[i->readpos], len);
149 i->readpos += len;
150 i->readpos %= i->buffersize;
152 r->available -= len;
153 return len;
155 void ringbuffer_put(ringbuffer_t*r, void*buf, int len)
157 unsigned char* data = (unsigned char*)buf;
158 ringbuffer_internal_t*i = (ringbuffer_internal_t*)r->internal;
160 if(i->buffersize - r->available < len)
162 unsigned char* buf2;
163 int newbuffersize = i->buffersize;
164 int oldavailable = r->available;
165 newbuffersize*=3;newbuffersize/=2; /*grow at least by 50% each time */
167 if(newbuffersize < r->available + len)
168 newbuffersize = r->available + len + 1024;
170 buf2 = (unsigned char*)malloc(newbuffersize);
171 ringbuffer_read(r, buf2, r->available);
172 free(i->buffer);
173 i->buffer = buf2;
174 i->buffersize = newbuffersize;
175 i->readpos = 0;
176 i->writepos = oldavailable;
177 r->available = oldavailable;
179 if(i->writepos + len > i->buffersize) {
180 int read1 = i->buffersize-i->writepos;
181 memcpy(&i->buffer[i->writepos], data, read1);
182 memcpy(&i->buffer[0], &data[read1], len - read1);
183 i->writepos = len - read1;
184 } else {
185 memcpy(&i->buffer[i->writepos], data, len);
186 i->writepos += len;
187 i->writepos %= i->buffersize;
189 r->available += len;
191 void ringbuffer_clear(ringbuffer_t*r)
193 ringbuffer_internal_t*i = (ringbuffer_internal_t*)r->internal;
194 free(i->buffer);i->buffer = 0;
195 free(i);
198 // ------------------------------- string_t -----------------------------------
200 void string_set2(string_t*str, char*text, int len)
202 str->len = len;
203 str->str = text;
205 void string_set(string_t*str, char*text)
207 str->len = strlen(text);
208 str->str = text;
210 void string_dup2(string_t*str, const char*text, int len)
212 str->len = len;
213 str->str = strdup_n(text, len);
215 void string_dup(string_t*str, const char*text)
217 str->len = strlen(text);
218 str->str = strdup(text);
220 int string_equals(string_t*str, const char*text)
222 int l = strlen(text);
223 if(str->len == l && !strncmp(str->str, text, l))
224 return 1;
225 return 0;
227 int string_equals2(string_t*str, string_t*str2)
229 if(str->len == str2->len && !strncmp(str->str, str2->str, str->len))
230 return 1;
231 return 0;
233 char* string_cstr(string_t*str)
235 return strdup_n(str->str, str->len);
238 // ------------------------------- stringarray_t ------------------------------
240 typedef struct _stringarray_internal_t
242 mem_t data;
243 mem_t pos;
244 int num;
245 } stringarray_internal_t;
246 void stringarray_init(stringarray_t*sa)
248 stringarray_internal_t*s;
249 sa->internal = (stringarray_internal_t*)malloc(sizeof(stringarray_internal_t));
250 memset(sa->internal, 0, sizeof(stringarray_internal_t));
251 s = (stringarray_internal_t*)sa->internal;
252 mem_init(&s->data);
253 mem_init(&s->pos);
255 void stringarray_put(stringarray_t*sa, string_t str)
257 stringarray_internal_t*s = (stringarray_internal_t*)sa->internal;
258 int pos;
259 pos = mem_putstring(&s->data, str);
260 mem_put(&s->pos, &pos, sizeof(int));
261 s->num++;
263 char* stringarray_at(stringarray_t*sa, int pos)
265 stringarray_internal_t*s = (stringarray_internal_t*)sa->internal;
266 int p;
267 if(pos<0 || pos>=s->num)
268 return 0;
269 p = *(int*)&s->pos.buffer[pos*sizeof(int)];
270 if(p<0)
271 return 0;
272 return &s->data.buffer[p];
274 string_t stringarray_at2(stringarray_t*sa, int pos)
276 string_t s;
277 s.str = stringarray_at(sa, pos);
278 s.len = s.str?strlen(s.str):0;
279 return s;
281 void stringarray_del(stringarray_t*sa, int pos)
283 stringarray_internal_t*s = (stringarray_internal_t*)sa->internal;
284 *(int*)&s->pos.buffer[pos*sizeof(int)] = -1;
286 int stringarray_find(stringarray_t*sa, string_t* str)
288 stringarray_internal_t*s = (stringarray_internal_t*)sa->internal;
289 int t;
290 for(t=0;t<s->num;t++) {
291 string_t s = stringarray_at2(sa, t);
292 if(s.str && string_equals2(&s, str)) {
293 return t;
296 return -1;
298 void stringarray_clear(stringarray_t*sa)
300 stringarray_internal_t*s = (stringarray_internal_t*)sa->internal;
301 mem_clear(&s->data);
302 mem_clear(&s->pos);
303 free(s);
305 void stringarray_destroy(stringarray_t*sa)
307 stringarray_clear(sa);
308 free(sa);
312 // ------------------------------- map_t --------------------------------------
314 typedef struct _map_internal_t
316 stringarray_t keys;
317 stringarray_t values;
318 int num;
319 } map_internal_t;
321 void map_init(map_t*map)
323 map_internal_t*m;
324 map->internal = (map_internal_t*)malloc(sizeof(map_internal_t));
325 memset(map->internal, 0, sizeof(map_internal_t));
326 m = (map_internal_t*)map->internal;
327 stringarray_init(&m->keys);
328 stringarray_init(&m->values);
330 void map_put(map_t*map, string_t t1, string_t t2)
332 map_internal_t*m = (map_internal_t*)map->internal;
333 stringarray_put(&m->keys, t1);
334 stringarray_put(&m->values, t2);
335 m->num++;
337 char* map_lookup(map_t*map, const char*name)
339 int s;
340 map_internal_t*m = (map_internal_t*)map->internal;
341 string_t str;
342 string_set(&str, (char*)name);
343 s = stringarray_find(&m->keys, &str);
344 if(s>=0) {
345 string_t s2 = stringarray_at2(&m->values, s);
346 return s2.str;
348 return 0;
350 void map_dump(map_t*map, FILE*fi, const char*prefix)
352 int t;
353 map_internal_t*m = (map_internal_t*)map->internal;
354 for(t=0;t<m->num;t++) {
355 string_t s1 = stringarray_at2(&m->keys, t);
356 string_t s2 = stringarray_at2(&m->values, t);
357 fprintf(fi, "%s%s=%s\n", prefix, s1.str, s2.str);
360 void map_clear(map_t*map)
362 map_internal_t*m = (map_internal_t*)map->internal;
363 stringarray_clear(&m->keys);
364 stringarray_clear(&m->values);
365 free(m);
367 void map_destroy(map_t*map)
369 map_clear(map);
370 free(map);
373 // ------------------------------- dictionary_t -------------------------------
375 typedef struct _dictionary_internal_t
377 stringarray_t keys;
378 mem_t values;
379 int num;
380 } dictionary_internal_t;
382 void dictionary_init(dictionary_t*dict)
384 dictionary_internal_t*d;
385 dict->internal = (dictionary_internal_t*)malloc(sizeof(dictionary_internal_t));
386 memset(dict->internal, 0, sizeof(dictionary_internal_t));
387 d = (dictionary_internal_t*)dict->internal;
388 stringarray_init(&d->keys);
389 mem_init(&d->values);
391 void dictionary_put(dictionary_t*dict, string_t t1, void* t2)
393 dictionary_internal_t*d = (dictionary_internal_t*)dict->internal;
394 int s=0;
395 s = stringarray_find(&d->keys, &t1);
396 if(s>=0) {
397 /* replace */
398 *(void**)(&d->values.buffer[s*sizeof(void*)]) = t2;
399 } else {
400 stringarray_put(&d->keys, t1);
401 mem_put(&d->values, &t2, sizeof(void*));
402 d->num++;
405 void dictionary_put2(dictionary_t*dict, const char*t1, void* t2)
407 string_t s;
408 string_set(&s, (char*)t1);
409 dictionary_put(dict, s, t2);
411 void* dictionary_lookup(dictionary_t*dict, const char*name)
413 int s;
414 dictionary_internal_t*d = (dictionary_internal_t*)dict->internal;
415 string_t str;
416 string_set(&str, (char*)name);
417 s = stringarray_find(&d->keys, &str);
418 if(s>=0) {
419 return *(void**)&d->values.buffer[sizeof(void*)*s];
421 return 0;
423 void dictionary_dump(dictionary_t*dict, FILE*fi, const char*prefix)
425 dictionary_internal_t*d = (dictionary_internal_t*)dict->internal;
426 int t;
427 for(t=0;t<d->num;t++) {
428 string_t s1 = stringarray_at2(&d->keys, t);
429 fprintf(fi, "%s%s=%08x\n", prefix, s1.str, *(void**)&d->values.buffer[sizeof(void*)*t]);
432 void dictionary_del(dictionary_t*dict, const char* name)
434 dictionary_internal_t*d = (dictionary_internal_t*)dict->internal;
435 int s;
436 string_t str;
437 string_set(&str, (char*)name);
438 s = stringarray_find(&d->keys, &str);
439 if(s>=0) {
440 *(void**)(&d->values.buffer[s*sizeof(void*)]) = 0;
441 stringarray_del(&d->keys, s);
444 void dictionary_clear(dictionary_t*dict)
446 dictionary_internal_t*d = (dictionary_internal_t*)dict->internal;
447 stringarray_clear(&d->keys);
448 mem_clear(&d->values);
449 free(d);
451 void dictionary_destroy(dictionary_t*dict)
453 dictionary_clear(dict);
454 free(dict);