Panda3D

pzip.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 pzip.cxx
10 */
11
12 #include "filename.h"
13 #include "compress_string.h"
14 #include "pnotify.h"
15 #include "panda_getopt.h"
16 #include "preprocess_argv.h"
17
18 using std::cerr;
19 using std::cin;
20 using std::cout;
21 using std::endl;
22
23 void
24 usage() {
25 cerr
26 << "\nUsage:\n"
27 << " pzip file [file2 file3 ...]\n"
28 << " pzip -c <file >dest_file\n"
29 << " pzip -o dest_file file\n\n"
30
31 << "This program compresses the named file(s) using the Panda native\n"
32 << "compression algorithm (gzip in practice, but with a different file\n"
33 << "header). The compressed versions are written to a file with the\n"
34 << "same name as the original, but the extension .pz added to the\n"
35 << "filename, and the original file is removed (unless the version with\n"
36 << "-o is used, in which case you can compress only one file, you specify\n"
37 << "the destination file name, and the original file is not removed).\n\n"
38
39 << "In many cases, Panda can read the resulting .pz file directly,\n"
40 << "exactly as if it were still in its uncompressed original form.\n"
41 << "In fact, unless vfs-implicit-pz is set to false in your Config.prc\n"
42 << "file, you can also load the file by referencing it with its original\n"
43 << "filename (without the .pz extension), even though it no longer exists\n"
44 << "under that filename, and Panda will find the .pz file and transparently\n"
45 << "decompress it on the fly, as if the original, uncompressed file still\n"
46 << "existed.\n\n"
47
48 << "Note that if you are adding files to a Panda multifile (.mf file) with\n"
49 << "the multify command, it is not necessary to compress them separately;\n"
50 << "multify has an inline compression option.\n\n"
51
52 << "Options:\n\n"
53
54 << " -1 compress faster\n"
55 << " -6 compress default\n"
56 << " -9 compress better (intermediate compression levels supported also)\n\n";
57
58 }
59
60 int
61 main(int argc, char **argv) {
62 extern char *optarg;
63 extern int optind;
64 const char *optstr = "o:c123456789h";
65
66 Filename dest_filename;
67 bool got_dest_filename = false;
68 bool use_stdout = false;
69 int compression_level = 6;
70
71 preprocess_argv(argc, argv);
72 int flag = getopt(argc, argv, optstr);
73
74 while (flag != EOF) {
75 switch (flag) {
76 case 'o':
77 dest_filename = Filename::from_os_specific(optarg);
78 got_dest_filename = true;
79 break;
80
81 case 'c':
82 use_stdout = true;
83 break;
84
85 case '1':
86 compression_level = 1;
87 break;
88
89 case '2':
90 compression_level = 2;
91 break;
92
93 case '3':
94 compression_level = 3;
95 break;
96
97 case '4':
98 compression_level = 4;
99 break;
100
101 case '5':
102 compression_level = 5;
103 break;
104
105 case '6':
106 compression_level = 6;
107 break;
108
109 case '7':
110 compression_level = 7;
111 break;
112
113 case '8':
114 compression_level = 8;
115 break;
116
117 case '9':
118 compression_level = 9;
119 break;
120
121 case 'h':
122 case '?':
123 default:
124 usage();
125 return 1;
126 }
127 flag = getopt(argc, argv, optstr);
128 }
129
130 argc -= (optind-1);
131 argv += (optind-1);
132
133 if (use_stdout) {
134 if (argc > 1) {
135 cerr << "No filenames allowed in conjunction with -c.\n";
136 return 1;
137 }
138
139 bool success = compress_stream(cin, cout, compression_level);
140 if (!success) {
141 cerr << "Failure compressing standard input\n";
142 return 1;
143 }
144 return 0;
145 }
146
147 if (argc < 2) {
148 usage();
149 return 1;
150 }
151
152 if (got_dest_filename && argc > 2) {
153 cerr << "Only one input file allowed in conjunction with -o.\n";
154 return 1;
155 }
156
157 bool all_ok = true;
158 for (int i = 1; i < argc; i++) {
159 Filename source_file = Filename::from_os_specific(argv[i]);
160 if (source_file.get_extension() == "pz") {
161 cerr << source_file << " already ends .pz; skipping.\n";
162 } else {
163 Filename dest_file = dest_filename;
164 if (!got_dest_filename) {
165 dest_file = source_file.get_fullpath() + ".pz";
166 }
167
168 // Open source file
169 pifstream read_stream;
170 source_file.set_binary();
171 if (!source_file.open_read(read_stream)) {
172 cerr << "Couldn't read: " << source_file << endl;
173 all_ok = false;
174
175 } else {
176 // Open destination file
177 pofstream write_stream;
178 dest_file.set_binary();
179 if (!dest_file.open_write(write_stream, true)) {
180 cerr << "Failed to open: " << dest_file << endl;
181 all_ok = false;
182
183 } else {
184 cerr << dest_file << "\n";
185 bool success = compress_stream(read_stream, write_stream, compression_level);
186
187 read_stream.close();
188 write_stream.close();
189
190 if (!success) {
191 cerr << "Failure writing " << dest_file << "\n";
192 all_ok = false;
193 dest_file.unlink();
194
195 } else {
196 if (!got_dest_filename) {
197 source_file.unlink();
198 }
199 }
200 }
201 }
202 }
203 }
204
205 if (all_ok) {
206 return 0;
207 } else {
208 return 1;
209 }
210 }
Filename
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
Filename::open_read
bool open_read(std::ifstream &stream) const
Opens the indicated ifstream for reading the file, if possible.
Definition: filename.cxx:1863
Filename::unlink
bool unlink() const
Permanently deletes the file associated with the filename, if possible.
Definition: filename.cxx:2319
Filename::set_binary
void set_binary()
Indicates that the filename represents a binary file.
Definition: filename.I:414
Filename::get_fullpath
std::string get_fullpath() const
Returns the entire filename: directory, basename, extension.
Definition: filename.I:338
Filename::from_os_specific
static Filename from_os_specific(const std::string &os_specific, Type type=T_general)
This named constructor returns a Panda-style filename (that is, using forward slashes,...
Definition: filename.cxx:328
Filename::open_write
bool open_write(std::ofstream &stream, bool truncate=true) const
Opens the indicated ifstream for writing the file, if possible.
Definition: filename.cxx:1899
Filename::get_extension
std::string get_extension() const
Returns the file extension.
Definition: filename.I:400
compress_string.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
filename.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
panda_getopt.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pnotify.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
preprocess_argv
void preprocess_argv(int &argc, char **&argv)
Processes the argc, argv pair as needed before passing it to getopt().
Definition: preprocess_argv.cxx:30
preprocess_argv.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.