swfc initial revision.
[swftools.git] / src / q.c
1 /* q.c
2
3    Part of the swftools package.
4    
5    Copyright (c) 2001 Matthias Kramm <kramm@quiss.org>
6
7    This file is distributed under the GPL, see file COPYING for details */
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <memory.h>
12 #include "q.h"
13
14 // ------------------------------- malloc, alloc routines ---------------------
15
16 #ifndef STRNDUP
17 char* strndup(const char*str, int size)
18 {
19     char*m = (char*)malloc(size+1);
20     memcpy(m, str, size);
21     m[size] = 0;
22     return m;
23 }
24 #endif
25 void* qmalloc_internal(int len)
26 {
27     void*val = malloc(len);
28     if(!val) {
29         printf("memory error! Couldn't reserve %d bytes\n", len);
30         fprintf(stderr, "memory error! Couldn't reserve %d bytes\n", len);
31         exit(1);
32     }
33     return val;
34 }
35 void* qrealloc_internal(void*old, int len)
36 {
37     void*val = realloc(old, len);
38     if(!val) {
39         printf("memory error! Couldn't reserve %d bytes\n", len);
40         fprintf(stderr, "memory error! Couldn't reserve %d bytes\n", len);
41         exit(1);
42     }
43     return val;
44 }
45 void qfree_internal(void*old)
46 {
47     free(old);
48 }
49 char*qstrdup(const char*string)
50 {
51     return strdup(string);
52 }
53 char*qstrndup(const char*string, int len)
54 {
55     return strndup(string, len);
56 }
57
58 // ------------------------------- mem_t --------------------------------------
59
60 void mem_init(mem_t*mem)
61 {
62     memset(mem, 0, sizeof(mem_t));
63 }
64 void mem_clear(mem_t*mem)
65 {
66     free(mem->buffer);
67 }
68 void mem_destroy(mem_t*mem)
69 {
70     mem_clear(mem);
71     free(mem);
72 }
73 static int mem_put_(mem_t*m,void*data, int length, int null)
74 {
75     int n = m->pos;
76     m->pos += length + (null?1:0);
77     if(m->pos > m->len)
78     { 
79         //m->len += 1024>length?1024:(null?length*2:length);
80
81         m->len *= 2;
82         while(m->len < m->pos)
83             m->len += 64;
84
85         m->buffer = m->buffer?realloc(m->buffer,m->len):malloc(m->len);
86     }
87     memcpy(&m->buffer[n], data, length);
88     if(null)
89         m->buffer[n + length] = 0;
90     return n;
91 }
92 int mem_put(mem_t*m,void*data, int length)
93 {
94     return mem_put_(m, data, length, 0);
95 }
96 int mem_putstring(mem_t*m,string_t str)
97 {
98     return mem_put_(m, str.str, str.len, 1);
99 }
100
101 // ------------------------------- string_t ------------------------------------
102
103 void string_set2(string_t*str, char*text, int len)
104 {
105     str->len = len;
106     str->str = text;
107 }
108 void string_set(string_t*str, char*text)
109 {
110     str->len = strlen(text);
111     str->str = text;
112 }
113 void string_dup2(string_t*str, const char*text, int len)
114 {
115     str->len = len;
116     str->str = strndup(text, len);
117 }
118 void string_dup(string_t*str, const char*text)
119 {
120     str->len = strlen(text);
121     str->str = strdup(text);
122 }
123 int string_equals(string_t*str, const char*text)
124 {
125     int l = strlen(text);
126     if(str->len == l && !strncmp(str->str, text, l))
127         return 1;
128     return 0;
129 }
130 int string_equals2(string_t*str, string_t*str2)
131 {
132     if(str->len == str2->len && !strncmp(str->str, str2->str, str->len))
133         return 1;
134     return 0;
135 }
136 char* string_cstr(string_t*str)
137 {
138     return strndup(str->str, str->len);
139 }
140
141 // ------------------------------- stringarray_t ------------------------------
142
143 typedef struct _stringarray_internal_t
144 {
145     mem_t data;
146     mem_t pos;
147     int num;
148 } stringarray_internal_t;
149 void stringarray_init(stringarray_t*sa)
150 {
151     stringarray_internal_t*s;
152     sa->internal = (stringarray_internal_t*)malloc(sizeof(stringarray_internal_t)); 
153     memset(sa->internal, 0, sizeof(stringarray_internal_t));
154     s = (stringarray_internal_t*)sa->internal;
155     mem_init(&s->data);
156     mem_init(&s->pos);
157 }
158 void stringarray_put(stringarray_t*sa, string_t str)
159 {
160     stringarray_internal_t*s = (stringarray_internal_t*)sa->internal;
161     int pos;
162     pos = mem_putstring(&s->data, str);
163     mem_put(&s->pos, &pos, sizeof(int));
164     s->num++;
165 }
166 char* stringarray_at(stringarray_t*sa, int pos)
167 {
168     stringarray_internal_t*s = (stringarray_internal_t*)sa->internal;
169     int p;
170     if(pos<0 || pos>=s->num)
171         return 0;
172     p = *(int*)&s->pos.buffer[pos*sizeof(int)];
173     if(p<0)
174         return 0;
175     return &s->data.buffer[p];
176 }
177 string_t stringarray_at2(stringarray_t*sa, int pos)
178 {
179     string_t s;
180     s.str = stringarray_at(sa, pos);
181     s.len = s.str?strlen(s.str):0;
182     return s;
183 }
184 void stringarray_del(stringarray_t*sa, int pos)
185 {
186     stringarray_internal_t*s = (stringarray_internal_t*)sa->internal;
187     *(int*)&s->pos.buffer[pos*sizeof(int)] = -1;
188 }
189 int stringarray_find(stringarray_t*sa, string_t* str)
190 {
191     stringarray_internal_t*s = (stringarray_internal_t*)sa->internal;
192     int t;
193     for(t=0;t<s->num;t++) {
194         string_t s = stringarray_at2(sa, t);
195         if(s.str && string_equals2(&s, str)) {
196             return t;
197         }
198     }
199     return -1;
200 }
201 void stringarray_clear(stringarray_t*sa)
202 {
203     stringarray_internal_t*s = (stringarray_internal_t*)sa->internal;
204     mem_clear(&s->data);
205     mem_clear(&s->pos);
206     free(s);
207 }
208 void stringarray_destroy(stringarray_t*sa)
209 {
210     stringarray_clear(sa);
211     free(sa);
212 }
213
214
215 // ------------------------------- map_t --------------------------------------
216
217 typedef struct _map_internal_t
218 {
219     stringarray_t keys;
220     stringarray_t values;
221     int num;
222 } map_internal_t;
223
224 void map_init(map_t*map)
225 {
226     map_internal_t*m;
227     map->internal = (map_internal_t*)malloc(sizeof(map_internal_t));
228     memset(map->internal, 0, sizeof(map_internal_t));
229     m = (map_internal_t*)map->internal;
230     stringarray_init(&m->keys);
231     stringarray_init(&m->values);
232 }
233 void map_put(map_t*map, string_t t1, string_t t2)
234 {
235     map_internal_t*m = (map_internal_t*)map->internal;
236     stringarray_put(&m->keys, t1);
237     stringarray_put(&m->values, t2);
238     m->num++;
239 }
240 char* map_lookup(map_t*map, const char*name)
241 {
242     int s;
243     map_internal_t*m = (map_internal_t*)map->internal;
244     string_t str;
245     string_set(&str, (char*)name);
246     s = stringarray_find(&m->keys, &str);
247     if(s>=0) {
248         string_t s2 = stringarray_at2(&m->values, s);
249         return s2.str;
250     }
251     return 0;
252 }
253 void map_dump(map_t*map, FILE*fi, const char*prefix)
254 {
255     int t;
256     map_internal_t*m = (map_internal_t*)map->internal;
257     for(t=0;t<m->num;t++) {
258         string_t s1 = stringarray_at2(&m->keys, t);
259         string_t s2 = stringarray_at2(&m->values, t);
260         fprintf(fi, "%s%s=%s\n", prefix, s1.str, s2.str);
261     }
262 }
263 void map_clear(map_t*map)
264 {
265     map_internal_t*m = (map_internal_t*)map->internal;
266     stringarray_clear(&m->keys);
267     stringarray_clear(&m->values);
268     free(m);
269 }
270 void map_destroy(map_t*map)
271 {
272     map_clear(map);
273     free(map);
274 }
275
276 // ------------------------------- dictionary_t --------------------------------------
277
278 typedef struct _dictionary_internal_t
279 {
280     stringarray_t keys;
281     mem_t values;
282     int num;
283 } dictionary_internal_t;
284
285 void dictionary_init(dictionary_t*dict)
286 {
287     dictionary_internal_t*d;
288     dict->internal = (dictionary_internal_t*)malloc(sizeof(dictionary_internal_t));
289     memset(dict->internal, 0, sizeof(dictionary_internal_t));
290     d = (dictionary_internal_t*)dict->internal;
291     stringarray_init(&d->keys);
292     mem_init(&d->values);
293 }
294 void dictionary_put(dictionary_t*dict, string_t t1, void* t2)
295 {
296     dictionary_internal_t*d = (dictionary_internal_t*)dict->internal;
297     int s=0;
298     s = stringarray_find(&d->keys, &t1);
299     if(s>=0) {
300         /* replace */
301         *(void**)(&d->values.buffer[s*sizeof(void*)]) = t2;
302     } else {
303         stringarray_put(&d->keys, t1);
304         mem_put(&d->values, &t2, sizeof(void*));
305         d->num++;
306     }
307 }
308 void dictionary_put2(dictionary_t*dict, const char*t1, void* t2)
309 {
310     string_t s;
311     string_set(&s, (char*)t1);
312     dictionary_put(dict, s, t2);
313 }
314 void* dictionary_lookup(dictionary_t*dict, const char*name)
315 {
316     int s;
317     dictionary_internal_t*d = (dictionary_internal_t*)dict->internal;
318     string_t str;
319     string_set(&str, (char*)name);
320     s = stringarray_find(&d->keys, &str);
321     if(s>=0) {
322         return *(void**)&d->values.buffer[sizeof(void*)*s];
323     }
324     return 0;
325 }
326 void dictionary_dump(dictionary_t*dict, FILE*fi, const char*prefix)
327 {
328     dictionary_internal_t*d = (dictionary_internal_t*)dict->internal;
329     int t;
330     for(t=0;t<d->num;t++) {
331         string_t s1 = stringarray_at2(&d->keys, t);
332         fprintf(fi, "%s%s=%08x\n", prefix, s1.str, *(void**)&d->values.buffer[sizeof(void*)*t]);
333     }
334 }
335 void dictionary_del(dictionary_t*dict, const char* name)
336 {
337     dictionary_internal_t*d = (dictionary_internal_t*)dict->internal;
338     int s;
339     string_t str;
340     string_set(&str, (char*)name);
341     s = stringarray_find(&d->keys, &str);
342     if(s>=0) {
343         *(void**)(&d->values.buffer[s*sizeof(void*)]) = 0;
344         stringarray_del(&d->keys, s);
345     }
346 }
347 void dictionary_clear(dictionary_t*dict)
348 {
349     dictionary_internal_t*d = (dictionary_internal_t*)dict->internal;
350     stringarray_clear(&d->keys);
351     mem_clear(&d->values);
352     free(d);
353 }
354 void dictionary_destroy(dictionary_t*dict)
355 {
356     dictionary_clear(dict);
357     free(dict);
358 }