00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "filename.h"
00016 #include "compress_string.h"
00017 #include "pnotify.h"
00018 #include "panda_getopt.h"
00019 #include "preprocess_argv.h"
00020
00021 void
00022 usage() {
00023 cerr
00024 << "\nUsage:\n"
00025 << " pzip file [file2 file3 ...]\n"
00026 << " pzip -c <file >dest_file\n"
00027 << " pzip -o dest_file file\n\n"
00028
00029 << "This program compresses the named file(s) using the Panda native\n"
00030 << "compression algorithm (gzip in practice, but with a different file\n"
00031 << "header). The compressed versions are written to a file with the\n"
00032 << "same name as the original, but the extension .pz added to the\n"
00033 << "filename, and the original file is removed (unless the version with\n"
00034 << "-o is used, in which case you can compress only one file, you specify\n"
00035 << "the destination file name, and the original file is not removed).\n\n"
00036
00037 << "In many cases, Panda can read the resulting .pz file directly,\n"
00038 << "exactly as if it were still in its uncompressed original form.\n"
00039 << "In fact, unless vfs-implicit-pz is set to false in your Config.prc\n"
00040 << "file, you can also load the file by referencing it with its original\n"
00041 << "filename (without the .pz extension), even though it no longer exists\n"
00042 << "under that filename, and Panda will find the .pz file and transparently\n"
00043 << "decompress it on the fly, as if the original, uncompressed file still\n"
00044 << "existed.\n\n"
00045
00046 << "Note that if you are adding files to a Panda multifile (.mf file) with\n"
00047 << "the multify command, it is not necessary to compress them separately;\n"
00048 << "multify has an inline compression option.\n\n"
00049
00050 << "Options:\n\n"
00051
00052 << " -1 compress faster\n"
00053 << " -6 compress default\n"
00054 << " -9 compress better (intermediate compression levels supported also)\n\n";
00055
00056 }
00057
00058 int
00059 main(int argc, char **argv) {
00060 extern char *optarg;
00061 extern int optind;
00062 const char *optstr = "o:c123456789h";
00063
00064 Filename dest_filename;
00065 bool got_dest_filename = false;
00066 bool use_stdout = false;
00067 int compression_level = 6;
00068
00069 preprocess_argv(argc, argv);
00070 int flag = getopt(argc, argv, optstr);
00071
00072 while (flag != EOF) {
00073 switch (flag) {
00074 case 'o':
00075 dest_filename = Filename::from_os_specific(optarg);
00076 got_dest_filename = true;
00077 break;
00078
00079 case 'c':
00080 use_stdout = true;
00081 break;
00082
00083 case '1':
00084 compression_level = 1;
00085 break;
00086
00087 case '2':
00088 compression_level = 2;
00089 break;
00090
00091 case '3':
00092 compression_level = 3;
00093 break;
00094
00095 case '4':
00096 compression_level = 4;
00097 break;
00098
00099 case '5':
00100 compression_level = 5;
00101 break;
00102
00103 case '6':
00104 compression_level = 6;
00105 break;
00106
00107 case '7':
00108 compression_level = 7;
00109 break;
00110
00111 case '8':
00112 compression_level = 8;
00113 break;
00114
00115 case '9':
00116 compression_level = 9;
00117 break;
00118
00119 case 'h':
00120 case '?':
00121 default:
00122 usage();
00123 return 1;
00124 }
00125 flag = getopt(argc, argv, optstr);
00126 }
00127
00128 argc -= (optind-1);
00129 argv += (optind-1);
00130
00131 if (use_stdout) {
00132 if (argc > 1) {
00133 cerr << "No filenames allowed in conjunction with -c.\n";
00134 return 1;
00135 }
00136
00137 bool success = compress_stream(cin, cout, compression_level);
00138 if (!success) {
00139 cerr << "Failure compressing standard input\n";
00140 return 1;
00141 }
00142 return 0;
00143 }
00144
00145 if (argc < 2) {
00146 usage();
00147 return 1;
00148 }
00149
00150 if (got_dest_filename && argc > 2) {
00151 cerr << "Only one input file allowed in conjunction with -o.\n";
00152 return 1;
00153 }
00154
00155 bool all_ok = true;
00156 for (int i = 1; i < argc; i++) {
00157 Filename source_file = Filename::from_os_specific(argv[i]);
00158 if (source_file.get_extension() == "pz") {
00159 cerr << source_file << " already ends .pz; skipping.\n";
00160 } else {
00161 Filename dest_file = dest_filename;
00162 if (!got_dest_filename) {
00163 dest_file = source_file.get_fullpath() + ".pz";
00164 }
00165
00166
00167 pifstream read_stream;
00168 source_file.set_binary();
00169 if (!source_file.open_read(read_stream)) {
00170 cerr << "Couldn't read: " << source_file << endl;
00171 all_ok = false;
00172
00173 } else {
00174
00175 pofstream write_stream;
00176 dest_file.set_binary();
00177 if (!dest_file.open_write(write_stream, true)) {
00178 cerr << "Failed to open: " << dest_file << endl;
00179 all_ok = false;
00180
00181 } else {
00182 cerr << dest_file << "\n";
00183 bool success = compress_stream(read_stream, write_stream, compression_level);
00184
00185 read_stream.close();
00186 write_stream.close();
00187
00188 if (!success) {
00189 cerr << "Failure writing " << dest_file << "\n";
00190 all_ok = false;
00191 dest_file.unlink();
00192
00193 } else {
00194 if (!got_dest_filename) {
00195 source_file.unlink();
00196 }
00197 }
00198 }
00199 }
00200 }
00201 }
00202
00203 if (all_ok) {
00204 return 0;
00205 } else {
00206 return 1;
00207 }
00208 }