00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "loaderFileTypeRegistry.h"
00016 #include "loaderFileType.h"
00017 #include "config_pgraph.h"
00018
00019 #include "load_dso.h"
00020 #include "string_utils.h"
00021 #include "indent.h"
00022
00023 #include <algorithm>
00024
00025 LoaderFileTypeRegistry *LoaderFileTypeRegistry::_global_ptr;
00026
00027
00028
00029
00030
00031
00032 LoaderFileTypeRegistry::
00033 LoaderFileTypeRegistry() {
00034 }
00035
00036
00037
00038
00039
00040
00041 LoaderFileTypeRegistry::
00042 ~LoaderFileTypeRegistry() {
00043 }
00044
00045
00046
00047
00048
00049
00050 void LoaderFileTypeRegistry::
00051 register_type(LoaderFileType *type) {
00052
00053 if (find(_types.begin(), _types.end(), type) != _types.end()) {
00054 if (loader_cat->is_debug()) {
00055 loader_cat->debug()
00056 << "Attempt to register LoaderFileType " << type->get_name()
00057 << " (" << type->get_type() << ") more than once.\n";
00058 }
00059 return;
00060 }
00061
00062 _types.push_back(type);
00063
00064 if (!type->get_extension().empty()) {
00065 record_extension(type->get_extension(), type);
00066 }
00067
00068 vector_string words;
00069 extract_words(type->get_additional_extensions(), words);
00070 vector_string::const_iterator wi;
00071 for (wi = words.begin(); wi != words.end(); ++wi) {
00072 record_extension(*wi, type);
00073 }
00074 }
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 void LoaderFileTypeRegistry::
00087 register_deferred_type(const string &extension, const string &library) {
00088 string dcextension = downcase(extension);
00089
00090 Extensions::const_iterator ei;
00091 ei = _extensions.find(dcextension);
00092 if (ei != _extensions.end()) {
00093
00094
00095 if (loader_cat->is_debug()) {
00096 loader_cat->debug()
00097 << "Attempt to register loader library " << library
00098 << " (" << dcextension << ") when extension is already known.\n";
00099 }
00100 return;
00101 }
00102
00103 DeferredTypes::const_iterator di;
00104 di = _deferred_types.find(dcextension);
00105 if (di != _deferred_types.end()) {
00106 if ((*di).second == library) {
00107 if (loader_cat->is_debug()) {
00108 loader_cat->debug()
00109 << "Attempt to register loader library " << library
00110 << " (" << dcextension << ") more than once.\n";
00111 }
00112 return;
00113 } else {
00114 if (loader_cat->is_debug()) {
00115 loader_cat->debug()
00116 << "Multiple libraries registered that use the extension "
00117 << dcextension << "\n";
00118 }
00119 }
00120 }
00121
00122 _deferred_types[dcextension] = library;
00123 }
00124
00125
00126
00127
00128
00129
00130 int LoaderFileTypeRegistry::
00131 get_num_types() const {
00132 return _types.size();
00133 }
00134
00135
00136
00137
00138
00139
00140 LoaderFileType *LoaderFileTypeRegistry::
00141 get_type(int n) const {
00142 nassertr(n >= 0 && n < (int)_types.size(), NULL);
00143 return _types[n];
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153 LoaderFileType *LoaderFileTypeRegistry::
00154 get_type_from_extension(const string &extension) {
00155 string dcextension = downcase(extension);
00156
00157 Extensions::const_iterator ei;
00158 ei = _extensions.find(dcextension);
00159 if (ei == _extensions.end()) {
00160
00161
00162 DeferredTypes::iterator di;
00163 di = _deferred_types.find(dcextension);
00164 if (di != _deferred_types.end()) {
00165
00166
00167
00168
00169 string name = (*di).second;
00170 Filename dlname = Filename::dso_filename("lib" + name + ".so");
00171 _deferred_types.erase(di);
00172
00173 loader_cat->info()
00174 << "loading file type module: " << name << endl;
00175 void *tmp = load_dso(get_plugin_path().get_value(), dlname);
00176 if (tmp == (void *)NULL) {
00177 loader_cat->warning()
00178 << "Unable to load " << dlname.to_os_specific() << ": "
00179 << load_dso_error() << endl;
00180 return NULL;
00181 }
00182
00183
00184 ei = _extensions.find(dcextension);
00185 }
00186 }
00187
00188 if (ei == _extensions.end()) {
00189
00190
00191 return NULL;
00192 }
00193
00194 return (*ei).second;
00195 }
00196
00197
00198
00199
00200
00201
00202
00203 void LoaderFileTypeRegistry::
00204 write(ostream &out, int indent_level) const {
00205 if (_types.empty()) {
00206 indent(out, indent_level) << "(No file types are known).\n";
00207 } else {
00208 Types::const_iterator ti;
00209 for (ti = _types.begin(); ti != _types.end(); ++ti) {
00210 LoaderFileType *type = (*ti);
00211 string name = type->get_name();
00212 indent(out, indent_level) << name;
00213 indent(out, max(30 - (int)name.length(), 0)) << " ";
00214
00215 bool comma = false;
00216 if (!type->get_extension().empty()) {
00217 out << " ." << type->get_extension();
00218 comma = true;
00219 }
00220
00221 vector_string words;
00222 extract_words(type->get_additional_extensions(), words);
00223 vector_string::const_iterator wi;
00224 for (wi = words.begin(); wi != words.end(); ++wi) {
00225 if (comma) {
00226 out << ",";
00227 } else {
00228 comma = true;
00229 }
00230 out << " ." << *wi;
00231 }
00232 out << "\n";
00233 }
00234 }
00235
00236 if (!_deferred_types.empty()) {
00237 indent(out, indent_level) << "Also available:";
00238 DeferredTypes::const_iterator di;
00239 for (di = _deferred_types.begin(); di != _deferred_types.end(); ++di) {
00240 const string &extension = (*di).first;
00241 out << " ." << extension;
00242 }
00243 out << "\n";
00244 }
00245 }
00246
00247
00248
00249
00250
00251
00252
00253 LoaderFileTypeRegistry *LoaderFileTypeRegistry::
00254 get_global_ptr() {
00255 if (_global_ptr == (LoaderFileTypeRegistry *)NULL) {
00256 _global_ptr = new LoaderFileTypeRegistry;
00257 }
00258 return _global_ptr;
00259 }
00260
00261
00262
00263
00264
00265
00266
00267 void LoaderFileTypeRegistry::
00268 record_extension(const string &extension, LoaderFileType *type) {
00269 string dcextension = downcase(extension);
00270 Extensions::const_iterator ei;
00271 ei = _extensions.find(dcextension);
00272 if (ei != _extensions.end()) {
00273 if (loader_cat->is_debug()) {
00274 loader_cat->debug()
00275 << "Multiple LoaderFileTypes registered that use the extension "
00276 << dcextension << "\n";
00277 }
00278 } else {
00279 _extensions.insert(Extensions::value_type(dcextension, type));
00280 }
00281
00282 _deferred_types.erase(dcextension);
00283 }