瀏覽代碼

Multifile should be reference-counted, so Python programmers are not tricked into deleting it

David Rose 21 年之前
父節點
當前提交
04ac1fd281

+ 10 - 9
panda/src/downloader/extractor.cxx

@@ -31,6 +31,7 @@
 Extractor::
 Extractor::
 Extractor() {
 Extractor() {
   _initiated = false;
   _initiated = false;
+  _multifile = new Multifile;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -54,7 +55,7 @@ bool Extractor::
 set_multifile(const Filename &multifile_name) {
 set_multifile(const Filename &multifile_name) {
   reset();
   reset();
   _multifile_name = multifile_name;
   _multifile_name = multifile_name;
-  return _multifile.open_read(multifile_name);
+  return _multifile->open_read(multifile_name);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -101,12 +102,12 @@ reset() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool Extractor::
 bool Extractor::
 request_subfile(const Filename &subfile_name) {
 request_subfile(const Filename &subfile_name) {
-  int index = _multifile.find_subfile(subfile_name);
+  int index = _multifile->find_subfile(subfile_name);
   if (index < 0) {
   if (index < 0) {
     return false;
     return false;
   }
   }
   _requests.push_back(index);
   _requests.push_back(index);
-  _requests_total_length += _multifile.get_subfile_length(index);
+  _requests_total_length += _multifile->get_subfile_length(index);
   return true;
   return true;
 }
 }
 
 
@@ -120,10 +121,10 @@ int Extractor::
 request_all_subfiles() {
 request_all_subfiles() {
   _requests.clear();
   _requests.clear();
   _requests_total_length = 0;
   _requests_total_length = 0;
-  int num_subfiles = _multifile.get_num_subfiles();
+  int num_subfiles = _multifile->get_num_subfiles();
   for (int i = 0; i < num_subfiles; i++) {
   for (int i = 0; i < num_subfiles; i++) {
     _requests.push_back(i);
     _requests.push_back(i);
-    _requests_total_length += _multifile.get_subfile_length(i);
+    _requests_total_length += _multifile->get_subfile_length(i);
   }
   }
   return num_subfiles;
   return num_subfiles;
 }
 }
@@ -164,7 +165,7 @@ step() {
 
 
     _subfile_index = _requests[_request_index];
     _subfile_index = _requests[_request_index];
     _subfile_filename = Filename(_extract_dir, 
     _subfile_filename = Filename(_extract_dir, 
-                                 _multifile.get_subfile_name(_subfile_index));
+                                 _multifile->get_subfile_name(_subfile_index));
     _subfile_filename.set_binary();
     _subfile_filename.set_binary();
     _subfile_filename.make_dir();
     _subfile_filename.make_dir();
     if (!_subfile_filename.open_write(_write, true)) {
     if (!_subfile_filename.open_write(_write, true)) {
@@ -174,13 +175,13 @@ step() {
       return EU_error_abort;
       return EU_error_abort;
     }
     }
 
 
-    _subfile_length = _multifile.get_subfile_length(_subfile_index);
+    _subfile_length = _multifile->get_subfile_length(_subfile_index);
     _subfile_pos = 0;
     _subfile_pos = 0;
-    _read = _multifile.open_read_subfile(_subfile_index);
+    _read = _multifile->open_read_subfile(_subfile_index);
     if (_read == (istream *)NULL) {
     if (_read == (istream *)NULL) {
       downloader_cat.error()
       downloader_cat.error()
         << "Unable to read subfile "
         << "Unable to read subfile "
-        << _multifile.get_subfile_name(_subfile_index) << ".\n";
+        << _multifile->get_subfile_name(_subfile_index) << ".\n";
       reset();
       reset();
       return EU_error_abort;
       return EU_error_abort;
     }
     }

+ 1 - 1
panda/src/downloader/extractor.h

@@ -59,7 +59,7 @@ PUBLISHED:
 
 
 private:
 private:
   Filename _multifile_name;
   Filename _multifile_name;
-  Multifile _multifile;
+  PT(Multifile) _multifile;
 
 
   Filename _extract_dir;
   Filename _extract_dir;
 
 

+ 40 - 39
panda/src/downloadertools/multify.cxx

@@ -23,6 +23,7 @@
   #include <getopt.h>
   #include <getopt.h>
 #endif
 #endif
 #include "multifile.h"
 #include "multifile.h"
+#include "pointerTo.h"
 #include "filename.h"
 #include "filename.h"
 #include "pset.h"
 #include "pset.h"
 #include <stdio.h>
 #include <stdio.h>
@@ -214,7 +215,7 @@ get_compression_level(const Filename &subfile_name) {
 }
 }
 
 
 bool
 bool
-add_directory(Multifile &multifile, const Filename &directory_name) {
+add_directory(Multifile *multifile, const Filename &directory_name) {
   vector_string files;
   vector_string files;
   if (!directory_name.scan_directory(files)) {
   if (!directory_name.scan_directory(files)) {
     cerr << "Unable to scan directory " << directory_name << "\n";
     cerr << "Unable to scan directory " << directory_name << "\n";
@@ -238,10 +239,10 @@ add_directory(Multifile &multifile, const Filename &directory_name) {
     } else {
     } else {
       string new_subfile_name;
       string new_subfile_name;
       if (update) {
       if (update) {
-        new_subfile_name = multifile.update_subfile
+        new_subfile_name = multifile->update_subfile
           (subfile_name, subfile_name, get_compression_level(subfile_name));
           (subfile_name, subfile_name, get_compression_level(subfile_name));
       } else {
       } else {
-        new_subfile_name = multifile.add_subfile
+        new_subfile_name = multifile->add_subfile
           (subfile_name, subfile_name, get_compression_level(subfile_name));
           (subfile_name, subfile_name, get_compression_level(subfile_name));
       }
       }
       if (new_subfile_name.empty()) {
       if (new_subfile_name.empty()) {
@@ -260,27 +261,27 @@ add_directory(Multifile &multifile, const Filename &directory_name) {
 
 
 bool
 bool
 add_files(int argc, char *argv[]) {
 add_files(int argc, char *argv[]) {
-  Multifile multifile;
+  PT(Multifile) multifile = new Multifile;
   if (append || update) {
   if (append || update) {
-    if (!multifile.open_read_write(multifile_name)) {
+    if (!multifile->open_read_write(multifile_name)) {
       cerr << "Unable to open " << multifile_name << " for updating.\n";
       cerr << "Unable to open " << multifile_name << " for updating.\n";
       return false;
       return false;
     }
     }
   } else {
   } else {
-    if (!multifile.open_write(multifile_name)) {
+    if (!multifile->open_write(multifile_name)) {
       cerr << "Unable to open " << multifile_name << " for writing.\n";
       cerr << "Unable to open " << multifile_name << " for writing.\n";
       return false;
       return false;
     }
     }
   }
   }
 
 
   if (encryption_flag) {
   if (encryption_flag) {
-    multifile.set_encryption_flag(true);
-    multifile.set_encryption_password(get_password());
+    multifile->set_encryption_flag(true);
+    multifile->set_encryption_password(get_password());
   }
   }
 
 
-  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);
   }
   }
 
 
   bool okflag = true;
   bool okflag = true;
@@ -298,10 +299,10 @@ add_files(int argc, char *argv[]) {
     } else {
     } else {
       string new_subfile_name;
       string new_subfile_name;
       if (update) {
       if (update) {
-        new_subfile_name = multifile.update_subfile
+        new_subfile_name = multifile->update_subfile
           (subfile_name, subfile_name, get_compression_level(subfile_name));
           (subfile_name, subfile_name, get_compression_level(subfile_name));
       } else {
       } else {
-        new_subfile_name = multifile.add_subfile
+        new_subfile_name = multifile->add_subfile
           (subfile_name, subfile_name, get_compression_level(subfile_name));
           (subfile_name, subfile_name, get_compression_level(subfile_name));
       }
       }
       if (new_subfile_name.empty()) {
       if (new_subfile_name.empty()) {
@@ -315,13 +316,13 @@ add_files(int argc, char *argv[]) {
     }
     }
   }
   }
 
 
-  if (multifile.needs_repack()) {
-    if (!multifile.repack()) {
+  if (multifile->needs_repack()) {
+    if (!multifile->repack()) {
       cerr << "Failed to write " << multifile_name << ".\n";
       cerr << "Failed to write " << multifile_name << ".\n";
       okflag = false;
       okflag = false;
     }
     }
   } else {
   } else {
-    if (!multifile.flush()) {
+    if (!multifile->flush()) {
       cerr << "Failed to write " << multifile_name << ".\n";
       cerr << "Failed to write " << multifile_name << ".\n";
       okflag = false;
       okflag = false;
     }
     }
@@ -336,13 +337,13 @@ extract_files(int argc, char *argv[]) {
     cerr << multifile_name << " not found.\n";
     cerr << multifile_name << " not found.\n";
     return false;
     return false;
   }
   }
-  Multifile multifile;
-  if (!multifile.open_read(multifile_name)) {
+  PT(Multifile) multifile = new Multifile;
+  if (!multifile->open_read(multifile_name)) {
     cerr << "Unable to open " << multifile_name << " for reading.\n";
     cerr << "Unable to open " << multifile_name << " for reading.\n";
     return false;
     return false;
   }
   }
 
 
-  int num_subfiles = multifile.get_num_subfiles();
+  int num_subfiles = multifile->get_num_subfiles();
 
 
   // First, check to see whether any of the named subfiles have been
   // First, check to see whether any of the named subfiles have been
   // encrypted.  If any have, we may need to prompt the user to enter
   // encrypted.  If any have, we may need to prompt the user to enter
@@ -350,21 +351,21 @@ extract_files(int argc, char *argv[]) {
   int i;
   int i;
   bool any_encrypted = false;
   bool any_encrypted = false;
   for (i = 0; i < num_subfiles && !any_encrypted; i++) {
   for (i = 0; i < num_subfiles && !any_encrypted; i++) {
-    string subfile_name = multifile.get_subfile_name(i);
+    string subfile_name = multifile->get_subfile_name(i);
     if (is_named(subfile_name, argc, argv)) {
     if (is_named(subfile_name, argc, argv)) {
-      if (multifile.is_subfile_encrypted(i)) {
+      if (multifile->is_subfile_encrypted(i)) {
         any_encrypted = true;
         any_encrypted = true;
       }
       }
     }
     }
   }
   }
 
 
   if (any_encrypted) {
   if (any_encrypted) {
-    multifile.set_encryption_password(get_password());
+    multifile->set_encryption_password(get_password());
   }
   }
 
 
   // Now walk back through the list and this time do the extraction.
   // Now walk back through the list and this time do the extraction.
   for (i = 0; i < num_subfiles; i++) {
   for (i = 0; i < num_subfiles; i++) {
-    string subfile_name = multifile.get_subfile_name(i);
+    string subfile_name = multifile->get_subfile_name(i);
     if (is_named(subfile_name, argc, argv)) {
     if (is_named(subfile_name, argc, argv)) {
       Filename filename = subfile_name;
       Filename filename = subfile_name;
       if (got_chdir_to) {
       if (got_chdir_to) {
@@ -374,12 +375,12 @@ extract_files(int argc, char *argv[]) {
         if (verbose) {
         if (verbose) {
           cerr << filename << "\n";
           cerr << filename << "\n";
         }
         }
-        multifile.extract_subfile_to(i, cout);
+        multifile->extract_subfile_to(i, cout);
       } else {
       } else {
         if (verbose) {
         if (verbose) {
           cout << filename << "\n";
           cout << filename << "\n";
         }
         }
-        multifile.extract_subfile(i, filename);
+        multifile->extract_subfile(i, filename);
       }
       }
     }
     }
   }
   }
@@ -393,58 +394,58 @@ list_files(int argc, char *argv[]) {
     cerr << multifile_name << " not found.\n";
     cerr << multifile_name << " not found.\n";
     return false;
     return false;
   }
   }
-  Multifile multifile;
-  if (!multifile.open_read(multifile_name)) {
+  PT(Multifile) multifile = new Multifile;
+  if (!multifile->open_read(multifile_name)) {
     cerr << "Unable to open " << multifile_name << " for reading.\n";
     cerr << "Unable to open " << multifile_name << " for reading.\n";
     return false;
     return false;
   }
   }
 
 
-  int num_subfiles = multifile.get_num_subfiles();
+  int num_subfiles = multifile->get_num_subfiles();
   
   
   if (verbose) {
   if (verbose) {
     cout << num_subfiles << " subfiles:\n" << flush;
     cout << num_subfiles << " subfiles:\n" << flush;
     for (int i = 0; i < num_subfiles; i++) {
     for (int i = 0; i < num_subfiles; i++) {
-      string subfile_name = multifile.get_subfile_name(i);
+      string subfile_name = multifile->get_subfile_name(i);
       if (is_named(subfile_name, argc, argv)) {
       if (is_named(subfile_name, argc, argv)) {
         char encrypted_symbol = ' ';
         char encrypted_symbol = ' ';
-        if (multifile.is_subfile_encrypted(i)) {
+        if (multifile->is_subfile_encrypted(i)) {
           encrypted_symbol = 'e';
           encrypted_symbol = 'e';
         }
         }
-        if (multifile.is_subfile_compressed(i)) {
-          size_t orig_length = multifile.get_subfile_length(i);
-          size_t internal_length = multifile.get_subfile_internal_length(i);
+        if (multifile->is_subfile_compressed(i)) {
+          size_t orig_length = multifile->get_subfile_length(i);
+          size_t internal_length = multifile->get_subfile_internal_length(i);
           double ratio = 1.0;
           double ratio = 1.0;
           if (orig_length != 0) {
           if (orig_length != 0) {
             ratio = (double)internal_length / (double)orig_length;
             ratio = (double)internal_length / (double)orig_length;
           }
           }
           if (ratio > 1.0) {
           if (ratio > 1.0) {
             printf("%12d worse %c %s\n",
             printf("%12d worse %c %s\n",
-                   multifile.get_subfile_length(i),
+                   multifile->get_subfile_length(i),
                    encrypted_symbol,
                    encrypted_symbol,
                    subfile_name.c_str());
                    subfile_name.c_str());
           } else {
           } else {
             printf("%12d  %3.0f%% %c %s\n",
             printf("%12d  %3.0f%% %c %s\n",
-                   multifile.get_subfile_length(i),
+                   multifile->get_subfile_length(i),
                    100.0 - ratio * 100.0, encrypted_symbol,
                    100.0 - ratio * 100.0, encrypted_symbol,
                    subfile_name.c_str());
                    subfile_name.c_str());
           }
           }
         } else {
         } else {
           printf("%12d       %c %s\n", 
           printf("%12d       %c %s\n", 
-                 multifile.get_subfile_length(i),
+                 multifile->get_subfile_length(i),
                  encrypted_symbol, subfile_name.c_str());
                  encrypted_symbol, subfile_name.c_str());
         }
         }
       }
       }
     }
     }
     fflush(stdout);
     fflush(stdout);
-    if (multifile.get_scale_factor() != 1) {
-      cout << "Scale factor is " << multifile.get_scale_factor() << "\n";
+    if (multifile->get_scale_factor() != 1) {
+      cout << "Scale factor is " << multifile->get_scale_factor() << "\n";
     }
     }
-    if (multifile.needs_repack()) {
+    if (multifile->needs_repack()) {
       cout << "Multifile needs to be repacked.\n";
       cout << "Multifile needs to be repacked.\n";
     }
     }
   } else {
   } else {
     for (int i = 0; i < num_subfiles; i++) {
     for (int i = 0; i < num_subfiles; i++) {
-      string subfile_name = multifile.get_subfile_name(i);
+      string subfile_name = multifile->get_subfile_name(i);
       if (is_named(subfile_name, argc, argv)) {
       if (is_named(subfile_name, argc, argv)) {
         cout << subfile_name << "\n";
         cout << subfile_name << "\n";
       }
       }

+ 2 - 1
panda/src/express/multifile.h

@@ -26,13 +26,14 @@
 #include "filename.h"
 #include "filename.h"
 #include "ordered_vector.h"
 #include "ordered_vector.h"
 #include "indirectLess.h"
 #include "indirectLess.h"
+#include "referenceCount.h"
 #include "pvector.h"
 #include "pvector.h"
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : Multifile
 //       Class : Multifile
 // Description : A file that contains a set of files.
 // Description : A file that contains a set of files.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-class EXPCL_PANDAEXPRESS Multifile {
+class EXPCL_PANDAEXPRESS Multifile : public ReferenceCount {
 PUBLISHED:
 PUBLISHED:
   Multifile();
   Multifile();
   ~Multifile();
   ~Multifile();

+ 0 - 5
panda/src/express/virtualFileMountMultifile.cxx

@@ -29,11 +29,6 @@ TypeHandle VirtualFileMountMultifile::_type_handle;
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 VirtualFileMountMultifile::
 VirtualFileMountMultifile::
 ~VirtualFileMountMultifile() {
 ~VirtualFileMountMultifile() {
-  if ((_mount_flags & VirtualFileSystem::MF_owns_pointer) != 0) {
-    // Delete the _multifile pointer if we own it.
-    nassertv(_multifile != (Multifile *)NULL);
-    delete _multifile;
-  }
 }
 }
 
 
 
 

+ 2 - 1
panda/src/express/virtualFileMountMultifile.h

@@ -23,6 +23,7 @@
 
 
 #include "virtualFileMount.h"
 #include "virtualFileMount.h"
 #include "multifile.h"
 #include "multifile.h"
+#include "pointerTo.h"
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : VirtualFileMountMultifile
 //       Class : VirtualFileMountMultifile
@@ -49,7 +50,7 @@ public:
 
 
 
 
 private:
 private:
-  Multifile *_multifile;
+  PT(Multifile) _multifile;
 
 
 
 
 public:
 public:

+ 2 - 7
panda/src/express/virtualFileSystem.cxx

@@ -53,9 +53,7 @@ VirtualFileSystem::
 //     Function: VirtualFileSystem::mount
 //     Function: VirtualFileSystem::mount
 //       Access: Published
 //       Access: Published
 //  Description: Mounts the indicated Multifile at the given mount
 //  Description: Mounts the indicated Multifile at the given mount
-//               point.  If flags contains MF_owns_pointer, the
-//               Multifile will be deleted when it is eventually
-//               unmounted.
+//               point.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool VirtualFileSystem::
 bool VirtualFileSystem::
 mount(Multifile *multifile, const string &mount_point, int flags) {
 mount(Multifile *multifile, const string &mount_point, int flags) {
@@ -98,7 +96,6 @@ mount(const Filename &physical_filename, const string &mount_point,
   }
   }
 
 
   if (physical_filename.is_directory()) {
   if (physical_filename.is_directory()) {
-    flags &= ~MF_owns_pointer;
     VirtualFileMountSystem *mount =
     VirtualFileMountSystem *mount =
       new VirtualFileMountSystem(this, physical_filename, 
       new VirtualFileMountSystem(this, physical_filename, 
                                  normalize_mount_point(mount_point),
                                  normalize_mount_point(mount_point),
@@ -108,7 +105,7 @@ mount(const Filename &physical_filename, const string &mount_point,
 
 
   } else {
   } else {
     // It's not a directory; it must be a Multifile.
     // It's not a directory; it must be a Multifile.
-    Multifile *multifile = new Multifile;
+    PT(Multifile) multifile = new Multifile;
 
 
     multifile->set_encryption_password(password);
     multifile->set_encryption_password(password);
 
 
@@ -120,8 +117,6 @@ mount(const Filename &physical_filename, const string &mount_point,
       return false;
       return false;
     }
     }
 
 
-    // We want to delete this pointer when we're done.
-    flags |= MF_owns_pointer;
     return mount(multifile, mount_point, flags);
     return mount(multifile, mount_point, flags);
   }
   }
 }
 }

+ 1 - 1
panda/src/express/virtualFileSystem.h

@@ -48,7 +48,7 @@ PUBLISHED:
   ~VirtualFileSystem();
   ~VirtualFileSystem();
 
 
   enum MountFlags {
   enum MountFlags {
-    MF_owns_pointer   = 0x0001,
+    MF_owns_pointer   = 0x0001,    // This flag is no longer used.
     MF_read_only      = 0x0002,
     MF_read_only      = 0x0002,
   };
   };