实用的数据压缩解压缩方法

/*
*
*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]);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值