00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef ACTIONS_H
00012 #define ACTIONS_H
00013
00014 #include <map>
00015 #include <string>
00016 #include "digester.h"
00017
00018 namespace desaxe {
00019
00028 class Action_body
00029 {
00030 protected:
00031 Action_body() : dig(NULL) {}
00032 virtual ~Action_body() {}
00033 virtual void begin(const Xml_string&, Xml_attr) {}
00034
00035 virtual void end(const Xml_string&) {}
00036 virtual void chars(const Xml_string&) {}
00037
00038 Digester* dig;
00039 private:
00040 int refs;
00041 friend class Action;
00042 };
00043
00044
00045
00058 class Action
00059 {
00060 public:
00061 inline Digester* digester() { return body->dig; }
00062 inline void setDigester(Digester* dig) { body->dig = dig; }
00063
00064 inline void begin(const Xml_string& tag, Xml_attr attr)
00065 { body->begin(tag, attr); }
00066 inline void end(const Xml_string& tag) { body->end(tag); }
00067 inline void chars(const Xml_string& data) { body->chars(data); }
00068
00069
00070 Action(const Action& other)
00071 {
00072 body = other.body;
00073 body->refs++;
00074 }
00075 virtual ~Action()
00076 {
00077 if (--body->refs == 0)
00078 delete body;
00079 }
00080 Action& operator=(const Action& other)
00081 {
00082 if (body != other.body) {
00083 if (--body->refs == 0)
00084 delete body;
00085 body = other.body;
00086 ++body->refs;
00087 }
00088 return *this;
00089 }
00090
00091 protected:
00092 Action(Action_body* body_)
00093 {
00094 body = body_;
00095 body->refs = 1;
00096 }
00097
00098 private:
00099 Action();
00100
00101 Action_body* body;
00102 };
00103
00104
00105 class Dummy {};
00106
00114 template <class Body, class Arg1=Dummy, class Arg2=Dummy, class Arg3=Dummy, class Arg4=Dummy, class Arg5=Dummy>
00115 struct MakeAction : public Action
00116 {
00117 MakeAction() : Action(new Body()) {}
00118 MakeAction(Arg1 a1) : Action(new Body(a1)) {}
00119 MakeAction(Arg1 a1, Arg2 a2) : Action(new Body(a1, a2)) {}
00120 MakeAction(Arg1 a1, Arg2 a2, Arg3 a3) : Action(new Body(a1, a2, a3)) {}
00121 MakeAction(Arg1 a1, Arg2 a2, Arg3 a3, Arg4 a4) : Action(new Body(a1, a2, a3, a4)) {}
00122 MakeAction(Arg1 a1, Arg2 a2, Arg3 a3, Arg4 a4, Arg5 a5) : Action(new Body(a1, a2, a3, a4, a5)) {}
00123 };
00124
00125
00126
00132 template<class Type>
00133 class Generator_body : public Action_body
00134 {
00135 public:
00136 virtual Type* eval(Digester* dig_, const Xml_string& tag, Xml_attr attr)
00137 {
00138 dig = dig_;
00139 begin(tag, attr);
00140 Type* res;
00141 res = dig->template top<Type>();
00142 end(tag);
00143 return res;
00144 }
00145 protected:
00146 virtual void end(const Xml_string& ) { dig->pop(); }
00147 };
00148
00149
00150
00154 template<class Type>
00155 class Generator : public Action
00156 {
00157 public:
00158 Type* eval(Digester* dig, const Xml_string& tag, Xml_attr attr)
00159 {
00160 return static_cast<Generator_body<Type>*>(body)->eval(dig, tag, attr);
00161 }
00162
00163 protected:
00164 Generator(Generator_body<Type>* body_) : Action(body_) {}
00165 };
00166
00167
00175 template <class Body, class Obj_Type, class Arg1=Dummy, class Arg2=Dummy, class Arg3=Dummy>
00176 struct MakeGenerator : public Generator<Obj_Type>
00177 {
00178 MakeGenerator() : Generator<Obj_Type>(new Body()) {}
00179 MakeGenerator(Arg1 a) : Generator<Obj_Type>(new Body(a)) {}
00180 MakeGenerator(Arg1 a1, Arg2 a2) : Generator<Obj_Type>(new Body(a1, a2)) {}
00181 MakeGenerator(Arg1 a1, Arg2 a2, Arg3 a3) : Generator<Obj_Type>(new Body(a1, a2, a3)) {}
00182 };
00183
00184 }
00185
00186 #endif