Panda3D

compress_string.cxx

00001 // Filename: compress_string.cxx
00002 // Created by:  drose (09Aug09)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "compress_string.h"
00016 
00017 #ifdef HAVE_ZLIB
00018 #include "zStream.h"
00019 #include "virtualFileSystem.h"
00020 #include "config_express.h"
00021 
00022 ////////////////////////////////////////////////////////////////////
00023 //     Function: compress_string
00024 //       Access: Published
00025 //  Description: Compress the indicated source string at the given
00026 //               compression level (1 through 9).  Returns the
00027 //               compressed string.
00028 ////////////////////////////////////////////////////////////////////
00029 string
00030 compress_string(const string &source, int compression_level) {
00031   ostringstream dest;
00032 
00033   {
00034     OCompressStream compress;
00035     compress.open(&dest, false, compression_level);
00036     compress.write(source.data(), source.length());
00037 
00038     if (compress.fail()) {
00039       return string();
00040     }
00041   }
00042 
00043   return dest.str();
00044 }
00045 
00046 ////////////////////////////////////////////////////////////////////
00047 //     Function: decompress_string
00048 //       Access: Published
00049 //  Description: Decompresss the previously-compressed string()).  The
00050 //               return value is the decompressed string.
00051 //
00052 //               Note that a decompression error cannot easily be
00053 //               detected, and the return value may simply be a
00054 //               garbage or truncated string.
00055 ////////////////////////////////////////////////////////////////////
00056 string
00057 decompress_string(const string &source) {
00058   istringstream source_stream(source);
00059   ostringstream dest_stream;
00060 
00061   if (!decompress_stream(source_stream, dest_stream)) {
00062     return string();
00063   }
00064 
00065   return dest_stream.str();
00066 }
00067 
00068 ////////////////////////////////////////////////////////////////////
00069 //     Function: compress_file
00070 //       Access: Published
00071 //  Description: Compresss the data from the source file at the given
00072 //               compression level (1 through 9).  The source file is
00073 //               read in its entirety, and the compressed results are
00074 //               written to the dest file, overwriting its contents.
00075 //               The return value is bool on success, or false on
00076 //               failure.
00077 ////////////////////////////////////////////////////////////////////
00078 EXPCL_PANDAEXPRESS bool 
00079 compress_file(const Filename &source, const Filename &dest, int compression_level) {
00080   Filename source_filename = Filename::binary_filename(source);
00081   VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
00082   istream *source_stream = vfs->open_read_file(source_filename, true);
00083   if (source_stream == NULL) {
00084     express_cat.info() << "Couldn't open file " << source_filename << "\n";
00085     return false;
00086   }
00087   
00088   Filename dest_filename = Filename::binary_filename(dest);
00089   pofstream dest_stream;
00090   if (!dest_filename.open_write(dest_stream)) {
00091     express_cat.info() << "Couldn't open file " << dest_filename << "\n";
00092     vfs->close_read_file(source_stream);
00093     return false;
00094   }
00095     
00096   bool result = compress_stream(*source_stream, dest_stream, compression_level);
00097   vfs->close_read_file(source_stream);
00098   return result;
00099 }
00100 
00101 ////////////////////////////////////////////////////////////////////
00102 //     Function: decompress_file
00103 //       Access: Published
00104 //  Description: Decompresss the data from the source file.  The
00105 //               source file is read in its entirety, and the
00106 //               decompressed results are written to the dest file,
00107 //               overwriting its contents.  The return value is bool
00108 //               on success, or false on failure.
00109 //
00110 //               Note that a decompression error cannot easily be
00111 //               detected, and the output may simply be a garbage
00112 //               or truncated string.
00113 ////////////////////////////////////////////////////////////////////
00114 EXPCL_PANDAEXPRESS bool 
00115 decompress_file(const Filename &source, const Filename &dest) {
00116   Filename source_filename = Filename::binary_filename(source);
00117   VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
00118   istream *source_stream = vfs->open_read_file(source_filename, false);
00119   if (source_stream == NULL) {
00120     express_cat.info() << "Couldn't open file " << source_filename << "\n";
00121     return false;
00122   }
00123   
00124   Filename dest_filename = Filename::binary_filename(dest);
00125   pofstream dest_stream;
00126   if (!dest_filename.open_write(dest_stream)) {
00127     express_cat.info() << "Couldn't open file " << dest_filename << "\n";
00128     vfs->close_read_file(source_stream);
00129     return false;
00130   }
00131     
00132   bool result = decompress_stream(*source_stream, dest_stream);
00133   vfs->close_read_file(source_stream);
00134   return result;
00135 }
00136 
00137 ////////////////////////////////////////////////////////////////////
00138 //     Function: compress_stream
00139 //       Access: Published
00140 //  Description: Compresss the data from the source stream at the
00141 //               given compression level (1 through 9).  The source
00142 //               stream is read from its current position to the
00143 //               end-of-file, and the compressed results are written
00144 //               to the dest stream.  The return value is bool on
00145 //               success, or false on failure.
00146 ////////////////////////////////////////////////////////////////////
00147 bool
00148 compress_stream(istream &source, ostream &dest, int compression_level) {
00149   OCompressStream compress;
00150   compress.open(&dest, false, compression_level);
00151     
00152   static const size_t buffer_size = 4096;
00153   char buffer[buffer_size];
00154 
00155   source.read(buffer, buffer_size);
00156   size_t count = source.gcount();
00157   while (count != 0) {
00158     compress.write(buffer, count);
00159     source.read(buffer, buffer_size);
00160     count = source.gcount();
00161   }
00162   compress.close();
00163 
00164   return (!source.fail() || source.eof()) && (!compress.fail());
00165 }
00166 
00167 ////////////////////////////////////////////////////////////////////
00168 //     Function: decompress_stream
00169 //       Access: Published
00170 //  Description: Decompresss the data from the previously-compressed
00171 //               source stream.  The source stream is read from its
00172 //               current position to the end-of-file, and the
00173 //               decompressed results are written to the dest stream.
00174 //               The return value is bool on success, or false on
00175 //               failure.
00176 //
00177 //               Note that a decompression error cannot easily be
00178 //               detected, and the output may simply be a garbage
00179 //               or truncated string.
00180 ////////////////////////////////////////////////////////////////////
00181 bool
00182 decompress_stream(istream &source, ostream &dest) {
00183   IDecompressStream decompress(&source, false);
00184 
00185   static const size_t buffer_size = 4096;
00186   char buffer[buffer_size];
00187 
00188   decompress.read(buffer, buffer_size);
00189   size_t count = decompress.gcount();
00190   while (count != 0) {
00191     dest.write(buffer, count);
00192     decompress.read(buffer, buffer_size);
00193     count = decompress.gcount();
00194   }
00195   
00196   return (!decompress.fail() || decompress.eof()) && (!dest.fail());
00197 }
00198 
00199 #endif // HAVE_ZLIB
 All Classes Functions Variables Enumerations