00001 /* $Id: typechain.hh,v 1.33 2003/07/24 17:37:44 tetron Exp $ */ 00002 00003 /* 00004 00005 This file is part of the Virtual Object System of 00006 the Interreality project (http://interreality.org). 00007 00008 Copyright (C) 2001, 2002,2002 Reed Hedges <reed@zerohour.net> 00009 00010 This library is free software; you can redistribute it and/or 00011 modify it under the terms of the GNU Lesser General Public 00012 License as published by the Free Software Foundation; either 00013 version 2 of the License, or (at your option) any later version. 00014 00015 This library is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 Lesser General Public License for more details. 00019 00020 You should have received a copy of the GNU Lesser General Public 00021 License along with this library; if not, write to the Free Software 00022 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00023 */ 00024 00025 #ifndef _TYPECHAIN_HH_ 00026 #define _TYPECHAIN_HH_ 00027 00028 #if defined(_WIN32) && defined(_MSC_VER) 00029 # ifdef TYPECHAIN_EXPORTS 00030 # define TYPECHAIN_API __declspec(dllexport) 00031 # else 00032 # define TYPECHAIN_API __declspec(dllimport) 00033 # endif 00034 #else 00035 # define TYPECHAIN_API 00036 #endif 00037 00038 #include <string> 00039 #include <map> 00040 #include <queue> 00041 #include <stdexcept> 00042 00043 using namespace std; 00044 00045 #define TYPECHAIN_DELIMS ";:|" // Typechain delimiters as described in typechian documentation. 00046 00047 00048 00049 #if !defined(TC_PLUGIN_DIR) 00050 #define TC_PLUGIN_DIR "/usr/local/lib/typehandlers" 00051 #endif 00052 00053 class TypeHandler; 00054 00055 /** This class helps you decode data with known encodings. Use it's static methods for registering 00056 and unregistering type/encoding handlers (TypeHandler), and for processing data according 00057 to typechain identifiers. 00058 Typechain is described in more detail in the Virtual Object System manual (see 00059 http://interreality.org/doc/manual/html) 00060 @todo encoding 00061 @todo methods that operate on streams 00062 @todo support "?" (unknown type): if type is unknown (no type identifier given), attempt to find 00063 a magic number or otherwise guess the datatype, and re-decode until next type in typestring 00064 (or an unknown type) is reached. 00065 @see TypeHandler 00066 @author Reed Hedges <reed@zerohour.net> February, 2002 00067 */ 00068 class TYPECHAIN_API TypeChain { 00069 00070 public: 00071 00072 /** Error decoding data */ 00073 class DecodeError : public runtime_error { 00074 public: 00075 string type; 00076 DecodeError(string info, string thetype) : runtime_error(info), type(thetype) { } 00077 virtual ~DecodeError() throw() { } 00078 }; 00079 00080 /** Error encoding data */ 00081 class EncodeError : public runtime_error { 00082 public: 00083 string type; 00084 EncodeError(string info, string thetype) : runtime_error(info), type(thetype) { } 00085 virtual ~EncodeError() throw() { } 00086 }; 00087 00088 /** the internal handlers list, which is a map<string, TypeHandler*>. 00089 If a key exists, but the type handler is a PluginPlaceholder, that means that the handler was 00090 detected as a plugin, but not loaded. 00091 @note Modify this map at your own risk. There are no garauntees here, especially regarding 00092 future version compatability. 00093 */ 00094 00095 static map<string, TypeHandler*> handlers; 00096 00097 /** internal list of abbreviated type names for filename "extensions" and type 00098 names: used by guessTypeFromFilename(). 00099 */ 00100 static map<string, string> filename_extensions; 00101 00102 /** Initialize plugins. Scans the plugins directory and loads (or schedules for later loading) 00103 dynamically loadable libraries whose names match a certain form. 00104 The plugin libraries should be named like this: 00105 Plugins should have a void function with no arguments named plugin_init(), which should call 00106 TypeChain::registerHandler(). 00107 00108 @bug On Mac OSX: crashes if there are any files in the plugins directory that are not MH_BUNDLE files. 00109 00110 */ 00111 static void initialize(); 00112 00113 00114 /** Initialize plugins. 00115 @param dirname,... search these directories for plugins as well as standard location. terminate list with 0. 00116 @see initialize(); 00117 @bug On Mac OSX: crashes if there are any files in a plugins directory that are not MH_BUNDLE files. 00118 */ 00119 static void initialize(const char* dirname, ...); 00120 00121 /** Uninitialize typechain: all handlers are deleted and DLL's are closed. */ 00122 static void uninitialize(); 00123 00124 00125 /** Decode data (stored in a string) according to a type identifier. 00126 For each unit in the type identifier, the first type handler in the handlers list is 00127 @param data Reference to the data being processed: will be replaced with the new data. (your old data WILL be clobbered!!) 00128 @param type type identifier. (not clobbered) 00129 @param params parameters may be passed to and from the handlers using this map. 00130 @return the new type identifier for the new data. 00131 */ 00132 00133 static string decode(string& data, const string& type, map<string,string>& params) ; 00134 00135 /** Decode data, with no params list. */ 00136 static string decode(string& data, const string& type) { 00137 map<string,string> foo; 00138 return decode(data, type, foo); 00139 } 00140 00141 00142 /** Encode data according to type identifier, analagous to decode. 00143 @param data Reference to data to encode. it will be replaced by new encoded data. 00144 @param type type identifier to encode towards. 00145 @return the new type identifer (ie, should be identical to param type if successful) 00146 @warning does nothing currently 00147 00148 */ 00149 static void encode(string& data, const string& type, map<string,string>& params); 00150 00151 /** Encode data, with no params list. */ 00152 static void encode(string& data, const string& type) { 00153 map<string,string> foo; 00154 encode(data, type, foo); 00155 } 00156 00157 /** Register a type handler. If it already exists, it will be replaced. 00158 @param handler instance of a TypeHandler derivation. don't use the same handler pointer twice: the uninitialize() method will attempt to delete it twice. 00159 */ 00160 static void registerHandler(TypeHandler* handler); 00161 00162 00163 /** Unregister a type handler (remove from internal list). 00164 @return the handler removed (TypeHandler*). You probably want to <code>delete</code> it if you're not going to use it anymore. 00165 @param type type/encoding identifier. 00166 */ 00167 static TypeHandler *removeHandler(const string& type); 00168 00169 /** Unregister a type handler, and also delete it: 00170 it will be removed from internal list, and the C++ handler object 00171 will be destroyed with 'delete'. 00172 @param type type/encoding identifier. 00173 */ 00174 static void deleteHandler(const string& type); 00175 00176 00177 00178 /** Guess at the type of a file, given the filename with an abbreviated extension, 00179 based on currently registered set of type handlers. 00180 */ 00181 static string guessTypeFromFilename(const string& filename); 00182 00183 /** Construct useful filename from type */ 00184 static string makeFilename(const string& type, const string& basename); 00185 00186 00187 protected: 00188 00189 public: 00190 00191 int countEncodings(const string& type); 00192 00193 00194 }; 00195 00196 00197 00198 #endif