mirror of
https://github.com/radareorg/radare2.git
synced 2024-10-07 10:33:30 +00:00
* Initial import of RMixed datatype
- Crashy and crispy atm. needs love * Little cleanup in RFlag. RBtree must be removed here
This commit is contained in:
parent
7b221b7089
commit
a74b312765
@ -1,35 +1,27 @@
|
||||
/* radare - LGPL - Copyright 2007-2010 pancake<nopcode.org> */
|
||||
/* radare - LGPL - Copyright 2007-2011 pancake<nopcode.org> */
|
||||
|
||||
#include <r_flags.h>
|
||||
#include <r_util.h>
|
||||
#include <r_cons.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// TODO: remove dependency of r_cons here..
|
||||
// TODO: implement btree
|
||||
// TODO: remove r_cons dependency here..
|
||||
// remove btree here.. we want something funnier like.. RMixed :D
|
||||
|
||||
/* compare names */
|
||||
static int ncmp(const void *a, const void *b) {
|
||||
RFlagItem *fa = (RFlagItem *)a;
|
||||
RFlagItem *fb = (RFlagItem *)b;
|
||||
int ret = 0;
|
||||
/* we cannot use a simple substraction coz ut64 > s32 :) */
|
||||
ret = strcmp (fa->name, fb->name);
|
||||
// TODO: Deprecate namehash..
|
||||
// if (fa->namehash > fb->namehash) ret = 1;
|
||||
// else if (fa->namehash < fb->namehash) ret = -1;
|
||||
return ret;
|
||||
return strcmp (fa->name, fb->name);
|
||||
}
|
||||
|
||||
/* compare offsets */
|
||||
static int cmp(const void *a, const void *b) {
|
||||
RFlagItem *fa = (RFlagItem *)a;
|
||||
RFlagItem *fb = (RFlagItem *)b;
|
||||
int ret = 0;
|
||||
/* we cannot use a simple substraction coz ut64 > s32 :) */
|
||||
if (fa->offset > fb->offset) ret = 1;
|
||||
else if (fa->offset < fb->offset) ret = -1;
|
||||
return ret;
|
||||
if (fa->offset > fb->offset) return 1;
|
||||
else if (fa->offset < fb->offset) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
R_API int r_flag_sort(RFlag *f, int namesort) {
|
||||
@ -37,9 +29,7 @@ R_API int r_flag_sort(RFlag *f, int namesort) {
|
||||
int changes;
|
||||
RFlagItem *flag, *fi = NULL;
|
||||
RListIter *iter, *it_elem;
|
||||
RList *tmp;
|
||||
|
||||
tmp = r_list_new ();
|
||||
RList *tmp = r_list_new ();
|
||||
// find bigger ones after this
|
||||
do {
|
||||
changes = 0;
|
||||
@ -76,10 +66,8 @@ R_API RFlag * r_flag_free(RFlag *f) {
|
||||
}
|
||||
|
||||
R_API RFlag * r_flag_new() {
|
||||
RFlag *f;
|
||||
int i;
|
||||
|
||||
f = R_NEW (RFlag);
|
||||
RFlag *f = R_NEW (RFlag);
|
||||
if (f) {
|
||||
f->flags = r_list_new ();
|
||||
f->flags->free = free;
|
||||
@ -89,7 +77,7 @@ R_API RFlag * r_flag_new() {
|
||||
btree_init (&f->tree);
|
||||
btree_init (&f->ntree);
|
||||
#endif
|
||||
for (i=0;i<R_FLAG_SPACES_MAX;i++)
|
||||
for (i=0; i<R_FLAG_SPACES_MAX; i++)
|
||||
f->spaces[i] = NULL;
|
||||
}
|
||||
return f;
|
||||
@ -117,25 +105,16 @@ R_API void r_flag_list(RFlag *f, int rad) {
|
||||
}
|
||||
|
||||
R_API RFlagItem *r_flag_get(RFlag *f, const char *name) {
|
||||
#if USE_BTREE
|
||||
RFlagItem tmp;
|
||||
#else
|
||||
RFlagItem *flag;
|
||||
RListIter *iter;
|
||||
#endif
|
||||
if (name==NULL || name[0]=='\0' || (name[0]>='0'&& name[0]<='9'))
|
||||
if (strnull (name) || (name[0]>='0' && name[0]<='9'))
|
||||
return NULL;
|
||||
#if USE_BTREE
|
||||
tmp.namehash = r_str_hash64 (name);
|
||||
return btree_get (f->ntree, &tmp, ncmp);
|
||||
#else
|
||||
ut64 hash = r_str_hash64 (name);
|
||||
r_list_foreach_prev (f->flags, iter, flag) {
|
||||
//if (!strcmp (name, flag->name))
|
||||
if (hash == flag->namehash)
|
||||
return flag;
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -33,27 +33,27 @@ static int r_flag_name_validate_char(const char ch) {
|
||||
return 0;
|
||||
default:
|
||||
if (((ch >= '0') && (ch <= '9')))
|
||||
return 1;
|
||||
return R_TRUE;
|
||||
if (!IS_PRINTABLE (ch))
|
||||
return 0;
|
||||
return R_FALSE;
|
||||
}
|
||||
return 1;
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
R_API int r_flag_name_check(const char *name) {
|
||||
if (name[0]=='\0')
|
||||
return 0;
|
||||
return R_FALSE;
|
||||
for (;*name!='\0'; name++)
|
||||
if (!r_flag_name_validate_char (*name))
|
||||
return 0;
|
||||
return 1;
|
||||
return R_FALSE;
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
R_API int r_flag_name_filter(char *name) {
|
||||
int i;
|
||||
char *oname;
|
||||
name = oname = r_str_trim (name);
|
||||
for (i=0;*name!='\0'; name = name +1,i++) {
|
||||
for (i=0; *name!='\0'; name = name +1,i++) {
|
||||
if (i>R_FLAG_NAME_SIZE) {
|
||||
name[0] = '\0';
|
||||
break;
|
||||
|
@ -45,7 +45,7 @@ R_API void r_flag_space_set(RFlag *f, const char *name) {
|
||||
}
|
||||
}
|
||||
/* not found */
|
||||
for(i=0;i<R_FLAG_SPACES_MAX;i++) {
|
||||
for (i=0;i<R_FLAG_SPACES_MAX;i++) {
|
||||
if (f->spaces[i] == NULL) {
|
||||
f->spaces[i] = strdup (name);
|
||||
f->space_idx = i;
|
||||
@ -56,9 +56,9 @@ R_API void r_flag_space_set(RFlag *f, const char *name) {
|
||||
|
||||
R_API void r_flag_space_list(RFlag *f) {
|
||||
int i,j = 0;
|
||||
for(i=0;i<R_FLAG_SPACES_MAX;i++) {
|
||||
for (i=0;i<R_FLAG_SPACES_MAX;i++) {
|
||||
if (f->spaces[i])
|
||||
printf("%02d %c %s\n", j++,
|
||||
printf ("%02d %c %s\n", j++,
|
||||
(i==f->space_idx)?'*':' ', f->spaces[i]);
|
||||
}
|
||||
}
|
||||
|
@ -41,8 +41,8 @@ typedef struct r_oflist_t {
|
||||
#define r_list_iter_cur(x) x->p
|
||||
#define r_list_iter_unref(x) x
|
||||
R_API RList *r_list_new();
|
||||
R_API RListIter *r_list_append(RList *list, void *data);
|
||||
R_API RListIter *r_list_prepend(RList *list, void *data);
|
||||
R_API RListIter *r_list_append(RList *list, const void *data);
|
||||
R_API RListIter *r_list_prepend(RList *list, const void *data);
|
||||
R_API int r_list_length(RList *list);
|
||||
R_API void r_list_add_sorted(RList *list, void *data, RListComparator cmp);
|
||||
R_API void r_list_sort(RList *list, RListComparator cmp);
|
||||
|
@ -21,3 +21,6 @@ include ../rules.mk
|
||||
ht64:
|
||||
cat ht.c | sed -e s,hashtable,hashtable64,g -e s,HashTable,HashTable64,g -e s,ut32,ut64,g > ht64.c
|
||||
#cat ht.c ht64.c | sed -e 's,) {,);,'
|
||||
m:
|
||||
gcc mixed.c -I ../include/ -DTEST=1 -lr_util -g
|
||||
./a.out
|
||||
|
@ -104,7 +104,7 @@ R_API RListIter *r_list_item_new (void *data) {
|
||||
return new;
|
||||
}
|
||||
|
||||
R_API RListIter *r_list_append(RList *list, void *data) {
|
||||
R_API RListIter *r_list_append(RList *list, const void *data) {
|
||||
RListIter *new = NULL;
|
||||
if (data) {
|
||||
new = R_NEW (RListIter);
|
||||
@ -120,7 +120,7 @@ R_API RListIter *r_list_append(RList *list, void *data) {
|
||||
return new;
|
||||
}
|
||||
|
||||
R_API RListIter *r_list_prepend(RList *list, void *data) {
|
||||
R_API RListIter *r_list_prepend(RList *list, const void *data) {
|
||||
RListIter *new = R_NEW (RListIter);
|
||||
if (list->head)
|
||||
list->head->p = new;
|
||||
|
207
libr/util/mixed.c
Normal file
207
libr/util/mixed.c
Normal file
@ -0,0 +1,207 @@
|
||||
/*
|
||||
* mixed data type
|
||||
*/
|
||||
|
||||
// we need to store information in this way:
|
||||
// indexed by strings, ut32, ut64 .. r_hashtable
|
||||
// iterate over them
|
||||
// get subset
|
||||
|
||||
#include <r_util.h>
|
||||
|
||||
#define RMIXED_MAXKEYS 256
|
||||
typedef struct r_mixed_data_t {
|
||||
int size;
|
||||
union {
|
||||
RHashTable *ht;
|
||||
RHashTable64 *ht64;
|
||||
} hash;
|
||||
} RMixedData;
|
||||
|
||||
typedef struct r_mixed_t {
|
||||
RList *list;
|
||||
RMixedData *keys[RMIXED_MAXKEYS];
|
||||
} RMixed;
|
||||
|
||||
R_API RMixed *r_mixed_new () {
|
||||
RMixed *m = R_NEW (RMixed);
|
||||
if (!m) return NULL;
|
||||
memset (m->keys, 0, sizeof (m->keys));
|
||||
m->list = r_list_new ();
|
||||
return m;
|
||||
}
|
||||
|
||||
R_API void r_mixed_free (RMixed *m) {
|
||||
int i;
|
||||
for (i=0; i<RMIXED_MAXKEYS; i++) {
|
||||
if (m->keys[i]) {
|
||||
switch (m->keys[i]->size) {
|
||||
case 1: case 2: case 4:
|
||||
r_hashtable_free (m->keys[i]->hash.ht);
|
||||
break;
|
||||
case 8: r_hashtable64_free (m->keys[i]->hash.ht64);
|
||||
break;
|
||||
}
|
||||
free (m->keys[i]);
|
||||
m->keys[i] = NULL;
|
||||
}
|
||||
}
|
||||
r_list_destroy (m->list);
|
||||
free (m);
|
||||
}
|
||||
|
||||
R_API int r_mixed_key_check(RMixed *m, int key, int sz) {
|
||||
if (key>=0 && key<RMIXED_MAXKEYS) {
|
||||
if (sz==1 || sz==2 || sz==4 || sz==8)
|
||||
return R_TRUE;
|
||||
}
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
#define R_MIXED_KEY(m,x,y,z) r_mixed_key(m, r_offsetof(x,z), sizeof(y->z))
|
||||
R_API int r_mixed_key(RMixed *m, int key, int size) {
|
||||
if (size>0 && r_mixed_key_check (m, key, size)) {
|
||||
if (m->keys[key]) {
|
||||
m->keys[key]->size = size;
|
||||
} else {
|
||||
m->keys[key] = R_NEW (RMixedData);
|
||||
m->keys[key]->size = size;
|
||||
switch (size) {
|
||||
case 1: case 2: case 4:
|
||||
m->keys[key]->hash.ht = r_hashtable_new ();
|
||||
eprintf ("new hash %d = %p\n", key, m->keys[key]->hash.ht);
|
||||
return R_TRUE;
|
||||
case 8: m->keys[key]->hash.ht64 = r_hashtable64_new ();
|
||||
eprintf ("---new hash %d\n", key);
|
||||
return R_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
// static
|
||||
R_API ut64 r_mixed_get_value(int key, int sz, const void *p) {
|
||||
switch (sz) {
|
||||
case 1: return (ut64) *((ut8*)((ut8*)p+key));
|
||||
case 2: return (ut64) *((ut16*)((ut8*)p+key));
|
||||
case 4: return (ut64) *((ut32*)((ut8*)p+key));
|
||||
case 8: return (ut64) *((ut32*)((ut8*)p+key));
|
||||
}
|
||||
return 0LL;
|
||||
}
|
||||
|
||||
R_API RList *r_mixed_get (RMixed *m, int key, ut64 value) {
|
||||
if (key>=0 && key<RMIXED_MAXKEYS)
|
||||
if (m->keys[key])
|
||||
switch (m->keys[key]->size) {
|
||||
case 1: case 2: case 4:
|
||||
eprintf ("sz = %d ht=%p\n", m->keys[key]->size, m->keys[key]->hash.ht);
|
||||
return r_hashtable_lookup (m->keys[key]->hash.ht, (ut32)value);
|
||||
case 8: return r_hashtable64_lookup (m->keys[key]->hash.ht64, value);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
R_API void *r_mixed_get0 (RMixed *m, int key, ut64 value) {
|
||||
RList *list = r_mixed_get (m, key, value);
|
||||
printf ("LURKITAPP %d = %p\n", key, r_hashtable_lookup (m->keys[key]->hash.ht, (ut32)value));
|
||||
eprintf ("lookup for %llx\n", value);
|
||||
eprintf ("LIST = %p\n", list);
|
||||
//eprintf ("HEAD = %p\n", r_list_head (list));
|
||||
//eprintf ("DATA = %p\n", r_list_head (list)->data);
|
||||
if (list && !r_list_empty (list))
|
||||
return r_list_head (list)->data;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
R_API int r_mixed_add (RMixed *m, void *p) {
|
||||
RHashTable *ht;
|
||||
RHashTable64 *ht64;
|
||||
RList *list = NULL;
|
||||
ut64 value;
|
||||
int i, size;
|
||||
r_list_append (m->list, p);
|
||||
for (i=0; i<RMIXED_MAXKEYS; i++) {
|
||||
if (!m->keys[i])
|
||||
continue;
|
||||
size = m->keys[i]->size;
|
||||
value = r_mixed_get_value (i, size, p);
|
||||
switch (size) {
|
||||
case 1: case 2: case 4:
|
||||
ht = m->keys[i]->hash.ht;
|
||||
list = r_hashtable_lookup (ht, (ut32)value);
|
||||
if (!list) {
|
||||
list = r_list_new ();
|
||||
r_hashtable_insert (ht, (ut32)value, list);
|
||||
printf ("INSERTING NEWTABLE AT %d PWND = %p\n", i, r_hashtable_lookup (ht, (ut32)value));
|
||||
}
|
||||
eprintf ("key=%d newlist=%p value=%llx p=%p\n", i, list, value, p);
|
||||
r_list_append (list, p);
|
||||
break;
|
||||
case 8:
|
||||
ht64 = m->keys[i]->hash.ht64;
|
||||
list = r_hashtable64_lookup (ht64, value);
|
||||
if (!list) {
|
||||
list = r_list_new ();
|
||||
r_hashtable64_insert (ht64, value, list);
|
||||
}
|
||||
eprintf ("key64=%d newlist=%p value=%llx p=%p\n", i, list, value, p);
|
||||
r_list_append (list, p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
R_API int r_mixed_del (RMixed *m, const void *p) {
|
||||
int i;
|
||||
r_list_delete_data (m->list, p);
|
||||
// TODO delete indexed hashtables
|
||||
for (i=0; i<RMIXED_MAXKEYS; i++) {
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
ut32 hashname;
|
||||
int length;
|
||||
ut64 offset;
|
||||
} TestStruct;
|
||||
|
||||
TestStruct *test_struct_new(const char *name, int length, ut64 offset) {
|
||||
TestStruct *ts = R_NEW (TestStruct);
|
||||
ts->name = strdup (name);
|
||||
ts->hashname = r_str_hash (name);
|
||||
ts->length = length;
|
||||
ts->offset = offset;
|
||||
eprintf ("name : %s\n", name);
|
||||
return ts;
|
||||
}
|
||||
|
||||
void test_struct_free(TestStruct *ts) {
|
||||
free (ts->name);
|
||||
free (ts);
|
||||
}
|
||||
|
||||
int main () {
|
||||
TestStruct *ts;
|
||||
RMixed *mx = r_mixed_new ();
|
||||
R_MIXED_KEY (mx, TestStruct, ts, hashname);
|
||||
R_MIXED_KEY (mx, TestStruct, ts, offset);
|
||||
|
||||
r_mixed_add (mx, test_struct_new ("food", 12, 0x839481222000));
|
||||
r_mixed_add (mx, test_struct_new ("food", 12, 0x839481222000));
|
||||
r_mixed_add (mx, test_struct_new ("baar", 12, 0x441242910));
|
||||
r_mixed_add (mx, test_struct_new ("cocktel", 12, 0x224944));
|
||||
r_mixed_add (mx, test_struct_new ("cocktel2", 16, 0x224944));
|
||||
r_mixed_add (mx, test_struct_new ("cocktel3", 17, 0x224944));
|
||||
|
||||
ts = r_mixed_get0 (mx, r_offsetof (TestStruct, hashname), (ut64)r_str_hash ("food"));
|
||||
if (ts) {
|
||||
printf ("NAM: %s\n", ts->name);
|
||||
printf ("LEN: %d\n", ts->length);
|
||||
printf ("OFF: %llx\n", ts->offset);
|
||||
} else eprintf ("oops. cannot find 'food'\n");
|
||||
|
||||
r_mixed_free (mx);
|
||||
}
|
@ -25,3 +25,5 @@ R_API int r_str_re_replace(const char *str, const char *reg, const char *sub) {
|
||||
/* TODO: not yet implemented */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Added glob stuff here */
|
||||
|
Loading…
Reference in New Issue
Block a user