00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "interrogateDatabase.h"
00020 #include "config_interrogatedb.h"
00021 #include "indexRemapper.h"
00022 #include "interrogate_datafile.h"
00023
00024 InterrogateDatabase *InterrogateDatabase::_global_ptr = NULL;
00025 int InterrogateDatabase::_file_major_version = 0;
00026 int InterrogateDatabase::_file_minor_version = 0;
00027 int InterrogateDatabase::_current_major_version = 2;
00028 int InterrogateDatabase::_current_minor_version = 2;
00029
00030
00031
00032
00033
00034
00035 InterrogateDatabase::
00036 InterrogateDatabase() {
00037 _next_index = 1;
00038 _lookups_fresh = 0;
00039 }
00040
00041
00042
00043
00044
00045
00046
00047 InterrogateDatabase *InterrogateDatabase::
00048 get_ptr() {
00049 if (_global_ptr == (InterrogateDatabase *)NULL) {
00050 if (interrogatedb_cat->is_debug()) {
00051 interrogatedb_cat->debug()
00052 << "Creating interrogate database\n";
00053 }
00054 _global_ptr = new InterrogateDatabase;
00055 }
00056 return _global_ptr;
00057 }
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 void InterrogateDatabase::
00069 request_module(InterrogateModuleDef *def) {
00070 if (interrogatedb_cat->is_debug()) {
00071 if (def->library_name == (const char *)NULL) {
00072 interrogatedb_cat->debug()
00073 << "Got interrogate data for anonymous module\n";
00074 } else {
00075 interrogatedb_cat->debug()
00076 << "Got interrogate data for module " << def->library_name << "\n";
00077 }
00078 }
00079
00080 int num_indices = def->next_index - def->first_index;
00081 if (num_indices > 0) {
00082
00083
00084 def->first_index = _next_index;
00085 _next_index += num_indices;
00086 def->next_index = _next_index;
00087
00088
00089
00090
00091 _modules.push_back(def);
00092 }
00093
00094 if (def->num_unique_names > 0 && def->library_name != (const char *)NULL) {
00095
00096
00097 _modules_by_hash[def->library_hash_name] = def;
00098 }
00099
00100 if (def->database_filename != (const char *)NULL) {
00101 _requests.push_back(def);
00102 }
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 int InterrogateDatabase::
00116 get_num_global_types() {
00117 check_latest();
00118 return _global_types.size();
00119 }
00120
00121
00122
00123
00124
00125
00126
00127 TypeIndex InterrogateDatabase::
00128 get_global_type(int n) {
00129 check_latest();
00130 if (n >= 0 && n < (int)_global_types.size()) {
00131 return _global_types[n];
00132 }
00133 return 0;
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 int InterrogateDatabase::
00145 get_num_all_types() {
00146 check_latest();
00147 return _all_types.size();
00148 }
00149
00150
00151
00152
00153
00154
00155
00156 TypeIndex InterrogateDatabase::
00157 get_all_type(int n) {
00158 check_latest();
00159 if (n >= 0 && n < (int)_all_types.size()) {
00160 return _all_types[n];
00161 }
00162 return 0;
00163 }
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 int InterrogateDatabase::
00174 get_num_global_functions() {
00175 check_latest();
00176 return _global_functions.size();
00177 }
00178
00179
00180
00181
00182
00183
00184
00185 FunctionIndex InterrogateDatabase::
00186 get_global_function(int n) {
00187 check_latest();
00188 if (n >= 0 && n < (int)_global_functions.size()) {
00189 return _global_functions[n];
00190 }
00191 return 0;
00192 }
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 int InterrogateDatabase::
00203 get_num_all_functions() {
00204 check_latest();
00205 return _all_functions.size();
00206 }
00207
00208
00209
00210
00211
00212
00213
00214 FunctionIndex InterrogateDatabase::
00215 get_all_function(int n) {
00216 check_latest();
00217 if (n >= 0 && n < (int)_all_functions.size()) {
00218 return _all_functions[n];
00219 }
00220 return 0;
00221 }
00222
00223
00224
00225
00226
00227
00228
00229 int InterrogateDatabase::
00230 get_num_global_manifests() {
00231 check_latest();
00232 return _global_manifests.size();
00233 }
00234
00235
00236
00237
00238
00239
00240
00241 ManifestIndex InterrogateDatabase::
00242 get_global_manifest(int n) {
00243 check_latest();
00244 if (n >= 0 && n < (int)_global_manifests.size()) {
00245 return _global_manifests[n];
00246 }
00247 return 0;
00248 }
00249
00250
00251
00252
00253
00254
00255
00256 int InterrogateDatabase::
00257 get_num_global_elements() {
00258 check_latest();
00259 return _global_elements.size();
00260 }
00261
00262
00263
00264
00265
00266
00267
00268 ElementIndex InterrogateDatabase::
00269 get_global_element(int n) {
00270 check_latest();
00271 if (n >= 0 && n < (int)_global_elements.size()) {
00272 return _global_elements[n];
00273 }
00274 return 0;
00275 }
00276
00277
00278
00279
00280
00281
00282
00283 const InterrogateType &InterrogateDatabase::
00284 get_type(TypeIndex type) {
00285 static InterrogateType bogus_type;
00286
00287 check_latest();
00288 TypeMap::const_iterator ti;
00289 ti = _type_map.find(type);
00290 if (ti == _type_map.end()) {
00291 return bogus_type;
00292 }
00293 return (*ti).second;
00294 }
00295
00296
00297
00298
00299
00300
00301
00302 const InterrogateFunction &InterrogateDatabase::
00303 get_function(FunctionIndex function) {
00304 static InterrogateFunction bogus_function;
00305
00306 check_latest();
00307 FunctionMap::const_iterator fi;
00308 fi = _function_map.find(function);
00309 if (fi == _function_map.end()) {
00310 return bogus_function;
00311 }
00312 return *(*fi).second;
00313 }
00314
00315
00316
00317
00318
00319
00320
00321 const InterrogateFunctionWrapper &InterrogateDatabase::
00322 get_wrapper(FunctionWrapperIndex wrapper) {
00323 static InterrogateFunctionWrapper bogus_wrapper;
00324
00325 check_latest();
00326 FunctionWrapperMap::const_iterator wi;
00327 wi = _wrapper_map.find(wrapper);
00328 if (wi == _wrapper_map.end()) {
00329 return bogus_wrapper;
00330 }
00331 return (*wi).second;
00332 }
00333
00334
00335
00336
00337
00338
00339
00340 const InterrogateManifest &InterrogateDatabase::
00341 get_manifest(ManifestIndex manifest) {
00342 static InterrogateManifest bogus_manifest;
00343
00344 check_latest();
00345 ManifestMap::const_iterator mi;
00346 mi = _manifest_map.find(manifest);
00347 if (mi == _manifest_map.end()) {
00348 return bogus_manifest;
00349 }
00350 return (*mi).second;
00351 }
00352
00353
00354
00355
00356
00357
00358
00359 const InterrogateElement &InterrogateDatabase::
00360 get_element(ElementIndex element) {
00361 static InterrogateElement bogus_element;
00362
00363 check_latest();
00364 ElementMap::const_iterator ei;
00365 ei = _element_map.find(element);
00366 if (ei == _element_map.end()) {
00367 return bogus_element;
00368 }
00369 return (*ei).second;
00370 }
00371
00372
00373
00374
00375
00376
00377 void InterrogateDatabase::
00378 remove_type(TypeIndex type) {
00379 _type_map.erase(type);
00380 }
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390 void *InterrogateDatabase::
00391 get_fptr(FunctionWrapperIndex wrapper) {
00392 InterrogateModuleDef *def;
00393 int module_index;
00394 if (find_module(wrapper, def, module_index)) {
00395 if (module_index >= 0 && module_index < def->num_fptrs) {
00396 return def->fptrs[module_index];
00397 }
00398 }
00399 return (void *)NULL;
00400 }
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 FunctionWrapperIndex InterrogateDatabase::
00411 get_wrapper_by_unique_name(const string &unique_name) {
00412
00413
00414
00415
00416 string library_hash_name = unique_name.substr(0, 4);
00417 string wrapper_hash_name = unique_name.substr(4);
00418
00419
00420 ModulesByHash::const_iterator mi;
00421 mi = _modules_by_hash.find(library_hash_name);
00422 if (mi == _modules_by_hash.end()) {
00423 return 0;
00424 }
00425
00426 InterrogateModuleDef *def = (*mi).second;
00427 int index_offset =
00428 binary_search_wrapper_hash(def->unique_names,
00429 def->unique_names + def->num_unique_names,
00430 wrapper_hash_name);
00431 if (index_offset >= 0) {
00432 return def->first_index + index_offset;
00433 }
00434
00435 return 0;
00436 }
00437
00438
00439
00440
00441
00442
00443
00444 int InterrogateDatabase::
00445 get_file_major_version() {
00446 return _file_major_version;
00447 }
00448
00449
00450
00451
00452
00453
00454
00455 int InterrogateDatabase::
00456 get_file_minor_version() {
00457 return _file_minor_version;
00458 }
00459
00460
00461
00462
00463
00464
00465
00466
00467 int InterrogateDatabase::
00468 get_current_major_version() {
00469 return _current_major_version;
00470 }
00471
00472
00473
00474
00475
00476
00477
00478
00479 int InterrogateDatabase::
00480 get_current_minor_version() {
00481 return _current_minor_version;
00482 }
00483
00484
00485
00486
00487
00488
00489
00490
00491 int InterrogateDatabase::
00492 get_next_index() {
00493 return _next_index++;
00494 }
00495
00496
00497
00498
00499
00500
00501
00502 void InterrogateDatabase::
00503 add_type(TypeIndex index, const InterrogateType &type) {
00504 assert(index != 0);
00505 bool inserted =
00506 _type_map.insert(TypeMap::value_type(index, type)).second;
00507
00508 if (!inserted) {
00509
00510
00511
00512 InterrogateType &old_type = _type_map[index];
00513 assert(!old_type.is_fully_defined());
00514
00515
00516 old_type.merge_with(type);
00517 }
00518
00519 if (type.is_global()) {
00520 _global_types.push_back(index);
00521 }
00522 _all_types.push_back(index);
00523 }
00524
00525
00526
00527
00528
00529
00530
00531 void InterrogateDatabase::
00532 add_function(FunctionIndex index, InterrogateFunction *function) {
00533 bool inserted =
00534 _function_map.insert(FunctionMap::value_type(index, function)).second;
00535 assert(inserted);
00536
00537 if (function->is_global()) {
00538 _global_functions.push_back(index);
00539 }
00540 _all_functions.push_back(index);
00541 }
00542
00543
00544
00545
00546
00547
00548
00549 void InterrogateDatabase::
00550 add_wrapper(FunctionWrapperIndex index,
00551 const InterrogateFunctionWrapper &wrapper) {
00552 bool inserted =
00553 _wrapper_map.insert(FunctionWrapperMap::value_type(index, wrapper)).second;
00554 assert(inserted);
00555 }
00556
00557
00558
00559
00560
00561
00562
00563 void InterrogateDatabase::
00564 add_manifest(ManifestIndex index, const InterrogateManifest &manifest) {
00565 bool inserted =
00566 _manifest_map.insert(ManifestMap::value_type(index, manifest)).second;
00567 assert(inserted);
00568
00569 _global_manifests.push_back(index);
00570 }
00571
00572
00573
00574
00575
00576
00577
00578 void InterrogateDatabase::
00579 add_element(ElementIndex index, const InterrogateElement &element) {
00580 bool inserted =
00581 _element_map.insert(ElementMap::value_type(index, element)).second;
00582 assert(inserted);
00583
00584 if (element.is_global()) {
00585 _global_elements.push_back(index);
00586 }
00587 }
00588
00589
00590
00591
00592
00593
00594
00595 InterrogateType &InterrogateDatabase::
00596 update_type(TypeIndex type) {
00597 assert(type != 0);
00598 check_latest();
00599 return _type_map[type];
00600 }
00601
00602
00603
00604
00605
00606
00607
00608 InterrogateFunction &InterrogateDatabase::
00609 update_function(FunctionIndex function) {
00610 check_latest();
00611 return *_function_map[function];
00612 }
00613
00614
00615
00616
00617
00618
00619
00620 InterrogateFunctionWrapper &InterrogateDatabase::
00621 update_wrapper(FunctionWrapperIndex wrapper) {
00622 check_latest();
00623 return _wrapper_map[wrapper];
00624 }
00625
00626
00627
00628
00629
00630
00631
00632 InterrogateManifest &InterrogateDatabase::
00633 update_manifest(ManifestIndex manifest) {
00634 check_latest();
00635 return _manifest_map[manifest];
00636 }
00637
00638
00639
00640
00641
00642
00643
00644 InterrogateElement &InterrogateDatabase::
00645 update_element(ElementIndex element) {
00646 check_latest();
00647 return _element_map[element];
00648 }
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659 int InterrogateDatabase::
00660 remap_indices(int first_index) {
00661 IndexRemapper remap;
00662 return remap_indices(first_index, remap);
00663 }
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674 int InterrogateDatabase::
00675 remap_indices(int first_index, IndexRemapper &remap) {
00676 remap.clear();
00677
00678
00679
00680
00681
00682 FunctionWrapperMap new_wrapper_map;
00683 FunctionWrapperMap::iterator wi;
00684 for (wi = _wrapper_map.begin(); wi != _wrapper_map.end(); ++wi) {
00685 remap.add_mapping((*wi).first, first_index);
00686 new_wrapper_map[first_index] = (*wi).second;
00687 first_index++;
00688 }
00689
00690
00691 FunctionMap new_function_map;
00692 FunctionMap::iterator fi;
00693 for (fi = _function_map.begin(); fi != _function_map.end(); ++fi) {
00694 remap.add_mapping((*fi).first, first_index);
00695 new_function_map[first_index] = (*fi).second;
00696 first_index++;
00697 }
00698
00699 TypeMap new_type_map;
00700 TypeMap::iterator ti;
00701 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
00702 assert((*ti).first != 0);
00703 remap.add_mapping((*ti).first, first_index);
00704 new_type_map[first_index] = (*ti).second;
00705 first_index++;
00706 }
00707
00708 ManifestMap new_manifest_map;
00709 ManifestMap::iterator mi;
00710 for (mi = _manifest_map.begin(); mi != _manifest_map.end(); ++mi) {
00711 remap.add_mapping((*mi).first, first_index);
00712 new_manifest_map[first_index] = (*mi).second;
00713 first_index++;
00714 }
00715
00716 ElementMap new_element_map;
00717 ElementMap::iterator ei;
00718 for (ei = _element_map.begin(); ei != _element_map.end(); ++ei) {
00719 remap.add_mapping((*ei).first, first_index);
00720 new_element_map[first_index] = (*ei).second;
00721 first_index++;
00722 }
00723
00724 _next_index = first_index;
00725
00726 _wrapper_map.swap(new_wrapper_map);
00727 _function_map.swap(new_function_map);
00728 _type_map.swap(new_type_map);
00729 _manifest_map.swap(new_manifest_map);
00730 _element_map.swap(new_element_map);
00731
00732
00733 for (wi = _wrapper_map.begin(); wi != _wrapper_map.end(); ++wi) {
00734 (*wi).second.remap_indices(remap);
00735 }
00736 for (fi = _function_map.begin(); fi != _function_map.end(); ++fi) {
00737 (*fi).second->remap_indices(remap);
00738 }
00739 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
00740 (*ti).second.remap_indices(remap);
00741 }
00742 for (mi = _manifest_map.begin(); mi != _manifest_map.end(); ++mi) {
00743 (*mi).second.remap_indices(remap);
00744 }
00745 for (ei = _element_map.begin(); ei != _element_map.end(); ++ei) {
00746 (*ei).second.remap_indices(remap);
00747 }
00748 GlobalFunctions::iterator gfi;
00749 for (gfi = _global_functions.begin(); gfi != _global_functions.end(); ++gfi) {
00750 (*gfi) = remap.map_from(*gfi);
00751 }
00752 for (gfi = _all_functions.begin(); gfi != _all_functions.end(); ++gfi) {
00753 (*gfi) = remap.map_from(*gfi);
00754 }
00755 GlobalTypes::iterator gti;
00756 for (gti = _global_types.begin(); gti != _global_types.end(); ++gti) {
00757 (*gti) = remap.map_from(*gti);
00758 }
00759 for (gti = _all_types.begin(); gti != _all_types.end(); ++gti) {
00760 (*gti) = remap.map_from(*gti);
00761 }
00762 GlobalManifests::iterator gmi;
00763 for (gmi = _global_manifests.begin(); gmi != _global_manifests.end(); ++gmi) {
00764 (*gmi) = remap.map_from(*gmi);
00765 }
00766 GlobalElements::iterator gei;
00767 for (gei = _global_elements.begin(); gei != _global_elements.end(); ++gei) {
00768 (*gei) = remap.map_from(*gei);
00769 }
00770
00771 return _next_index;
00772 }
00773
00774
00775
00776
00777
00778
00779
00780 void InterrogateDatabase::
00781 write(ostream &out, InterrogateModuleDef *def) const {
00782
00783 out << def->file_identifier << "\n"
00784 << _current_major_version << " " << _current_minor_version << "\n";
00785
00786
00787 idf_output_string(out, def->library_name);
00788 idf_output_string(out, def->library_hash_name);
00789 idf_output_string(out, def->module_name);
00790 out << "\n";
00791
00792
00793
00794 out << _function_map.size() << "\n";
00795 FunctionMap::const_iterator fi;
00796 for (fi = _function_map.begin(); fi != _function_map.end(); ++fi) {
00797 out << (*fi).first << " " << *(*fi).second << "\n";
00798 }
00799
00800 out << _wrapper_map.size() << "\n";
00801 FunctionWrapperMap::const_iterator wi;
00802 for (wi = _wrapper_map.begin(); wi != _wrapper_map.end(); ++wi) {
00803 out << (*wi).first << " " << (*wi).second << "\n";
00804 }
00805
00806 out << _type_map.size() << "\n";
00807 TypeMap::const_iterator ti;
00808 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
00809 out << (*ti).first << " " << (*ti).second << "\n";
00810 }
00811
00812 out << _manifest_map.size() << "\n";
00813 ManifestMap::const_iterator mi;
00814 for (mi = _manifest_map.begin(); mi != _manifest_map.end(); ++mi) {
00815 out << (*mi).first << " " << (*mi).second << "\n";
00816 }
00817
00818 out << _element_map.size() << "\n";
00819 ElementMap::const_iterator ei;
00820 for (ei = _element_map.begin(); ei != _element_map.end(); ++ei) {
00821 out << (*ei).first << " " << (*ei).second << "\n";
00822 }
00823 }
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838 bool InterrogateDatabase::
00839 read(istream &in, InterrogateModuleDef *def) {
00840 InterrogateDatabase temp;
00841 if (!temp.read_new(in, def)) {
00842 return false;
00843 }
00844
00845 if (def->first_index == 0 && def->next_index == 0) {
00846 _next_index = temp.remap_indices(_next_index);
00847
00848 } else {
00849 int next = temp.remap_indices(def->first_index);
00850 if (next != def->next_index) {
00851 interrogatedb_cat->error()
00852 << "Module database file " << def->database_filename
00853 << " is out of date.\n";
00854 return false;
00855 }
00856 }
00857
00858 merge_from(temp);
00859 return true;
00860 }
00861
00862
00863
00864
00865
00866
00867 void InterrogateDatabase::
00868 load_latest() {
00869 const DSearchPath &searchpath = get_interrogatedb_path();
00870
00871 Requests copy_requests;
00872 copy_requests.swap(_requests);
00873
00874 Requests::const_iterator ri;
00875 for (ri = copy_requests.begin(); ri != copy_requests.end(); ++ri) {
00876 InterrogateModuleDef *def = (*ri);
00877
00878 if (def->database_filename != (char *)NULL) {
00879 Filename filename = def->database_filename;
00880 Filename pathname = filename;
00881 if (!pathname.empty() && pathname[0] != '/') {
00882 pathname = searchpath.find_file(pathname);
00883 }
00884
00885 if (pathname.empty()) {
00886 interrogatedb_cat->error()
00887 << "Unable to find " << filename << " on " << searchpath << "\n";
00888 } else {
00889
00890 ifstream input;
00891 pathname.set_text();
00892 if (!pathname.open_read(input)) {
00893 interrogatedb_cat->error() << "Unable to read " << pathname << ".\n";
00894 } else {
00895 int file_identifier;
00896 input >> file_identifier
00897 >> _file_major_version >> _file_minor_version;
00898
00899 if (def->file_identifier != 0 &&
00900 file_identifier != def->file_identifier) {
00901 interrogatedb_cat->warning()
00902 << "Interrogate data in " << pathname
00903 << " is out of sync with the compiled-in data.\n";
00904 }
00905
00906 if (_file_major_version != _current_major_version ||
00907 _file_minor_version > _current_minor_version) {
00908 interrogatedb_cat->error()
00909 << "Cannot read interrogate data in " << pathname
00910 << "; database is version " << _file_major_version << "."
00911 << _file_minor_version << " while we are expecting "
00912 << _current_major_version << "." << _current_minor_version
00913 << ".\n";
00914 } else {
00915 if (interrogatedb_cat->is_debug()) {
00916 interrogatedb_cat->debug()
00917 << "Reading " << filename << "\n";
00918 }
00919 if (!read(input, def)) {
00920 interrogatedb_cat->error()
00921 << "Error reading " << pathname << ".\n";
00922 }
00923 }
00924 }
00925 }
00926 }
00927 }
00928
00929 _requests.clear();
00930 }
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940 bool InterrogateDatabase::
00941 read_new(istream &in, InterrogateModuleDef *def) {
00942
00943 idf_input_string(in, def->library_name);
00944 idf_input_string(in, def->library_hash_name);
00945 idf_input_string(in, def->module_name);
00946
00947
00948
00949 {
00950 int num_functions;
00951 in >> num_functions;
00952 if (in.fail()) {
00953 return false;
00954 }
00955
00956 while (num_functions > 0) {
00957 FunctionIndex index;
00958 InterrogateFunction *function = new InterrogateFunction(def);
00959 in >> index >> *function;
00960 if (in.fail()) {
00961 delete function;
00962 return false;
00963 }
00964
00965 add_function(index, function);
00966 num_functions--;
00967 }
00968 }
00969
00970 {
00971 int num_wrappers;
00972 in >> num_wrappers;
00973 if (in.fail()) {
00974 return false;
00975 }
00976
00977 while (num_wrappers > 0) {
00978 FunctionWrapperIndex index;
00979 InterrogateFunctionWrapper wrapper(def);
00980 in >> index >> wrapper;
00981 if (in.fail()) {
00982 return false;
00983 }
00984
00985 add_wrapper(index, wrapper);
00986 num_wrappers--;
00987 }
00988 }
00989
00990 {
00991 int num_types;
00992 in >> num_types;
00993 if (in.fail()) {
00994 return false;
00995 }
00996
00997 while (num_types > 0) {
00998 TypeIndex index;
00999 InterrogateType type(def);
01000 in >> index >> type;
01001 if (in.fail()) {
01002 return false;
01003 }
01004
01005 add_type(index, type);
01006 num_types--;
01007 }
01008 }
01009
01010 {
01011 int num_manifests;
01012 in >> num_manifests;
01013 if (in.fail()) {
01014 return false;
01015 }
01016
01017 while (num_manifests > 0) {
01018 ManifestIndex index;
01019 InterrogateManifest manifest(def);
01020 in >> index >> manifest;
01021 if (in.fail()) {
01022 return false;
01023 }
01024
01025 add_manifest(index, manifest);
01026 num_manifests--;
01027 }
01028 }
01029
01030 {
01031 int num_elements;
01032 in >> num_elements;
01033 if (in.fail()) {
01034 return false;
01035 }
01036
01037 while (num_elements > 0) {
01038 ElementIndex index;
01039 InterrogateElement element(def);
01040 in >> index >> element;
01041 if (in.fail()) {
01042 return false;
01043 }
01044
01045 add_element(index, element);
01046 num_elements--;
01047 }
01048 }
01049
01050 return true;
01051 }
01052
01053
01054
01055
01056
01057
01058
01059
01060 void InterrogateDatabase::
01061 merge_from(const InterrogateDatabase &other) {
01062
01063 IndexRemapper remap;
01064
01065
01066
01067 map<string, TypeIndex> types_by_name;
01068
01069 TypeMap::const_iterator ti;
01070 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
01071 const InterrogateType &type = (*ti).second;
01072 if (type.has_true_name()) {
01073 types_by_name[type.get_true_name()] = (*ti).first;
01074 }
01075 }
01076
01077
01078
01079 for (ti = other._type_map.begin(); ti != other._type_map.end(); ++ti) {
01080 TypeIndex other_type_index = (*ti).first;
01081 const InterrogateType &other_type = (*ti).second;
01082
01083 if (other_type.has_name()) {
01084 map<string, TypeIndex>::iterator ni;
01085 ni = types_by_name.find(other_type.get_true_name());
01086 if (ni != types_by_name.end()) {
01087
01088
01089 TypeIndex this_type_index = (*ni).second;
01090 remap.add_mapping(other_type_index, this_type_index);
01091 }
01092 }
01093 }
01094
01095
01096
01097 for (ti = other._type_map.begin(); ti != other._type_map.end(); ++ti) {
01098 TypeIndex other_type_index = (*ti).first;
01099 const InterrogateType &other_type = (*ti).second;
01100
01101 if (!remap.in_map(other_type_index)) {
01102
01103 add_type(other_type_index, other_type);
01104 update_type(other_type_index).remap_indices(remap);
01105
01106 } else {
01107
01108 TypeIndex this_type_index = remap.map_from(other_type_index);
01109
01110 InterrogateType &this_type = update_type(this_type_index);
01111 if (!this_type.is_global() && other_type.is_global()) {
01112
01113
01114 _global_types.push_back(this_type_index);
01115 }
01116
01117 InterrogateType merge_type = other_type;
01118 merge_type.remap_indices(remap);
01119 this_type.merge_with(merge_type);
01120 }
01121 }
01122
01123
01124 FunctionMap::const_iterator fi;
01125 for (fi = other._function_map.begin();
01126 fi != other._function_map.end();
01127 ++fi) {
01128 FunctionIndex other_function_index = (*fi).first;
01129 InterrogateFunction *other_function = (*fi).second;
01130 add_function(other_function_index, other_function);
01131 update_function(other_function_index).remap_indices(remap);
01132 }
01133
01134 FunctionWrapperMap::const_iterator wi;
01135 for (wi = other._wrapper_map.begin();
01136 wi != other._wrapper_map.end();
01137 ++wi) {
01138 FunctionWrapperIndex other_wrapper_index = (*wi).first;
01139 const InterrogateFunctionWrapper &other_wrapper = (*wi).second;
01140 add_wrapper(other_wrapper_index, other_wrapper);
01141 update_wrapper(other_wrapper_index).remap_indices(remap);
01142 }
01143
01144 ManifestMap::const_iterator mi;
01145 for (mi = other._manifest_map.begin();
01146 mi != other._manifest_map.end();
01147 ++mi) {
01148 ManifestIndex other_manifest_index = (*mi).first;
01149 const InterrogateManifest &other_manifest = (*mi).second;
01150 add_manifest(other_manifest_index, other_manifest);
01151 update_manifest(other_manifest_index).remap_indices(remap);
01152 }
01153
01154 ElementMap::const_iterator ei;
01155 for (ei = other._element_map.begin();
01156 ei != other._element_map.end();
01157 ++ei) {
01158 ElementIndex other_element_index = (*ei).first;
01159 const InterrogateElement &other_element = (*ei).second;
01160 add_element(other_element_index, other_element);
01161 update_element(other_element_index).remap_indices(remap);
01162 }
01163
01164 _lookups_fresh = 0;
01165 }
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179 bool InterrogateDatabase::
01180 find_module(FunctionWrapperIndex wrapper, InterrogateModuleDef *&def,
01181 int &module_index) {
01182 if (_modules.empty()) {
01183 return false;
01184 }
01185
01186 int mi = binary_search_module(0, _modules.size(), wrapper);
01187 assert(mi >= 0 && mi < (int)_modules.size());
01188 def = _modules[mi];
01189 module_index = wrapper - def->first_index;
01190
01191 return (wrapper < def->next_index);
01192 }
01193
01194
01195
01196
01197
01198
01199
01200 int InterrogateDatabase::
01201 binary_search_module(int begin, int end, FunctionIndex function) {
01202 int mid = begin + (end - begin) / 2;
01203 if (mid == begin) {
01204 return mid;
01205 }
01206
01207 int index = _modules[mid]->first_index;
01208 if (index <= function) {
01209 return binary_search_module(mid, end, function);
01210
01211 } else {
01212 return binary_search_module(begin, mid, function);
01213 }
01214 }
01215
01216
01217
01218
01219
01220
01221
01222
01223 int InterrogateDatabase::
01224 binary_search_wrapper_hash(InterrogateUniqueNameDef *begin,
01225 InterrogateUniqueNameDef *end,
01226 const string &wrapper_hash_name) {
01227 if (end <= begin) {
01228 return -1;
01229 }
01230
01231 InterrogateUniqueNameDef *mid = begin + (end - begin) / 2;
01232 string name = mid->name;
01233 if (name < wrapper_hash_name) {
01234 return binary_search_wrapper_hash(mid, end, wrapper_hash_name);
01235
01236 } else if (wrapper_hash_name < name) {
01237 return binary_search_wrapper_hash(begin, mid, wrapper_hash_name);
01238
01239 } else {
01240 return mid->index_offset;
01241 }
01242 }
01243
01244
01245
01246
01247
01248
01249 void InterrogateDatabase::
01250 freshen_types_by_name() {
01251 _types_by_name.clear();
01252 TypeMap::const_iterator ti;
01253 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
01254 _types_by_name[(*ti).second.get_name()] = (*ti).first;
01255 }
01256 }
01257
01258
01259
01260
01261
01262
01263 void InterrogateDatabase::
01264 freshen_types_by_scoped_name() {
01265 _types_by_scoped_name.clear();
01266 TypeMap::const_iterator ti;
01267 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
01268 _types_by_scoped_name[(*ti).second.get_scoped_name()] = (*ti).first;
01269 }
01270 }
01271
01272
01273
01274
01275
01276
01277 void InterrogateDatabase::
01278 freshen_types_by_true_name() {
01279 _types_by_true_name.clear();
01280 TypeMap::const_iterator ti;
01281 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
01282 _types_by_true_name[(*ti).second.get_true_name()] = (*ti).first;
01283 }
01284 }
01285
01286
01287
01288
01289
01290
01291 void InterrogateDatabase::
01292 freshen_manifests_by_name() {
01293 _manifests_by_name.clear();
01294 ManifestMap::const_iterator ti;
01295 for (ti = _manifest_map.begin(); ti != _manifest_map.end(); ++ti) {
01296 _manifests_by_name[(*ti).second.get_name()] = (*ti).first;
01297 }
01298 }
01299
01300
01301
01302
01303
01304
01305 void InterrogateDatabase::
01306 freshen_elements_by_name() {
01307 _elements_by_name.clear();
01308 ElementMap::const_iterator ti;
01309 for (ti = _element_map.begin(); ti != _element_map.end(); ++ti) {
01310 _elements_by_name[(*ti).second.get_name()] = (*ti).first;
01311 }
01312 }
01313
01314
01315
01316
01317
01318
01319 void InterrogateDatabase::
01320 freshen_elements_by_scoped_name() {
01321 _elements_by_scoped_name.clear();
01322 ElementMap::const_iterator ti;
01323 for (ti = _element_map.begin(); ti != _element_map.end(); ++ti) {
01324 _elements_by_scoped_name[(*ti).second.get_scoped_name()] = (*ti).first;
01325 }
01326 }
01327
01328
01329
01330
01331
01332
01333
01334
01335 int InterrogateDatabase::
01336 lookup(const string &name, Lookup &lookup, LookupType type,
01337 void (InterrogateDatabase::*freshen)()) {
01338 if ((_lookups_fresh & (int)type) == 0) {
01339
01340 (this->*freshen)();
01341 _lookups_fresh |= (int)type;
01342 }
01343
01344 Lookup::const_iterator li;
01345 li = lookup.find(name);
01346 if (li != lookup.end()) {
01347 return (*li).second;
01348 }
01349 return 0;
01350 }