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 #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 // Open source file 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 // Open destination file 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 }