appack.c
来自「一些初级的网络编程」· C语言 代码 · 共 285 行
C
285 行
/*
* aPLib compression library - the smaller the better :)
*
* C example
*
* Copyright (c) 1998-2004 by Joergen Ibsen / Jibz
* All Rights Reserved
*
* http://www.ibsensoftware.com/
*/
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <stddef.h>
#include <limits.h>
#include "aplib.h"
/*
* Calling convention for the callback.
*/
#ifndef CB_CALLCONV
# if defined(AP_DLL)
# define CB_CALLCONV __stdcall
# elif defined(__GNUC__)
# define CB_CALLCONV
# else
# define CB_CALLCONV __cdecl
# endif
#endif
/*
* Unsigned char type.
*/
typedef unsigned char byte;
/*
* Compute ratio between two numbers.
*/
unsigned int ratio(unsigned int x, unsigned int y)
{
if (x <= UINT_MAX / 100) x *= 100; else y /= 100;
if (y == 0) y = 1;
return x / y;
}
/*
* Compression callback.
*/
int CB_CALLCONV callback(unsigned int insize, unsigned int inpos, unsigned int outpos, void *cbparam)
{
printf("\rcompressed %u -> %u bytes (%u%% done)", inpos, outpos, ratio(inpos, insize));
return 1;
}
/*
* Compress a file.
*/
int compress_file(const char *oldname, const char *packedname)
{
FILE *oldfile;
FILE *packedfile;
size_t insize, outsize;
clock_t clocks;
byte *data, *packed, *workmem;
/* open input file */
if ((oldfile = fopen(oldname, "rb")) == NULL)
{
printf("\nERR: unable to open input file\n");
return 1;
}
/* get size of input file */
fseek(oldfile, 0, SEEK_END);
insize = (size_t) ftell(oldfile);
fseek(oldfile, 0, SEEK_SET);
/* allocate memory */
if ((data = (byte *) malloc(insize)) == NULL ||
(packed = (byte *) malloc(aP_max_packed_size(insize))) == NULL ||
(workmem = (byte *) malloc(aP_workmem_size(insize))) == NULL)
{
printf("\nERR: not enough memory\n");
return 1;
}
if (fread(data, 1, insize, oldfile) != insize)
{
printf("\nERR: error reading from input file\n");
return 1;
}
clocks = clock();
/* compress data block */
outsize = aPsafe_pack(data, packed, insize, workmem, callback, NULL);
clocks = clock() - clocks;
/* check for compression error */
if (outsize == APLIB_ERROR)
{
printf("\nERR: an error occured while compressing\n");
return 1;
}
/* create output file */
if ((packedfile = fopen(packedname, "wb")) == NULL)
{
printf("\nERR: unable to create output file\n");
return 1;
}
fwrite(packed, 1, outsize, packedfile);
/* show result */
printf("\rcompressed %u -> %u bytes (%u%%) in %.2f seconds\n",
insize, outsize, ratio(outsize, insize),
(double)clocks / (double)CLOCKS_PER_SEC);
/* close files */
fclose(packedfile);
fclose(oldfile);
/* free memory */
free(workmem);
free(packed);
free(data);
return 0;
}
/*
* Decompress a file.
*/
int decompress_file(const char *packedname, const char *newname)
{
FILE *newfile;
FILE *packedfile;
size_t insize, outsize;
clock_t clocks;
byte *data, *packed;
size_t depackedsize;
/* open input file */
if ((packedfile = fopen(packedname, "rb")) == NULL)
{
printf("\nERR: unable to open input file\n");
return 1;
}
/* get size of input file */
fseek(packedfile, 0, SEEK_END);
insize = (size_t) ftell(packedfile);
fseek(packedfile, 0, SEEK_SET);
/* allocate memory */
if ((packed = (byte *) malloc(insize)) == NULL)
{
printf("\nERR: not enough memory\n");
return 1;
}
if (fread(packed, 1, insize, packedfile) != insize)
{
printf("\nERR: error reading from input file\n");
return 1;
}
depackedsize = aPsafe_get_orig_size(packed);
if (depackedsize == APLIB_ERROR)
{
printf("\nERR: compressed data error\n");
return 1;
}
/* allocate memory */
if ((data = (byte *) malloc(depackedsize)) == NULL)
{
printf("\nERR: not enough memory\n");
return 1;
}
clocks = clock();
/* decompress data */
outsize = aPsafe_depack(packed, insize, data, depackedsize);
clocks = clock() - clocks;
/* check for decompression error */
if (outsize != depackedsize)
{
printf("\nERR: an error occured while decompressing\n");
return 1;
}
/* create output file */
if ((newfile = fopen(newname, "wb")) == NULL)
{
printf("\nERR: unable to create output file\n");
return 1;
}
/* write decompressed data */
fwrite(data, 1, outsize, newfile);
/* show result */
printf("decompressed %u -> %u bytes in %.2f seconds\n",
insize, outsize,
(double)clocks / (double)CLOCKS_PER_SEC);
/* close files */
fclose(packedfile);
fclose(newfile);
/* free memory */
free(packed);
free(data);
return 0;
}
/*
* Show program syntax.
*/
void show_syntax(void)
{
printf("syntax:\n\n"
" compress : appack c <file> <packed_file>\n"
" decompress : appack d <packed_file> <depacked_file>\n\n");
}
/*
* Main.
*/
int main(int argc, char *argv[])
{
/* show banner */
printf("===============================================================================\n"
"aPLib example Copyright (c) 1998-2004 by Joergen Ibsen / Jibz\n"
" All Rights Reserved\n\n"
" http://www.ibsensoftware.com/\n"
"===============================================================================\n\n");
/* check number of arguments */
if (argc != 4)
{
show_syntax();
return 1;
}
#ifdef __WATCOMC__
/* OpenWatcom 1.2 line buffers stdout, so we unbuffer stdout manually
to make the progress indication in the callback work.
*/
setbuf(stdout, NULL);
#endif
/* check first character of first argument to determine action */
if (argv[1][0] && argv[1][1] == '\0')
{
switch (argv[1][0])
{
/* compress file */
case 'c':
case 'C': return compress_file(argv[2], argv[3]);
/* decompress file */
case 'd':
case 'D': return decompress_file(argv[2], argv[3]);
}
}
/* show program syntax */
show_syntax();
return 1;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?