3 Part of the swftools package.
5 Copyright (c) 2001,2002,2003,2004 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 */
28 // ------------------------------- malloc, alloc routines ---------------------
31 char* strdup_n(const char*str, int size)
33 char*m = (char*)malloc(size+1);
39 char*qstrdup(const char*string)
41 return strdup(string);
43 char*qstrndup(const char*string, int len)
45 return strdup_n(string, len);
48 // ------------------------------- mem_t --------------------------------------
50 void mem_init(mem_t*mem)
52 memset(mem, 0, sizeof(mem_t));
54 void mem_clear(mem_t*mem)
56 free(mem->buffer);mem->buffer = 0;
58 void mem_destroy(mem_t*mem)
63 static int mem_put_(mem_t*m,const void*data, int length, int null)
66 m->pos += length + (null?1:0);
68 m->len = (m->pos+63)&~63;
69 m->buffer = m->buffer?(char*)realloc(m->buffer,m->len):(char*)malloc(m->len);
71 memcpy(&m->buffer[n], data, length);
73 m->buffer[n + length] = 0;
76 int mem_put(mem_t*m,void*data, int length)
78 return mem_put_(m, data, length, 0);
80 int mem_putstring(mem_t*m,string_t str)
82 return mem_put_(m, str.str, str.len, 1);
85 // ------------------------------- ringbuffer_t -------------------------------
87 typedef struct _ringbuffer_internal_t
93 } ringbuffer_internal_t;
95 void ringbuffer_init(ringbuffer_t*r)
97 ringbuffer_internal_t*i = (ringbuffer_internal_t*)malloc(sizeof(ringbuffer_internal_t));
98 memset(r, 0, sizeof(ringbuffer_t));
99 memset(i, 0, sizeof(ringbuffer_internal_t));
101 i->buffer = (unsigned char*)malloc(1024);
102 i->buffersize = 1024;
104 int ringbuffer_read(ringbuffer_t*r, void*buf, int len)
106 unsigned char* data = (unsigned char*)buf;
107 ringbuffer_internal_t*i = (ringbuffer_internal_t*)r->internal;
108 if(r->available < len)
112 if(i->readpos + len > i->buffersize) {
113 int read1 = i->buffersize-i->readpos;
114 memcpy(data, &i->buffer[i->readpos], read1);
115 memcpy(&data[read1], &i->buffer[0], len - read1);
116 i->readpos = len - read1;
118 memcpy(data, &i->buffer[i->readpos], len);
120 i->readpos %= i->buffersize;
125 void ringbuffer_put(ringbuffer_t*r, void*buf, int len)
127 unsigned char* data = (unsigned char*)buf;
128 ringbuffer_internal_t*i = (ringbuffer_internal_t*)r->internal;
130 if(i->buffersize - r->available < len)
133 int newbuffersize = i->buffersize;
134 int oldavailable = r->available;
135 newbuffersize*=3;newbuffersize/=2; /*grow at least by 50% each time */
137 if(newbuffersize < r->available + len)
138 newbuffersize = r->available + len + 1024;
140 buf2 = (unsigned char*)malloc(newbuffersize);
141 ringbuffer_read(r, buf2, r->available);
144 i->buffersize = newbuffersize;
146 i->writepos = oldavailable;
147 r->available = oldavailable;
149 if(i->writepos + len > i->buffersize) {
150 int read1 = i->buffersize-i->writepos;
151 memcpy(&i->buffer[i->writepos], data, read1);
152 memcpy(&i->buffer[0], &data[read1], len - read1);
153 i->writepos = len - read1;
155 memcpy(&i->buffer[i->writepos], data, len);
157 i->writepos %= i->buffersize;
161 void ringbuffer_clear(ringbuffer_t*r)
163 ringbuffer_internal_t*i = (ringbuffer_internal_t*)r->internal;
164 free(i->buffer);i->buffer = 0;
168 // ------------------------------- heap_t -------------------------------
170 void heap_init(heap_t*h,int n,int elem_size, int(*compare)(const void *, const void *))
172 memset(h, 0, sizeof(heap_t));
175 h->elem_size = elem_size;
176 h->compare = compare;
177 h->elements = (void**)malloc(n*sizeof(void*));memset(h->elements, 0, n*sizeof(void*));
178 h->data = (char*)malloc(h->max_size*h->elem_size);memset(h->data, 0, h->max_size*h->elem_size);
180 void heap_clear(heap_t*h)
186 #define HEAP_NODE_SMALLER(h,node1,node2) ((h)->compare((node1),(node2))>0)
188 static void up(heap_t*h, int node)
190 void*node_p = h->elements[node];
196 h->elements[node] = h->elements[parent];
197 } while(HEAP_NODE_SMALLER(h,h->elements[parent], node_p));
199 h->elements[node] = node_p;
201 static void down(heap_t*h, int node)
203 void*node_p = h->elements[node];
208 /* determine new child's position */
212 if(child+1 < h->size && HEAP_NODE_SMALLER(h,h->elements[child],h->elements[child+1])) // search for bigger child
215 h->elements[node] = h->elements[child];
216 } while(HEAP_NODE_SMALLER(h,node_p, h->elements[child]));
218 h->elements[node] = node_p;
220 void heap_put(heap_t*h, void*e)
223 memcpy(&h->data[pos*h->elem_size],e,h->elem_size);
224 h->elements[pos] = &h->data[pos];
227 int heap_size(heap_t*h)
231 void* heap_max(heap_t*h)
233 return h->elements[0];
235 void* heap_chopmax(heap_t*h)
237 void*p = h->elements[0];
238 h->elements[0] = h->elements[--h->size];
242 void heap_dump(heap_t*h, FILE*fi)
245 for(t=0;t<h->size;t++) {
247 for(s=0;s<=t;s=(s+1)*2-1) {
248 if(s==t) fprintf(fi,"\n");
250 //fprintf(fi,"%d ", h->elements[t]->x); //?
253 void** heap_flatten(heap_t*h)
255 void**nodes = (void**)malloc(h->size*sizeof(void*));
259 /*printf("Heap Size: %d\n", h->size);
260 heap_print(stdout, h);
262 *p++ = heap_chopmax(h);
267 // ------------------------------- crc32 --------------------------------------
268 static unsigned int*crc32 = 0;
269 static void crc32_init(void)
274 crc32= (unsigned int*)malloc(sizeof(unsigned int)*256);
275 for(t=0; t<256; t++) {
278 for (s = 0; s < 8; s++) {
279 c = (0xedb88320L*(c&1)) ^ (c >> 1);
284 // ------------------------------- string_t -----------------------------------
286 void string_set2(string_t*str, const char*text, int len)
291 void string_set(string_t*str, const char*text)
293 str->len = strlen(text);
296 string_t string_new(const char*text, int len)
303 string_t string_new2(const char*text)
306 s.len = strlen(text);
310 unsigned int string_hash(string_t*str)
313 unsigned int checksum = 0;
316 for(t=0;t<str->len;t++) {
317 checksum = checksum>>8 ^ crc32[(str->str[t]^checksum)&0xff];
321 unsigned int string_hash2(const char*str)
323 unsigned int checksum = 0;
327 checksum = checksum>>8 ^ crc32[(*str^checksum)&0xff];
332 void string_dup2(string_t*str, const char*text, int len)
335 str->str = strdup_n(text, len);
337 void string_dup(string_t*str, const char*text)
339 str->len = strlen(text);
340 str->str = strdup(text);
342 int string_equals(string_t*str, const char*text)
344 int l = strlen(text);
345 if(str->len == l && !memcmp(str->str, text, l))
349 int string_equals2(string_t*str, string_t*str2)
351 if(str->len == str2->len && !memcmp(str->str, str2->str, str->len))
355 char* string_cstr(string_t*str)
357 return strdup_n(str->str, str->len);
360 // ------------------------------- stringarray_t ------------------------------
362 #define DEFAULT_HASH_SIZE 257
364 typedef struct _stringlist {
366 struct _stringlist*next;
369 typedef struct _stringarray_internal_t
375 } stringarray_internal_t;
377 void stringarray_init(stringarray_t*sa, int hashsize)
379 stringarray_internal_t*s;
381 sa->internal = (stringarray_internal_t*)malloc(sizeof(stringarray_internal_t));
382 memset(sa->internal, 0, sizeof(stringarray_internal_t));
383 s = (stringarray_internal_t*)sa->internal;
385 s->hash = malloc(sizeof(stringlist_t*)*hashsize);
386 memset(s->hash, 0, sizeof(stringlist_t*)*hashsize);
387 s->hashsize = hashsize;
389 void stringarray_put(stringarray_t*sa, string_t str)
391 stringarray_internal_t*s = (stringarray_internal_t*)sa->internal;
393 int hash = string_hash(&str) % s->hashsize;
395 char*ss = string_cstr(&str);
396 mem_put(&s->pos, &ss, sizeof(char*));
398 stringlist_t*l = malloc(sizeof(stringlist_t));
400 l->next = s->hash[hash];
405 char* stringarray_at(stringarray_t*sa, int pos)
407 stringarray_internal_t*s = (stringarray_internal_t*)sa->internal;
409 if(pos<0 || pos>=s->num)
411 p = *(char**)&s->pos.buffer[pos*sizeof(char*)];
416 string_t stringarray_at2(stringarray_t*sa, int pos)
419 s.str = stringarray_at(sa, pos);
420 s.len = s.str?strlen(s.str):0;
423 static stringlist_t* stringlist_del(stringarray_t*sa, stringlist_t*l, int index)
426 stringlist_t*old = l;
428 if(index==l->index) {
430 memset(l, 0, sizeof(stringlist_t));
440 fprintf(stderr, "Internal error: did not find string %d in hash\n", index);
444 void stringarray_del(stringarray_t*sa, int pos)
446 stringarray_internal_t*s = (stringarray_internal_t*)sa->internal;
447 string_t str = stringarray_at2(sa, pos);
448 int hash = string_hash(&str) % s->hashsize;
449 s->hash[hash] = stringlist_del(sa, s->hash[hash], pos);
450 *(char**)&s->pos.buffer[pos*sizeof(char*)] = 0;
452 int stringarray_find(stringarray_t*sa, string_t* str)
454 stringarray_internal_t*s = (stringarray_internal_t*)sa->internal;
455 int hash = string_hash(str) % s->hashsize;
457 stringlist_t*l = s->hash[hash];
460 string_t s = stringarray_at2(sa, l->index);
461 if(string_equals2(str, &s)) {
468 void stringarray_clear(stringarray_t*sa)
470 stringarray_internal_t*s = (stringarray_internal_t*)sa->internal;
473 for(t=0;t<s->hashsize;t++) {
474 stringlist_t*l = s->hash[t];
476 stringlist_t*next = l->next;
477 memset(l, 0, sizeof(stringlist_t));
482 free(s->hash);s->hash=0;
485 void stringarray_destroy(stringarray_t*sa)
487 stringarray_clear(sa);
492 // ------------------------------- dictionary_t -------------------------------
496 dict_t*d = malloc(sizeof(dict_t));
500 void dict_init(dict_t*h)
502 memset(h, 0, sizeof(dict_t));
503 h->hashsize = DEFAULT_HASH_SIZE;
504 h->slots = malloc(sizeof(dictentry_t*)*h->hashsize);
506 memset(h->slots, 0, sizeof(dictentry_t*)*h->hashsize);
508 void dict_put(dict_t*h, string_t s, void* data)
510 unsigned int checksum = string_hash(&s) % h->hashsize;
511 dictentry_t*e = (dictentry_t*)malloc(sizeof(dictentry_t));
512 e->s = strdup(s.str);
513 e->next = h->slots[checksum];
515 h->slots[checksum] = e;
518 void dict_put2(dict_t*h, const char*s, void*data)
522 dict_put(h, s2, data);
524 void dict_dump(dict_t*h, FILE*fi, const char*prefix)
527 for(t=0;t<h->hashsize;t++) {
528 dictentry_t*e = h->slots[t];
530 fprintf(fi, "%s%s=%08x\n", prefix, e->s, e->data);
535 int dict_count(dict_t*h)
539 void* dict_lookup(dict_t*h, const char*s)
541 unsigned int checksum = string_hash2(s) % h->hashsize;
542 dictentry_t*e = h->slots[checksum];
544 if(!strcmp(e->s, s)) {
551 char dict_del(dict_t*h, const char*s)
553 unsigned int checksum = string_hash2(s) % h->hashsize;
554 dictentry_t*head = h->slots[checksum];
555 dictentry_t*e = head, *prev=0;
557 if(!strcmp(e->s, s)) {
558 dictentry_t*next = e->next;
560 memset(e, 0, sizeof(dictentry_t));
563 h->slots[checksum] = 0;
574 void dict_foreach_keyvalue(dict_t*h, void (*runFunction)(void*data, const char*key, void*val), void*data)
577 for(t=0;t<h->hashsize;t++) {
578 dictentry_t*e = h->slots[t];
580 dictentry_t*next = e->next;
582 runFunction(data, e->s, e->data);
588 void dict_foreach_value(dict_t*h, void (*runFunction)(void*))
591 for(t=0;t<h->hashsize;t++) {
592 dictentry_t*e = h->slots[t];
594 dictentry_t*next = e->next;
596 runFunction(e->data);
602 void dict_free_all(dict_t*h, void (*freeFunction)(void*))
605 for(t=0;t<h->hashsize;t++) {
606 dictentry_t*e = h->slots[t];
608 dictentry_t*next = e->next;
611 freeFunction(e->data);
613 memset(e, 0, sizeof(dictentry_t));
618 free(h->slots);h->slots = 0;
620 void dict_clear(dict_t*h)
624 void dict_destroy(dict_t*dict)
630 // ------------------------------- map_t --------------------------------------
632 typedef struct _map_internal_t
637 void map_init(map_t*map)
640 map->internal = (map_internal_t*)malloc(sizeof(map_internal_t));
641 memset(map->internal, 0, sizeof(map_internal_t));
642 m = (map_internal_t*)map->internal;
645 void map_put(map_t*map, string_t t1, string_t t2)
647 map_internal_t*m = (map_internal_t*)map->internal;
648 dict_put2(&m->d, string_cstr(&t1), (void*)string_cstr(&t2));
650 const char* map_lookup(map_t*map, const char*name)
652 map_internal_t*m = (map_internal_t*)map->internal;
653 const char*value = dict_lookup(&m->d, name);
656 void dumpmapentry(void*data, const char*key, void*value)
658 FILE*fi = (FILE*)data;
659 fprintf(fi, "%s=%s\n", key, (char*)value);
661 void map_dump(map_t*map, FILE*fi, const char*prefix)
664 map_internal_t*m = (map_internal_t*)map->internal;
665 fprintf(fi, "ERROR: map dumping not implemented yet\n");
666 dict_foreach_keyvalue(&m->d, dumpmapentry, fi);
668 void map_clear(map_t*map)
670 map_internal_t*m = (map_internal_t*)map->internal;
674 void map_destroy(map_t*map)