Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/pnmimage/pnmFileTypeRegistry.cxx

Go to the documentation of this file.
00001 // Filename: pnmFileTypeRegistry.cxx
00002 // Created by:  drose (15Jun00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "pnmFileTypeRegistry.h"
00020 #include "pnmFileType.h"
00021 #include "config_pnmimage.h"
00022 
00023 #include "string_utils.h"
00024 #include "indent.h"
00025 #include "pset.h"
00026 
00027 #include <algorithm>
00028 
00029 PNMFileTypeRegistry *PNMFileTypeRegistry::_global_ptr;
00030 
00031 ////////////////////////////////////////////////////////////////////
00032 //     Function: PNMFileTypeRegistry::Constructor
00033 //       Access: Public
00034 //  Description:
00035 ////////////////////////////////////////////////////////////////////
00036 PNMFileTypeRegistry::
00037 PNMFileTypeRegistry() {
00038   _requires_sort = false;
00039 }
00040 
00041 ////////////////////////////////////////////////////////////////////
00042 //     Function: PNMFileTypeRegistry::Destructor
00043 //       Access: Public
00044 //  Description:
00045 ////////////////////////////////////////////////////////////////////
00046 PNMFileTypeRegistry::
00047 ~PNMFileTypeRegistry() {
00048 }
00049 
00050 ////////////////////////////////////////////////////////////////////
00051 //     Function: PNMFileTypeRegistry::get_ptr
00052 //       Access: Public, Static
00053 //  Description: Returns a pointer to the global PNMFileTypeRegistry
00054 //               object.
00055 ////////////////////////////////////////////////////////////////////
00056 PNMFileTypeRegistry *PNMFileTypeRegistry::
00057 get_ptr() {
00058   if (_global_ptr == (PNMFileTypeRegistry *)NULL) {
00059     _global_ptr = new PNMFileTypeRegistry;
00060   }
00061   return _global_ptr;
00062 }
00063 
00064 ////////////////////////////////////////////////////////////////////
00065 //     Function: PNMFileTypeRegistry::get_num_types
00066 //       Access: Public
00067 //  Description: Returns the total number of types registered.
00068 ////////////////////////////////////////////////////////////////////
00069 int PNMFileTypeRegistry::
00070 get_num_types() const {
00071   if (_requires_sort) {
00072     ((PNMFileTypeRegistry *)this)->sort_preferences();
00073   }
00074   return _types.size();
00075 }
00076 
00077 ////////////////////////////////////////////////////////////////////
00078 //     Function: PNMFileTypeRegistry::get_type
00079 //       Access: Public
00080 //  Description: Returns the nth type registered.
00081 ////////////////////////////////////////////////////////////////////
00082 PNMFileType *PNMFileTypeRegistry::
00083 get_type(int n) const {
00084   nassertr(n >= 0 && n < (int)_types.size(), NULL);
00085   return _types[n];
00086 }
00087 
00088 ////////////////////////////////////////////////////////////////////
00089 //     Function: PNMFileTypeRegistry::get_type_from_extension
00090 //       Access: Public
00091 //  Description: Tries to determine what the PNMFileType is likely to
00092 //               be for a particular image file based on its
00093 //               extension.  Returns a suitable PNMFileType pointer,
00094 //               or NULL if no type can be determined.
00095 ////////////////////////////////////////////////////////////////////
00096 PNMFileType *PNMFileTypeRegistry::
00097 get_type_from_extension(const string &filename) const {
00098   if (_requires_sort) {
00099     ((PNMFileTypeRegistry *)this)->sort_preferences();
00100   }
00101 
00102   // Extract the extension from the filename; if there is no dot, use
00103   // the whole filename as the extension.  This allows us to pass in
00104   // just a dotless extension name in lieu of a filename.
00105 
00106   string extension;
00107   size_t dot = filename.rfind('.');
00108 
00109   if (dot == string::npos) {
00110     extension = filename;
00111   } else {
00112     extension = filename.substr(dot + 1);
00113   }
00114 
00115   if (extension.find('/') != string::npos) {
00116     // If we picked the whole filename and it contains slashes, or if
00117     // the rightmost dot wasn't in the basename of the filename, then
00118     // it's actually a filename without an extension.
00119     extension = "";
00120   }
00121 
00122   Extensions::const_iterator ei;
00123   ei = _extensions.find(extension);
00124   if (ei == _extensions.end() || (*ei).second.empty()) {
00125     // Nothing matches that string.
00126     return NULL;
00127   }
00128 
00129   // Return the first file type associated with the given extension.
00130   return (*ei).second.front();
00131 }
00132 
00133 ////////////////////////////////////////////////////////////////////
00134 //     Function: PNMFileTypeRegistry::get_type_from_magic_number
00135 //       Access: Public
00136 //  Description: Tries to determine what the PNMFileType is likely to
00137 //               be for a particular image file based on its
00138 //               magic number, the first two bytes read from the
00139 //               file.  Returns a suitable PNMFileType pointer, or
00140 //               NULL if no type can be determined.
00141 ////////////////////////////////////////////////////////////////////
00142 PNMFileType *PNMFileTypeRegistry::
00143 get_type_from_magic_number(const string &magic_number) const {
00144   if (_requires_sort) {
00145     ((PNMFileTypeRegistry *)this)->sort_preferences();
00146   }
00147 
00148   Types::const_iterator ti;
00149   for (ti = _types.begin(); ti != _types.end(); ++ti) {
00150     PNMFileType *type = (*ti);
00151     if (type->has_magic_number() &&
00152         type->matches_magic_number(magic_number)) {
00153       return type;
00154     }
00155   }
00156 
00157   return NULL;
00158 }
00159 
00160 ////////////////////////////////////////////////////////////////////
00161 //     Function: PNMFileTypeRegistry::get_type_by_handle
00162 //       Access: Public
00163 //  Description: Returns the PNMFileType instance stored in the
00164 //               registry for the given TypeHandle, e.g. as retrieved
00165 //               by a previous call to get_type() on the type
00166 //               instance.
00167 ////////////////////////////////////////////////////////////////////
00168 PNMFileType *PNMFileTypeRegistry::
00169 get_type_by_handle(TypeHandle handle) const {
00170   Handles::const_iterator hi;
00171   hi = _handles.find(handle);
00172   if (hi != _handles.end()) {
00173     return (*hi).second;
00174   }
00175 
00176   return (PNMFileType *)NULL;
00177 }
00178 
00179 ////////////////////////////////////////////////////////////////////
00180 //     Function: PNMFileTypeRegistry::write_types
00181 //       Access: Public
00182 //  Description: Writes a list of supported image file types to the
00183 //               indicated output stream, one per line.
00184 ////////////////////////////////////////////////////////////////////
00185 void PNMFileTypeRegistry::
00186 write_types(ostream &out, int indent_level) const {
00187   if (_types.empty()) {
00188     indent(out, indent_level) << "(No image types are known).\n";
00189   } else {
00190     Types::const_iterator ti;
00191     for (ti = _types.begin(); ti != _types.end(); ++ti) {
00192       PNMFileType *type = (*ti);
00193       string name = type->get_name();
00194       indent(out, indent_level) << name;
00195       indent(out, max(30 - (int)name.length(), 0)) << "  ";
00196 
00197       int num_extensions = type->get_num_extensions();
00198       if (num_extensions == 1) {
00199         out << "." << type->get_extension(0);
00200       } else if (num_extensions > 1) {
00201         out << "." << type->get_extension(0);
00202         for (int i = 1; i < num_extensions; i++) {
00203           out << ", ." << type->get_extension(i);
00204         }
00205       }
00206       out << "\n";
00207     }
00208   }
00209 }
00210 
00211 ////////////////////////////////////////////////////////////////////
00212 //     Function: PNMFileTypeRegistry::register_type
00213 //       Access: Public
00214 //  Description: Defines a new PNMFileType in the universe.
00215 ////////////////////////////////////////////////////////////////////
00216 void PNMFileTypeRegistry::
00217 register_type(PNMFileType *type) {
00218   // Make sure we haven't already registered this type.
00219   Handles::iterator hi = _handles.find(type->get_type());
00220   if (hi != _handles.end()) {
00221     pnmimage_cat.warning()
00222       << "Attempt to register PNMFileType " << type->get_name()
00223       << " (" << type->get_type() << ") more than once.\n";
00224     return;
00225   }
00226 
00227   _types.push_back(type);
00228   _handles.insert(Handles::value_type(type->get_type(), type));
00229 
00230   // Collect the unique extensions associated with the type.
00231   pset<string> unique_extensions;
00232   int num_extensions = type->get_num_extensions();
00233   for (int i = 0; i < num_extensions; i++) {
00234     string extension = downcase(type->get_extension(i));
00235 
00236     if (!unique_extensions.insert(extension).second) {
00237       pnmimage_cat.warning()
00238         << "PNMFileType " << type->get_name()
00239         << " (" << type->get_type() << ") defined extension "
00240         << extension << " more than once.\n";
00241     }
00242   }
00243 
00244   pset<string>::iterator ui;
00245   for (ui = unique_extensions.begin(); ui != unique_extensions.end(); ++ui) {
00246     _extensions[*ui].push_back(type);
00247   }
00248 
00249   _requires_sort = true;
00250 }
00251 
00252 ////////////////////////////////////////////////////////////////////
00253 //     Function: PNMFileTypeRegistry::sort_preferences
00254 //       Access: Private
00255 //  Description: Sorts the PNMFileType pointers in order according to
00256 //               user-specified preferences in the config file.  This
00257 //               allows us to choose a particular PNMFileType over
00258 //               another for particular extensions when multiple file
00259 //               types map to the same extension, or for file types
00260 //               that have no magic number.
00261 ////////////////////////////////////////////////////////////////////
00262 void PNMFileTypeRegistry::
00263 sort_preferences() {
00264   // So, we don't do anything here yet.  One day we will.
00265 
00266   _requires_sort = false;
00267 }

Generated on Fri May 2 00:43:07 2003 for Panda by doxygen1.3