#include "myjson.h" #include "board.h" #include "debug.h" #include "mystdlib.h" #include "bytearray.h" // json字符串转化为json,返回临时指针 cJSON *json_parse(const char *jstr) { cJSON *json=cJSON_Parse(jstr); if(json){ return tappend(json,cJSON_Delete); } return json; } /*r{ json 转列表 }c*/ list_def *jarray_to_list(cJSON *jarray,obj_def *obj) { param_check(obj); param_check(obj->to_obj_fun); param_check(obj->obj_size); param_check(jarray); list_def *l=list_creat(obj->obj_size,obj->sub,obj->del,0); void *o; int array_size; if(jarray->type!=cJSON_Array){ DBG_WARN("json:%s not a array obj.",jarray->string?jarray->string:"null"); goto err; } array_size=cJSON_GetArraySize(jarray); for(int i=0;ito_obj_fun(cJSON_GetArrayItem(jarray,i)); if(o==0) { DBG_WARN("json:%s conversion failed.",jarray->string?jarray->string:"null"); goto err; } list_append(l,o); if(obj->del_fun) obj->del_fun(o); } err: return l; } /*r{ json转整形 }c*/ static void *json_to_int(cJSON *j) { if(j->type==cJSON_Number) { int *ret=malloc(sizeof(int)); param_check(ret); *ret=j->valueint; return ret; } return 0; } static obj_def g_obj_int={ .obj_size=sizeof(int), .to_obj_fun=json_to_int, .del_fun=free, .sub=INT_SUB, .del=INT_DEL }; obj_def *obj_int(void) { return &g_obj_int; } /*r{ json转字符串 }c*/ static void *json_to_str(cJSON *j) { if(j->type==cJSON_String) { int len=strlen(j->valuestring)+1; char *ret=malloc(len); char **ret_ptr=malloc(sizeof(char *)); param_check(ret); param_check(ret_ptr); memcpy(ret,j->valuestring,len+1); *ret_ptr=ret; return ret_ptr; } return 0; } static obj_def g_obj_str={ .obj_size=sizeof(char *), .to_obj_fun=json_to_str, .del_fun=free, .sub=STR_SUB, .del=STR_DEL }; obj_def *obj_str(void) { return &g_obj_str; } static void *json_to_range(cJSON *j) { sch_range *s=malloc(sizeof(sch_range)); param_check(s); JSON_GET_INT(cJSON_GetObjectItem(j,"Max"),s->max); JSON_GET_INT(cJSON_GetObjectItem(j,"Min"),s->min); if(s->min>s->max){ DBG_WARN("range is empty."); } return s; } static obj_def g_obj_range={ .obj_size=sizeof(sch_range), .to_obj_fun=json_to_range, .del_fun=free, .sub=0, .del=0 }; obj_def *obj_range(void) { return &g_obj_range; } // 返回1,在范围内 int range_in_range(sch_range *r,int num) { if(num>=r->min&&num<=r->max) return 1; else return 0; } static void *json_to_task(cJSON *j) { sch_task *task=calloc(1,sizeof(sch_range)); JSON_GET_STR(cJSON_GetObjectItem(j,"TaskBrief"),task->brief); JSON_GET_INT(cJSON_GetObjectItem(j,"TaskID"),task->task_id); JSON_GET_INT(cJSON_GetObjectItem(j,"TaskIndex"),task->index); JSON_GET_INT(cJSON_GetObjectItem(j,"ErrJumpTo"),task->err_jump); JSON_GET_INT(cJSON_GetObjectItem(j,"RetryCount"),task->retry); JSON_GET_INT(cJSON_GetObjectItem(j,"ParamCount"),task->param_num); JSON_GET_INT(cJSON_GetObjectItem(j,"ReturnCount"),task->return_num); task->params_info=jarray_to_list(cJSON_GetObjectItem(j,"ParamInfo"),obj_str()); task->returns_info=jarray_to_list(cJSON_GetObjectItem(j,"ReturnInfo"),obj_str()); task->params=jarray_to_list(cJSON_GetObjectItem(j,"ParamVal"),obj_int()); task->ranges=jarray_to_list(cJSON_GetObjectItem(j,"TestStandard"),obj_range()); JSON_GET_INT(cJSON_GetObjectItem(j,"ExecuteErrCode"),task->failed_code); task->ret_failed_code=jarray_to_list(cJSON_GetObjectItem(j,"ResultErrCode"),obj_int()); return task; } static int _list_del_task(void *p) { sch_task *t=p; CHECK_DO(t->brief,free); CHECK_DO(t->params_info,list_delete); CHECK_DO(t->returns_info,list_delete); CHECK_DO(t->params,list_delete); CHECK_DO(t->ranges,list_delete); CHECK_DO(t->ret_failed_code,list_delete); CHECK_DO(t->ch_errcode,list_delete); return 0; } static obj_def g_obj_task={ .obj_size=sizeof(sch_task), .to_obj_fun=json_to_task, .del_fun=free, .sub=0, .del=_list_del_task }; obj_def *obj_task(void) { return &g_obj_task; } // 任务转化为数组 array_def *task_to_array(sch_task *t) { array_def *a=arr_creat(); arr_append(a,(uint8_t)t->task_id); arr_append(a,(uint8_t)t->index); arr_append(a,(uint8_t)t->retry); arr_append(a,(uint8_t)t->err_jump); arr_append(a,(uint8_t)(t->param_num&0x0f)|(t->return_num<<4)); for(int i=0;iparams);i++) { arr_append(a,(uint8_t)(list_get_int(t->params,i)&0xff)); arr_append(a,(uint8_t)(list_get_int(t->params,i)>>8)); } if(list_length(t->params)!=t->param_num) { DBG_WARN("name=%s param_num!=params.size().",t->brief); } if(t->return_num>list_length(t->returns_info)) { DBG_WARN("name=%s return_num>returns_info.size().",t->brief); } if(list_length(t->ch_errcode)!=list_length(t->ranges)) { DBG_WARN("name=%s ch_errcode.size()!=ranges.size().",t->brief); } return a; } // ack==0成功 task_returns *task_check_returns(sch_task *t,int ack,array_def *data) { int size=sizeof(task_returns)+sizeof(reurn_item)*t->return_num; task_returns *res=malloc(size); param_check(res); res->size=size; memset(res,0,size); if(t->ch_errcode==0) t->ch_errcode=list_creat_int(); list_clear(t->ch_errcode); res->index=t->index; res->id=t->task_id; res->ack=ack; if(res->ack==0){ res->exe_err=0; }else{ res->exe_err=t->failed_code; list_append_int(t->ch_errcode,t->failed_code); } if(arr_length(data)/2return_num){ DBG_WARN("task=%s, data size too less.",t->brief); }else{ for(int i=0;ireturn_num;i++) { reurn_item *item=&res->items[i]; int value=arr_get(data,i*2)|(arr_get(data,i*2+1)<<8); item->value=value; if(list_length(t->ranges)>i) { if(range_in_range(list_get(t->ranges,i),value)) item->err=0; else{ if(list_length(t->ret_failed_code)>i) { item->err=list_get_int(t->ret_failed_code,i); list_append_int(t->ch_errcode,item->err); } } } } } return res; } static void *json_to_errcode(cJSON *j) { sch_errcode *e=calloc(1,sizeof(sch_errcode)); param_check(e); JSON_GET_INT(cJSON_GetObjectItem(j,"MajorErrCode"),e->err); JSON_GET_STR(cJSON_GetObjectItem(j,"Info"),e->info); e->suberr=jarray_to_list(cJSON_GetObjectItem(j,"SubErrCode"),obj_int()); return e; } static int _list_del_errcode(void *p) { sch_errcode *e=p; CHECK_DO(e->info,free); CHECK_DO(e->suberr,list_delete); return 0; } static obj_def g_obj_errcode={ .obj_size=sizeof(sch_errcode), .to_obj_fun=json_to_errcode, .del_fun=free, .sub=0, .del=_list_del_errcode }; obj_def *obj_errcode(void) { return &g_obj_errcode; } // 返回1在范围内 int errcode_in_range(sch_errcode *e,int subcode) { param_check(e); for(int i=0;isuberr);i++) { if(subcode==list_get_int(e->suberr,i)) return 1; } return 0; } static void *_json_to_scheme(cJSON *j) { scheme_def *s=calloc(1,sizeof(scheme_def)); param_check(s); JSON_GET_INT(cJSON_GetObjectItem(j,"PlanID"),s->plan_id); JSON_GET_STR(cJSON_GetObjectItem(j,"PlanBrief"),s->brief); s->slave_soft_versions=jarray_to_list(cJSON_GetObjectItem(j,"CheckSoftVersion"),obj_int()); s->slave_hard_versions=jarray_to_list(cJSON_GetObjectItem(j,"CheckHardVersion"),obj_int()); JSON_GET_INT(cJSON_GetObjectItem(j,"TimeOutS"),s->timeout_s); JSON_GET_INT(cJSON_GetObjectItem(j,"TimeOutM"),s->timeout_m); JSON_GET_INT(cJSON_GetObjectItem(j,"TaskIDMax"),s->task_id_max); s->errs=jarray_to_list(cJSON_GetObjectItem(j,"MajorErrInfo"),obj_errcode()); s->tasks=jarray_to_list(cJSON_GetObjectItem(j,"TaskArray"),obj_task()); return s; } static int _list_del_scheme(void *p) { scheme_def *t=p; CHECK_DO(t->brief,free); CHECK_DO(t->slave_soft_versions,list_delete); CHECK_DO(t->slave_hard_versions,list_delete); CHECK_DO(t->errs,list_delete); CHECK_DO(t->tasks,list_delete); CHECK_DO(t->ch_errcode,list_delete); return 0; } static obj_def g_obj_scheme={ .obj_size=sizeof(scheme_def), .to_obj_fun=_json_to_scheme, .del_fun=free, .sub=0, .del=_list_del_scheme }; obj_def *obj_scheme(void) { return &g_obj_scheme; } scheme_def *json_to_scheme(cJSON *j) { param_check(j); obj_def *obj=obj_scheme(); scheme_def *s=obj->to_obj_fun(j); return s; } void scheme_delete(scheme_def *s) { obj_def *obj=obj_scheme(); param_check(s); obj->del(s); obj->del_fun(s); } // 任务id转化为字节数据 #define TASKSID_MAX_SIZE 0x100 static array_def *scheme_taskid_to_array(scheme_def *s) { param_check(s); array_def *res=arr_creat(); param_check(res); arr_append(res,s->plan_id&0xff); arr_append(res,(s->plan_id>>8)&0xff); arr_append(res,(s->plan_id>>16)&0xff); arr_append(res,(s->plan_id>>24)&0xff); for(int i=0;itasks);i++) { sch_task *t=list_get(s->tasks,i); arr_append(res,t->task_id); } int size=arr_length(res); if(sizetasks);i++) { sch_task *t=list_get(s->tasks,i); array_def *a=task_to_array(t); arr_appends_from(res,a); arr_delete(a); } int size=arr_length(res); if(sizetasks);i++) { sch_task *t=list_get(s->tasks,i); num+=t->return_num; } return num; } // 返回0成功,1失败 int scheme_check_ack(array_def *data,int index) { param_check(index>=0); param_check(indexerrs);i++) { sch_errcode *e=list_get(s->errs,i); if(errcode_in_range(e,subcode)) return e->err; } return 0; } // 判定检测数据 scheme_returns *scheme_check_returns(scheme_def *s,array_def *data) { int size=0; size+=sizeof(scheme_returns); size+=sizeof(task_returns)*list_length(s->tasks); size+=sizeof(reurn_item)*scheme_get_returns_num(s); scheme_returns *res=malloc(size); param_check(res); memset(res,0,size); res->size=size; if(s->ch_errcode==0) s->ch_errcode= list_creat_int(); list_clear(s->ch_errcode); int start=16; int off=0; for(int i=0;itasks);i++) { int ack=scheme_check_ack(data,i); sch_task *t=list_get(s->tasks,i); array_def *arr_temp=arr_mid(data,start,t->return_num*2); task_returns *task_ret=task_check_returns(t,ack,arr_temp); arr_delete(arr_temp); memcpy(&res->data[off],task_ret,task_ret->size); off+=task_ret->size; start+=t->return_num*2; list_append_from(s->ch_errcode,t->ch_errcode); } if(list_length(s->ch_errcode)>0) { res->errcode=scheme_fine_majercode(s,list_get_int(s->ch_errcode,0)); }else{ res->errcode=0; } return res; }