Răsfoiți Sursa

support seek-by-index

David Rose 21 ani în urmă
părinte
comite
2c934140ba

+ 50 - 35
direct/src/dcparser/dcPacker.cxx

@@ -295,25 +295,52 @@ end_repack() {
 ////////////////////////////////////////////////////////////////////
 bool DCPacker::
 seek(const string &field_name) {
-  if (_mode == M_unpack) {
-    if (_catalog == (DCPackerCatalog *)NULL) {
-      _catalog = _root->get_catalog();
-      _live_catalog = _catalog->get_live_catalog(_unpack_data, _unpack_length);
-    }
-    nassertr(_catalog != (DCPackerCatalog *)NULL, false);
-    if (_live_catalog == NULL) {
-      _pack_error = true;
-      return false;
-    }
+  if (_catalog == (DCPackerCatalog *)NULL) {
+    _catalog = _root->get_catalog();
+    _live_catalog = _catalog->get_live_catalog(_unpack_data, _unpack_length);
+  }
+  nassertr(_catalog != (DCPackerCatalog *)NULL, false);
+  if (_live_catalog == NULL) {
+    _pack_error = true;
+    return false;
+  }
+  
+  int seek_index = _live_catalog->find_entry_by_name(field_name);
+  if (seek_index < 0) {
+    // The field was not known.
+    _pack_error = true;
+    return false;
+  }
 
-    int entry_index = _live_catalog->find_entry_by_name(field_name);
-    if (entry_index < 0) {
-      // The field was not known.
-      _pack_error = true;
-      return false;
-    }
+  return seek(seek_index);
+}
 
-    const DCPackerCatalog::Entry &entry = _live_catalog->get_entry(entry_index);
+////////////////////////////////////////////////////////////////////
+//     Function: DCPacker::seek
+//       Access: Published
+//  Description: Seeks to the field indentified by seek_index, which
+//               was returned by an earlier call to
+//               DCField::find_seek_index() to get the index of some
+//               nested field.  Also see the version of seek() that
+//               accepts a field name.
+//
+//               Returns true if successful, false if the field is not
+//               known (or if the packer is in an invalid mode).
+////////////////////////////////////////////////////////////////////
+bool DCPacker::
+seek(int seek_index) {
+  if (_catalog == (DCPackerCatalog *)NULL) {
+    _catalog = _root->get_catalog();
+    _live_catalog = _catalog->get_live_catalog(_unpack_data, _unpack_length);
+  }
+  nassertr(_catalog != (DCPackerCatalog *)NULL, false);
+  if (_live_catalog == NULL) {
+    _pack_error = true;
+    return false;
+  }
+  
+  if (_mode == M_unpack) {
+    const DCPackerCatalog::Entry &entry = _live_catalog->get_entry(seek_index);
 
     // If we are seeking, we don't need to remember our current stack
     // position.
@@ -322,7 +349,7 @@ seek(const string &field_name) {
     _current_parent = entry._parent;
     _current_field_index = entry._field_index;
     _num_nested_fields = _current_parent->get_num_nested_fields();
-    _unpack_p = _live_catalog->get_begin(entry_index);
+    _unpack_p = _live_catalog->get_begin(seek_index);
 
     // We don't really need _push_marker and _pop_marker now, except
     // that we should set _push_marker in case we have just seeked to
@@ -342,19 +369,7 @@ seek(const string &field_name) {
       _pack_error = true;
       return false;
     }
-    if (_live_catalog == NULL) {
-      _pack_error = true;
-      return false;
-    }
-
-    int entry_index = _live_catalog->find_entry_by_name(field_name);
-    if (entry_index < 0) {
-      // The field was not known.
-      _pack_error = true;
-      return false;
-    }
-
-    const DCPackerCatalog::Entry &entry = _live_catalog->get_entry(entry_index);
+    const DCPackerCatalog::Entry &entry = _live_catalog->get_entry(seek_index);
 
     if (entry._parent->as_switch_parameter() != (DCSwitchParameter *)NULL) {
       // If the parent is a DCSwitch, that can only mean that the
@@ -366,7 +381,7 @@ seek(const string &field_name) {
       return false;
     }
 
-    size_t begin = _live_catalog->get_begin(entry_index);
+    size_t begin = _live_catalog->get_begin(seek_index);
     if (begin < _unpack_p) {
       // Whoops, we are seeking fields out-of-order.  That means we
       // need to write the entire record and start again. 
@@ -384,7 +399,7 @@ seek(const string &field_name) {
         return false;
       }
 
-      begin = _live_catalog->get_begin(entry_index);
+      begin = _live_catalog->get_begin(seek_index);
     }
 
     // Now copy the bytes from _unpack_p to begin from the
@@ -398,12 +413,12 @@ seek(const string &field_name) {
     _current_parent = entry._parent;
     _current_field_index = entry._field_index;
     _num_nested_fields = 1;
-    _unpack_p = _live_catalog->get_end(entry_index);
+    _unpack_p = _live_catalog->get_end(seek_index);
 
     // Set up push_marker and pop_marker so we won't try to advance
     // beyond this field.
     _push_marker = begin;
-    _pop_marker = _live_catalog->get_end(entry_index);
+    _pop_marker = _live_catalog->get_end(seek_index);
 
     return true;
   }

+ 1 - 0
direct/src/dcparser/dcPacker.h

@@ -62,6 +62,7 @@ PUBLISHED:
   bool end_repack();
 
   bool seek(const string &field_name);
+  bool seek(int seek_index);
 
   INLINE bool has_nested_fields() const;
   INLINE int get_num_nested_fields() const;

+ 20 - 0
direct/src/dcparser/dcPackerInterface.cxx

@@ -71,6 +71,26 @@ DCPackerInterface::
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: DCPackerInterface::find_seek_index
+//       Access: Published
+//  Description: Returns the index number to be passed to a future
+//               call to DCPacker::seek() to seek directly to the
+//               named field without having to look up the field name
+//               in a table later, or -1 if the named field cannot be
+//               found.
+//
+//               If the named field is nested within a switch or some
+//               similar dynamic structure that reveals different
+//               fields based on the contents of the data, this
+//               mechanism cannot be used to pre-fetch the field index
+//               number--you must seek for the field by name.
+////////////////////////////////////////////////////////////////////
+int DCPackerInterface::
+find_seek_index(const string &name) const {
+  return get_catalog()->find_entry_by_name(name);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: DCPackerInterface::as_field
 //       Access: Published, Virtual

+ 1 - 0
direct/src/dcparser/dcPackerInterface.h

@@ -75,6 +75,7 @@ public:
 
 PUBLISHED:
   INLINE const string &get_name() const;
+  int find_seek_index(const string &name) const;
 
   virtual DCField *as_field();
   virtual const DCField *as_field() const;