From 18b2ebe3df26009ef6b2aeb0670a396e876fca25 Mon Sep 17 00:00:00 2001 From: FreeArtMan Date: Sun, 4 Jun 2017 00:17:22 +0100 Subject: Added nb_match functionality --- netbytes.c | 184 +++++++++++++++++++++++++++--------- netbytes.h | 43 +++++---- test/Makefile | 4 +- test/test_key_value_load.c | 124 +++++++++++++++--------- test/test_key_value_match.c | 223 ++++++++++++++++++++++++++++++++++++++++++++ test/test_key_value_store.c | 4 +- 6 files changed, 474 insertions(+), 108 deletions(-) create mode 100644 test/test_key_value_match.c diff --git a/netbytes.c b/netbytes.c index 0bca647..ecbb87e 100644 --- a/netbytes.c +++ b/netbytes.c @@ -667,15 +667,19 @@ int nb_type( netbyte_store *store, int count, __NBT_TYPED **type ) return 0; } -int nb_val( netbyte_store *store, int count, uint8_t **val ) +int nb_val( netbyte_store *store, int count, __nb_type **type ) { - if ( store == NULL ) + if (!store) + { return -1; + } - if ( store->count < count ) - return -2; + if ((count < 0)||(count > store->count)) + { + return -1; + } - *val = store->types[count].nb_val; + *type = &store->types[count]; return 0; } @@ -771,6 +775,88 @@ int nb_print(netbyte_store *store) return 0; } +int nb_match(netbyte_store *store, nb_tok_arr *pattern) +{ + int i; + int ret = 0; + + if (store == NULL) + { + return -1; + } + + if (pattern == NULL) + { + return -1; + } + + if (store->count != pattern->len) + { + return 1; + } + + printf("pat->len%d\n",pattern->len); + for (i=0;i < pattern->len;i++) + { + printf("[%d]\n",i); + __NBT_TYPED type = store->types[i].type; + void *val = store->types[i].nb_val; + nb_tok pat_tok = pattern->tok[i]; + int eq = 0; + + switch (type) + { + case NBT_U8: + { + printf("NBT_U8\n"); + nb_u8 *u8 = (nb_u8 *)val; + + if ((pat_tok.type_size == 8)&& + (pat_tok.sign == SIGN_UNSIGNED)&& + (pat_tok.arr == 0)) + { + eq = 1; + } + break; + } + //if array 0 then its same as [] == [0]! + case NBT_U8ARRAY: + { + printf("NBT_U8ARRAY\n"); + nb_u8arr *u8arr = (nb_u8arr *)val; + + if ((pat_tok.type_size == 8)&& + (pat_tok.sign == SIGN_UNSIGNED)&& + (pat_tok.arr == 1)) //&& + //(u8arr->len == pat_tok.len)) //could be bug with []/[0] + { + eq = 1; + } + break; + } + case NBT_I32: + { + printf("NBT_I32\n"); + if ((pat_tok.type_size == 32)&& + (pat_tok.sign == SIGN_SIGNED)) + { + eq = 1; + } + break; + } + default: + printf(">>nb_match ERROR<<\n"); + } + if (eq==0) + { + ret = 1; + break; + } + } + + return ret; +} + nb_tok_arr *nb_tok_create(int size) { nb_tok_arr *ret=NULL; @@ -838,11 +924,11 @@ void nb_tok_destroy(nb_tok_arr *arr) #define S_END 10 #define S_STARTE 11 -#define MATCH(CH) ((*c)==(CH)) -#define MATCHDIG() (isdigit(*c)) -#define MOVE() c++; +#define NB_MATCH(CH) ((*c)==(CH)) +#define NB_MATCHDIG() (isdigit(*c)) +#define NB_MOVE() (c++); -int parse_num(char *s, char *e) +int nb_parse_num(char *s, char *e) { const int num_sz = 17; int str_sz=-1; @@ -861,9 +947,9 @@ int parse_num(char *s, char *e) return atoi(num); } -int parse(char *str, nb_tok_arr *arr) +int nb_parse(char *str, nb_tok_arr *arr) { - int cnt; + int cnt=0; nb_tok tok; int state = S_START; char *c; @@ -872,7 +958,7 @@ int parse(char *str, nb_tok_arr *arr) int ret = 0; memset(&tok, 0, sizeof(tok)); - + printf("\"%s\"\n",str); while (*c!=0) { printf("[%c] ",*c); @@ -882,18 +968,21 @@ int parse(char *str, nb_tok_arr *arr) { printf("START\n"); - if (MATCH('u')) + if (NB_MATCH('u')) { + printf("!1\n"); tok.sign = SIGN_UNSIGNED; state = S_SIGN; - } else if (MATCH('i')) + } else if (NB_MATCH('i')) { + printf("!2\n"); tok.sign = SIGN_SIGNED; state = S_SIGN; - } else - { + } else { + printf("!3\n"); state = S_ERR; } + printf("!\n"); break; } case S_STARTE: @@ -910,14 +999,14 @@ int parse(char *str, nb_tok_arr *arr) case S_SIGN: { printf("SIGN\n"); - if (MATCH('i')) + if (NB_MATCH('i')) { state = S_SIZE; - MOVE(); - } else if (MATCH('u')) + NB_MOVE(); + } else if (NB_MATCH('u')) { state = S_SIZE; - MOVE(); + NB_MOVE(); } else { state = S_ERR; @@ -927,30 +1016,30 @@ int parse(char *str, nb_tok_arr *arr) case S_SIZE: { printf("SIZE\n"); - if (MATCHDIG()) + if (NB_MATCHDIG()) { if (st==NULL) st=c; - MOVE(); - } else if (MATCH(',')) + NB_MOVE(); + } else if (NB_MATCH(',')) { en=c; - tok.type_size = parse_num(st,en); + tok.type_size = nb_parse_num(st,en); en=NULL; st=NULL; state = S_STARTE; - MOVE(); - } else if (MATCH('[')) + NB_MOVE(); + } else if (NB_MATCH('[')) { en=c; - tok.type_size = parse_num(st,en); + tok.type_size = nb_parse_num(st,en); en=NULL; st=NULL; state = S_LBREAK; - MOVE(); - } else if (MATCH(' ')) + NB_MOVE(); + } else if (NB_MATCH(' ')) { en=c; - tok.type_size = parse_num(st,en); + tok.type_size = nb_parse_num(st,en); en=NULL; st=NULL; state = S_END; @@ -963,20 +1052,20 @@ int parse(char *str, nb_tok_arr *arr) case S_NUMBER: { printf("NUMBER\n"); - if (MATCHDIG()) + if (NB_MATCHDIG()) { if(st==NULL) st=c; - MOVE(); - } else if (MATCH(']')) + NB_MOVE(); + } else if (NB_MATCH(']')) { en=c; - tok.type_size = parse_num(st,en); + tok.type_size = nb_parse_num(st,en); tok.arr = 1; en=NULL; st=NULL; state = S_RBREAK; - MOVE(); + NB_MOVE(); } break; } @@ -984,7 +1073,7 @@ int parse(char *str, nb_tok_arr *arr) { printf("COMM\n"); state = S_STARTE; - MOVE(); + NB_MOVE(); break; } case S_ERR: @@ -996,13 +1085,14 @@ int parse(char *str, nb_tok_arr *arr) case S_LBREAK: { printf("LBREAK\n"); - if (MATCHDIG()) + if (NB_MATCHDIG()) { state = S_NUMBER; - } else if (MATCH(']')) + } else if (NB_MATCH(']')) { state = S_RBREAK; - MOVE(); + tok.arr = 1; + NB_MOVE(); } else { state = S_ERR; @@ -1012,7 +1102,7 @@ int parse(char *str, nb_tok_arr *arr) case S_RBREAK: { printf("RBREAK\n"); - if (MATCH(',')) + if (NB_MATCH(',')) { state = S_COMM; } else @@ -1039,13 +1129,21 @@ int parse(char *str, nb_tok_arr *arr) } default: { - + printf("Unknown state\n"); } } cnt++; - if (cnt>32) break; - if (state == -1) break; + if (cnt>32) + { + printf("Loop\n"); + break; + } + if (state == -1) + { + printf("state\n"); + break; + } } return ret; diff --git a/netbytes.h b/netbytes.h index a73dcc6..3960142 100644 --- a/netbytes.h +++ b/netbytes.h @@ -124,6 +124,21 @@ typedef struct netbyte_load uint8_t *buf; } netbyte_load; +typedef struct nb_tok +{ + int sign; + int type_size; + int len; + int arr; +} nb_tok; + +typedef struct nb_tok_arr +{ + int size; + int len; + nb_tok *tok; +} nb_tok_arr; + int nb_u8_create( nb_u8 *s, uint8_t val ); int nb_u8arr_create( nb_u8arr *s, __NBT_U8ARR_LEN len, uint8_t *val ); int nb_u16_create( nb_u16 *s, uint16_t val ); @@ -150,35 +165,27 @@ int nb_free(netbyte_store *store); int nb_load( netbyte_store *store, uint8_t *data ); int nb_count( netbyte_store *store ); int nb_type( netbyte_store *store, int count, __NBT_TYPED **type ); -int nb_val( netbyte_store *store, int count, uint8_t **val ); +int nb_val( netbyte_store *store, int count, __nb_type **type ); int nb_fread( netbyte_store *store, int fd); //print all all values in netbyte string int nb_print(netbyte_store *store); -//check if netbyte matches particular format -int nb_match(netbyte_store *store, int size); +/* +check if netbyte matches particular format +-1 err +1 not match +0 match +*/ +int nb_match(netbyte_store *store, nb_tok_arr *pattern); #define SIGN_UNSIGNED 1 #define SIGN_SIGNED 2 -typedef struct nb_tok -{ - int sign; - int type_size; - int len; - int arr; -} nb_tok; - -typedef struct nb_tok_arr -{ - int size; - int len; - nb_tok *tok; -} nb_tok_arr; - nb_tok_arr *nb_tok_create(int size); int nb_tok_add(nb_tok_arr *arr, int sign, int type_size, int len, int farr); void nb_tok_destroy(nb_tok_arr *arr); +int nb_parse(char *str, nb_tok_arr *arr); + #endif \ No newline at end of file diff --git a/test/Makefile b/test/Makefile index c70c7f0..75a56ef 100644 --- a/test/Makefile +++ b/test/Makefile @@ -3,13 +3,13 @@ CFLAGS=-g3 -I../ -lnetbytes -Wl,-rpath=../ -L../ LDFLAGS= SOURCE=test_save test_multiple_write test_multiple_read test_add_elem test_alltypes \ -test_key_value_store test_key_value_load +test_key_value_store test_key_value_load test_key_value_match SOURCES=$(SOURCE:=.c) make: $(SOURCE) leak: - valgrind --leak-check=full --track-origins=yes --log-file=log.txt ./test_key_value_store + valgrind --leak-check=full --track-origins=yes --log-file=log.txt ./test_key_value_load clean: rm -f $(SOURCE) \ No newline at end of file diff --git a/test/test_key_value_load.c b/test/test_key_value_load.c index f020e34..afe5450 100644 --- a/test/test_key_value_load.c +++ b/test/test_key_value_load.c @@ -3,80 +3,118 @@ #include -void pr_u8( nb_u8 *u8 ) +char *alloc_new_str_s(char *str, size_t size) { - if ( !u8 ) - { - printf("u8: NULL\n"); - return; - } else + char *ret = NULL; + + if (str == NULL) { - printf("u8: t=0x%x v=0x%x\n", u8->type, u8->val ); + return NULL; } -} -void pr_u8arr( nb_u8arr *u8arr ) -{ - if (!u8arr) + //1MB is enought + if (size > (1024*1024)) { - printf("u8arr: NULL\n"); - return ; - } else + return NULL; + } + + ret = malloc(size+1); //extra for 1 zero at then end + if (ret == NULL) { - printf("u8arr: t=0x%x l=0x%x v=0x%x\n", - u8arr->type, u8arr->len, u8arr->val ); + return NULL; } + + memcpy(ret, str, size); + ret[size] = 0; //add zero at the end + + return ret; +} + +char *alloc_new_str(char *str) +{ + return alloc_new_str_s(str, strlen(str)); } -void pr_store( netbyte_store *nb ) +typedef struct kv_user_name { - int i; + int id; + char *name; + char *desc; +} kv_user_name; - if (!nb) +kv_user_name* kv_new(int id, char *name, char *desc) +{ + kv_user_name *ret = NULL; + + ret = malloc(sizeof(kv_user_name)); + if (!ret) { - printf("nb: NULL\n"); - return; + return NULL; } - printf("nb: s=0x%x c=0x%x\n", nb->size, nb->count ); - for (i=0;icount;i++) + ret->id = id; + ret->name = alloc_new_str(name); + ret->desc = alloc_new_str(desc); + + return ret; +} + +netbyte_store* kv_marsh(kv_user_name *kv) +{ + netbyte_store *nb=NULL; + nb_u8 nb_id; + nb_u8arr nb_name, nb_desc; + + nb = calloc(1,sizeof(netbyte_store)); + nb_init(nb); + + nb_u8_create(&nb_id, kv->id); + nb_add_u8(nb, &nb_id); + nb_u8arr_create(&nb_name, strlen(kv->name), kv->name); + nb_add_u8arr(nb, &nb_name); + nb_u8arr_create(&nb_desc, strlen(kv->desc), kv->desc); + nb_add_u8arr(nb, &nb_desc); + + nb_print(nb); + nb_print(nb); + + return nb; +} + +void kv_free(kv_user_name *kv) +{ + if (kv!=NULL) { - printf("\t[%x] -> ",i ); - if ( nb->types[i].type == NBT_U8 ) - { - pr_u8( (nb_u8 *)nb->types[i].nb_val ); - } else if ( nb->types[i].type == NBT_U8ARRAY ) - { - pr_u8arr( (nb_u8arr *)nb->types[i].nb_val ); - } else - { - printf("Unknown\n"); - } + free(kv->name); + free(kv->desc); + free(kv); } } int main() { - - int er; - uint8_t *res; - FILE *f; + int er=-1; + uint8_t *res=NULL; + FILE *f=NULL; int i=0; - netbyte_store nb; + netbyte_store *nb=malloc(sizeof(netbyte_store)); printf("Start test\n"); - nb_init( &nb ); - f = fopen("test_many.nb","r"); - while (nb_fread( &nb, fileno(f) ) == 0) + f = fopen("test_kv_save.md","r"); + while (nb_fread( nb, fileno(f) ) == 0) { printf("ITER %d: ", i ); - pr_store( &nb ); + nb_print( nb ); i += 1; + } fclose( f ); + nb_free(nb); + + printf("End test\n"); return 0; } \ No newline at end of file diff --git a/test/test_key_value_match.c b/test/test_key_value_match.c new file mode 100644 index 0000000..4384a07 --- /dev/null +++ b/test/test_key_value_match.c @@ -0,0 +1,223 @@ +#include +#include + +#include + +char *alloc_new_str_s(char *str, size_t size) +{ + char *ret = NULL; + + if (str == NULL) + { + return NULL; + } + + //1MB is enought + if (size > (1024*1024)) + { + return NULL; + } + + ret = malloc(size+1); //extra for 1 zero at then end + if (ret == NULL) + { + return NULL; + } + + memcpy(ret, str, size); + ret[size] = 0; //add zero at the end + + return ret; +} + +char *alloc_new_str(char *str) +{ + return alloc_new_str_s(str, strlen(str)); +} + +typedef struct kv_user_name +{ + int id; + char *name; + char *desc; +} kv_user_name; + +kv_user_name* kv_new(int id, char *name, char *desc) +{ + kv_user_name *ret = NULL; + + ret = malloc(sizeof(kv_user_name)); + if (!ret) + { + return NULL; + } + + ret->id = id; + ret->name = alloc_new_str(name); + ret->desc = alloc_new_str(desc); + + return ret; +} + +kv_user_name* kv_empty() +{ + kv_user_name *ret = NULL; + + ret = calloc(1, sizeof(kv_user_name)); + if (!ret) + { + return NULL; + } + + + return ret; +} + +netbyte_store* kv_marsh(kv_user_name *kv) +{ + netbyte_store *nb=NULL; + nb_u8 nb_id; + nb_u8arr nb_name, nb_desc; + + nb = calloc(1,sizeof(netbyte_store)); + nb_init(nb); + + nb_u8_create(&nb_id, kv->id); + nb_add_u8(nb, &nb_id); + nb_u8arr_create(&nb_name, strlen(kv->name), kv->name); + nb_add_u8arr(nb, &nb_name); + nb_u8arr_create(&nb_desc, strlen(kv->desc), kv->desc); + nb_add_u8arr(nb, &nb_desc); + + nb_print(nb); + nb_print(nb); + + return nb; +} + + +int kv_unmarsh(netbyte_store *store, kv_user_name *kv) +{ + __nb_type *type=NULL; + + if (!store) + { + return -1; + } + + if (!kv) + { + return -1; + } + + if (0 == nb_val(store, 0, &type)) + if (type->type == NBT_U8) + { + nb_u8 *u8 = (nb_u8 *)type->nb_val; + kv->id = u8->val; + } else + { + printf("ERR\n"); + } + + if (0 == nb_val(store, 1, &type)) + if (type->type == NBT_U8ARRAY) + { + nb_u8arr *u8arr = (nb_u8arr *)type->nb_val; + kv->name = alloc_new_str_s(u8arr->val, u8arr->len); + } else + { + printf("ERR\n"); + } + + if (0 == nb_val(store, 2, &type)) + if (type->type == NBT_U8ARRAY) + { + nb_u8arr *u8arr = (nb_u8arr *)type->nb_val; + kv->desc = alloc_new_str_s(u8arr->val, u8arr->len); + } else + { + printf("ERR\n"); + } + + return 0; +} + + +void kv_free(kv_user_name *kv) +{ + if (kv!=NULL) + { + free(kv->name); + free(kv->desc); + free(kv); + } +} + +int main() +{ + int er=-1; + uint8_t *res=NULL; + FILE *f=NULL; + int i=0; + + kv_user_name *kv=NULL; + + netbyte_store *nb=malloc(sizeof(netbyte_store)); + nb_tok_arr *pat = NULL; + + printf("Start test\n"); + + f = fopen("test_kv_save.md","r"); + if (nb_fread( nb, fileno(f) ) == 0) + { + nb_print( nb ); + } + fclose( f ); + + + pat = nb_tok_create(32); + if (pat == NULL) + { + printf("ERR nb_tok_create\n"); + } + if (-1 == nb_parse("u8,u8[],u8[] ",pat)) + { + printf("ERR nb_parse\n"); + } + + + for (i=0;ilen;i++) + { + nb_tok tok = pat->tok[i]; + printf("%d S:%d TS:%d L:%d A:%d\n", + i, tok.sign, tok.type_size, tok.len, tok.arr + ); + } + + if (nb_match(nb, pat)==0) + { + printf("Match\n"); + } else + { + printf("No match\n"); + } + + + + kv = kv_empty(); + kv_unmarsh(nb, kv); + + + printf("ID:%d\n", kv->id); + printf("NAME:%s\n",kv->name); + printf("DESC:%s\n", kv->desc); + + kv_free(kv); + + nb_free(nb); + + + printf("End test\n"); + return 0; +} \ No newline at end of file diff --git a/test/test_key_value_store.c b/test/test_key_value_store.c index b499c9a..de939da 100644 --- a/test/test_key_value_store.c +++ b/test/test_key_value_store.c @@ -106,7 +106,7 @@ int main() printf("Start test\n"); - kv = kv_new(1,"Name","Name of the human"); + kv = kv_new(1,"Jhony","Name of the human"); nb = kv_marsh(kv); nb_print(nb); kv_free(kv); @@ -114,7 +114,7 @@ int main() //nb_print(nb); res = nb_create(nb); - f = fopen("test_kv_save.nd","w+"); + f = fopen("test_kv_save.md","w+"); fwrite(res, 1, nb->size, f); fclose(f); -- cgit v1.2.3