/*
简单说明:
针对libzip库,封装了两个接口,compressString 压缩字符串 ,uncompressString 解压字符串
zhangtao /2016/06/13 使用者请联系406878851@qq.com
测试代码:
char inbuf[]="HELLOWORLD";
int inLen=strlen(inbuf);
char outbuf[8192];
int outLen=0;
compressString(inbuf,inLen,outbuf,8192,&outLen) ;
char outbuf2[8192];
int outLen2=0;
uncompressString(outbuf,outLen,outbuf2,8192,&outLen2);
printf("uncompressString %d %s\n",outLen2,outbuf2);
*/
static const char* ziparchive="data.zip";
static const char* archive="data";
static void saveZip(char* apOutBuf,int auOutBufSize)
{
FILE* fp;
if ((fp=fopen(ziparchive, "wb")) == NULL) {
fprintf(stderr, "fopen failed: %s\n", strerror(errno));
return ;
}
printf("fwrite size:%d\n",auOutBufSize);
if (fwrite(apOutBuf, auOutBufSize, 1, fp) < 1) {
fprintf(stderr, "fwrite failed: %s\n", strerror(errno));
fclose(fp);
return;
}
if (fclose(fp) != 0) {
fprintf(stderr, "fclose failed: %s\n", strerror(errno));
return;
}
}
static int compressString(const char* apData,int auDataSize,char* apOutBuf,int auOutBufSize,int* apOutBufLen)
{
int ret=-1;
*apOutBufLen=0;
zip_t *za;
zip_source_t *zs;
zip_stat_t zst;
struct stat st;
zip_source_t *src;
zip_error_t error;
int err;
do
{
src = zip_source_buffer_create(NULL,0, 0, &error);
if (src == NULL) {
err = zip_error_code_zip(&error);
errno = zip_error_code_system(&error);
fprintf(stderr, "zip_source_buffer_create faild: %d\n",err);
break;
}
za = zip_open_from_source(src, 1, &error);
if (za == NULL) {
err = zip_error_code_zip(&error);
errno = zip_error_code_system(&error);
fprintf(stderr, "zip_open_from_source faild: %d\n",err);
break;
}
zip_source_keep(src);
if ((zs=zip_source_buffer(za, apData, auDataSize, 0)) == NULL) {
fprintf(stderr, "can't create zip_source from buffer: %s\n", zip_strerror(za));
break;
}
if (zip_add(za, archive, zs) == -1) {
fprintf(stderr, "can't add file '%s': %s\n", archive, zip_strerror(za));
break;
}
if (zip_close(za) == -1) {
fprintf(stderr, "can't close zip archive '%s': %s\n", archive, zip_strerror(za));
break;
}
za=NULL;
if (zip_source_stat(src, &zst) < 0) {
fprintf(stderr, "zip_source_stat on buffer failed: %s\n", zip_error_strerror(zip_source_error(src)));
break;
}
if (zst.size <=0){
printf(" size error 000\n");
break;
}
if (zst.size >= auOutBufSize){
printf(" size error 111\n");
break;
}
if (zip_source_open(src) < 0) {
if (zip_error_code_zip(zip_source_error(src)) == ZIP_ER_DELETED) {
if (unlink(archive) < 0 && errno != ENOENT) {
fprintf(stderr, "unlink failed: %s\n", strerror(errno));
break;
}
break;
}
fprintf(stderr, "zip_source_open on buffer failed: %s\n", zip_error_strerror(zip_source_error(src)));
break;
}
if (zip_source_read(src, apOutBuf, zst.size) < (zip_int64_t)zst.size) {
fprintf(stderr, "zip_source_read on buffer failed: %s\n", zip_error_strerror(zip_source_error(src)));
zip_source_close(src);
break;
}
zip_source_close(src);
*apOutBufLen = (int)(zst.size);
ret=0;
//saveZip(apOutBuf,*apOutBufLen );
} while (0);
if (NULL != src)
{
zip_source_free(src);
src=NULL;
}
if (NULL != za)
{
zip_close(za);
za=NULL;
}
return ret;
}
static int uncompressString(const char* apData,int auDataSize,char* apOutBuf,int auOutBufSize,int* apOutBufLen)
{
int ret=-1;
*apOutBufLen=0;
zip_error_t error;
int err=0;
char* buf=apOutBuf;
int totalSize=0;
zip_int64_t n = 0;
zip_source_t *src=NULL;
zip_t *za=NULL;
struct zip_file *f=NULL;
do
{
zip_error_init(&error);
/* create source from buffer */
if ((src = zip_source_buffer_create(apData, auDataSize, 1, &error)) == NULL) {
fprintf(stderr, "can't create source: %s\n", zip_error_strerror(&error));
zip_error_fini(&error);
break;
}
/* open zip archive from source */
if ((za = zip_open_from_source(src, 0, &error)) == NULL) {
fprintf(stderr, "can't open zip from source: %s\n", zip_error_strerror(&error));
zip_error_fini(&error);
break;
}
zip_error_fini(&error);
zip_source_keep(src);
zip_int64_t c = zip_get_num_entries(za, ZIP_FL_UNCHANGED);
if ( c != 1)
{
printf("zip_get_num_entries 0 \n");
break;
}
const char * name = zip_get_name(za, 0, ZIP_FL_ENC_GUESS);
if (NULL == name)
{
printf("zip_get_name 0 \n");
break;
}
f = zip_fopen(za, name, 0);
if (NULL == f)
{
printf("zip_fopen 0 \n");
break;
}
if ( auOutBufSize < 4096)
{
printf("auOutBufSize < 4096 \n");
break;
}
totalSize=0;
while( totalSize < auOutBufSize)
{
buf = apOutBuf+ totalSize;
n = zip_fread(f, buf, 4096);
if (n <=0 )
{
break;
}
totalSize += n;
}
if (totalSize >= auOutBufSize)
{
printf("totalSize too big \n");
break;
}
*apOutBufLen=totalSize;
ret=0;
} while (0);
if (NULL != f)
{
zip_fclose(f);
f=NULL;
}
if (NULL != za)
{
//lt-in-memory: free(): invalid pointer: 0x00007fff9c75c6d0 ***
//zip_close(za);
za=NULL;
}
if (NULL != src)
{
zip_source_free(src);
src=NULL;
}
return ret;
}