mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 09:23:03 -04:00
multify -P
This commit is contained in:
parent
e7b00c6e92
commit
d807610d32
@ -31,9 +31,9 @@ bool append = false; // -r
|
|||||||
bool update = false; // -u
|
bool update = false; // -u
|
||||||
bool tlist = false; // -t
|
bool tlist = false; // -t
|
||||||
bool extract = false; // -x
|
bool extract = false; // -x
|
||||||
bool kill_cmd = false; // -k
|
bool kill_cmd = false; // -k
|
||||||
bool verbose = false; // -v
|
bool verbose = false; // -v
|
||||||
bool compress_flag = false; // -z
|
bool compress_flag = false; // -z
|
||||||
int default_compression_level = 6;
|
int default_compression_level = 6;
|
||||||
Filename multifile_name; // -f
|
Filename multifile_name; // -f
|
||||||
bool got_multifile_name = false;
|
bool got_multifile_name = false;
|
||||||
@ -41,13 +41,15 @@ bool to_stdout = false; // -O
|
|||||||
bool encryption_flag = false; // -e
|
bool encryption_flag = false; // -e
|
||||||
string password; // -p
|
string password; // -p
|
||||||
bool got_password = false;
|
bool got_password = false;
|
||||||
|
string header_prefix; // -P
|
||||||
|
bool got_header_prefix = false;
|
||||||
Filename chdir_to; // -C
|
Filename chdir_to; // -C
|
||||||
bool got_chdir_to = false;
|
bool got_chdir_to = false;
|
||||||
size_t scale_factor = 0; // -F
|
size_t scale_factor = 0; // -F
|
||||||
pset<string> dont_compress; // -Z
|
pset<string> dont_compress; // -Z
|
||||||
|
|
||||||
// Default extensions not to compress. May be overridden with -Z.
|
// Default extensions not to compress. May be overridden with -Z.
|
||||||
string dont_compress_str = "jpg,mp3";
|
string dont_compress_str = "jpg,png,mp3,ogg";
|
||||||
|
|
||||||
bool got_record_timestamp_flag = false;
|
bool got_record_timestamp_flag = false;
|
||||||
bool record_timestamp_flag = true;
|
bool record_timestamp_flag = true;
|
||||||
@ -178,6 +180,15 @@ help() {
|
|||||||
" specified, and passwords are required, the user will be prompted from\n"
|
" specified, and passwords are required, the user will be prompted from\n"
|
||||||
" standard input.\n\n"
|
" standard input.\n\n"
|
||||||
|
|
||||||
|
" -P \"prefix\"\n"
|
||||||
|
" Specifies a header_prefix to write to the beginning of the multifile.\n"
|
||||||
|
" This is primarily useful for creating a multifile that can be invoked\n"
|
||||||
|
" directly as a program from the shell on Unix-like environments,\n"
|
||||||
|
" for instance, p3d files. The header_prefix must begin with a hash\n"
|
||||||
|
" mark and end with a newline; this will be enforced if it is not\n"
|
||||||
|
" already so. This only has effect in conjunction with with -c, -u,\n"
|
||||||
|
" or -k.\n\n"
|
||||||
|
|
||||||
" -F <scale_factor>\n"
|
" -F <scale_factor>\n"
|
||||||
" Specify a Multifile scale factor. This is only necessary to support\n"
|
" Specify a Multifile scale factor. This is only necessary to support\n"
|
||||||
" Multifiles that will exceed 4GB in size. The default scale factor is\n"
|
" Multifiles that will exceed 4GB in size. The default scale factor is\n"
|
||||||
@ -330,6 +341,10 @@ add_files(int argc, char *argv[]) {
|
|||||||
multifile->set_encryption_password(get_password());
|
multifile->set_encryption_password(get_password());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (got_header_prefix) {
|
||||||
|
multifile->set_header_prefix(header_prefix);
|
||||||
|
}
|
||||||
|
|
||||||
if (scale_factor != 0 && scale_factor != multifile->get_scale_factor()) {
|
if (scale_factor != 0 && scale_factor != multifile->get_scale_factor()) {
|
||||||
cerr << "Setting scale factor to " << scale_factor << "\n";
|
cerr << "Setting scale factor to " << scale_factor << "\n";
|
||||||
multifile->set_scale_factor(scale_factor);
|
multifile->set_scale_factor(scale_factor);
|
||||||
@ -451,6 +466,10 @@ kill_files(int argc, char *argv[]) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (got_header_prefix) {
|
||||||
|
multifile->set_header_prefix(header_prefix);
|
||||||
|
}
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < multifile->get_num_subfiles()) {
|
while (i < multifile->get_num_subfiles()) {
|
||||||
string subfile_name = multifile->get_subfile_name(i);
|
string subfile_name = multifile->get_subfile_name(i);
|
||||||
@ -628,7 +647,7 @@ main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
extern char *optarg;
|
extern char *optarg;
|
||||||
extern int optind;
|
extern int optind;
|
||||||
static const char *optflags = "crutxkvz123456789Z:T:f:OC:ep:F:h";
|
static const char *optflags = "crutxkvz123456789Z:T:f:OC:ep:P:F:h";
|
||||||
int flag = getopt(argc, argv, optflags);
|
int flag = getopt(argc, argv, optflags);
|
||||||
Filename rel_path;
|
Filename rel_path;
|
||||||
while (flag != EOF) {
|
while (flag != EOF) {
|
||||||
@ -727,6 +746,10 @@ main(int argc, char *argv[]) {
|
|||||||
password = optarg;
|
password = optarg;
|
||||||
got_password = true;
|
got_password = true;
|
||||||
break;
|
break;
|
||||||
|
case 'P':
|
||||||
|
header_prefix = optarg;
|
||||||
|
got_header_prefix = true;
|
||||||
|
break;
|
||||||
case 'F':
|
case 'F':
|
||||||
{
|
{
|
||||||
char *endptr;
|
char *endptr;
|
||||||
|
@ -377,25 +377,6 @@ get_magic_number() {
|
|||||||
return string(_header, _header_size);
|
return string(_header, _header_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: Multifile::set_header_prefix
|
|
||||||
// Access: Published
|
|
||||||
// Description: Sets the string which is written to the Multifile
|
|
||||||
// before the Multifile header. This string must begin
|
|
||||||
// with a hash mark and end with a newline character,
|
|
||||||
// and include at least 6 characters; and if it includes
|
|
||||||
// embedded newline characters, each one must be
|
|
||||||
// followed by a hash mark.
|
|
||||||
//
|
|
||||||
// This is primarily useful as a simple hack to allow
|
|
||||||
// p3d applications to be run directly from the command
|
|
||||||
// line on Unix-like systems.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE void Multifile::
|
|
||||||
set_header_prefix(const string &header_prefix) {
|
|
||||||
_header_prefix = header_prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Multifile::get_header_prefix
|
// Function: Multifile::get_header_prefix
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -691,7 +691,7 @@ flush() {
|
|||||||
// Also update the overall timestamp.
|
// Also update the overall timestamp.
|
||||||
if (_timestamp_dirty) {
|
if (_timestamp_dirty) {
|
||||||
nassertr(!_write->fail(), false);
|
nassertr(!_write->fail(), false);
|
||||||
static const size_t timestamp_pos = _header_size + 2 + 2 + 4;
|
static const size_t timestamp_pos = _header_prefix.size() + _header_size + 2 + 2 + 4;
|
||||||
_write->seekp(timestamp_pos);
|
_write->seekp(timestamp_pos);
|
||||||
nassertr(!_write->fail(), false);
|
nassertr(!_write->fail(), false);
|
||||||
|
|
||||||
@ -1336,6 +1336,56 @@ ls(ostream &out) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Multifile::set_header_prefix
|
||||||
|
// Access: Published
|
||||||
|
// Description: Sets the string which is written to the Multifile
|
||||||
|
// before the Multifile header. This string must begin
|
||||||
|
// with a hash mark and end with a newline character;
|
||||||
|
// and if it includes embedded newline characters, each
|
||||||
|
// one must be followed by a hash mark. If these
|
||||||
|
// conditions are not initially true, the string will be
|
||||||
|
// modified as necessary to make it so.
|
||||||
|
//
|
||||||
|
// This is primarily useful as a simple hack to allow
|
||||||
|
// p3d applications to be run directly from the command
|
||||||
|
// line on Unix-like systems.
|
||||||
|
//
|
||||||
|
// The return value is true if successful, or false on
|
||||||
|
// failure (for instance, because the header prefix
|
||||||
|
// violates the above rules).
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void Multifile::
|
||||||
|
set_header_prefix(const string &header_prefix) {
|
||||||
|
string new_header_prefix = header_prefix;
|
||||||
|
|
||||||
|
if (!new_header_prefix.empty()) {
|
||||||
|
// It must begin with a hash mark.
|
||||||
|
if (new_header_prefix[0] != '#') {
|
||||||
|
new_header_prefix = string("#") + new_header_prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
// It must end with a newline.
|
||||||
|
if (new_header_prefix[new_header_prefix.size() - 1] != '\n') {
|
||||||
|
new_header_prefix += string("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Embedded newlines must be followed by a hash mark.
|
||||||
|
size_t newline = new_header_prefix.find('\n');
|
||||||
|
while (newline < new_header_prefix.size() - 1) {
|
||||||
|
if (new_header_prefix[newline + 1] != '#') {
|
||||||
|
new_header_prefix = new_header_prefix.substr(0, newline + 1) + string("#") + new_header_prefix.substr(newline + 1);
|
||||||
|
}
|
||||||
|
newline = new_header_prefix.find('#', newline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_header_prefix != new_header_prefix) {
|
||||||
|
_header_prefix = new_header_prefix;
|
||||||
|
_needs_repack = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Multifile::read_subfile
|
// Function: Multifile::read_subfile
|
||||||
@ -1535,28 +1585,17 @@ read_index() {
|
|||||||
|
|
||||||
char this_header[_header_size];
|
char this_header[_header_size];
|
||||||
read->seekg(0);
|
read->seekg(0);
|
||||||
read->read(this_header, _header_size);
|
|
||||||
if (read->fail() || read->gcount() != (unsigned)_header_size) {
|
|
||||||
express_cat.info()
|
|
||||||
<< "Unable to read Multifile header " << _multifile_name << ".\n";
|
|
||||||
_read->release();
|
|
||||||
close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Here's a special case: if the multifile begins with a hash
|
// Here's a special case: if the multifile begins with a hash
|
||||||
// character, then we skip at least 6 characters (the length of the
|
// character, then we continue reading and discarding lines of ASCII
|
||||||
// original header string we already read), and continue reading and
|
// text, until we come across a nonempty line that does not begin
|
||||||
// discarding lines of ASCII text, until we come across a nonempty
|
// with a hash character. This allows a P3D application (which is a
|
||||||
// line that does not begin with a hash character. This allows a
|
// multifile) to be run directly on the command line on Unix-based
|
||||||
// P3D application (which is a multifile) to be run directly on the
|
// systems.
|
||||||
// command line on Unix-based systems.
|
|
||||||
_header_prefix = string();
|
_header_prefix = string();
|
||||||
|
int ch = read->get();
|
||||||
|
|
||||||
if (this_header[0] == '#') {
|
if (ch == '#') {
|
||||||
_header_prefix = string(this_header, _header_size);
|
|
||||||
int ch = '#';
|
|
||||||
|
|
||||||
while (ch != EOF && ch == '#') {
|
while (ch != EOF && ch == '#') {
|
||||||
// Skip to the end of the line.
|
// Skip to the end of the line.
|
||||||
while (ch != EOF && ch != '\n') {
|
while (ch != EOF && ch != '\n') {
|
||||||
@ -1569,10 +1608,17 @@ read_index() {
|
|||||||
ch = read->get();
|
ch = read->get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Now fill up the header.
|
// Now read the actual Multifile header.
|
||||||
this_header[0] = ch;
|
this_header[0] = ch;
|
||||||
read->read(this_header + 1, _header_size - 1);
|
read->read(this_header + 1, _header_size - 1);
|
||||||
|
if (read->fail() || read->gcount() != (unsigned)(_header_size - 1)) {
|
||||||
|
express_cat.info()
|
||||||
|
<< "Unable to read Multifile header " << _multifile_name << ".\n";
|
||||||
|
_read->release();
|
||||||
|
close();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memcmp(this_header, _header, _header_size) != 0) {
|
if (memcmp(this_header, _header, _header_size) != 0) {
|
||||||
|
@ -114,7 +114,7 @@ PUBLISHED:
|
|||||||
|
|
||||||
static INLINE string get_magic_number();
|
static INLINE string get_magic_number();
|
||||||
|
|
||||||
INLINE void set_header_prefix(const string &header_prefix);
|
void set_header_prefix(const string &header_prefix);
|
||||||
INLINE const string &get_header_prefix() const;
|
INLINE const string &get_header_prefix() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user