Added abstract Compressor class for data (de)compression.

git-svn-id: http://voip.null.ro/svn/yate@3423 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
marian 2010-07-09 10:20:08 +00:00
parent 5770afed26
commit 25e288711c
3 changed files with 260 additions and 1 deletions

105
engine/Compressor.cpp Normal file
View File

@ -0,0 +1,105 @@
/**
* Compressor.cpp
* This file is part of the YATE Project http://YATE.null.ro
*
* Yet Another Telephony Engine - a fully featured software PBX and IVR
* Copyright (C) 2004-2010 Null Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "yatengine.h"
using namespace TelEngine;
// Compress the input buffer, flush all data,
// append compressed data to the received data block
int Compressor::compress(const void* buf, unsigned int len, DataBlock& dest)
{
XDebug(DebugAll,"Compressor(%s)::compress(%p,%u) dest len %u [%p]",
toString().c_str(),buf,len,dest.length(),this);
if (!(buf && len)) {
buf = 0;
len = 0;
}
const unsigned char* wrBuf = (const unsigned char*)buf;
int ret = 0;
while (true) {
int wr = 0;
if (len) {
wr = writeComp(wrBuf + ret,len,false);
XDebug(DebugAll,"Compressor(%s)::compress() wrote %d [%p]",
toString().c_str(),wr,this);
if (wr > 0) {
ret += wr;
len -= wr;
}
}
int rd = readComp(dest,true);
XDebug(DebugAll,"Compressor(%s)::compress() read %d [%p]",
toString().c_str(),rd,this);
// Don't stop if write succeeded and was partial
if (rd >= 0 && wr >= 0 && len)
continue;
// Set return value to error or 0 if nothing wrote so far
if (!ret)
ret = wr;
break;
}
XDebug(DebugAll,"Compressor(%s)::compress(%p,%u) returning %d dest len %u [%p]",
toString().c_str(),buf,len,ret,dest.length(),this);
return ret;
}
// Decompress the input buffer, flush all data,
// append decompressed data to the received data block
int Compressor::decompress(const void* buf, unsigned int len, DataBlock& dest)
{
XDebug(DebugAll,"Compressor(%s)::decompress(%p,%u) dest len %u [%p]",
toString().c_str(),buf,len,dest.length(),this);
if (!(buf && len)) {
buf = 0;
len = 0;
}
const unsigned char* wrBuf = (const unsigned char*)buf;
int ret = 0;
while (true) {
int wr = 0;
if (len) {
wr = writeDecomp(wrBuf + ret,len,false);
XDebug(DebugAll,"Compressor(%s)::decompress() wrote %d [%p]",
toString().c_str(),wr,this);
if (wr > 0) {
ret += wr;
len -= wr;
}
}
int rd = readDecomp(dest,true);
XDebug(DebugAll,"Compressor(%s)::decompress() read %d [%p]",
toString().c_str(),rd,this);
// Don't stop if write succeeded and was partial
if (rd >= 0 && wr >= 0 && len)
continue;
// Set return value to error or 0 if nothing wrote so far
if (!ret)
ret = wr;
break;
}
XDebug(DebugAll,"Compressor(%s)::decompress(%p,%u) returning %d dest len %u [%p]",
toString().c_str(),buf,len,ret,dest.length(),this);
return ret;
}
/* vi: set ts=8 sw=4 sts=4 noet: */

View File

@ -27,7 +27,7 @@ LIBS :=
CLSOBJS := TelEngine.o ObjList.o HashList.o Mutex.o Thread.o Socket.o \
String.o DataBlock.o NamedList.o Evaluator.o \
URI.o Mime.o Array.o Iterator.o \
YMD5.o YSHA1.o Base64.o Cipher.o
YMD5.o YSHA1.o Base64.o Cipher.o Compressor.o
ENGOBJS := Configuration.o Message.o Engine.o Plugin.o
TELOBJS := DataFormat.o Channel.o
CLIOBJS := Client.o ClientLogic.o

View File

