Back to index

scribus-ng  1.3.4.dfsg+svn20071115
actions.h
Go to the documentation of this file.
00001 /*
00002  *  actions.h
00003  *  
00004  *
00005  *  Created by Andreas Vox on 02.06.06.
00006  *  Copyright 2006 under GPL2. All rights reserved.
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        // Handle stuff:
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();  // not defined
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 } // namespace
00185 
00186 #endif