Files
checker_m4/source/soft/history/myjson.c

557 lines
12 KiB
C
Raw Normal View History

2023-06-25 15:30:36 +08:00
#include "myjson.h"
#include "board.h"
#include "debug.h"
#include "mystdlib.h"
#include "bytearray.h"
// json<6F>ַ<EFBFBD><D6B7><EFBFBD>ת<EFBFBD><D7AA>Ϊjson,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱָ<CAB1><D6B8>
cJSON *json_parse(const char *jstr)
{
cJSON *json=cJSON_Parse(jstr);
if(json){
return tappend(json,cJSON_Delete);
}
return json;
}
/*r{ json ת<>б<EFBFBD> }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;i<array_size;i++)
{
o=obj->to_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ת<6E><D7AA><EFBFBD><EFBFBD> }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ת<6E>ַ<EFBFBD><D6B7><EFBFBD> }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;
}
// <20><><EFBFBD><EFBFBD>1<EFBFBD><31><EFBFBD>ڷ<EFBFBD>Χ<EFBFBD><CEA7>
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;
}
// <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>
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;i<list_length(t->params);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<>ɹ<EFBFBD>
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)/2<t->return_num){
DBG_WARN("task=%s, data size too less.",t->brief);
}else{
for(int i=0;i<t->return_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;
}
// <20><><EFBFBD><EFBFBD>1<EFBFBD>ڷ<EFBFBD>Χ<EFBFBD><CEA7>
int errcode_in_range(sch_errcode *e,int subcode)
{
param_check(e);
for(int i=0;i<list_length(e->suberr);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);
}
// <20><><EFBFBD><EFBFBD>idת<64><D7AA>Ϊ<EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
#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;i<list_length(s->tasks);i++)
{
sch_task *t=list_get(s->tasks,i);
arr_append(res,t->task_id);
}
int size=arr_length(res);
if(size<TASKSID_MAX_SIZE){
arr_append_num(res,TASKSID_MAX_SIZE-size,0xff);
}else{
DBG_WARN("taskid array size too larg.");
}
return res;
}
// <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
#define TASKS_MAX_SIZE (0x700-4)
static array_def *scheme_tasks_to_array(scheme_def *s)
{
param_check(s);
array_def *res=arr_creat();
param_check(res);
for(int i=0;i<list_length(s->tasks);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(size<TASKS_MAX_SIZE)
{
arr_append_num(res,TASKS_MAX_SIZE-size,0xff);
}else{
DBG_WARN("tasks array size too larg.");
}
return res;
}
// <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
array_def *scheme_to_byte_array(scheme_def *s)
{
param_check(s);
array_def *res=arr_creat();
param_check(res);
array_def *src;
src=scheme_taskid_to_array(s);
arr_appends_from(res,src);
arr_delete(src);
src=scheme_tasks_to_array(s);
arr_appends_from(res,src);
arr_delete(src);
return res;
}
// ͳ<>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
int scheme_get_returns_num(scheme_def *s)
{
int num=0;
for(int i=0;i<list_length(s->tasks);i++)
{
sch_task *t=list_get(s->tasks,i);
num+=t->return_num;
}
return num;
}
// <20><><EFBFBD><EFBFBD>0<EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><31><CAA7>
int scheme_check_ack(array_def *data,int index)
{
param_check(index>=0);
param_check(index<arr_length(data)*8);
uint8_t temp=arr_get(data,index/8);
if((temp&(1<<(index%8)))!=0)
{return 1;}else{return 0;}
}
// <20><><EFBFBD><EFBFBD><EFBFBD>Ӵ<EFBFBD><D3B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܷ<EFBFBD><DCB7><EFBFBD>0
int scheme_fine_majercode(scheme_def *s,int subcode)
{
for(int i=0;i<list_length(s->errs);i++)
{
sch_errcode *e=list_get(s->errs,i);
if(errcode_in_range(e,subcode))
return e->err;
}
return 0;
}
// <20>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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;i<list_length(s->tasks);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;
}