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;t<str->len;t++) {
+ if(str->str[t]<0x20)
+ len+=3;
+ else
+ len++;
+ }
+ char*s = malloc(len+1);
+ char*p=s;
+ for(t=0;t<str->len;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)
{
}
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;
// ------------------------------- 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)
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->len<s2->len?s1->len:s2->len;
}
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,
type_t stringstruct_type = {
equals: stringstruct_equals,
hash: stringstruct_hash,
- dup: stringstruct_dup,
+ dup: (dup_func)string_dup3,
free: stringstruct_free,
};
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;
/* 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;
}
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)
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;