00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <sys/types.h>
00025
00026 #include <errno.h>
00027 #include <sys/stat.h>
00028 #include <string.h>
00029 #include <dirent.h>
00030
00031 #ifdef HAVE_UNISTD_H
00032 #include <unistd.h>
00033 #endif
00034
00035
00036 #include <stdarg.h>
00037
00038 #include <string>
00039 #include <map>
00040 #include <vector>
00041 #include <list>
00042 #include <iostream>
00043
00044 #include <pluginloader/plugins.hh>
00045
00046 #include "typechain.hh"
00047 #include "typehandler.hh"
00048
00049 #include "tclexer.hh"
00050
00051
00052
00053 #if !defined(LOGLEV)
00054 #define LOGLEV 2
00055 #else
00056
00057 #endif
00058
00059 #define LOG(c, l, m) if (l <= LOGLEV) std::clog << c << ": " << m << endl;
00060
00061
00062
00063 class DecodingTCLexer : public TypechainLexer {
00064 protected:
00065
00066
00067 string* datap;
00068 string finaltype;
00069 map<string,string> finalparams;
00070
00071 void complete_token(string token, map<string, string> params) ;
00072 void final_type(string type, map<string, string> params);
00073
00074
00075 public:
00076 DecodingTCLexer(const string& t);
00077 string decode(string& data, map<string,string>& params) ;
00078 };
00079
00080
00081 class EncodingTCLexer : public TypechainLexer {
00082 protected:
00083
00084
00085 string* datap;
00086 string finaltype;
00087 map<string, string> finalparams;
00088 void complete_token(string token, map<string, string> params);
00089 void final_type(string type, map<string, string> params);
00090 public:
00091 EncodingTCLexer(const string& t);
00092 void encode(string& data, map<string, string>& params);
00093 };
00094
00095
00096
00097
00098
00099
00100
00101 class FilenameTCLexer : public TypechainLexer {
00102 protected:
00103 string filename;
00104 void complete_token(string token, map<string, string> params) ;
00105 void final_type(string type, map<string, string> params) ;
00106 public:
00107 FilenameTCLexer(string t) : TypechainLexer(t) {
00108 }
00109 string makeExtensions() ;
00110 };
00111
00112
00113
00114
00115 DecodingTCLexer::DecodingTCLexer(const string& t) :
00116 TypechainLexer(t), datap(0) { }
00117
00118 string DecodingTCLexer::decode(string& targetdata, map<string,string>& params) {
00119 datap = &targetdata;
00120 LOG("DecodingTCLexer::decode", 5, "parsing data...");
00121 yylex();
00122 LOG("DecodingTCLexer::decode", 5, "done parsing data. final type is " << finaltype);
00123 params = finalparams;
00124
00125 return finaltype;
00126 }
00127
00128 void DecodingTCLexer::complete_token(string token, map<string,string> params) {
00129 if( (token != "") && (token != "type") && (token != "?") )
00130 {
00131 if (TypeChain::handlers.find(token) == TypeChain::handlers.end()) {
00132 throw TypeChain::DecodeError("No handler found", token);
00133 }
00134
00135
00136 LOG("TypeChain decoding lexer", 5, "decoding data of type " << token << "...");
00137 TypeChain::handlers[token]->decode(*datap, params);
00138 }
00139 }
00140
00141 void DecodingTCLexer::final_type(string token, map<string,string> params) {
00142 finaltype = token;
00143 finalparams = params;
00144 }
00145
00146
00147
00148
00149 EncodingTCLexer::EncodingTCLexer(const string& t) :
00150 TypechainLexer(t), datap(0) { }
00151
00152 void EncodingTCLexer::encode(string& targetdata, map<string, string>& params) {
00153 datap = &targetdata;
00154 yylex();
00155 params = finalparams;
00156
00157 }
00158
00159 void EncodingTCLexer::complete_token(string token, map<string, string> params) {
00160 if( (token != "") && (token != "type") && (token != "?") )
00161 {
00162 if(TypeChain::handlers.find(token) == TypeChain::handlers.end()) {
00163 throw TypeChain::EncodeError("No handler found", token);
00164 }
00165 TypeChain::handlers[token]->encode(*datap, params);
00166 }
00167 }
00168
00169 void EncodingTCLexer::final_type(string token, map<string, string> params) {
00170 finaltype = token;
00171 finalparams = params;
00172 }
00173
00174
00175
00176
00177
00178
00179 map<string,TypeHandler*> TypeChain::handlers;
00180 map<string,string> TypeChain::filename_extensions;
00181
00182
00183 void TypeChain::initialize() {
00184 TypeChain::registerHandler(new TypeHandler("identity"));
00185 Plugins::scanDir(TC_PLUGIN_DIR, "plugin_init", (void*)&TypeChain::registerHandler);
00186 }
00187
00188
00189 void TypeChain::initialize(const char *dirname, ...) {
00190
00191 LOG("typechain", 4, "initialize: registering handler for identity");
00192 TypeChain::registerHandler(new TypeHandler("identity"));
00193
00194 LOG("typechain", 4, "initialize: scanning directory with libplugins: " << dirname);
00195
00196 Plugins::scanDir(dirname, "plugin_init", (void*)&TypeChain::registerHandler);
00197
00198 va_list args;
00199 va_start(args, dirname);
00200 for(;;) {
00201 char* dir=va_arg(args, char*);
00202 if(dir == 0) break;
00203 LOG("typechain", 4, "initialize: scanning directory with libplugins: " << dir);
00204 Plugins::scanDir(dir, "plugin_init", (void*)&TypeChain::registerHandler);
00205 }
00206 va_end(args);
00207
00208 LOG("typechain", 4, "initialize: scanning directory: " << TC_PLUGIN_DIR);
00209 Plugins::scanDir(TC_PLUGIN_DIR, "plugin_init", (void*)&TypeChain::registerHandler);
00210 }
00211
00212 void TypeChain::uninitialize() {
00213
00214 LOG("typechain", 3, "uninitialize: deleting handlers...");
00215
00216 for( map<string, TypeHandler*>::iterator i = handlers.begin(); i != handlers.end(); i++) {
00217 LOG("typechain", 4, "removing handler for " << (*i).first);
00218 if( (*i).second != NULL )
00219 delete (*i).second;
00220 else
00221 LOG("typechain", 4, "handler was NULL. not deleted.");
00222 handlers.erase(i);
00223 }
00224
00225 for( map<string, string>::iterator i = filename_extensions.begin(); i != filename_extensions.end(); i++) {
00226 filename_extensions.erase(i);
00227 }
00228
00229 LOG("typechain", 3, "closing plugins...");
00230
00231 Plugins::closeAll();
00232 LOG("typechain", 3, "done.");
00233 }
00234
00235 string TypeChain::decode(string& data, const string& type, map<string,string>& params) {
00236 LOG("typechain", 5, "TypeChain::decode: calling DecodingTCLexer.decode()");
00237 DecodingTCLexer lexer(type);
00238 return lexer.decode(data, params);
00239 }
00240
00241
00242
00243
00244 void TypeChain::encode(string& data, const string& type, map<string,string>& params) {
00245 EncodingTCLexer lexer(type);
00246 lexer.encode(data, params);
00247 }
00248
00249
00250 void TypeChain::registerHandler(TypeHandler* handler) {
00251 LOG("typechain", 3, "registering handler for " << handler->type_name);
00252 handlers[handler->type_name] = handler;
00253 filename_extensions[handler->filename_extension] = handler->type_name;
00254 }
00255
00256
00257
00258 TypeHandler* TypeChain::removeHandler(const string& type) {
00259 TypeHandler* h;
00260 h = handlers[type];
00261 handlers.erase(type);
00262 return h;
00263 }
00264
00265 void TypeChain::deleteHandler(const string& type) {
00266 TypeHandler* h;
00267 h = handlers[type];
00268 handlers.erase(type);
00269 delete h;
00270 }
00271
00272
00273 inline string string_tolower(string s) {
00274 return s;
00275
00276 }
00277
00278 string TypeChain::guessTypeFromFilename(const string& filename) {
00279 unsigned int oldpos, pos;
00280 string type;
00281
00282 oldpos = filename.find('.') + 1;
00283 pos = filename.find('.', oldpos);
00284 while(pos != filename.npos) {
00285 type = ";" + filename_extensions[ string_tolower( filename.substr(oldpos, (pos-oldpos)) ) ] + type;;
00286 pos = filename.find('.', oldpos);
00287 oldpos = pos + 1;
00288 }
00289
00290
00291 type.erase(0, 1);
00292
00293 return type;
00294 }
00295
00296
00297 string TypeChain::makeFilename(const string& type, const string& basename) {
00298 FilenameTCLexer lex(type);
00299 return basename + lex.makeExtensions();
00300 }
00301
00302 void FilenameTCLexer::complete_token(string token, map<string, string> params) {
00303 filename = "." + TypeChain::handlers[token]->filename_extension + filename;
00304 }
00305
00306 void FilenameTCLexer::final_type(string type, map<string, string> params) {
00307 complete_token(type, params);
00308 }
00309
00310 string FilenameTCLexer::makeExtensions() {
00311 filename = "";
00312 yylex();
00313 return filename;
00314 }
00315
00316
00317 class CountEncodingsLexer : public TypechainLexer {
00318 protected:
00319 int n;
00320 public:
00321 CountEncodingsLexer(string t) : TypechainLexer(t), n(0) {};
00322 void complete_token(string, map<string,string>) {
00323 n++;
00324 }
00325 void final_type(string , map<string, string> ) { }
00326 int count() {
00327 n = 0;
00328 yylex();
00329 return n;
00330 }
00331 };
00332
00333 int TypeChain::countEncodings(const string& type) {
00334 CountEncodingsLexer lexer(type);
00335 return lexer.count();
00336 }