Panda3D
|
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