Panda3D
Loading...
Searching...
No Matches
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
21using std::istream;
22using std::istringstream;
23using std::ostream;
24using std::ostringstream;
25using std::string;
26
27/**
28 * Compress the indicated source string at the given compression level (1
29 * through 9). Returns the compressed string.
30 */
31string
32compress_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 */
55string
56decompress_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 */
73EXPCL_PANDA_EXPRESS bool
74compress_file(const Filename &source, const Filename &dest, int compression_level) {
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 */
110EXPCL_PANDA_EXPRESS bool
111decompress_file(const Filename &source, const Filename &dest) {
112 Filename source_filename = Filename::binary_filename(source);
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 */
144bool
145compress_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 */
173bool
174decompress_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
The name of a file, such as a texture file or an Egg file.
Definition filename.h:44
void set_binary()
Indicates that the filename represents a binary file.
Definition filename.I:414
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
A hierarchy of directories and files that appears to be one continuous file system,...
static void close_write_file(std::ostream *stream)
Closes a file opened by a previous call to 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,...
static void close_read_file(std::istream *stream)
Closes a file opened by a previous call to 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,...
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.