📄 pack.c
字号:
count_of_VPart=0;
count_of_OPart=0;
pos_V[0]=0;
pos_O[0]=0;
for (i=0;i<format_len;i++) //计算格式串中 V O 的个数
{
c=format[i];
if (c=='V' || c=='v')
pos_V[count_of_VPart++]=i; //记录V在格式串中的位置
else
if (c=='O' || c=='o')
pos_O[count_of_OPart++]=i; //记录O在格式串中的位置
}
if(pos_O[0])
pos_V[count_of_VPart]=pos_O[0];
else
pos_V[count_of_VPart]=i; //置最后一个V类描述符在格式串中的位置
pos_O[count_of_OPart]=i; //置最后一个O类描述符在格式串中的位置
Ooffset=(count_of_OPart==0) ? 0 : 1;//标志是否有O类描述符
len=SubCommonSubFlatPack(buf,format,pos_V[0],p,finish);//调用上层函数处理F类描述符
k=0;
if (count_of_VPart) //若有V类描述符则处理之
{
if(flag) //若有L描述符,则按两字节填写
for(j=0;j<count_of_VPart;j++)
{
(int)p=finish[0];
temp=k+(count_of_VPart+Ooffset-j)*2; //计算偏移地址
memcpy(&buf[len+j*2],&temp,2); //填入两字节中
//调用处理F类描述符的程序对之进行处理
m=SubCommonSubFlatPack(buf+len+(count_of_VPart+Ooffset)*2+k+2,
format+pos_V[j]+1,pos_V[j+1]-pos_V[j],p,finish);
memcpy(&buf[len+(count_of_VPart+Ooffset)*2+k],&m,2); //填入V部分的长度
k+=m+2;
}
else
for (j=0;j<count_of_VPart;j++)
{
(int)p=finish[0]; //取得编程数据地址
buf[len+j]=k+count_of_VPart+Ooffset-j; //填入指向V部分的指针
//调用处理F类描述符的程序对之进行处理
m=SubCommonSubFlatPack(buf+len+count_of_VPart+Ooffset+k+1,
format+pos_V[j]+1,pos_V[j+1]-pos_V[j],p,finish);
buf[len+count_of_VPart+Ooffset+k]=m; //填入V部分的长度
k+=m+1;
}
}
if (count_of_OPart) //若有O类描述符则处理之
{
if(flag)
{ //置指向O部分的指针
buf[len+count_of_VPart*2]=(pos_O[1]-pos_O[0]<3) ? 0 :k+2;
buf[len+count_of_VPart*2+1]=(pos_O[1]-pos_O[0]<3) ? 0 :((k+2)>>8);
for (j=0;j<count_of_OPart;j++)
{
(int)p=finish[0]; //取得编程数据地址
if (pos_O[j+1]-pos_O[j]>=3) //如两O之间有描述符,则进行如下处理
{
buf[len+(count_of_VPart+Ooffset)*2+k]=*p++; //填入O部分的名称
//调用处理F类描述符的程序对之进行处理
m=SubCommonSubFlatPack(buf+len+(count_of_VPart+Ooffset)*2+k+3,
format+pos_O[j]+1,pos_O[j+1]-pos_O[j],p,finish);
memcpy(&buf[len+(count_of_VPart+Ooffset)*2+k+1],&m,2); //填入O部分的长度
k+=m+3;
}
else //如两O之间无描述符,则相应位置置零
{
memset(&buf[len+(count_of_VPart+Ooffset)*2+k],0,3);
k+=3;
}
}
}
else
{
//置指向O部分的指针
buf[len+count_of_VPart]=(pos_O[1]-pos_O[0]<3) ? 0 : k+1;
for (j=0;j<count_of_OPart;j++)
{
(int)p=finish[0]; //取得编程数据地址
if (pos_O[j+1]-pos_O[j]>=3) //如两O之间有描述符,则进行如下处理
{
buf[len+count_of_VPart+Ooffset+k]=*p++; //填入O部分的名称
//调用处理F类描述符的程序对之进行处理
m=SubCommonSubFlatPack(buf+len+count_of_VPart+Ooffset+k+2,
format+pos_O[j]+1,pos_O[j+1]-pos_O[j],p,finish);
buf[len+count_of_VPart+Ooffset+k+1]=m; //填入O部分的长度
k+=m+2;
}
else //如两O之间无描述符,则相应位置置零
{
buf[len+count_of_VPart+Ooffset+k]=0;
buf[len+count_of_VPart+Ooffset+k+1]=0;
k+=2;
}
}
}
}
if(flag)
return len+(count_of_VPart+Ooffset)*2+k;//返回打入的协议数据字节数
else
return len+count_of_VPart+Ooffset+k;
}
//*******************************************************
// 一次性打包函数 *
// buf->协议数据区,format->格式串, para->编程数据区 *
//*******************************************************
int FlatPack(BYTE * buf,BYTE * format,...)
{
int x;
return CommonSubFlatPack(buf,format,strlen(format),((int *)&format)+1,&x);
}
int show(BYTE * buf,int len)
{
int i,j;
for (i=0;i<len;i++)
{
j=buf[i];
j=j>>4;
if(j>9) j+=7;
j+='0';
putchar(j);
j=buf[i];
j&=0x0f;
if(j>9) j+=7;
j+='0';
putchar(j);
putchar(',');
}
return 0;
}
//***************************************
// 一次性解包函数FlatUnPack *
//***************************************
//***************************************
// 底层函数 *
// 实现 宽度,位序,压缩 描述符 *
// flag_RS--位序,flag_pack--压缩 *
// buf->协议数据区,s->编程数据区 *
//返回值 失败:0 成功:协议数据区宽度 *
//***************************************
int SubUnPackIt(BYTE * buf,BYTE * s,int width,int flag_RS,int flag_pack)
{
int i,j,k,awidth,temp,temp1;
//对一些特殊宽度进行处理
if(width==-1) return 0; //如由n描述符读入的宽度<=0,则返回0
else if(width==0)
width=1; //如由数字读入的宽度==0,则将宽度定为1
if (flag_pack==0) //若无压缩描述符,处理如下
{
switch(flag_RS) //根据不同的位序描述符进行处理
{
case 0: //无位序描述符
memcpy(s,buf,width);
return width;
case 1:
for (i=0,j=width-1;i<width;i++,j--) s[i]=buf[j]; // 整串反序
return width;
case 2: // 单字反序
for (i=0;i<width;i=i+2)
for (k=i,j=i+1;k<i+2;k++,j--) s[k]=buf[j];
return width;
case 3: // 双字反序
for (i=0;i<width;i=i+4)
for (k=i,j=i+3;k<i+4;k++,j--) s[k]=buf[j];
return width;
case 4: // 四字反序
for (i=0;i<width;i=i+8)
for (k=i,j=i+7;k<i+8;k++,j--) s[k]=buf[j];
return width;
default:
return width;
}
}
if(flag_pack==1) //#压缩描述符,处理如下
{
awidth=(width+1)/2; //调整协议数据区宽度
switch(flag_RS) //先进行位序描述符处理
{
case 0: //无位序描述符
memcpy(s,buf,awidth);
break;
case 1:
for (i=0,j=awidth-1;i<awidth;i++,j--) s[i]=buf[j]; // 整串反序
break;
case 2: // 单字反序
for (i=0;i<awidth;i=i+2)
for (k=i,j=i+1;k<i+2;k++,j--) s[k]=buf[j];
break;
case 3: // 双字反序
for (i=0;i<awidth;i=i+4)
for (k=i,j=i+3;k<i+4;k++,j--) s[k]=buf[j];
break;
case 4: // 四字反序
for (i=0;i<awidth;i=i+8)
for (k=i,j=i+7;k<i+8;k++,j--) s[k]=buf[j];
break;
default:
break;
}
if(width%2!=0) //对奇数比特进行解压缩
{
i=awidth-1;j=i+i;
s[j]=s[i]&0x0f;
for(i--,j=i+i;i>=0;i--,j-=2)
{
temp=temp1=s[i];
s[j]=temp&0x0f;
s[j+1]=temp1>>4;
}
}
else
for (i=(awidth-1),j=i+i;i>=0;i--,j-=2) //再进行解压缩
{
temp=temp1=s[i];
s[j]=temp&0x0f;
s[j+1]=temp1>>4;
}
return awidth; //返回解出的协议字节数
}
if(flag_pack==2) //$压缩描述符,处理如下
{
awidth=(width+1)/2; //调整协议数据区宽度
switch(flag_RS) //先进行位序描述符处理
{
case 0: //无位序描述符
memcpy(s,buf,width);
break;
case 1:
for (i=0,j=awidth-1;i<awidth;i++,j--) s[i]=buf[j]; // 整串反序
break;
case 2: // 单字反序
for (i=0;i<awidth;i=i+2)
for (k=i,j=i+1;k<i+2;k++,j--) s[k]=buf[j];
break;
case 3: // 双字反序
for (i=0;i<awidth;i=i+4)
for (k=i,j=i+3;k<i+4;k++,j--) s[k]=buf[j];
break;
case 4: // 四字反序
for (i=0;i<awidth;i=i+8)
for (k=i,j=i+7;k<i+8;k++,j--) s[k]=buf[j];
break;
default:
break;
}
if(width%2!=0) //对奇数比特进行解压缩
{
i=awidth-1;j=i+i;
s[j]=s[i]>>4;
for(i--,j=i+i;i>=0;i--,j-=2)
{
temp=temp1=s[i];
s[j]=temp1>>0x0f;
s[j+1]=temp&0x0f;
}
}
else
for (i=(awidth-1),j=i*2;i>=0;i--,j-=2) //再进行解压缩
{
temp=temp1=s[i];
s[j]=temp1>>4;
s[j+1]=temp&0x0f;
}
return awidth; //返回解出的协议字节数
}
return 0;
}
//***************************************
// 实现F类描述符 *
// buf->协议数据区,p->编程数据区 *
// finish[] 记录格式串位置 *
//***************************************
int SubCommonSubUnFlatPack(BYTE * buf,BYTE * format,int format_len,
int p[],int finish[])
{
int i,len,width,state,flag_RS,flag_pack,flag;
int offset;
BYTE c,*pb,p1,p2;
DWORD j,temp,*k;
len=0; //为各计数变量赋处值
width=0;
flag_RS=0;
flag_pack=0;
for (i=0;i<format_len;i++) //对格式串按给定长度进行一遍扫描
switch(c=format[i])
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
c-='0';
width=width*10+c; //计算宽度
break;
case 'n':
case 'N':
width=*p++;
if(width<=0) width=-1; //如由n描述符读入的宽度<=0
//则将宽度定为-1,否则不变
break;
case 'r':
flag_RS=1;
break;
case 'R':
flag_RS=2;
break;
case 's':
flag_RS=3;
break;
case 'S': //记录位序描述符
flag_RS=4;
break;
case '#':
flag_pack=1;
break;
case '$': //记录压缩描述符
flag_pack=2;
break;
case 'f': //遇F类描述符即调用上层函数处理格式串
case 'F':
len+=SubUnPackIt(buf+len,(BYTE *)*p,width,flag_RS,flag_pack);
p++; //P指针后移
width=0; //重置各计数变量
flag_RS=0;
flag_pack=0;
break;
//遇比特描述符立即处理格式串用两个变量记录比特描述符的
case 'b': //大小写与宽度 state:宽度,flag:大小写
case 'B':
state=1;
flag=0;
goto l;
case 'w':
state=2;
flag=0;
goto l;
case 'd':
state=4;
flag=0;
goto l;
case 'W':
state=2;
flag=1;
goto l;
case 'D':
state=4;
flag=1;
goto l;
default:
break;
l:
i++;
while(format[i]==' '&&format[i]!='\0') //移动指针,跳过空格
i++;
k=(DWORD*)(buf+len); //先从协议数据中提取4个字节
temp=*k; //将temp中变量调整到Intel格式
if(flag)
{
switch(state) //如描述符是W,则将temp变量的
{ //前两个字节互换位子
case 2:
j=temp;
j>>=8;
j&=0xff;
temp<<=8;
temp|=j;
break;
case 4: //如描述符是D,则将temp变量的
pb=(BYTE*)&temp; //第一 第四字节互换位子
p1=pb[0]; //第二 第三字节互换位子
p2=pb[3];
pb[0]=p2;
pb[3]=p1;
p1=pb[1];
p2=pb[2];
pb[1]=p2;
pb[2]=p1;
break;
default:
break;
}
}
if(format[i]=='\0'||format[i]!='(') //若比特描述符为单个 直接将
{ //协议数据写入变量
offset=state*8; //计算需屏蔽的位数
*(int*)p[0]>>=offset; //屏蔽编程数据的某几位
*(int*)p[0]<<=offset;
j=temp;
j<<=(32-offset);
j>>=(32-offset);
*(int*)p[0]|=(int)j; //将协议数据的比特位按要求赋给编程数据
p++;
}
else //否则按(...)中的描述符处理
{
offset=0; //将各变量置处值
for(;format[i-1]!=')'&&i<format_len;i++) //若格式串不遇')' or 不超规定
switch (c=format[i]) //长度则继续扫描
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -