X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fq.c;h=8c67d06e0275525cbd90e12bab3f82ba68efbdeb;hb=b1993c38d9f4ba57943c607b2151eca7d1c125b7;hp=221ea5af9e7dc2218ebb8a6d13523ab5c8e37033;hpb=54404e00634570d9d7e37f45969c1c9317a2e82e;p=swftools.git diff --git a/lib/q.c b/lib/q.c index 221ea5a..8c67d06 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) { @@ -523,6 +585,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 +626,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 +642,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 +684,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 +800,12 @@ int dict_count(dict_t*h) return h->num; } -void* dict_lookup(dict_t*h, const void*key) +void dict_do_lookup(dict_t*h, const void*key, void***match) { - if(!h->num) - return 0; + if(!h->num) { + *match = 0; + return; + } unsigned int ohash = h->key_type->hash(key); unsigned int hash = ohash % h->hashsize; @@ -712,7 +813,8 @@ 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; + *match = &e->data; + return; } else if(e) { e = e->next; } @@ -733,12 +835,28 @@ void* dict_lookup(dict_t*h, const void*key) /* check subsequent entries for a match */ while(e) { if(h->key_type->equals(e->key, key)) { - return e->data; + *match = &e->data; + return; } e = e->next; } + *match = 0; +} +void* dict_lookup(dict_t*h, const void*key) +{ + void**data = 0; + dict_do_lookup(h, key, &data); + if(data) + return *data; return 0; } +char dict_contains(dict_t*h, const void*key) +{ + void**data = 0; + dict_do_lookup(h, key, &data); + return !!data; +} + char dict_del(dict_t*h, const void*key) { if(!h->num)