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)
{
// ------------------------------- 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,
};
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<h->hashsize;t++) {
- dictentry_t*e = h->slots[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->data = h->key_type->dup(e->data);
+ 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;
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)