Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Related Pages

ZlibStringCompressor.cpp

00001 #include <zlib.h>
00002 #include <sys/stat.h>
00003 #include <iostream>
00004 #include "mrs/message.h"
00005 #include "Sct/StdExceptionWrapper.h"
00006 #include "ZlibStringCompressor.h"
00007 #include "ZlibException.h"
00008 using std::string;
00009 
00010 namespace SctArchiving{
00011 
00012 ZlibStringCompressor::ZlibStringCompressor(unsigned long bufferSize) 
00013   : m_bufferSize(0), m_buffer(0), m_debugLevel(0) {
00014   if (bufferSize) setBufferSize(bufferSize);
00015 }
00016 
00017 unsigned long ZlibStringCompressor::getBufferSize(){
00018   return m_bufferSize;
00019 }
00020 
00021 Bytef* ZlibStringCompressor::setBufferSize(const unsigned long size){
00022   delete m_buffer;
00023   if (getDebugLevel()>0) std::cout << "Deleted buffer" << std::endl;
00024   m_bufferSize=0;
00025   try {
00026     m_buffer = new Bytef[size];
00027   } catch (std::bad_alloc&){
00028     throw ZlibException("Caught std::bad_alloc", __FILE__, __LINE__);
00029   } 
00030   if (getDebugLevel()>0) std::cout << "Set buffer size to " << size  << std::endl;
00031   m_bufferSize=size;
00032   return m_buffer;
00033 }
00034 
00035 void ZlibStringCompressor::checkZlibResult(const int result, const char* file, const int line){
00036   switch (result) {
00037   case  (Z_OK) : { /* "zlib returned ok" */ break;}
00038   case (Z_MEM_ERROR) : { throw ZlibException("zlib reports memory error", file, line);}
00039   case (Z_BUF_ERROR) : { throw ZlibException("zlib buffer insufficient", file, line);}
00040   case (Z_STREAM_ERROR) : { throw ZlibException("zlib reports stream error", file, line);}
00041   case (Z_DATA_ERROR) : { throw ZlibException("zlib reports data corrupted error", file,  line);}
00042   default : {
00043     std::ostringstream oss;
00044     oss << "zlib returned the unknown value of `" << result << "'";
00045     throw ZlibException(oss.str(), file, line);
00046   }
00047   }
00048 }
00049 
00050 const string ZlibStringCompressor::compress(const string& s_in, int level){
00051   // find minimum buffer size for compressed string
00052   unsigned long required_length=findRequiredBufferSize(findSizeInBytes(s_in));
00053   // make sure buffer is at least that size - if its too small add a factor of 2 safety margin!
00054   if ( required_length>getBufferSize() ) {
00055     setBufferSize( required_length*2 );
00056   }
00057 
00058   // reinterpret input string as an array of bytes.
00059   const char* input_char = s_in.c_str();
00060   const Bytef* input_bytes = reinterpret_cast<const Bytef*> ( input_char );
00061   
00062   // make sure level is in the range 1->9
00063   int checked_level = (level<1) ? 1 : (level>9) ? 9 : level;
00064 
00065   unsigned long output_length = getBufferSize();
00066   int result = compress2 (m_buffer, &output_length, input_bytes, 
00067               findSizeInBytes(s_in), checked_level);
00068   
00069   checkZlibResult(result, __FILE__, __LINE__);
00070   const char* result_char=reinterpret_cast<const char*>(m_buffer);
00071   unsigned long char_length=output_length/sizeof(char);
00072   const string s_out(result_char, char_length);
00073   return s_out;
00074 }
00075 
00076 const string ZlibStringCompressor::inflate(const string& s){
00077   long unsigned compressed_length=findSizeInBytes(s);
00078   if (compressed_length*10 > getBufferSize() ){
00079     setBufferSize(compressed_length*10);
00080   }
00081 
00082   long unsigned inflated_length=0;
00083   const char* compressed_c_str=s.c_str();
00084   const Bytef* compressed_bytes=reinterpret_cast<const Bytef*>(compressed_c_str);
00085   
00086   int result = Z_OK;
00087   do {
00088     inflated_length=getBufferSize();
00089     result = uncompress (m_buffer, &inflated_length, compressed_bytes, findSizeInBytes(s));
00090     if (result==Z_BUF_ERROR) setBufferSize(getBufferSize()*2);
00091   } while (result==Z_BUF_ERROR);
00092 
00093   checkZlibResult(result,__FILE__,__LINE__);
00094 
00095   unsigned long inflated_char_length=inflated_length/sizeof(char);
00096   const string s_inflated((char*)m_buffer, inflated_char_length);
00097 
00098   return s_inflated;
00099 }
00100 
00101 }

Generated on Thu Jul 15 09:51:02 2004 for SCT DAQ/DCS Software - C++ by doxygen 1.3.5