Panda3D
|
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 }