📄 ps_client_zip.cpp
字号:
// PS_client_zip.cpp: implementation of the CPSClientZip class.
//
//////////////////////////////////////////////////////////////////////
#include "PS_client_zip.h"
#include "PS_blowfish.h"
#ifndef WIN32
#include <unistd.h>
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CPSClientZip::CPSClientZip():m_nBufferSize(4096)
{
m_mode = 0;
}
CPSClientZip::~CPSClientZip()
{
}
int CPSClientZip::PS_zip_init(int mode)
{
m_mode = mode;
return 1;
}
int CPSClientZip::PS_zip_str_commpress(const char *src, char *dest)
{
if (src == NULL || dest == NULL)
{
return -3;
}
if (strlen(src) >= m_nBufferSize)
{
return -2;
}
int ret = str_deflate((Byte *)dest, m_nBufferSize, src);
if (ret != 0)
return -1;
return 0;
}
int CPSClientZip::PS_zip_str_uncommpress(const char *src, char *dest)
{
if (src == NULL || dest == NULL)
{
return -3;
}
if (strlen(src) >= m_nBufferSize)
{
return -2;
}
int ret = str_inflate((Byte *)src, m_nBufferSize, (Byte *)dest, m_nBufferSize);
if (ret != 0)
{
return -1;
}
return 0;
}
int CPSClientZip::PS_zip_file_compress(const char *filename, char *destfile, int mode)
{
if (filename == NULL || destfile == NULL) // 传入指针为空
{
return -3;
}
if (strlen(filename) >= MAX_NAME_LEN || strlen(destfile) >= MAX_NAME_LEN) // 长度超出最大范围
{
return -2;
}
char outmode[20];
strcpy(outmode, "wb6 ");
if (strlen(destfile) == 0)
{
strcpy(destfile, filename);
strcat(destfile, GZ_SUFFIX);
}
int ret = file_compress(filename, outmode, destfile);
if (mode != 0)
{
unlink(filename);
}
return ret;
}
int CPSClientZip::PS_zip_file_uncompress(const char *filename, char *destfile, int mode)
{
if (filename == NULL || destfile == NULL) // 传入指针为空
{
return -3;
}
if (strlen(filename) >= MAX_NAME_LEN || strlen(destfile) >= MAX_NAME_LEN) // 长度超出最大范围
{
return -2;
}
if (strlen(destfile) == 0) // 字符串长度为0
{
uInt len = (uInt)strlen(filename);
strcpy(destfile, filename);
if (len > SUFFIX_LEN && strcmp(filename+len-SUFFIX_LEN, GZ_SUFFIX) == 0)
{
destfile[len-4] = '\0';
}
}
int ret = file_uncompress(filename, destfile);
if (mode != 0)
{
unlink(filename);
}
return ret;
}
int CPSClientZip::PS_zip_set_mode(int mode)
{
m_mode = mode;
return 1;
}
int CPSClientZip::PS_zip_buf_to_file_compress(const char *buf, char *destfile, unsigned long size)
{
char outmode[20];
strcpy(outmode, "wb6 ");
int err;
const char *p = NULL;
unsigned char *pbuf = NULL;
unsigned long ulsize;
if (m_mode == 1)
{
CBlowFish blow;
unsigned char psw[19] = {0};
blow.GenKey(psw, 18);
blow.Initialize(psw, 18);
ulsize = blow.GetOutputLength(size);
pbuf = new unsigned char[ulsize];
blow.Encode((unsigned char *)buf, pbuf, size);
p = (char *)pbuf;
}
else
{
ulsize = size;
p = buf;
}
gzFile file;
file = gzopen(destfile, outmode);
if (file == NULL)
{
fprintf(stderr, "gzopen error\n");
return 0;
}
while (ulsize > BUFLEN)
{
if (gzwrite(file, p, BUFLEN) != (int)BUFLEN)
{
error(gzerror(file, &err));
gzclose(file);
return 0;
}
p += BUFLEN;
ulsize -= BUFLEN;
}
if (ulsize > 0 && ulsize <= BUFLEN)
{
if (gzwrite(file, p, ulsize) != (int)ulsize)
{
error(gzerror(file, &err));
gzclose(file);
return 0;
}
}
gzclose(file);
if (m_mode == 1)
{
delete []pbuf;
}
return 1;
}
int CPSClientZip::PS_zip_file_to_buf_uncompress(char *filename, char *buf, unsigned long size)
{
local char buffer[BUFLEN];
uLong len;
int err;
char *p = NULL;
unsigned char *pbuf = NULL;
unsigned long ulsize;
if (m_mode == 1)
{
ulsize = CBlowFish::GetOutputLength(size);
pbuf = new unsigned char[ulsize];
p = (char *)pbuf;
}
else
{
ulsize = size;
p = buf;
}
gzFile file;
file = gzopen(filename, "rb");
if (file == NULL)
{
fprintf(stderr, "gzopen error\n");
delete []pbuf;
return 0;
}
unsigned long destsize(0);
while (ulsize > 0)
{
len = gzread(file, buffer, BUFLEN);
if (len < 0)
{
error (gzerror(file, &err));
break;
}
if (len == 0)
break;
if (ulsize > len) // 剩余缓冲区比len大
{
memcpy(p, buffer, len);
p += len;
destsize += len;
}
else // 剩余缓冲区比len小,则写入size否则缓冲区溢出
{
memcpy(p, buffer, len);
destsize += ulsize;
break;
}
ulsize -= len;
}
gzclose(file);
if (m_mode == 1)
{
if (0 != destsize % 8)
{
delete []pbuf;
return 0;
}
CBlowFish blow;
unsigned char psw[19] = {0};
blow.GenKey(psw, 18);
blow.Initialize(psw, 18);
unsigned char *ptmp = new unsigned char[destsize];
blow.Decode((unsigned char *)pbuf, ptmp, destsize);
memcpy(buf, ptmp, destsize);
delete []pbuf;
delete []ptmp;
}
return 1;
}
char *prog;
/* ===========================================================================
* Display error message and exit
*/
void error(const char *msg)
{
fprintf(stderr, "%s: %s\n", prog, msg);
exit(1);
}
/* ===========================================================================
* Compress input to output then close both files.
*/
void CPSClientZip::gz_compress(FILE *in, gzFile out)
{
local char buf[BUFLEN];
int len;
int err;
#ifdef USE_MMAP
/* Try first compressing with mmap. If mmap fails (minigzip used in a
* pipe), use the normal fread loop.
*/
if (gz_compress_mmap(in, out) == Z_OK) return;
#endif
for (;;) {
len = (int)fread(buf, 1, sizeof(buf), in);
if (ferror(in)) {
perror("fread");
exit(1);
}
if (len == 0) break;
if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
}
fclose(in);
if (gzclose(out) != Z_OK) error("failed gzclose");
}
#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
/* Try compressing the input file at once using mmap. Return Z_OK if
* if success, Z_ERRNO otherwise.
*/
int gz_compress_mmap(in, out)
FILE *in;
gzFile out;
{
int len;
int err;
int ifd = fileno(in);
caddr_t buf; /* mmap'ed buffer for the entire input file */
off_t buf_len; /* length of the input file */
struct stat sb;
/* Determine the size of the file, needed for mmap: */
if (fstat(ifd, &sb) < 0) return Z_ERRNO;
buf_len = sb.st_size;
if (buf_len <= 0) return Z_ERRNO;
/* Now do the actual mmap: */
buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
if (buf == (caddr_t)(-1)) return Z_ERRNO;
/* Compress the whole file at once: */
len = gzwrite(out, (char *)buf, (unsigned)buf_len);
if (len != (int)buf_len) error(gzerror(out, &err));
munmap(buf, buf_len);
fclose(in);
if (gzclose(out) != Z_OK) error("failed gzclose");
return Z_OK;
}
#endif /* USE_MMAP */
/* ===========================================================================
* Uncompress input to output then close both files.
*/
void CPSClientZip::gz_uncompress(gzFile in, FILE *out)
{
local char buf[BUFLEN];
int len;
int err;
for (;;) {
len = gzread(in, buf, sizeof(buf));
if (len < 0) error (gzerror(in, &err));
if (len == 0) break;
if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
error("failed fwrite");
}
}
if (fclose(out)) error("failed fclose");
if (gzclose(in) != Z_OK) error("failed gzclose");
}
/* ===========================================================================
* Compress the given file: create a corresponding .rsp file
*/
int CPSClientZip::file_compress(const char *file, char *mode, char *destfile)
{
FILE *in;
gzFile out;
in = fopen(file, "rb");
if (in == NULL) {
perror(file);
return -1;
exit(1);
}
out = gzopen(destfile, mode);
if (out == NULL) {
fprintf(stderr, "%s: can't gzopen %s\n", prog, destfile);
return -1;
exit(1);
}
gz_compress(in, out);
return 0;
}
/* ===========================================================================
* Uncompress the given file
*/
int CPSClientZip::file_uncompress(const char *file, char *destfile)
{
FILE *out;
gzFile in;
uInt len = (uInt)strlen(file);
in = gzopen(file, "rb");
if (in == NULL) {
fprintf(stderr, "%s: can't gzopen %s\n", prog, file);
return -1;
}
out = fopen(destfile, "wb");
if (out == NULL) {
perror(destfile);
return -1;
}
gz_uncompress(in, out);
return 0;
}
/* ===========================================================================
* Test deflate() with small buffers
*/
int str_deflate(Byte *compr, uLong comprLen, const char *src)
{
z_stream c_stream; /* compression stream */
int err;
uLong len = (uLong)strlen(src)+1;
c_stream.zalloc = (alloc_func)0;
c_stream.zfree = (free_func)0;
c_stream.opaque = (voidpf)0;
err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
CHECK_ERR(err, "deflateInit");
c_stream.next_in = (Bytef*)src;
c_stream.next_out = compr;
while (c_stream.total_in != len && c_stream.total_out < comprLen) {
c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
err = deflate(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate");
}
/* Finish the stream, still forcing small buffers: */
for (;;) {
c_stream.avail_out = 1;
err = deflate(&c_stream, Z_FINISH);
if (err == Z_STREAM_END) break;
CHECK_ERR(err, "deflate");
}
err = deflateEnd(&c_stream);
CHECK_ERR(err, "deflateEnd");
return err;
}
/* ===========================================================================
* Test inflate() with small buffers
*/
int str_inflate(Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen)
{
int err;
z_stream d_stream; /* decompression stream */
strcpy((char*)uncompr, "garbage");
d_stream.zalloc = (alloc_func)0;
d_stream.zfree = (free_func)0;
d_stream.opaque = (voidpf)0;
d_stream.next_in = compr;
d_stream.avail_in = 0;
d_stream.next_out = uncompr;
err = inflateInit(&d_stream);
CHECK_ERR(err, "inflateInit");
while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
err = inflate(&d_stream, Z_NO_FLUSH);
if (err == Z_STREAM_END) break;
CHECK_ERR(err, "inflate");
}
err = inflateEnd(&d_stream);
CHECK_ERR(err, "inflateEnd");
return err;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -