diff options
Diffstat (limited to 'project2/variables.cpp')
-rw-r--r-- | project2/variables.cpp | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/project2/variables.cpp b/project2/variables.cpp new file mode 100644 index 0000000..f8fe4bb --- /dev/null +++ b/project2/variables.cpp @@ -0,0 +1,148 @@ +#include "variables.h" +#include "appEngine.h" +#include "perRowValues.h" +#include "session.h" +#include <libxml++/nodes/textnode.h> +#include <stdexcept> +#include <boost/tokenizer.hpp> +#include <boost/foreach.hpp> + +class VariableLiteral : public VariableImpl { + public: + VariableLiteral(const Glib::ustring & src) : VariableImpl(src) { } + + virtual const Glib::ustring & value() const { return source; } +}; + +class VariableImplDyn : public VariableImpl { + public: + VariableImplDyn(const Glib::ustring & src) : VariableImpl(src), cacheValid(false) { } + virtual const Glib::ustring & value() const = 0; + + protected: + mutable Glib::ustring cache; + mutable bool cacheValid; +}; + +class VariableSession : public VariableImplDyn { + public: + VariableSession(const Glib::ustring & src) : VariableImplDyn(src) { } + const Glib::ustring & value() const + { + if (!cacheValid) { + cache = ApplicationEngine::getCurrent()->session()->GetValue(source.substr(1)); + cacheValid = true; + } + return cache; + } +}; + +class VariableParam : public VariableImplDyn { + public: + VariableParam(const Glib::ustring & src) : VariableImplDyn(src) { } + const Glib::ustring & value() const + { + if (!cacheValid) { + cache = ApplicationEngine::getCurrent()->env()->getParamQuery(source.substr(1)); + cacheValid = true; + } + return cache; + } +}; + +class VariableUri : public VariableImplDyn { + public: + VariableUri(const Glib::ustring & src) : VariableImplDyn(src) { } + const Glib::ustring & value() const + { + if (!cacheValid) { + cache = ApplicationEngine::getCurrent()->env()->getParamUri(source.substr(1)); + cacheValid = true; + } + return cache; + } +}; + +class VariableParent : public VariableImplDyn { + public: + VariableParent(const Glib::ustring & src) : VariableImplDyn(src) { } + const Glib::ustring & value() const + { + if (!cacheValid) { + PerRowValues::RowValuesStack::const_iterator r = PerRowValues::Stack().end(); + Glib::ustring::const_iterator c = source.begin(); + while (*c == '^') { + r--; + c++; + } + cache = (*r)->getCurrentValue(Glib::ustring(c, source.end())); + cacheValid = true; + } + return cache; + } +}; + +class VariableParse : public VariableImplDyn { + public: + VariableParse(const Glib::ustring & src) : VariableImplDyn(src) { } + const Glib::ustring & value() const + { + if (!cacheValid) { + boost::char_separator<char> sep(" "); + boost::tokenizer<boost::char_separator<char> > tokens(source.raw(), sep); + std::list<Variable::VariableImplPtr> vars; + size_t len = 0; + BOOST_FOREACH(std::string t, tokens) { + Variable::VariableImplPtr vip = Variable::create(t); + len += vip->value().length() + 1; + vars.push_back(vip); + } + cache.reserve(len); + BOOST_FOREACH(Variable::VariableImplPtr v, vars) { + if (cache.length()) { + cache.append(" "); + } + cache.append(v->value()); + } + cacheValid = true; + } + return cache; + } +}; + +Variable::Variable(const Glib::ustring & s) : + var(create(s)) +{ +} + +Variable::Variable(xmlpp::Attribute * a) : + var(create(a->get_value())) +{ +} + +Variable::Variable(xmlpp::Element * e) : + var(create(e->get_child_text()->get_content())) +{ +} + +Variable::VariableImplPtr +Variable::create(const Glib::ustring & s) +{ + switch (s[0]) { + case '$': // param + return VariableImplPtr(new VariableParam(s)); + case '%': // session + return VariableImplPtr(new VariableSession(s)); + case '^': // parent + return VariableImplPtr(new VariableParent(s)); + case '/': // uri + return VariableImplPtr(new VariableUri(s)); + case '*': // parser + return VariableImplPtr(new VariableParse(s)); + case '=': // literal (explicit) + return VariableImplPtr(new VariableParse(s.substr(1))); + default: + return VariableImplPtr(new VariableLiteral(s)); + } +} + |