/* * This file is a part of CMSLU -- Content Management System like Unix * and is not publicly distributed * * Copyright (c) 2008-2009, Tomasz Sowa * All rights reserved. * */ #include "compress.h" #include "log.h" Compress::Compress() { buffer = 0; buffer_max_len = 65536; // 64KB ready_for_compress = false; } Compress::~Compress() { if( buffer ) delete [] buffer; } bool Compress::AllocateMemory() { if( buffer ) delete [] buffer; try { buffer = new char[buffer_max_len]; } catch(const std::bad_alloc &) { log << log1 << "Compress: can't allocate memory" << logend; buffer = 0; return false; } return true; } /* return: 0 - ok; 1 - can't allocate memory 100 - unknown */ int Compress::Init(int compress_level) { if( buffer == 0 ) if( !AllocateMemory() ) return 1; strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; int ret = deflateInit(&strm, compress_level); if( ret != Z_OK ) log << log1 << "Compress: problem with deflateInit()" << logend; if( ret == Z_MEM_ERROR ) return 1; if( ret != Z_OK ) return 100; ready_for_compress = true; return 0; } int Compress::MakeCompress(const char * source, size_t source_len, FCGX_Stream * out_stream) { int ret, flush; size_t have; do { strm.avail_in = (source_len > buffer_max_len) ? buffer_max_len : source_len; source_len -= strm.avail_in; flush = (source_len == 0) ? Z_FINISH : Z_NO_FLUSH; strm.next_in = (Bytef*)source; source += strm.avail_in; do { strm.avail_out = buffer_max_len; strm.next_out = (Bytef*)buffer; ret = deflate(&strm, flush); if( ret == Z_STREAM_ERROR || ret == Z_BUF_ERROR ) { log << log1 << "Compress: problem with deflate()" << logend; return 2; } have = buffer_max_len - strm.avail_out; last_out_size += have; FCGX_PutStr(buffer, have, out_stream); } while( strm.avail_out == 0 ); if( strm.avail_in != 0 ) { log << log1 << "Compress: problem with deflate() - not all input is used" << logend; return 2; } } while( flush != Z_FINISH ); if( ret != Z_STREAM_END ) { log << log1 << "Compress: problem with deflate() - stream not complete" << logend; return 2; } return 0; } /* return: 0 - ok; 1 - can't allocate memory 2 - error during compressing 3 - not inited (use Init() first) 100 - unknown */ int Compress::CompressAndPut(const char * source, size_t source_len, FCGX_Stream * out_stream, int level) { int ret; last_out_size = 0; if( !ready_for_compress ) { log << log1 << "Compress: not ready yet" << logend; return 3; } if( source_len == 0 ) return 0; ret = MakeCompress(source, source_len, out_stream); if( deflateReset(&strm) != Z_OK ) log << log1 << "Compress: problem with deflateReset()" << logend; double ratio = 100.0 - (double(last_out_size) / double(source_len) * 100.0); char buffer[30]; sprintf(buffer, "%.1f", ratio); log << log2 << "Compress: original size: " << source_len << ", compress size: " << (int)last_out_size << ", ratio: " << buffer << "%" << logend; return ret; }