在我们处理业务代码时,时常会写出多层嵌套的if else代码,这样代码肯定是不符合软件规范的,
如下代码:
if( head->playloadlen != 1 )
{
if( head->packet_type == PERIOD_INSTRUCTION_REQ )
{
//LOG_DATA(data + sizeof(cdc_packet_head), len - sizeof(cdc_packet_head));
ack_rep = can_periodinfo_def(ctx->singal_data, data + sizeof(cdc_packet_head), len - sizeof(cdc_packet_head),&(ctx->udp));
sdc_send_ack(ctx,ack_rep);
free(ack_rep);
}
else if(head-> packet_type == COMPLETE_INSTRUCTION_REQ)
{
ack_rep = can_completeinfo_def(ctx->singal_data, data + sizeof(cdc_packet_head), len - sizeof(cdc_packet_head),&(ctx->udp));
sdc_send_ack(ctx,ack_rep);
free(ack_rep);
}
else
{
;
}
}
else //服务返回ack接受情况
{
//正确接受数据
if( *(data + sizeof(cdc_packet_head)) == 0x00)
{
}
//组包失败或接受数据失败,重新传输
else if(*(data + sizeof(cdc_packet_head)) == 0x01)
{
}
//多次传输后,仍然错误,删除数据
else if(*(data + sizeof(cdc_packet_head)) == 0x02)
在上面代码中,有两层if else 嵌套,判断的条件变量和ack号和协议号。
怎样进行代码改进了,这样参照了linux内核中Netfilter NF_HOOK 中的方法,
改进代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define __CONNECT2(__A, __B) __A##__B
#define CONNECT2(__A, __B) __CONNECT2(__A, __B)
#define __CONNECT3(__A, __B, __C) __A##__B##__C
#define CONNECT3(__A, __B, __C) __CONNECT3(__A, __B, __C)
#define VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,__N,...) __N
#define VA_NUM_ARGS(...) \
VA_NUM_ARGS_IMPL(__VA_ARGS__,9,8,7,6,5,4,3,2,1)
typedef enum
{
SCRIPT_NEGATION = 0,
VEHICLE_STATUS_REQ,
VEHICLE_STATUS_REP,
PERIOD_INSTRUCTION_ISSUE,
PERIOD_INSTRUCTION_REP,
TRIGGER_INSTRUCTION_ISSUE,
TRIGGER_INSTRUCTION_REP,
FULL_INSTRUCTION_ISSUE,
FULL_INSTRUCTION_REP,
PERIOD_INSTRUCTION_UPLOAD,
PERIOD_INSTRUCTION_UPLOADREP,
TRIGGER_INSTRUCTION_UPLOAD,
TRIGGER_INSTRUCTION_UPLOADREP,
FULL_INSTRUCTION_UPLOAD,
FULL_INSTRUCTION_UPLOADREP,
VEHICLE_MAX_INSTRUCTION
}CSM_type;
struct trans_cmd_t_
{
CSM_type m_type;
int p_pro;
}VEHICLE_CMD_TO_INDEX[] =
{
{SCRIPT_NEGATION,0x0000},
{VEHICLE_STATUS_REQ,0x0001},
{VEHICLE_STATUS_REP,0x0002},
{PERIOD_INSTRUCTION_ISSUE,0x2001},
{PERIOD_INSTRUCTION_REP,0x2002},
{TRIGGER_INSTRUCTION_ISSUE,0x2011},
{TRIGGER_INSTRUCTION_REP,0x2012},
{FULL_INSTRUCTION_ISSUE,0x2021},
{FULL_INSTRUCTION_REP,0x2022},
{PERIOD_INSTRUCTION_UPLOAD,0x9001},
{PERIOD_INSTRUCTION_UPLOADREP,0x9002},
{TRIGGER_INSTRUCTION_UPLOAD,0x9011},
{TRIGGER_INSTRUCTION_UPLOADREP,0x9012},
{FULL_INSTRUCTION_UPLOAD,0x9021},
{VEHICLE_MAX_INSTRUCTION,0x9022},
};
typedef void (*ap_hookfn)(int pri,void* arg);
void test1(int c,void *arg)
{
printf("test1----%d %p--\n",c,arg);
}
void test2(int c,void *arg)
{
printf("test2----%d %p--\n",c,arg);
}
void test3(int c,void *arg)
{
printf("test3----%d %p--\n",c,arg);
}
void test4(int c,void *arg)
{
printf("test4----%d %p--\n",c,arg);
}
struct list_head
{
struct list_head * next;
};
/********************************************************************************
*Function:vehicle_to_index
*Description:车辆类型转换
*Return: -1:转换失败,其他成功
Param:
*@packettype[in]:协议类型
********************************************************************************/
static CSM_type vehicle_to_index(unsigned short provalue)
{
int i = 0;
for( i = 0; i < VEHICLE_MAX_INSTRUCTION;i++)
{
if( VEHICLE_CMD_TO_INDEX[i].p_pro == provalue)
{
return i;
}
}
return -1;
}
typedef struct ack_and_packet_hook_ops
{
struct list_head list;
ap_hookfn m_hook;
int m_ackvalue;
}ack_and_packet_hook_ops;
//头部插入,插在头结点之后,
static inline void list_add_head(struct list_head *new, struct list_head *head)
{
new->next = head->next;
head->next = new;
}
ack_and_packet_hook_ops* init_hook_ops(void)
{
ack_and_packet_hook_ops *hook_ops = (ack_and_packet_hook_ops*)malloc(sizeof(ack_and_packet_hook_ops) * VEHICLE_MAX_INSTRUCTION);
memset(hook_ops,0x00,sizeof(ack_and_packet_hook_ops)*VEHICLE_MAX_INSTRUCTION);
int i = 0;
for( i = 0; i < VEHICLE_MAX_INSTRUCTION;i++)
{
hook_ops[i].list.next = &(hook_ops[i].list);
}
return hook_ops;
}
int register_hook_ops4(ack_and_packet_hook_ops* ops,unsigned short provalue,unsigned char ackvalue,ap_hookfn hook)
{
int trans_pro_value = vehicle_to_index(provalue);
ack_and_packet_hook_ops* new_class = (ack_and_packet_hook_ops*)calloc(1,sizeof(ack_and_packet_hook_ops));
printf("new calloc %p\n",new_class);
printf("new calloc %p\n",&new_class->list);
new_class->m_ackvalue = ackvalue;
new_class->m_hook = hook;
list_add_head(&(new_class->list), &(ops[trans_pro_value].list));
return 0;
}
int register_hook_ops3(ack_and_packet_hook_ops* ops,unsigned short provalue,ap_hookfn hook)
{
int trans_pro_value = vehicle_to_index(provalue);
printf("trans_pro_value is %d\n",trans_pro_value);
ops[trans_pro_value].m_hook = hook;
return 0;
}
#define register_hook_ops(...) \
CONNECT2(register_hook_ops, VA_NUM_ARGS(__VA_ARGS__)) \
(__VA_ARGS__)
int cdc_hook_thresh(ack_and_packet_hook_ops* ops,unsigned short pro,int ack,int arg1,void* arg2)
{
unsigned short actpro = vehicle_to_index(pro);
if(ack >= 0)
{
ack_and_packet_hook_ops* tmp = &(ops[actpro]);
while(tmp->list.next != &(tmp->list))
{
ack_and_packet_hook_ops*l_tmp = (ack_and_packet_hook_ops*)tmp->list.next;
if(l_tmp->m_ackvalue == ack)
{
if(l_tmp->m_hook)
{
l_tmp->m_hook(arg1,arg2);
}
}
printf("&&&&&&&&&&&&&&&&&\n");
tmp->list.next = tmp->list.next->next;
}
}
else
{
printf("cdc_hook_thresh %d\n",actpro);
ops[actpro].m_hook(1,NULL);
}
}
void deinit_hook_ops(ack_and_packet_hook_ops* ops)
{
int i = 0;
for( i = 0; i < VEHICLE_MAX_INSTRUCTION;i++)
{
ack_and_packet_hook_ops* tmp = 0;
printf("----------------%d----------\n",i);
while( ops[i].list.next != &(ops[i].list))
{
printf("----------------%d----------\n",i);
tmp = (ack_and_packet_hook_ops*)ops[i].list.next;
printf("*********%d***%p**\n",i,ops[i].list.next);
ops[i].list.next = ops[i].list.next->next;
free(tmp);
}
}
free(ops);
return ;
}
#define CDC_HOOK_THRESH(ops,pro,ack,arg1,arg2) cdc_hook_thresh(ops,pro,ack,arg1,arg2);
int main(int argc,char* argv[])
{
// 测试方法
ack_and_packet_hook_ops* test = (ack_and_packet_hook_ops*)calloc(1,sizeof(ack_and_packet_hook_ops));
printf("%p---%p\n",test,&(test->list));
ack_and_packet_hook_ops* ps = init_hook_ops();
/*登记服务器返回协议ACK处理函数*/
register_hook_ops(ps,0x2001,0x00,test1);
register_hook_ops(ps,0x2001,0x01,test2);
register_hook_ops(ps,0x2002,0x00,test1);
register_hook_ops(ps,0x2002,0x01,test2);
/*登记处理服务器下发的协议*/
register_hook_ops(ps,0x2012,test3);
char p[] = "hello world";
printf("%p\n",p);
//CDC_HOOK_THRESH(ps,0x2002,0x00,1,p);
//CDC_HOOK_THRESH(ps,0x2012,-1,1,p);
deinit_hook_ops(ps);
return 0;
}