@ -6178,6 +6178,160 @@ private:
static const TokenDict s_directions[];
};
/**
* The Compressor class provides an abstraction for data (de)compressor classes.
* The String component keeps an optional object name to be used for debug purposes
* @short An abstract data (de)compressor
*/
class YATE_API Compressor : public String
{
YCLASS(Compressor,String)
YNOCOPY(Compressor); // no automatic copies please
public:
/**
* Constructor
* @param format Compression format
* @param name Optional object name
*/
inline Compressor(const char* format, const char* name = 0)
: String(name), m_format(format)
{}
/**
* Destructor
*/
virtual ~Compressor()
{}
/**
* Retrieve (de)compressor format
* @return The format of this (de)compressor
*/
inline const String& format() const
{ return m_format; }
/**
* Initialize
* @param comp True to initialize compressor
* @param decomp True to initialize decompressor
* @param params Optional parameters
* @return True on success
*/
virtual bool init(bool comp = true, bool decomp = true,
const NamedList& params = NamedList::empty())
{ return true; }
/**
* Finalize the (de)compression
* @param comp True to finalize compression, false to finalize decompression
*/
virtual void finalize(bool comp)
{}
/**
* Compress the input buffer, flush all pending data,
* append compressed data to the received data block
* @param buf Pointer to input data
* @param len Length of input in bytes
* @param dest Destination buffer
* @return The number of bytes wrote to compressor, negative on error
*/
virtual int compress(const void* buf, unsigned int len, DataBlock& dest);
/**
* Decompress the input buffer, flush all pending data,
* append decompressed data to the received data block
* @param buf Pointer to input data
* @param len Length of input in bytes
* @param dest Destination buffer
* @return The number of bytes wrote to decompressor, negative on error
*/
virtual int decompress(const void* buf, unsigned int len, DataBlock& dest);
/**
* Push data to compressor. Flush compressor input if input buffer is NULL
* or the length is 0 and flush is true
* @param buf Pointer to input data
* @param len Length of input in bytes
* @param flush True to compress all now, false to let the compressor accumulate
* more data for better compression
* @return The number of bytes written, negative on error. An incomplete write may occur
* if the output buffer is full
*/
virtual int writeComp(const void* buf, unsigned int len, bool flush) = 0;
/**
* Push data to compressor
* @param data Input data block
* @param flush True to compress all now, false to let the compressor accumulate
* more data for better compression
* @return The number of bytes written, negative on error. An incomplete write may occur
* if the output buffer is full
*/
inline int writeComp(const DataBlock& data, bool flush)
{ return writeComp(data.data(),data.length(),flush); }
/**
* Push data to compressor
* @param data Input string
* @param flush True to compress all now, false to let the compressor accumulate
* more data for better compression
* @return The number of bytes written, negative on error. An incomplete write may occur
* if the output buffer is full
*/
inline int writeComp(const String& data, bool flush)
{ return writeComp(data.c_str(),data.length(),flush); }
/**
* Read data from compressor. Append it to 'buf'
* @param buf Destination data block
* @param flush True to flush all compressor input data
* @return The number of bytes read, negative on error
*/
virtual int readComp(DataBlock& buf, bool flush) = 0;
/**
* Push data to decompressor
* @param buf Pointer to input data
* @param len Length of input in bytes
* @param flush True to try to decompress all data
* @return The number of bytes written, negative on error. An incomplete write may occur
* if the output buffer is full
*/
virtual int writeDecomp(const void* buf, unsigned int len, bool flush) = 0;
/**
* Push data to decompressor
* @param data Input data block
* @param flush True to try to decompress all data
* @return The number of bytes written, negative on error. An incomplete write may occur
* if the output buffer is full
*/
inline int writeDecomp(const DataBlock& data, bool flush)
{ return writeDecomp(data.data(),data.length(),flush); }
/**
* Push data to decompressor
* @param data Input string
* @param flush True to try to decompress all data
* @return The number of bytes written, negative on error. An incomplete write may occur
* if the output buffer is full
*/
inline int writeDecomp(const String& data, bool flush)
{ return writeDecomp(data.c_str(),data.length(),flush); }
/**
* Read data from decompressor. Append it to 'buf'
* @param buf Destination data block
* @param flush True to flush all decompressor input data
* @return The number of bytes read, negative on error
*/
virtual int readDecomp(DataBlock& buf, bool flush) = 0;
protected:
String m_format;
};
/**
* The SysUsage class allows collecting some statistics about engine's usage
* of system resources