00001 #ifndef DVCGI_DISPATCHER_H 00002 #define DVCGI_DISPATCHER_H 00003 // $Id: dispatch.h,v 1.1 2003/08/10 13:21:03 dvermeir Exp $ 00004 #include <string> 00005 #include <stdexcept> 00006 #include <iostream> 00007 #include <dvcgi/cgi.h> 00008 00009 namespace Dv { 00010 namespace Cgi { 00011 /** A class template framework to dispatch the control of a Cgi 00012 * program based on a key in the formdata. 00013 * 00014 * We assume that a cgi application has two main objects: a 00015 * Dv::Cgi::Cgi input object and an application object of class 00016 * Application. 00017 * 00018 * The main function would construct both 00019 * @code 00020 * int main(int, char**) { 00021 * .. // get configuration info 00022 * Application application(config-info) 00023 * Dv::Cgi::Cgi cgi(..) 00024 * if (application.main(cgi)) 00025 * return 0; 00026 * else { 00027 * cgi.header().content_type("text/plain"); 00028 * cgi << "Error: " << ... << std::endl; 00029 * return 1; 00030 * } 00031 * } 00032 * @endcode 00033 * 00034 * We also assume that there is a single formdata key that determines 00035 * the action to take, e.g. a key "opcode". Moreover, for each 00036 * relevant key value, there should be a member function 00037 * 00038 * Application::handle_value(Dv::Cgi::Cgi& cgi, const std::string& value); 00039 * 00040 * The class template below makes it easy to dispatch to the correct 00041 * handler-function, based on the value of the specified formdata key. 00042 * 00043 * To use, an instance should define Dispatcher<Application>::table as in the 00044 * example below. 00045 * @code 00046 * Dispatcher<Application>::Entry 00047 * Dispatcher<Application>::table[] = { 00048 * { "", &Application::default_handler }, 00049 * { "a", &Application::handle_a }, 00050 * { "b", &Application::handle_b }, 00051 * { "c", &Application::handle_c }, 00052 * { "", &Application::default_handler } // if "opcode" not defined, should be last 00053 * }; 00054 * @endcode 00055 * 00056 * The main function in the Application could use a Dispatcher as shown below. 00057 * @code 00058 * class Application { 00059 * public: 00060 * bool main(const Dv::Cgi::Cgi& cgi); 00061 * return Dispatcher<Application>::handle(*this, cgi, "opcode"); 00062 * } 00063 * }; 00064 * @endcode 00065 * @sa Dv::Cgi::Cgi 00066 */ 00067 template <class Application> 00068 class Dispatcher { 00069 public: 00070 typedef bool (Application::*Handler)(const Dv::Cgi::Cgi& cgi, const std::string& value); 00071 typedef struct { std::string key; Handler h; } Entry; 00072 static Entry table[]; 00073 static bool handle(Application& c, Dv::Cgi::Cgi& cgi, const std::string& key) { 00074 std::string* value(cgi.props().find(key)); 00075 if (value) { 00076 for (Entry* e(table); (e->key.size()) ; ++e) 00077 if (e->key==*value) 00078 return (c.*(e->h))(cgi, *value); 00079 } 00080 else { 00081 for (Entry* e(table); (e->key.size()) ; ++e) 00082 if (e->key.size() == 0) 00083 return (c.*(e->h))(cgi, ""); 00084 } 00085 return false; 00086 } 00087 }; 00088 00089 }} 00090 #endif
dvcgi-0.5.9 | [10 August, 2003] |