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