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(!s)
+ return checksum;
while(*s) {
checksum = crc32_add_byte(checksum, *s);
s++;
// ------------------------------- 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)
+ return o1==o2;
return !strcmp(o1,o2);
}
unsigned int charptr_hash(const void*o)
{
+ if(!o)
+ return 0;
return string_hash2(o);
}
void* charptr_dup(const void*o)
{
+ if(!o)
+ return 0;
return strdup(o);
}
void charptr_free(void*o)
{
- rfx_free(o);
+ if(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->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,
};
dict_t*dict_new()
{
dict_t*d = rfx_alloc(sizeof(dict_t));
- dict_init(d);
+ dict_init(d, INITIAL_SIZE);
return d;
}
dict_t*dict_new2(type_t*t)
{
dict_t*d = rfx_alloc(sizeof(dict_t));
- dict_init(d);
+ dict_init(d, INITIAL_SIZE);
d->key_type = t;
return d;
}
-void dict_init(dict_t*h)
+void dict_init(dict_t*h, int size)
{
memset(h, 0, sizeof(dict_t));
- h->hashsize = INITIAL_SIZE;
+ h->hashsize = size;
h->slots = h->hashsize?(dictentry_t**)rfx_calloc(sizeof(dictentry_t*)*h->hashsize):0;
h->num = 0;
h->key_type = &charptr_type;
}
+dict_t*dict_clone(dict_t*o)
+{
+ dict_t*h = rfx_alloc(sizeof(dict_t));
+ memcpy(h, o, sizeof(dict_t));
+ h->slots = h->hashsize?(dictentry_t**)rfx_calloc(sizeof(dictentry_t*)*h->hashsize):0;
+ int t;
+ for(t=0;t<o->hashsize;t++) {
+ dictentry_t*e = o->slots[t];
+ while(e) {
+ dictentry_t*n = (dictentry_t*)rfx_alloc(sizeof(dictentry_t));
+ memcpy(n, e, sizeof(dictentry_t));
+ n->key = h->key_type->dup(e->key);
+ n->data = e->data;
+ n->next = h->slots[t];
+ h->slots[t] = n;
+ e = e->next;
+ }
+ }
+ return h;
+}
+
static void dict_expand(dict_t*h, int newlen)
{
assert(h->hashsize < newlen);
for(t=0;t<h->hashsize;t++) {
dictentry_t*e = h->slots[t];
while(e) {
- if(h->key_type==&charptr_type) {
+ if(h->key_type!=&charptr_type) {
fprintf(fi, "%s%08x=%08x\n", prefix, e->key, e->data);
} else {
fprintf(fi, "%s%s=%08x\n", prefix, e->key, e->data);
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;
/* 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;
}
/* 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)
return 0;
}
-static dictentry_t* dict_get_slot(dict_t*h, const void*key)
+dictentry_t* dict_get_slot(dict_t*h, const void*key)
{
if(!h->num)
return 0;
rfx_free(e);
e = next;
}
+ h->slots[t]=0;
}
rfx_free(h->slots);
memset(h, 0, sizeof(dict_t));
map_internal_t*m;
map->internal = (map_internal_t*)rfx_calloc(sizeof(map_internal_t));
m = (map_internal_t*)map->internal;
- dict_init(&m->d);
+ dict_init(&m->d, INITIAL_SIZE);
}
void map_put(map_t*map, string_t t1, string_t t2)
{
listinfo_t info[0];
} commonlist_t;
-int list_length(void*_list)
+int list_length_(void*_list)
{
commonlist_t*l = (commonlist_t*)_list;
if(!l)
commonlist_t**list = (commonlist_t**)_list;
commonlist_t* n = 0;
if(!*list) {
- n = malloc(sizeof(commonlist_t)+sizeof(listinfo_t));
+ n = (commonlist_t*)malloc(sizeof(commonlist_t)+sizeof(listinfo_t));
*list = n;
(*list)->info[0].size = 0;
} else {
(*list)->info[0].last = n;
(*list)->info[0].size++;
}
+/* notice: prepending uses slighly more space than appending */
+void list_prepend_(void*_list, void*entry)
+{
+ commonlist_t**list = (commonlist_t**)_list;
+ commonlist_t* n = (commonlist_t*)malloc(sizeof(commonlist_t)+sizeof(listinfo_t));
+ int size = 0;
+ commonlist_t* last = 0;
+ if(*list) {
+ last = (*list)->info[0].last;
+ size = (*list)->info[0].size;
+ }
+ n->next = *list;
+ n->entry = entry;
+ *list = n;
+ (*list)->info[0].last = last;
+ (*list)->info[0].size = size+1;
+}
void list_free_(void*_list)
{
commonlist_t**list = (commonlist_t**)_list;