X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fq.c;h=9bdcdf07cdf0524a1f45b7663b07fdc85b37d5ed;hb=0145b57ec3f740ab015cc314835d18a59ea1748e;hp=221ea5af9e7dc2218ebb8a6d13523ab5c8e37033;hpb=54404e00634570d9d7e37f45969c1c9317a2e82e;p=swftools.git diff --git a/lib/q.c b/lib/q.c index 221ea5a..9bdcdf0 100644 --- a/lib/q.c +++ b/lib/q.c @@ -318,10 +318,72 @@ string_t string_new2(const char*text) s.str = text; return s; } +string_t* string_new3(const char*text, int len) +{ + if(!text) { + string_t*s = malloc(sizeof(string_t)); + s->len = 0; + s->str = 0; + return s; + } else { + string_t*s = malloc(sizeof(string_t)+len+1); + s->len = len; + s->str = (const char*)(s+1); + memcpy((char*)s->str, text, len); + ((char*)s->str)[len]=0; + return s; + } +} +string_t* string_new4(const char*text) +{ + int l = strlen(text); + return string_new3(text, l); +} + +void string_free(string_t*s) +{ + if(!s) + return; + s->len = 0; + if((string_t*)(s->str) == s+1) { + s->str = 0; + rfx_free(s); + } else { + rfx_free((char*)(s->str)); + s->str = 0; + rfx_free(s); + } +} char* string_cstr(string_t*str) { return strdup_n(str->str, str->len); } +char* string_escape(string_t*str) +{ + int t; + int len = 0; + for(t=0;tlen;t++) { + if(str->str[t]<0x20) + len+=3; + else + len++; + } + char*s = malloc(len+1); + char*p=s; + for(t=0;tlen;t++) { + if(str->str[t]<0x20) { + *p++ ='\\'; + unsigned char c = str->str[t]; + *p++ = "0123456789abcdef"[c>>4]; + *p++ = "0123456789abcdef"[c&0x0f]; + } else { + *p++ = str->str[t]; + } + } + *p++ = 0; + assert(p == &s[len+1]); + return s; +} unsigned int crc32_add_byte(unsigned int checksum, unsigned char b) { @@ -331,10 +393,12 @@ unsigned int crc32_add_byte(unsigned int checksum, unsigned char b) } unsigned int crc32_add_string(unsigned int checksum, const char*s) { + if(!crc32) + crc32_init(); if(!s) return checksum; while(*s) { - checksum = crc32_add_byte(checksum, *s); + checksum = checksum>>8 ^ crc32[(*s^checksum)&0xff]; s++; } return checksum; @@ -523,6 +587,23 @@ void stringarray_destroy(stringarray_t*sa) // ------------------------------- type_t ------------------------------- +char ptr_equals(const void*o1, const void*o2) +{ + return o1==o2; +} +unsigned int ptr_hash(const void*o) +{ + return string_hash3(o, sizeof(o)); +} +void* ptr_dup(const void*o) +{ + return (void*)o; +} +void ptr_free(void*o) +{ + return; +} + char charptr_equals(const void*o1, const void*o2) { if(!o1 || !o2) @@ -547,8 +628,11 @@ void charptr_free(void*o) rfx_free(o); } } + char stringstruct_equals(const void*o1, const void*o2) { + if(!o1 || !o2) + return o1==o2; string_t*s1 = (string_t*)o1; string_t*s2 = (string_t*)o2; int l = s1->lenlen?s1->len:s2->len; @@ -560,20 +644,37 @@ char stringstruct_equals(const void*o1, const void*o2) } unsigned int stringstruct_hash(const void*o) { + if(!o) return 0; return string_hash(o); } -void*stringstruct_dup(const void*o) +string_t*string_dup3(string_t*o) { - string_t*s = malloc(sizeof(string_t)); - string_set2(s, ((string_t*)o)->str, ((string_t*)o)->len); + if(!o) return 0; + if(!o->str) { + string_t*s = malloc(sizeof(string_t)); + s->str=0; + s->len=0; + return s; + } + string_t*s = rfx_alloc(sizeof(string_t)+o->len+1); + s->len = o->len; + s->str = (const char*)(s+1); + memcpy((char*)s->str, o->str, s->len); + ((char*)s->str)[s->len]=0; return s; } void stringstruct_free(void*o) { - rfx_free((void*)(((string_t*)o)->str)); - rfx_free((void*)o); + if(o) + string_free(o); } +type_t ptr_type = { + equals: ptr_equals, + hash: ptr_hash, + dup: ptr_dup, + free: ptr_free, +}; type_t charptr_type = { equals: charptr_equals, @@ -585,7 +686,7 @@ type_t charptr_type = { type_t stringstruct_type = { equals: stringstruct_equals, hash: stringstruct_hash, - dup: stringstruct_dup, + dup: (dup_func)string_dup3, free: stringstruct_free, }; @@ -701,10 +802,11 @@ int dict_count(dict_t*h) return h->num; } -void* dict_lookup(dict_t*h, const void*key) +static inline dictentry_t* dict_do_lookup(dict_t*h, const void*key) { - if(!h->num) + if(!h->num) { return 0; + } unsigned int ohash = h->key_type->hash(key); unsigned int hash = ohash % h->hashsize; @@ -712,7 +814,7 @@ void* dict_lookup(dict_t*h, const void*key) /* check first entry for match */ dictentry_t*e = h->slots[hash]; if(e && h->key_type->equals(e->key, key)) { - return e->data; + return e; } else if(e) { e = e->next; } @@ -728,17 +830,42 @@ void* dict_lookup(dict_t*h, const void*key) dict_expand(h, newsize); hash = ohash % h->hashsize; e = h->slots[hash]; + if(e && h->key_type->equals(e->key, key)) { + // omit move to front + return e; + } else if(e) { + e = e->next; + } } /* check subsequent entries for a match */ + dictentry_t*last = h->slots[hash]; while(e) { if(h->key_type->equals(e->key, key)) { - return e->data; + /* move to front- makes a difference of about 10% in most applications */ + last->next = e->next; + e->next = h->slots[hash]; + h->slots[hash] = e; + return e; } + last=e; e = e->next; } return 0; } +void* dict_lookup(dict_t*h, const void*key) +{ + dictentry_t*e = dict_do_lookup(h, key); + if(e) + return e->data; + return 0; +} +char dict_contains(dict_t*h, const void*key) +{ + dictentry_t*e = dict_do_lookup(h, key); + return !!e; +} + char dict_del(dict_t*h, const void*key) { if(!h->num) @@ -1004,6 +1131,20 @@ int list_length_(void*_list) return 0; return l->info[0].size; } +void list_concat_(void*_l1, void*_l2) +{ + commonlist_t**l1 = (commonlist_t**)_l1; + commonlist_t**l2 = (commonlist_t**)_l2; + + if(!*l1) { + *l1 = *l2; + } else if(*l2) { + (*l1)->info[0].last->next = *l2; + (*l1)->info[0].last = (*l2)->info[0].last; + (*l1)->info[0].size += (*l2)->info[0].size; + } + *l2 = 0; +} void list_append_(void*_list, void*entry) { commonlist_t**list = (commonlist_t**)_list;