/*
*
*time:2014-10-27
*/
#define DATA_NUM 4
#define DATA_LENGTH 256
typedef unsigned char Byte;
//reach_data, contains several data blocks
typedef struct st_ReachData{
int sth;//identify for reach_data
size_t length[DATA_NUM];//data length
Byte data[DATA_NUM][DATA_LENGTH];//several data blocks
}ReachData;
//thin_data,contains only one data block
typedef struct st_ThinData{
int sth;//identify for original reach_data
int index;//current data block 's index in original reach_data
size_t length;//data length
Byte data[DATA_LENGTH];//data
}ThinData;
void*CopyMem(const void*src, void*dst, size_t length){
const Byte*bsrc;
Byte *bdst;
assert(src!=NULL&&dst!=NULL);
bsrc=(Byte*)src;
bdst=(Byte*)dst;
while(length-->0)
*bdst++=*bsrc++;
return dst;
}
//zip,ReachData->ThinData;
//reachData
//pNum; when return , is the num of reach_data contains effective data blocks
//thinData
//return: num of thin_data
int ZipData(const ReachData*reachData, int*pNum, ThinData*thinData){
int num=*pNum, realNum=*pNum;
int thinNum=0;
const ReachData*tmp;
ThinData*tmpThin,*thinDst=thinData;
assert(reachData!=NULL&&pNum!=NULL&&thinData!=NULL);
for(tmp=reachData; tmp<reachData+num; ++tmp){
bool isEmpty=true;
for(int j=0; j<DATA_NUM; ++j){
if(tmp->length[j]>0){
isEmpty=false;
++thinNum;
}
}
if(isEmpty)
--realNum;
}
if(0==thinNum){
*pNum=0;
return 0;
}
tmpThin=new ThinData[thinNum];
for(tmp=reachData, thinData=tmpThin; tmp<reachData+num; ++tmp){
for(int j=0; j<DATA_NUM; ++j){
if(tmp->length[j]>0){
thinData->sth=tmp->sth;
thinData->length=tmp->length[j];
thinData->index=j;
CopyMem(tmp->data[j], thinData->data, thinData->length);
++thinData;
}
}
}
for(int k=0; k<thinNum; ++k)
thinDst[k]=tmpThin[k];
delete[]tmpThin;
*pNum=realNum;
return thinNum;
}
//Unzip:ThinData->ReachData;assume thin data comes from zip
//return:num of reach_data
int UnZipData(const ThinData*thinData, int num, ReachData*reachData){
int reachNum=0;
ReachData*tmpReach=NULL, *tmp;
assert(num>=0);
if(num==0)
return 0;
//tempt buffer
tmpReach=new ReachData[num];
tmp=tmpReach;
for(int j=0; j<num; ++tmp){
tmp->sth=thinData[j].sth;
for(int k=0; k<DATA_NUM; ++k)
tmp->length[k]=0;
while(j<num&&thinData[j].sth==tmp->sth){
int index=thinData[j].index;//index of current data block
assert(0<=index&&DATA_NUM>index);
tmp->length[index]=thinData[j].length;//length
//copy data
CopyMem(thinData[j].data, tmp->data[index], thinData[j].length);
++j;
}
}
//富数据的个数
reachNum=tmp-tmpReach;
//复制到目的地
for(tmp=tmpReach; tmp<tmpReach+reachNum;)
*reachData++=*tmp++;
delete[]tmpReach;
return reachNum;
}
//test: ZipData&UnZipData
void TestZipUnZip(void){
const int REACH_LEN=10;
const int THIN_LEN=REACH_LEN*DATA_NUM;
ReachData reachData[REACH_LEN];
ThinData thinData[THIN_LEN];
Byte data[DATA_LENGTH]="hello, world!";
//test zip
//prepare some reach data for test
for(int k=0; k<REACH_LEN; ++k){
reachData[k].sth=k;
for(int j=0; j<DATA_NUM; ++j)
reachData[k].length[j]=0;
if(k<3){
// reachData[k].length[0]=0;
}else if(k<6){
reachData[k].length[0]=DATA_LENGTH;
CopyMem(data, reachData[k].data[0], DATA_LENGTH);
}else{
reachData[k].length[1]=DATA_LENGTH;
CopyMem(data, reachData[k].data[1], DATA_LENGTH);
reachData[k].length[2]=DATA_LENGTH;
CopyMem(data, reachData[k].data[2], DATA_LENGTH);
}
}
int rnum=REACH_LEN;
//zip
int tnum=ZipData(reachData, &rnum, thinData);
printf("zip: reachNum=%d, thinNum=%d\n", rnum, tnum);
for(int k=0; k<tnum; ++k){
printf("sth=%d, length=%d, index=%d\n",
thinData[k].sth, thinData[k].length, thinData[k].index);
}
//unZip,result is same with that before zip
memset(reachData, 0, sizeof(reachData));
rnum=UnZipData(thinData, tnum, reachData);
printf("unZip: rnum=%d\n", rnum);
assert(REACH_LEN-3==rnum);
for(int k=0; k<rnum; ++k){
printf("sth=%d\n", reachData[k].sth);
for(int j=0; j<DATA_NUM; ++j)
if(reachData[k].length[j]>0)
printf("index=%d, length=%d, data=%s\n",
j, reachData[k].length[j], reachData[k].data[j]);
}
}
实用的数据压缩解压缩方法
最新推荐文章于 2022-06-11 10:24:53 发布