Panda3D

interrogateDatabase.cxx

00001 // Filename: interrogateDatabase.cxx
00002 // Created by:  drose (01Aug00)
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 "interrogateDatabase.h"
00016 #include "config_interrogatedb.h"
00017 #include "indexRemapper.h"
00018 #include "interrogate_datafile.h"
00019 
00020 InterrogateDatabase *InterrogateDatabase::_global_ptr = NULL;
00021 int InterrogateDatabase::_file_major_version = 0;
00022 int InterrogateDatabase::_file_minor_version = 0;
00023 int InterrogateDatabase::_current_major_version = 2;
00024 int InterrogateDatabase::_current_minor_version = 2;
00025 
00026 ////////////////////////////////////////////////////////////////////
00027 //     Function: InterrogateDatabase::Constructor
00028 //       Access: Private
00029 //  Description:
00030 ////////////////////////////////////////////////////////////////////
00031 InterrogateDatabase::
00032 InterrogateDatabase() {
00033   _error_flag = false;
00034   _next_index = 1;
00035   _lookups_fresh = 0;
00036 }
00037 
00038 ////////////////////////////////////////////////////////////////////
00039 //     Function: InterrogateDatabase::get_ptr
00040 //       Access: Private
00041 //  Description: Returns the global pointer to the one
00042 //               InterrogateDatabase.
00043 ////////////////////////////////////////////////////////////////////
00044 InterrogateDatabase *InterrogateDatabase::
00045 get_ptr() {
00046   if (_global_ptr == (InterrogateDatabase *)NULL) {
00047     if (interrogatedb_cat->is_debug()) {
00048       interrogatedb_cat->debug()
00049         << "Creating interrogate database\n";
00050     }
00051     _global_ptr = new InterrogateDatabase;
00052   }
00053   return _global_ptr;
00054 }
00055 
00056 ////////////////////////////////////////////////////////////////////
00057 //     Function: InterrogateDatabase::request_module
00058 //       Access: Public
00059 //  Description: Requests that the interrogate data for the given
00060 //               module be made available.  The function pointers will
00061 //               be made available immediately, while the database
00062 //               file will be read later, the next time someone asks
00063 //               for interrogate data that requires it.
00064 ////////////////////////////////////////////////////////////////////
00065 void InterrogateDatabase::
00066 request_module(InterrogateModuleDef *def) {
00067   if (interrogatedb_cat->is_debug()) {
00068     if (def->library_name == (const char *)NULL) {
00069       interrogatedb_cat->debug()
00070         << "Got interrogate data for anonymous module\n";
00071     } else {
00072       interrogatedb_cat->debug()
00073         << "Got interrogate data for module " << def->library_name << "\n";
00074     }
00075   }
00076 
00077   int num_indices = def->next_index - def->first_index;
00078   if (num_indices > 0) {
00079     // If the module def has any definitions--any index numbers
00080     // used--assign it to its own unique range of index numbers.
00081     def->first_index = _next_index;
00082     _next_index += num_indices;
00083     def->next_index = _next_index;
00084 
00085     // Assign a reference to the module def by index number.  When we
00086     // need to look up a function by its index number, we'll be able
00087     // to use this.
00088     _modules.push_back(def);
00089   }
00090 
00091   if (def->num_unique_names > 0 && def->library_name != (const char *)NULL) {
00092     // Define a lookup by hash for this module, mainly so we can look
00093     // up functions by their unique names.
00094     _modules_by_hash[def->library_hash_name] = def;
00095   }
00096 
00097   if (def->database_filename != (const char *)NULL) {
00098     _requests.push_back(def);
00099   }
00100 }
00101 
00102 ////////////////////////////////////////////////////////////////////
00103 //     Function: InterrogateDatabase::get_error_flag
00104 //       Access: Public
00105 //  Description: Returns the global error flag.  This will be set true
00106 //               if there was some problem importing the database
00107 //               (e.g. cannot find an .in file), or false if
00108 //               everything is ok.
00109 ////////////////////////////////////////////////////////////////////
00110 bool InterrogateDatabase::
00111 get_error_flag() {
00112   return _error_flag;
00113 }
00114 
00115 ////////////////////////////////////////////////////////////////////
00116 //     Function: InterrogateDatabase::get_num_global_types
00117 //       Access: Public
00118 //  Description: Returns the total number of "global" types known to
00119 //               the interrogate database.  These are types defined at
00120 //               the global level that should be considered for
00121 //               exporting, but not the incidental types (like
00122 //               pointers, etc.) that must be defined to support
00123 //               these.
00124 ////////////////////////////////////////////////////////////////////
00125 int InterrogateDatabase::
00126 get_num_global_types() {
00127   check_latest();
00128   return _global_types.size();
00129 }
00130 
00131 ////////////////////////////////////////////////////////////////////
00132 //     Function: InterrogateDatabase::get_global_type
00133 //       Access: Public
00134 //  Description: Returns the index of the nth global type known to the
00135 //               interrogate database.
00136 ////////////////////////////////////////////////////////////////////
00137 TypeIndex InterrogateDatabase::
00138 get_global_type(int n) {
00139   check_latest();
00140   if (n >= 0 && n < (int)_global_types.size()) {
00141     return _global_types[n];
00142   }
00143   return 0;
00144 }
00145 
00146 ////////////////////////////////////////////////////////////////////
00147 //     Function: InterrogateDatabase::get_num_all_types
00148 //       Access: Public
00149 //  Description: Returns the total number of types known to the
00150 //               interrogate database.  This includes all known types,
00151 //               global as well as incidental.  See also
00152 //               get_num_global_types().
00153 ////////////////////////////////////////////////////////////////////
00154 int InterrogateDatabase::
00155 get_num_all_types() {
00156   check_latest();
00157   return _all_types.size();
00158 }
00159 
00160 ////////////////////////////////////////////////////////////////////
00161 //     Function: InterrogateDatabase::get_all_type
00162 //       Access: Public
00163 //  Description: Returns the index of the nth type known to the
00164 //               interrogate database.
00165 ////////////////////////////////////////////////////////////////////
00166 TypeIndex InterrogateDatabase::
00167 get_all_type(int n) {
00168   check_latest();
00169   if (n >= 0 && n < (int)_all_types.size()) {
00170     return _all_types[n];
00171   }
00172   return 0;
00173 }
00174 
00175 ////////////////////////////////////////////////////////////////////
00176 //     Function: InterrogateDatabase::get_num_global_functions
00177 //       Access: Public
00178 //  Description: Returns the total number of global functions known to
00179 //               the interrogate database.  These are functions
00180 //               defined at the global level, e.g. non-member
00181 //               functions.
00182 ////////////////////////////////////////////////////////////////////
00183 int InterrogateDatabase::
00184 get_num_global_functions() {
00185   check_latest();
00186   return _global_functions.size();
00187 }
00188 
00189 ////////////////////////////////////////////////////////////////////
00190 //     Function: InterrogateDatabase::get_global_function
00191 //       Access: Public
00192 //  Description: Returns the index of the nth global function known to
00193 //               the interrogate database.
00194 ////////////////////////////////////////////////////////////////////
00195 FunctionIndex InterrogateDatabase::
00196 get_global_function(int n) {
00197   check_latest();
00198   if (n >= 0 && n < (int)_global_functions.size()) {
00199     return _global_functions[n];
00200   }
00201   return 0;
00202 }
00203 
00204 ////////////////////////////////////////////////////////////////////
00205 //     Function: InterrogateDatabase::get_num_all_functions
00206 //       Access: Public
00207 //  Description: Returns the total number of functions known to the
00208 //               interrogate database.  This includes all known
00209 //               functions, global, method, or synthesized.  See also
00210 //               get_num_global_functions().
00211 ////////////////////////////////////////////////////////////////////
00212 int InterrogateDatabase::
00213 get_num_all_functions() {
00214   check_latest();
00215   return _all_functions.size();
00216 }
00217 
00218 ////////////////////////////////////////////////////////////////////
00219 //     Function: InterrogateDatabase::get_all_function
00220 //       Access: Public
00221 //  Description: Returns the index of the nth function known to the
00222 //               interrogate database.
00223 ////////////////////////////////////////////////////////////////////
00224 FunctionIndex InterrogateDatabase::
00225 get_all_function(int n) {
00226   check_latest();
00227   if (n >= 0 && n < (int)_all_functions.size()) {
00228     return _all_functions[n];
00229   }
00230   return 0;
00231 }
00232 
00233 ////////////////////////////////////////////////////////////////////
00234 //     Function: InterrogateDatabase::get_num_global_manifests
00235 //       Access: Public
00236 //  Description: Returns the total number of global manifest constants
00237 //               known to the interrogate database.
00238 ////////////////////////////////////////////////////////////////////
00239 int InterrogateDatabase::
00240 get_num_global_manifests() {
00241   check_latest();
00242   return _global_manifests.size();
00243 }
00244 
00245 ////////////////////////////////////////////////////////////////////
00246 //     Function: InterrogateDatabase::get_global_manifest
00247 //       Access: Public
00248 //  Description: Returns the index of the nth global manifest constant
00249 //               known to the interrogate database.
00250 ////////////////////////////////////////////////////////////////////
00251 ManifestIndex InterrogateDatabase::
00252 get_global_manifest(int n) {
00253   check_latest();
00254   if (n >= 0 && n < (int)_global_manifests.size()) {
00255     return _global_manifests[n];
00256   }
00257   return 0;
00258 }
00259 
00260 ////////////////////////////////////////////////////////////////////
00261 //     Function: InterrogateDatabase::get_num_global_elements
00262 //       Access: Public
00263 //  Description: Returns the total number of global data elements
00264 //               known to the interrogate database.
00265 ////////////////////////////////////////////////////////////////////
00266 int InterrogateDatabase::
00267 get_num_global_elements() {
00268   check_latest();
00269   return _global_elements.size();
00270 }
00271 
00272 ////////////////////////////////////////////////////////////////////
00273 //     Function: InterrogateDatabase::get_global_element
00274 //       Access: Public
00275 //  Description: Returns the index of the nth global data element
00276 //               known to the interrogate database.
00277 ////////////////////////////////////////////////////////////////////
00278 ElementIndex InterrogateDatabase::
00279 get_global_element(int n) {
00280   check_latest();
00281   if (n >= 0 && n < (int)_global_elements.size()) {
00282     return _global_elements[n];
00283   }
00284   return 0;
00285 }
00286 
00287 ////////////////////////////////////////////////////////////////////
00288 //     Function: InterrogateDatabase::get_type
00289 //       Access: Public
00290 //  Description: Returns the type associated with the given TypeIndex,
00291 //               if there is one.
00292 ////////////////////////////////////////////////////////////////////
00293 const InterrogateType &InterrogateDatabase::
00294 get_type(TypeIndex type) {
00295   static InterrogateType bogus_type;
00296 
00297   check_latest();
00298   TypeMap::const_iterator ti;
00299   ti = _type_map.find(type);
00300   if (ti == _type_map.end()) {
00301     return bogus_type;
00302   }
00303   return (*ti).second;
00304 }
00305 
00306 ////////////////////////////////////////////////////////////////////
00307 //     Function: InterrogateDatabase::get_function
00308 //       Access: Public
00309 //  Description: Returns the function associated with the given
00310 //               FunctionIndex, if there is one.
00311 ////////////////////////////////////////////////////////////////////
00312 const InterrogateFunction &InterrogateDatabase::
00313 get_function(FunctionIndex function) {
00314   static InterrogateFunction bogus_function;
00315 
00316   check_latest();
00317   FunctionMap::const_iterator fi;
00318   fi = _function_map.find(function);
00319   if (fi == _function_map.end()) {
00320     return bogus_function;
00321   }
00322   return *(*fi).second;
00323 }
00324 
00325 ////////////////////////////////////////////////////////////////////
00326 //     Function: InterrogateDatabase::get_wrapper
00327 //       Access: Public
00328 //  Description: Returns the function wrapper associated with the
00329 //               given FunctionWrapperIndex, if there is one.
00330 ////////////////////////////////////////////////////////////////////
00331 const InterrogateFunctionWrapper &InterrogateDatabase::
00332 get_wrapper(FunctionWrapperIndex wrapper) {
00333   static InterrogateFunctionWrapper bogus_wrapper;
00334 
00335   check_latest();
00336   FunctionWrapperMap::const_iterator wi;
00337   wi = _wrapper_map.find(wrapper);
00338   if (wi == _wrapper_map.end()) {
00339     return bogus_wrapper;
00340   }
00341   return (*wi).second;
00342 }
00343 
00344 ////////////////////////////////////////////////////////////////////
00345 //     Function: InterrogateDatabase::get_manifest
00346 //       Access: Public
00347 //  Description: Returns the manifest constant associated with the
00348 //               given ManifestIndex, if there is one.
00349 ////////////////////////////////////////////////////////////////////
00350 const InterrogateManifest &InterrogateDatabase::
00351 get_manifest(ManifestIndex manifest) {
00352   static InterrogateManifest bogus_manifest;
00353 
00354   check_latest();
00355   ManifestMap::const_iterator mi;
00356   mi = _manifest_map.find(manifest);
00357   if (mi == _manifest_map.end()) {
00358     return bogus_manifest;
00359   }
00360   return (*mi).second;
00361 }
00362 
00363 ////////////////////////////////////////////////////////////////////
00364 //     Function: InterrogateDatabase::get_element
00365 //       Access: Public
00366 //  Description: Returns the data element associated with the
00367 //               given ElementIndex, if there is one.
00368 ////////////////////////////////////////////////////////////////////
00369 const InterrogateElement &InterrogateDatabase::
00370 get_element(ElementIndex element) {
00371   static InterrogateElement bogus_element;
00372 
00373   check_latest();
00374   ElementMap::const_iterator ei;
00375   ei = _element_map.find(element);
00376   if (ei == _element_map.end()) {
00377     return bogus_element;
00378   }
00379   return (*ei).second;
00380 }
00381 
00382 ////////////////////////////////////////////////////////////////////
00383 //     Function: InterrogateDatabase::get_make_seq
00384 //       Access: Public
00385 //  Description: Returns the make_seq associated with the given
00386 //               MakeSeqIndex, if there is one.
00387 ////////////////////////////////////////////////////////////////////
00388 const InterrogateMakeSeq &InterrogateDatabase::
00389 get_make_seq(MakeSeqIndex make_seq) {
00390   static InterrogateMakeSeq bogus_make_seq;
00391 
00392   check_latest();
00393   MakeSeqMap::const_iterator si;
00394   si = _make_seq_map.find(make_seq);
00395   if (si == _make_seq_map.end()) {
00396     return bogus_make_seq;
00397   }
00398   return (*si).second;
00399 }
00400 
00401 ////////////////////////////////////////////////////////////////////
00402 //     Function: InterrogateDatabase::remove_type
00403 //       Access: Public
00404 //  Description: Erases the type from the database.
00405 ////////////////////////////////////////////////////////////////////
00406 void InterrogateDatabase::
00407 remove_type(TypeIndex type) {
00408   _type_map.erase(type);
00409 }
00410 
00411 ////////////////////////////////////////////////////////////////////
00412 //     Function: InterrogateDatabase::get_fptr
00413 //       Access: Public
00414 //  Description: Returns the function pointer associated with the
00415 //               given function wrapper, if it has a pointer
00416 //               available.  Returns NULL if the pointer is not
00417 //               available.
00418 ////////////////////////////////////////////////////////////////////
00419 void *InterrogateDatabase::
00420 get_fptr(FunctionWrapperIndex wrapper) {
00421   InterrogateModuleDef *def;
00422   int module_index;
00423   if (find_module(wrapper, def, module_index)) {
00424     if (module_index >= 0 && module_index < def->num_fptrs) {
00425       return def->fptrs[module_index];
00426     }
00427   }
00428   return (void *)NULL;
00429 }
00430 
00431 ////////////////////////////////////////////////////////////////////
00432 //     Function: InterrogateDatabase::get_wrapper_by_unique_name
00433 //       Access: Public
00434 //  Description: Looks up the function wrapper corresponding to the
00435 //               given unique name, if available.  Returns the
00436 //               corresponding wrapper index, or 0 if no such
00437 //               wrapper is found.
00438 ////////////////////////////////////////////////////////////////////
00439 FunctionWrapperIndex InterrogateDatabase::
00440 get_wrapper_by_unique_name(const string &unique_name) {
00441   // First, split the unique_name into a library_hash_name and a
00442   // wrapper_hash_name.
00443 
00444   // The first four characters are always the library_name.
00445   string library_hash_name = unique_name.substr(0, 4);
00446   string wrapper_hash_name = unique_name.substr(4);
00447 
00448   // Is the library_name defined?
00449   ModulesByHash::const_iterator mi;
00450   mi = _modules_by_hash.find(library_hash_name);
00451   if (mi == _modules_by_hash.end()) {
00452     return 0;
00453   }
00454 
00455   InterrogateModuleDef *def = (*mi).second;
00456   int index_offset =
00457     binary_search_wrapper_hash(def->unique_names,
00458                                def->unique_names + def->num_unique_names,
00459                                wrapper_hash_name);
00460   if (index_offset >= 0) {
00461     return def->first_index + index_offset;
00462   }
00463 
00464   return 0;
00465 }
00466 
00467 ////////////////////////////////////////////////////////////////////
00468 //     Function: InterrogateDatabase::get_file_major_version
00469 //       Access: Public
00470 //  Description: Returns the major version number of the interrogate
00471 //               database file currently being read.
00472 ////////////////////////////////////////////////////////////////////
00473 int InterrogateDatabase::
00474 get_file_major_version() {
00475   return _file_major_version;
00476 }
00477 
00478 ////////////////////////////////////////////////////////////////////
00479 //     Function: InterrogateDatabase::get_file_minor_version
00480 //       Access: Public
00481 //  Description: Returns the minor version number of the interrogate
00482 //               database file currently being read.
00483 ////////////////////////////////////////////////////////////////////
00484 int InterrogateDatabase::
00485 get_file_minor_version() {
00486   return _file_minor_version;
00487 }
00488 
00489 ////////////////////////////////////////////////////////////////////
00490 //     Function: InterrogateDatabase::get_current_major_version
00491 //       Access: Public
00492 //  Description: Returns the major version number currently expected
00493 //               in interrogate database files generated by this code
00494 //               base.
00495 ////////////////////////////////////////////////////////////////////
00496 int InterrogateDatabase::
00497 get_current_major_version() {
00498   return _current_major_version;
00499 }
00500 
00501 ////////////////////////////////////////////////////////////////////
00502 //     Function: InterrogateDatabase::get_current_minor_version
00503 //       Access: Public
00504 //  Description: Returns the minor version number currently expected
00505 //               in interrogate database files generated by this code
00506 //               base.
00507 ////////////////////////////////////////////////////////////////////
00508 int InterrogateDatabase::
00509 get_current_minor_version() {
00510   return _current_minor_version;
00511 }
00512 
00513 ////////////////////////////////////////////////////////////////////
00514 //     Function: InterrogateDatabase::set_error_flag
00515 //       Access: Public
00516 //  Description: Sets the global error flag.  This should be set true
00517 //               if there was some problem importing the database
00518 //               (e.g. cannot find an .in file).
00519 ////////////////////////////////////////////////////////////////////
00520 void InterrogateDatabase::
00521 set_error_flag(bool error_flag) {
00522   _error_flag = error_flag;
00523 }
00524 
00525 ////////////////////////////////////////////////////////////////////
00526 //     Function: InterrogateDatabase::get_next_index
00527 //       Access: Public
00528 //  Description: Returns a new index number suitable for the next
00529 //               thing, that will not be shared with any other index
00530 //               numbers.
00531 ////////////////////////////////////////////////////////////////////
00532 int InterrogateDatabase::
00533 get_next_index() {
00534   return _next_index++;
00535 }
00536 
00537 ////////////////////////////////////////////////////////////////////
00538 //     Function: InterrogateDatabase::add_type
00539 //       Access: Public
00540 //  Description: Adds the indicated type to the database at the given
00541 //               index number.
00542 ////////////////////////////////////////////////////////////////////
00543 void InterrogateDatabase::
00544 add_type(TypeIndex index, const InterrogateType &type) {
00545   assert(index != 0);
00546   bool inserted =
00547     _type_map.insert(TypeMap::value_type(index, type)).second;
00548 
00549   if (!inserted) {
00550     // If there was already a type at that index, maybe it was a
00551     // forward reference.  If its _fully_defined bit isn't set, then
00552     // it's ok.
00553     InterrogateType &old_type = _type_map[index];
00554     assert(!old_type.is_fully_defined());
00555 
00556     // It was a forward reference.  Merge it with the new one.
00557     old_type.merge_with(type);
00558   }
00559 
00560   if (type.is_global()) {
00561     _global_types.push_back(index);
00562   }
00563   _all_types.push_back(index);
00564 }
00565 
00566 ////////////////////////////////////////////////////////////////////
00567 //     Function: InterrogateDatabase::add_function
00568 //       Access: Public
00569 //  Description: Adds the indicated function to the database at
00570 //               the given index number.
00571 ////////////////////////////////////////////////////////////////////
00572 void InterrogateDatabase::
00573 add_function(FunctionIndex index, InterrogateFunction *function) {
00574   bool inserted =
00575     _function_map.insert(FunctionMap::value_type(index, function)).second;
00576   assert(inserted);
00577 
00578   if (function->is_global()) {
00579     _global_functions.push_back(index);
00580   }
00581   _all_functions.push_back(index);
00582 }
00583 
00584 ////////////////////////////////////////////////////////////////////
00585 //     Function: InterrogateDatabase::add_wrapper
00586 //       Access: Public
00587 //  Description: Adds the indicated function wrapper to the database at
00588 //               the given index number.
00589 ////////////////////////////////////////////////////////////////////
00590 void InterrogateDatabase::
00591 add_wrapper(FunctionWrapperIndex index,
00592             const InterrogateFunctionWrapper &wrapper) {
00593   bool inserted =
00594     _wrapper_map.insert(FunctionWrapperMap::value_type(index, wrapper)).second;
00595   assert(inserted);
00596 }
00597 
00598 ////////////////////////////////////////////////////////////////////
00599 //     Function: InterrogateDatabase::add_manifest
00600 //       Access: Public
00601 //  Description: Adds the indicated manifest constant to the database
00602 //               at the given index number.
00603 ////////////////////////////////////////////////////////////////////
00604 void InterrogateDatabase::
00605 add_manifest(ManifestIndex index, const InterrogateManifest &manifest) {
00606   bool inserted =
00607     _manifest_map.insert(ManifestMap::value_type(index, manifest)).second;
00608   assert(inserted);
00609 
00610   _global_manifests.push_back(index);
00611 }
00612 
00613 ////////////////////////////////////////////////////////////////////
00614 //     Function: InterrogateDatabase::add_element
00615 //       Access: Public
00616 //  Description: Adds the indicated data element to the database
00617 //               at the given index number.
00618 ////////////////////////////////////////////////////////////////////
00619 void InterrogateDatabase::
00620 add_element(ElementIndex index, const InterrogateElement &element) {
00621   bool inserted =
00622     _element_map.insert(ElementMap::value_type(index, element)).second;
00623   assert(inserted);
00624 
00625   if (element.is_global()) {
00626     _global_elements.push_back(index);
00627   }
00628 }
00629 
00630 ////////////////////////////////////////////////////////////////////
00631 //     Function: InterrogateDatabase::add_make_seq
00632 //       Access: Public
00633 //  Description: Adds the indicated make_seq to the database at
00634 //               the given index number.
00635 ////////////////////////////////////////////////////////////////////
00636 void InterrogateDatabase::
00637 add_make_seq(MakeSeqIndex index, const InterrogateMakeSeq &make_seq) {
00638   bool inserted =
00639     _make_seq_map.insert(MakeSeqMap::value_type(index, make_seq)).second;
00640   assert(inserted);
00641 }
00642 
00643 ////////////////////////////////////////////////////////////////////
00644 //     Function: InterrogateDatabase::update_type
00645 //       Access: Public
00646 //  Description: Returns a non-const reference to the indicated type,
00647 //               allowing the user to update it.
00648 ////////////////////////////////////////////////////////////////////
00649 InterrogateType &InterrogateDatabase::
00650 update_type(TypeIndex type) {
00651   assert(type != 0);
00652   check_latest();
00653   return _type_map[type];
00654 }
00655 
00656 ////////////////////////////////////////////////////////////////////
00657 //     Function: InterrogateDatabase::update_function
00658 //       Access: Public
00659 //  Description: Returns a non-const reference to the indicated
00660 //               function, allowing the user to update it.
00661 ////////////////////////////////////////////////////////////////////
00662 InterrogateFunction &InterrogateDatabase::
00663 update_function(FunctionIndex function) {
00664   check_latest();
00665   return *_function_map[function];
00666 }
00667 
00668 ////////////////////////////////////////////////////////////////////
00669 //     Function: InterrogateDatabase::update_wrapper
00670 //       Access: Public
00671 //  Description: Returns a non-const reference to the indicated
00672 //               function wrapper, allowing the user to update it.
00673 ////////////////////////////////////////////////////////////////////
00674 InterrogateFunctionWrapper &InterrogateDatabase::
00675 update_wrapper(FunctionWrapperIndex wrapper) {
00676   check_latest();
00677   return _wrapper_map[wrapper];
00678 }
00679 
00680 ////////////////////////////////////////////////////////////////////
00681 //     Function: InterrogateDatabase::update_manifest
00682 //       Access: Public
00683 //  Description: Returns a non-const reference to the indicated
00684 //               manifest constant, allowing the user to update it.
00685 ////////////////////////////////////////////////////////////////////
00686 InterrogateManifest &InterrogateDatabase::
00687 update_manifest(ManifestIndex manifest) {
00688   check_latest();
00689   return _manifest_map[manifest];
00690 }
00691 
00692 ////////////////////////////////////////////////////////////////////
00693 //     Function: InterrogateDatabase::update_element
00694 //       Access: Public
00695 //  Description: Returns a non-const reference to the indicated
00696 //               data element, allowing the user to update it.
00697 ////////////////////////////////////////////////////////////////////
00698 InterrogateElement &InterrogateDatabase::
00699 update_element(ElementIndex element) {
00700   check_latest();
00701   return _element_map[element];
00702 }
00703 
00704 ////////////////////////////////////////////////////////////////////
00705 //     Function: InterrogateDatabase::update_make_seq
00706 //       Access: Public
00707 //  Description: Returns a non-const reference to the indicated
00708 //               make_seq, allowing the user to update it.
00709 ////////////////////////////////////////////////////////////////////
00710 InterrogateMakeSeq &InterrogateDatabase::
00711 update_make_seq(MakeSeqIndex make_seq) {
00712   check_latest();
00713   return _make_seq_map[make_seq];
00714 }
00715 
00716 ////////////////////////////////////////////////////////////////////
00717 //     Function: InterrogateDatabase::remap_indices
00718 //       Access: Public
00719 //  Description: Resequences all of the various index numbers so that
00720 //               all of the functions start at first_index and
00721 //               increment consecutively from there, and then all of
00722 //               the types follow.  Returns the next available index
00723 //               number.
00724 ////////////////////////////////////////////////////////////////////
00725 int InterrogateDatabase::
00726 remap_indices(int first_index) {
00727   IndexRemapper remap;
00728   return remap_indices(first_index, remap);
00729 }
00730 
00731 ////////////////////////////////////////////////////////////////////
00732 //     Function: InterrogateDatabase::remap_indices
00733 //       Access: Public
00734 //  Description: This flavor of remap_indices() accepts a map that
00735 //               should be empty on initial call, and will be filled
00736 //               with the mapping of old index number to new index
00737 //               number.  This allows the caller to update its own
00738 //               data structures to match the new index numbers.
00739 ////////////////////////////////////////////////////////////////////
00740 int InterrogateDatabase::
00741 remap_indices(int first_index, IndexRemapper &remap) {
00742   remap.clear();
00743 
00744   // First, build up the complete map.
00745 
00746   // Get the wrapper indices first.  This is important, because the
00747   // InterrogateBuilder wants these to be first, and consecutive.
00748   FunctionWrapperMap new_wrapper_map;
00749   FunctionWrapperMap::iterator wi;
00750   for (wi = _wrapper_map.begin(); wi != _wrapper_map.end(); ++wi) {
00751     remap.add_mapping((*wi).first, first_index);
00752     new_wrapper_map[first_index] = (*wi).second;
00753     first_index++;
00754   }
00755 
00756   // Everything else can follow; it doesn't matter so much.
00757   FunctionMap new_function_map;
00758   FunctionMap::iterator fi;
00759   for (fi = _function_map.begin(); fi != _function_map.end(); ++fi) {
00760     remap.add_mapping((*fi).first, first_index);
00761     new_function_map[first_index] = (*fi).second;
00762     first_index++;
00763   }
00764 
00765   TypeMap new_type_map;
00766   TypeMap::iterator ti;
00767   for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
00768     assert((*ti).first != 0);
00769     remap.add_mapping((*ti).first, first_index);
00770     new_type_map[first_index] = (*ti).second;
00771     first_index++;
00772   }
00773 
00774   ManifestMap new_manifest_map;
00775   ManifestMap::iterator mi;
00776   for (mi = _manifest_map.begin(); mi != _manifest_map.end(); ++mi) {
00777     remap.add_mapping((*mi).first, first_index);
00778     new_manifest_map[first_index] = (*mi).second;
00779     first_index++;
00780   }
00781 
00782   ElementMap new_element_map;
00783   ElementMap::iterator ei;
00784   for (ei = _element_map.begin(); ei != _element_map.end(); ++ei) {
00785     remap.add_mapping((*ei).first, first_index);
00786     new_element_map[first_index] = (*ei).second;
00787     first_index++;
00788   }
00789 
00790   MakeSeqMap new_make_seq_map;
00791   MakeSeqMap::iterator si;
00792   for (si = _make_seq_map.begin(); si != _make_seq_map.end(); ++si) {
00793     remap.add_mapping((*si).first, first_index);
00794     new_make_seq_map[first_index] = (*si).second;
00795     first_index++;
00796   }
00797 
00798   _next_index = first_index;
00799 
00800   _wrapper_map.swap(new_wrapper_map);
00801   _function_map.swap(new_function_map);
00802   _type_map.swap(new_type_map);
00803   _manifest_map.swap(new_manifest_map);
00804   _element_map.swap(new_element_map);
00805   _make_seq_map.swap(new_make_seq_map);
00806 
00807   // Then, go back through and update all of the internal references.
00808   for (wi = _wrapper_map.begin(); wi != _wrapper_map.end(); ++wi) {
00809     (*wi).second.remap_indices(remap);
00810   }
00811   for (fi = _function_map.begin(); fi != _function_map.end(); ++fi) {
00812     (*fi).second->remap_indices(remap);
00813   }
00814   for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
00815     (*ti).second.remap_indices(remap);
00816   }
00817   for (mi = _manifest_map.begin(); mi != _manifest_map.end(); ++mi) {
00818     (*mi).second.remap_indices(remap);
00819   }
00820   for (ei = _element_map.begin(); ei != _element_map.end(); ++ei) {
00821     (*ei).second.remap_indices(remap);
00822   }
00823   for (si = _make_seq_map.begin(); si != _make_seq_map.end(); ++si) {
00824     (*si).second.remap_indices(remap);
00825   }
00826   GlobalFunctions::iterator gfi;
00827   for (gfi = _global_functions.begin(); gfi != _global_functions.end(); ++gfi) {
00828     (*gfi) = remap.map_from(*gfi);
00829   }
00830   for (gfi = _all_functions.begin(); gfi != _all_functions.end(); ++gfi) {
00831     (*gfi) = remap.map_from(*gfi);
00832   }
00833   GlobalTypes::iterator gti;
00834   for (gti = _global_types.begin(); gti != _global_types.end(); ++gti) {
00835     (*gti) = remap.map_from(*gti);
00836   }
00837   for (gti = _all_types.begin(); gti != _all_types.end(); ++gti) {
00838     (*gti) = remap.map_from(*gti);
00839   }
00840   GlobalManifests::iterator gmi;
00841   for (gmi = _global_manifests.begin(); gmi != _global_manifests.end(); ++gmi) {
00842     (*gmi) = remap.map_from(*gmi);
00843   }
00844   GlobalElements::iterator gei;
00845   for (gei = _global_elements.begin(); gei != _global_elements.end(); ++gei) {
00846     (*gei) = remap.map_from(*gei);
00847   }
00848 
00849   return _next_index;
00850 }
00851 
00852 ////////////////////////////////////////////////////////////////////
00853 //     Function: InterrogateDatabase::write
00854 //       Access: Public
00855 //  Description: Writes the database to the indicated stream for later
00856 //               reading.
00857 ////////////////////////////////////////////////////////////////////
00858 void InterrogateDatabase::
00859 write(ostream &out, InterrogateModuleDef *def) const {
00860   // Write out the file header.
00861   out << def->file_identifier << "\n"
00862       << _current_major_version << " " << _current_minor_version << "\n";
00863 
00864   // Write out the module definition.
00865   idf_output_string(out, def->library_name);
00866   idf_output_string(out, def->library_hash_name);
00867   idf_output_string(out, def->module_name);
00868   out << "\n";
00869 
00870   // Now write out the components.
00871 
00872   out << _function_map.size() << "\n";
00873   FunctionMap::const_iterator fi;
00874   for (fi = _function_map.begin(); fi != _function_map.end(); ++fi) {
00875     out << (*fi).first << " " << *(*fi).second << "\n";
00876   }
00877 
00878   out << _wrapper_map.size() << "\n";
00879   FunctionWrapperMap::const_iterator wi;
00880   for (wi = _wrapper_map.begin(); wi != _wrapper_map.end(); ++wi) {
00881     out << (*wi).first << " " << (*wi).second << "\n";
00882   }
00883 
00884   out << _type_map.size() << "\n";
00885   TypeMap::const_iterator ti;
00886   for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
00887     out << (*ti).first << " " << (*ti).second << "\n";
00888   }
00889 
00890   out << _manifest_map.size() << "\n";
00891   ManifestMap::const_iterator mi;
00892   for (mi = _manifest_map.begin(); mi != _manifest_map.end(); ++mi) {
00893     out << (*mi).first << " " << (*mi).second << "\n";
00894   }
00895 
00896   out << _element_map.size() << "\n";
00897   ElementMap::const_iterator ei;
00898   for (ei = _element_map.begin(); ei != _element_map.end(); ++ei) {
00899     out << (*ei).first << " " << (*ei).second << "\n";
00900   }
00901 
00902   out << _make_seq_map.size() << "\n";
00903   MakeSeqMap::const_iterator si;
00904   for (si = _make_seq_map.begin(); si != _make_seq_map.end(); ++si) {
00905     out << (*si).first << " " << (*si).second << "\n";
00906   }
00907 }
00908 
00909 ////////////////////////////////////////////////////////////////////
00910 //     Function: InterrogateDatabase::read
00911 //       Access: Public
00912 //  Description: Reads a database from the indicated stream,
00913 //               associated with the indicated module definition and
00914 //               merges it with any existing data in the database,
00915 //               according to the expected index numbers specified in
00916 //               the module def.  The header information has already
00917 //               been read.
00918 //
00919 //               Returns true if the file is read successfully, false
00920 //               if there is an error.
00921 ////////////////////////////////////////////////////////////////////
00922 bool InterrogateDatabase::
00923 read(istream &in, InterrogateModuleDef *def) {
00924   InterrogateDatabase temp;
00925   if (!temp.read_new(in, def)) {
00926     return false;
00927   }
00928 
00929   if (def->first_index == 0 && def->next_index == 0) {
00930     _next_index = temp.remap_indices(_next_index);
00931 
00932   } else {
00933     int next = temp.remap_indices(def->first_index);
00934     if (next != def->next_index) {
00935       interrogatedb_cat->error()
00936         << "Module database file " << def->database_filename
00937         << " is out of date.\n";
00938       return false;
00939     }
00940   }
00941 
00942   merge_from(temp);
00943   return true;
00944 }
00945 
00946 ////////////////////////////////////////////////////////////////////
00947 //     Function: InterrogateDatabase::load_latest
00948 //       Access: Private
00949 //  Description: Reads in the latest interrogate data.
00950 ////////////////////////////////////////////////////////////////////
00951 void InterrogateDatabase::
00952 load_latest() {
00953   const DSearchPath &searchpath = interrogatedb_path;
00954 
00955   Requests copy_requests;
00956   copy_requests.swap(_requests);
00957 
00958   Requests::const_iterator ri;
00959   for (ri = copy_requests.begin(); ri != copy_requests.end(); ++ri) {
00960     InterrogateModuleDef *def = (*ri);
00961 
00962     if (def->database_filename != (char *)NULL) {
00963       Filename filename = def->database_filename;
00964       Filename pathname = filename;
00965       if (!pathname.empty() && pathname[0] != '/') {
00966         pathname = searchpath.find_file(pathname);
00967       }
00968 
00969       if (pathname.empty()) {
00970         interrogatedb_cat->error()
00971           << "Unable to find " << filename << " on " << searchpath << "\n";
00972         set_error_flag(true);
00973 
00974       } else {
00975 
00976         pifstream input;
00977         pathname.set_text();
00978         if (!pathname.open_read(input)) {
00979           interrogatedb_cat->error() << "Unable to read " << pathname << ".\n";
00980           set_error_flag(true);
00981 
00982         } else {
00983           int file_identifier;
00984           input >> file_identifier
00985                 >> _file_major_version >> _file_minor_version;
00986 
00987           if (def->file_identifier != 0 &&
00988               file_identifier != def->file_identifier) {
00989             interrogatedb_cat->warning()
00990               << "Interrogate data in " << pathname
00991               << " is out of sync with the compiled-in data"
00992               << " (" << file_identifier << " != " << def->file_identifier << ").\n";
00993             set_error_flag(true);
00994           }
00995 
00996           if (_file_major_version != _current_major_version ||
00997               _file_minor_version > _current_minor_version) {
00998             interrogatedb_cat->error()
00999               << "Cannot read interrogate data in " << pathname
01000               << "; database is version " << _file_major_version << "."
01001               << _file_minor_version << " while we are expecting "
01002               << _current_major_version << "." << _current_minor_version
01003               << ".\n";
01004             set_error_flag(true);
01005 
01006           } else {
01007             if (interrogatedb_cat->is_debug()) {
01008               interrogatedb_cat->debug()
01009                 << "Reading " << filename << "\n";
01010             }
01011             if (!read(input, def)) {
01012               interrogatedb_cat->error()
01013                 << "Error reading " << pathname << ".\n";
01014               set_error_flag(true);
01015             }
01016           }
01017         }
01018       }
01019     }
01020   }
01021 
01022   _requests.clear();
01023 }
01024 
01025 ////////////////////////////////////////////////////////////////////
01026 //     Function: InterrogateDatabase::read_new
01027 //       Access: Private
01028 //  Description: Reads from the indicated stream (the header
01029 //               information has already been read) into the
01030 //               newly-created database.  It is an error if the
01031 //               database already has some data in it.
01032 ////////////////////////////////////////////////////////////////////
01033 bool InterrogateDatabase::
01034 read_new(istream &in, InterrogateModuleDef *def) {
01035   // We've already read the header.  Read the module definition.
01036   idf_input_string(in, def->library_name);
01037   idf_input_string(in, def->library_hash_name);
01038   idf_input_string(in, def->module_name);
01039 
01040   // Now read all of the components.
01041 
01042   { // Functions.
01043     int num_functions;
01044     in >> num_functions;
01045     if (in.fail()) {
01046       return false;
01047     }
01048 
01049     while (num_functions > 0) {
01050       FunctionIndex index;
01051       InterrogateFunction *function = new InterrogateFunction(def);
01052       in >> index >> *function;
01053       if (in.fail()) {
01054         delete function;
01055         return false;
01056       }
01057 
01058       add_function(index, function);
01059       num_functions--;
01060     }
01061   }
01062 
01063   { // Wrappers.
01064     int num_wrappers;
01065     in >> num_wrappers;
01066     if (in.fail()) {
01067       return false;
01068     }
01069 
01070     while (num_wrappers > 0) {
01071       FunctionWrapperIndex index;
01072       InterrogateFunctionWrapper wrapper(def);
01073       in >> index >> wrapper;
01074       if (in.fail()) {
01075         return false;
01076       }
01077 
01078       add_wrapper(index, wrapper);
01079       num_wrappers--;
01080     }
01081   }
01082 
01083   { // Types.
01084     int num_types;
01085     in >> num_types;
01086     if (in.fail()) {
01087       return false;
01088     }
01089 
01090     while (num_types > 0) {
01091       TypeIndex index;
01092       InterrogateType type(def);
01093       in >> index >> type;
01094       if (in.fail()) {
01095         return false;
01096       }
01097 
01098       add_type(index, type);
01099       num_types--;
01100     }
01101   }
01102 
01103   { // Manifests.
01104     int num_manifests;
01105     in >> num_manifests;
01106     if (in.fail()) {
01107       return false;
01108     }
01109 
01110     while (num_manifests > 0) {
01111       ManifestIndex index;
01112       InterrogateManifest manifest(def);
01113       in >> index >> manifest;
01114       if (in.fail()) {
01115         return false;
01116       }
01117 
01118       add_manifest(index, manifest);
01119       num_manifests--;
01120     }
01121   }
01122 
01123   { // Elements.
01124     int num_elements;
01125     in >> num_elements;
01126     if (in.fail()) {
01127       return false;
01128     }
01129 
01130     while (num_elements > 0) {
01131       ElementIndex index;
01132       InterrogateElement element(def);
01133       in >> index >> element;
01134       if (in.fail()) {
01135         return false;
01136       }
01137 
01138       add_element(index, element);
01139       num_elements--;
01140     }
01141   }
01142 
01143   { // MakeSeqs.
01144     int num_make_seqs;
01145     in >> num_make_seqs;
01146     if (in.fail()) {
01147       return false;
01148     }
01149 
01150     while (num_make_seqs > 0) {
01151       MakeSeqIndex index;
01152       InterrogateMakeSeq make_seq(def);
01153       in >> index >> make_seq;
01154       if (in.fail()) {
01155         return false;
01156       }
01157 
01158       add_make_seq(index, make_seq);
01159       num_make_seqs--;
01160     }
01161   }
01162 
01163   return true;
01164 }
01165 
01166 ////////////////////////////////////////////////////////////////////
01167 //     Function: InterrogateDatabase::merge_from
01168 //       Access: Private
01169 //  Description: Copies all the data from the indicated database into
01170 //               this one.  It is an error if any index numbers are
01171 //               shared between the two databases.
01172 ////////////////////////////////////////////////////////////////////
01173 void InterrogateDatabase::
01174 merge_from(const InterrogateDatabase &other) {
01175   // We want to collapse shared types together.
01176   IndexRemapper remap;
01177 
01178   // First, we need to build a set of types by name, so we know what
01179   // types we already have.
01180   map<string, TypeIndex> types_by_name;
01181 
01182   TypeMap::const_iterator ti;
01183   for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
01184     const InterrogateType &type = (*ti).second;
01185     if (type.has_true_name()) {
01186       types_by_name[type.get_true_name()] = (*ti).first;
01187     }
01188   }
01189 
01190   // Now go through the other set of types and determine the mapping
01191   // into this set.
01192   for (ti = other._type_map.begin(); ti != other._type_map.end(); ++ti) {
01193     TypeIndex other_type_index = (*ti).first;
01194     const InterrogateType &other_type = (*ti).second;
01195 
01196     if (other_type.has_name()) {
01197       map<string, TypeIndex>::iterator ni;
01198       ni = types_by_name.find(other_type.get_true_name());
01199       if (ni != types_by_name.end()) {
01200         // Here's a type that we seem to have in common!  We'll have
01201         // to merge them.
01202         TypeIndex this_type_index = (*ni).second;
01203         remap.add_mapping(other_type_index, this_type_index);
01204       }
01205     }
01206   }
01207 
01208   // Now that we know the full type-to-type mapping, we can copy the
01209   // new types, one at a time.
01210   for (ti = other._type_map.begin(); ti != other._type_map.end(); ++ti) {
01211     TypeIndex other_type_index = (*ti).first;
01212     const InterrogateType &other_type = (*ti).second;
01213 
01214     if (!remap.in_map(other_type_index)) {
01215       // Here's a new type.
01216       add_type(other_type_index, other_type);
01217       update_type(other_type_index).remap_indices(remap);
01218 
01219     } else {
01220       // Here's a type to merge.
01221       TypeIndex this_type_index = remap.map_from(other_type_index);
01222 
01223       InterrogateType &this_type = update_type(this_type_index);
01224       if (!this_type.is_global() && other_type.is_global()) {
01225         // If the type is about to become global, we need to add it
01226         // to our global_types list.
01227         _global_types.push_back(this_type_index);
01228       }
01229 
01230       InterrogateType merge_type = other_type;
01231       merge_type.remap_indices(remap);
01232       this_type.merge_with(merge_type);
01233     }
01234   }
01235 
01236   // And copy all of the functions, wrappers, manifests, and elements.
01237   FunctionMap::const_iterator fi;
01238   for (fi = other._function_map.begin();
01239        fi != other._function_map.end();
01240        ++fi) {
01241     FunctionIndex other_function_index = (*fi).first;
01242     InterrogateFunction *other_function = (*fi).second;
01243     add_function(other_function_index, other_function);
01244     update_function(other_function_index).remap_indices(remap);
01245   }
01246 
01247   FunctionWrapperMap::const_iterator wi;
01248   for (wi = other._wrapper_map.begin();
01249        wi != other._wrapper_map.end();
01250        ++wi) {
01251     FunctionWrapperIndex other_wrapper_index = (*wi).first;
01252     const InterrogateFunctionWrapper &other_wrapper = (*wi).second;
01253     add_wrapper(other_wrapper_index, other_wrapper);
01254     update_wrapper(other_wrapper_index).remap_indices(remap);
01255   }
01256 
01257   ManifestMap::const_iterator mi;
01258   for (mi = other._manifest_map.begin();
01259        mi != other._manifest_map.end();
01260        ++mi) {
01261     ManifestIndex other_manifest_index = (*mi).first;
01262     const InterrogateManifest &other_manifest = (*mi).second;
01263     add_manifest(other_manifest_index, other_manifest);
01264     update_manifest(other_manifest_index).remap_indices(remap);
01265   }
01266 
01267   ElementMap::const_iterator ei;
01268   for (ei = other._element_map.begin();
01269        ei != other._element_map.end();
01270        ++ei) {
01271     ElementIndex other_element_index = (*ei).first;
01272     const InterrogateElement &other_element = (*ei).second;
01273     add_element(other_element_index, other_element);
01274     update_element(other_element_index).remap_indices(remap);
01275   }
01276 
01277   MakeSeqMap::const_iterator si;
01278   for (si = other._make_seq_map.begin();
01279        si != other._make_seq_map.end();
01280        ++si) {
01281     MakeSeqIndex other_make_seq_index = (*si).first;
01282     const InterrogateMakeSeq &other_make_seq = (*si).second;
01283     add_make_seq(other_make_seq_index, other_make_seq);
01284     update_make_seq(other_make_seq_index).remap_indices(remap);
01285   }
01286 
01287   _lookups_fresh = 0;
01288 }
01289 
01290 ////////////////////////////////////////////////////////////////////
01291 //     Function: InterrogateDatabase::find_module
01292 //       Access: Private
01293 //  Description: Looks up the wrapper definition in the set of module
01294 //               defs that are loaded in at runtime and represent the
01295 //               part of the interrogate database that's compiled in.
01296 //
01297 //               If the wrapper definition is not found, returns
01298 //               false.  If it is found, returns true and sets def and
01299 //               module_index to the particular module and the index
01300 //               within the module where the wrapper is defined.
01301 ////////////////////////////////////////////////////////////////////
01302 bool InterrogateDatabase::
01303 find_module(FunctionWrapperIndex wrapper, InterrogateModuleDef *&def,
01304             int &module_index) {
01305   if (_modules.empty()) {
01306     return false;
01307   }
01308 
01309   int mi = binary_search_module(0, _modules.size(), wrapper);
01310   assert(mi >= 0 && mi < (int)_modules.size());
01311   def = _modules[mi];
01312   module_index = wrapper - def->first_index;
01313 
01314   return (wrapper < def->next_index);
01315 }
01316 
01317 ////////////////////////////////////////////////////////////////////
01318 //     Function: InterrogateDatabase::binary_search_module
01319 //       Access: Private
01320 //  Description: Searches for the function module that includes the
01321 //               given function index by binary search.
01322 ////////////////////////////////////////////////////////////////////
01323 int InterrogateDatabase::
01324 binary_search_module(int begin, int end, FunctionIndex function) {
01325   int mid = begin + (end - begin) / 2;
01326   if (mid == begin) {
01327     return mid;
01328   }
01329 
01330   int index = _modules[mid]->first_index;
01331   if (index <= function) {
01332     return binary_search_module(mid, end, function);
01333 
01334   } else {
01335     return binary_search_module(begin, mid, function);
01336   }
01337 }
01338 
01339 ////////////////////////////////////////////////////////////////////
01340 //     Function: InterrogateDatabase::binary_search_wrapper_hash
01341 //       Access: Private
01342 //  Description: Searches for the particular function wrapper's hash
01343 //               name within a given module.  Returns the index number
01344 //               local to the module, or -1 if it is not found.
01345 ////////////////////////////////////////////////////////////////////
01346 int InterrogateDatabase::
01347 binary_search_wrapper_hash(InterrogateUniqueNameDef *begin,
01348                            InterrogateUniqueNameDef *end,
01349                            const string &wrapper_hash_name) {
01350   if (end <= begin) {
01351     return -1;
01352   }
01353 
01354   InterrogateUniqueNameDef *mid = begin + (end - begin) / 2;
01355   string name = mid->name;
01356   if (name < wrapper_hash_name) {
01357     return binary_search_wrapper_hash(mid, end, wrapper_hash_name);
01358 
01359   } else if (wrapper_hash_name < name) {
01360     return binary_search_wrapper_hash(begin, mid, wrapper_hash_name);
01361 
01362   } else {
01363     return mid->index_offset;
01364   }
01365 }
01366 
01367 ////////////////////////////////////////////////////////////////////
01368 //     Function: InterrogateDatabase::freshen_types_by_name
01369 //       Access: Private
01370 //  Description: Builds up the lookup of types by name.
01371 ////////////////////////////////////////////////////////////////////
01372 void InterrogateDatabase::
01373 freshen_types_by_name() {
01374   _types_by_name.clear();
01375   TypeMap::const_iterator ti;
01376   for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
01377     _types_by_name[(*ti).second.get_name()] = (*ti).first;
01378   }
01379 }
01380 
01381 ////////////////////////////////////////////////////////////////////
01382 //     Function: InterrogateDatabase::freshen_types_by_scoped_name
01383 //       Access: Private
01384 //  Description: Builds up the lookup of types by scoped name.
01385 ////////////////////////////////////////////////////////////////////
01386 void InterrogateDatabase::
01387 freshen_types_by_scoped_name() {
01388   _types_by_scoped_name.clear();
01389   TypeMap::const_iterator ti;
01390   for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
01391     _types_by_scoped_name[(*ti).second.get_scoped_name()] = (*ti).first;
01392   }
01393 }
01394 
01395 ////////////////////////////////////////////////////////////////////
01396 //     Function: InterrogateDatabase::freshen_types_by_true_name
01397 //       Access: Private
01398 //  Description: Builds up the lookup of types by true name.
01399 ////////////////////////////////////////////////////////////////////
01400 void InterrogateDatabase::
01401 freshen_types_by_true_name() {
01402   _types_by_true_name.clear();
01403   TypeMap::const_iterator ti;
01404   for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
01405     _types_by_true_name[(*ti).second.get_true_name()] = (*ti).first;
01406   }
01407 }
01408 
01409 ////////////////////////////////////////////////////////////////////
01410 //     Function: InterrogateDatabase::freshen_manifests_by_name
01411 //       Access: Private
01412 //  Description: Builds up the lookup of manifests by name.
01413 ////////////////////////////////////////////////////////////////////
01414 void InterrogateDatabase::
01415 freshen_manifests_by_name() {
01416   _manifests_by_name.clear();
01417   ManifestMap::const_iterator ti;
01418   for (ti = _manifest_map.begin(); ti != _manifest_map.end(); ++ti) {
01419     _manifests_by_name[(*ti).second.get_name()] = (*ti).first;
01420   }
01421 }
01422 
01423 ////////////////////////////////////////////////////////////////////
01424 //     Function: InterrogateDatabase::freshen_elements_by_name
01425 //       Access: Private
01426 //  Description: Builds up the lookup of elements by name.
01427 ////////////////////////////////////////////////////////////////////
01428 void InterrogateDatabase::
01429 freshen_elements_by_name() {
01430   _elements_by_name.clear();
01431   ElementMap::const_iterator ti;
01432   for (ti = _element_map.begin(); ti != _element_map.end(); ++ti) {
01433     _elements_by_name[(*ti).second.get_name()] = (*ti).first;
01434   }
01435 }
01436 
01437 ////////////////////////////////////////////////////////////////////
01438 //     Function: InterrogateDatabase::freshen_elements_by_scoped_name
01439 //       Access: Private
01440 //  Description: Builds up the lookup of elements by scoped name.
01441 ////////////////////////////////////////////////////////////////////
01442 void InterrogateDatabase::
01443 freshen_elements_by_scoped_name() {
01444   _elements_by_scoped_name.clear();
01445   ElementMap::const_iterator ti;
01446   for (ti = _element_map.begin(); ti != _element_map.end(); ++ti) {
01447     _elements_by_scoped_name[(*ti).second.get_scoped_name()] = (*ti).first;
01448   }
01449 }
01450 
01451 ////////////////////////////////////////////////////////////////////
01452 //     Function: InterrogateDatabase::lookup
01453 //       Access: Private
01454 //  Description: Looks up a type, manifest, or element in the
01455 //               indicated lookup table by name.  This is an internal
01456 //               support function.
01457 ////////////////////////////////////////////////////////////////////
01458 int InterrogateDatabase::
01459 lookup(const string &name, Lookup &lookup, LookupType type,
01460        void (InterrogateDatabase::*freshen)()) {
01461   if ((_lookups_fresh & (int)type) == 0) {
01462     // The lookup table isn't fresh; we need to freshen it.
01463     (this->*freshen)();
01464     _lookups_fresh |= (int)type;
01465   }
01466 
01467   Lookup::const_iterator li;
01468   li = lookup.find(name);
01469   if (li != lookup.end()) {
01470     return (*li).second;
01471   }
01472   return 0;
01473 }
 All Classes Functions Variables Enumerations