Panda3D

compress_string.cxx
Go to the documentation of this file.
1 /**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file compress_string.cxx
10 * @author drose
11 * @date 2009-08-09
12 */
13
14 #include "compress_string.h"
15
16 #ifdef HAVE_ZLIB
17 #include "zStream.h"
18 #include "virtualFileSystem.h"
19 #include "config_express.h"
20
21 using std::istream;
22 using std::istringstream;
23 using std::ostream;
24 using std::ostringstream;
25 using std::string;
26
27 /**
28 * Compress the indicated source string at the given compression level (1
29 * through 9). Returns the compressed string.
30 */
31 string
32 compress_string(const string &source, int compression_level) {
33 ostringstream dest;
34
35 {
36 OCompressStream compress;
37 compress.open(&dest, false, compression_level);
38 compress.write(source.data(), source.length());
39
40 if (compress.fail()) {
41 return string();
42 }
43 }
44
45 return dest.str();
46 }
47
48 /**
49 * Decompresss the previously-compressed string()). The return value is the
50 * decompressed string.
51 *
52 * Note that a decompression error cannot easily be detected, and the return
53 * value may simply be a garbage or truncated string.
54 */
55 string
56 decompress_string(const string &source) {
57 istringstream source_stream(source);
58 ostringstream dest_stream;
59
60 if (!decompress_stream(source_stream, dest_stream)) {
61 return string();
62 }
63
64 return dest_stream.str();
65 }
66
67 /**
68 * Compresss the data from the source file at the given compression level (1
69 * through 9). The source file is read in its entirety, and the compressed
70 * results are written to the dest file, overwriting its contents. The return
71 * value is bool on success, or false on failure.
72 */
73 EXPCL_PANDA_EXPRESS bool
74 compress_file(const Filename &source, const Filename &dest, int compression_level) {
75 VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
76 Filename source_filename = source;
77 if (!source_filename.is_binary_or_text()) {
78 // The default is binary, if not specified otherwise.
79 source_filename.set_binary();
80 }
81 istream *source_stream = vfs->open_read_file(source_filename, false);
82 if (source_stream == nullptr) {
83 express_cat.info() << "Couldn't open file " << source_filename << "\n";
84 return false;
85 }
86
87 Filename dest_filename = Filename::binary_filename(dest);
88 ostream *dest_stream = vfs->open_write_file(dest_filename, false, true);
89 if (dest_stream == nullptr) {
90 express_cat.info() << "Couldn't open file " << dest_filename << "\n";
91 vfs->close_read_file(source_stream);
92 return false;
93 }
94
95 bool result = compress_stream(*source_stream, *dest_stream, compression_level);
96 vfs->close_read_file(source_stream);
97 vfs->close_write_file(dest_stream);
98 return result;
99 }
100
101 /**
102 * Decompresss the data from the source file. The source file is read in its
103 * entirety, and the decompressed results are written to the dest file,
104 * overwriting its contents. The return value is bool on success, or false on
105 * failure.
106 *
107 * Note that a decompression error cannot easily be detected, and the output
108 * may simply be a garbage or truncated string.
109 */
110 EXPCL_PANDA_EXPRESS bool
111 decompress_file(const Filename &source, const Filename &dest) {
112 Filename source_filename = Filename::binary_filename(source);
113 VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
114 istream *source_stream = vfs->open_read_file(source_filename, false);
115 if (source_stream == nullptr) {
116 express_cat.info() << "Couldn't open file " << source_filename << "\n";
117 return false;
118 }
119
120 Filename dest_filename = dest;
121 if (!dest_filename.is_binary_or_text()) {
122 // The default is binary, if not specified otherwise.
123 dest_filename.set_binary();
124 }
125 ostream *dest_stream = vfs->open_write_file(dest_filename, false, true);
126 if (dest_stream == nullptr) {
127 express_cat.info() << "Couldn't open file " << dest_filename << "\n";
128 vfs->close_read_file(source_stream);
129 return false;
130 }
131
132 bool result = decompress_stream(*source_stream, *dest_stream);
133 vfs->close_read_file(source_stream);
134 vfs->close_write_file(dest_stream);
135 return result;
136 }
137
138 /**
139 * Compresss the data from the source stream at the given compression level (1
140 * through 9). The source stream is read from its current position to the
141 * end-of-file, and the compressed results are written to the dest stream.
142 * The return value is bool on success, or false on failure.
143 */
144 bool
145 compress_stream(istream &source, ostream &dest, int compression_level) {
146 OCompressStream compress;
147 compress.open(&dest, false, compression_level);
148
149 static const size_t buffer_size = 4096;
150 char buffer[buffer_size];
151
152 source.read(buffer, buffer_size);
153 size_t count = source.gcount();
154 while (count != 0) {
155 compress.write(buffer, count);
156 source.read(buffer, buffer_size);
157 count = source.gcount();
158 }
159 compress.close();
160
161 return (!source.fail() || source.eof()) && (!compress.fail());
162 }
163
164 /**
165 * Decompresss the data from the previously-compressed source stream. The
166 * source stream is read from its current position to the end-of-file, and the
167 * decompressed results are written to the dest stream. The return value is
168 * bool on success, or false on failure.
169 *
170 * Note that a decompression error cannot easily be detected, and the output
171 * may simply be a garbage or truncated string.
172 */
173 bool
174 decompress_stream(istream &source, ostream &dest) {
175 IDecompressStream decompress(&source, false);
176
177 static const size_t buffer_size = 4096;
178 char buffer[buffer_size];
179
180 decompress.read(buffer, buffer_size);
181 size_t count = decompress.gcount();
182 while (count != 0) {
183 dest.write(buffer, count);
184 decompress.read(buffer, buffer_size);
185 count = decompress.gcount();
186 }
187
188 return (!decompress.fail() || decompress.eof()) && (!dest.fail());
189 }
190
191 #endif // HAVE_ZLIB
Filename
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
Filename::set_binary
void set_binary()
Indicates that the filename represents a binary file.
Definition: filename.I:414
Filename::is_binary_or_text
bool is_binary_or_text() const
Returns true either is_binary() or is_text() is true; that is, that the filename has been specified a...
Definition: filename.I:445
VirtualFileSystem
A hierarchy of directories and files that appears to be one continuous file system,...
Definition: virtualFileSystem.h:40
VirtualFileSystem::close_write_file
static void close_write_file(std::ostream *stream)
Closes a file opened by a previous call to open_write_file().
Definition: virtualFileSystem.cxx:929
VirtualFileSystem::open_write_file
std::ostream * open_write_file(const Filename &filename, bool auto_wrap, bool truncate)
Convenience function; returns a newly allocated ostream if the file exists and can be written,...
Definition: virtualFileSystem.cxx:890
VirtualFileSystem::close_read_file
static void close_read_file(std::istream *stream)
Closes a file opened by a previous call to open_read_file().
Definition: virtualFileSystem.cxx:866
VirtualFileSystem::open_read_file
std::istream * open_read_file(const Filename &filename, bool auto_unwrap) const
Convenience function; returns a newly allocated istream if the file exists and can be read,...
Definition: virtualFileSystem.cxx:846
VirtualFileSystem::get_global_ptr
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
Definition: virtualFileSystem.cxx:741
compress_string.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
config_express.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtualFileSystem.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
zStream.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.