Panda3D
punzip.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 punzip.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  << " punzip file.pz [file2.pz file3.pz ...]\n"
28  << " punzip -c <file >dest_file\n"
29  << " punzip -o dest_file file.pz\n\n"
30 
31  << "This program reverses the operation of a previous pzip command. It\n"
32  << "uncompresses the contents of the named source file(s) and removes the .pz\n"
33  << "extension.\n\n";
34 }
35 
36 int
37 main(int argc, char **argv) {
38  extern char *optarg;
39  extern int optind;
40  const char *optstr = "o:ch";
41 
42  Filename dest_filename;
43  bool got_dest_filename = false;
44  bool use_stdout = false;
45 
46  preprocess_argv(argc, argv);
47  int flag = getopt(argc, argv, optstr);
48 
49  while (flag != EOF) {
50  switch (flag) {
51  case 'o':
52  dest_filename = Filename::from_os_specific(optarg);
53  got_dest_filename = true;
54  break;
55 
56  case 'c':
57  use_stdout = true;
58  break;
59 
60  case 'h':
61  case '?':
62  default:
63  usage();
64  return 1;
65  }
66  flag = getopt(argc, argv, optstr);
67  }
68 
69  argc -= (optind-1);
70  argv += (optind-1);
71 
72  if (use_stdout) {
73  if (argc > 1) {
74  cerr << "No filenames allowed in conjunction with -c.\n";
75  return 1;
76  }
77 
78  bool success = decompress_stream(cin, cout);
79  if (!success) {
80  cerr << "Failure compressing standard input\n";
81  return 1;
82  }
83  return 0;
84  }
85 
86  if (argc < 2) {
87  usage();
88  return 1;
89  }
90 
91  if (got_dest_filename && argc > 2) {
92  cerr << "Only one input file allowed in conjunction with -o.\n";
93  return 1;
94  }
95 
96  bool all_ok = true;
97  for (int i = 1; i < argc; i++) {
98  Filename source_file = Filename::from_os_specific(argv[i]);
99  if (!got_dest_filename && source_file.get_extension() != "pz") {
100  cerr << source_file
101  << " doesn't end in .pz; can't derive filename of output file.\n";
102  all_ok = false;
103 
104  } else {
105  Filename dest_file = dest_filename;
106  if (!got_dest_filename) {
107  dest_file = source_file.get_fullpath_wo_extension();
108  }
109 
110  // Open source file
111  pifstream read_stream;
112  source_file.set_binary();
113  if (!source_file.open_read(read_stream)) {
114  cerr << "Couldn't read: " << source_file << endl;
115  all_ok = false;
116 
117  } else {
118  // Open destination file
119  pofstream write_stream;
120  dest_file.set_binary();
121  if (!dest_file.open_write(write_stream, true)) {
122  cerr << "Failed to open: " << dest_file << endl;
123  all_ok = false;
124 
125  } else {
126  cerr << dest_file << "\n";
127  bool success = decompress_stream(read_stream, write_stream);
128 
129  read_stream.close();
130  write_stream.close();
131 
132  if (!success) {
133  cerr << "Failure decompressing " << source_file << "\n";
134  all_ok = false;
135  dest_file.unlink();
136 
137  } else {
138  if (!got_dest_filename) {
139  source_file.unlink();
140  }
141  }
142  }
143  }
144  }
145  }
146 
147  if (all_ok) {
148  return 0;
149  } else {
150  return 1;
151  }
152 }
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
std::string get_fullpath_wo_extension() const
Returns the full filename–directory and basename parts–except for the extension.
Definition: filename.I:377
bool open_read(std::ifstream &stream) const
Opens the indicated ifstream for reading the file, if possible.
Definition: filename.cxx:1863
bool unlink() const
Permanently deletes the file associated with the filename, if possible.
Definition: filename.cxx:2319
void set_binary()
Indicates that the filename represents a binary file.
Definition: filename.I:414
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
bool open_write(std::ofstream &stream, bool truncate=true) const
Opens the indicated ifstream for writing the file, if possible.
Definition: filename.cxx:1899
std::string get_extension() const
Returns the file extension.
Definition: filename.I:400
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.
void preprocess_argv(int &argc, char **&argv)
Processes the argc, argv pair as needed before passing it to getopt().
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.