diff options
Diffstat (limited to 'project2/variables.cpp')
-rw-r--r-- | project2/variables.cpp | 66 |
1 files changed, 43 insertions, 23 deletions
diff --git a/project2/variables.cpp b/project2/variables.cpp index f8fe4bb..cafb336 100644 --- a/project2/variables.cpp +++ b/project2/variables.cpp @@ -6,6 +6,7 @@ #include <stdexcept> #include <boost/tokenizer.hpp> #include <boost/foreach.hpp> +#include <boost/algorithm/string/predicate.hpp> class VariableLiteral : public VariableImpl { public: @@ -29,10 +30,7 @@ class VariableSession : public VariableImplDyn { VariableSession(const Glib::ustring & src) : VariableImplDyn(src) { } const Glib::ustring & value() const { - if (!cacheValid) { - cache = ApplicationEngine::getCurrent()->session()->GetValue(source.substr(1)); - cacheValid = true; - } + cache = ApplicationEngine::getCurrent()->session()->GetValue(source.substr(1)); return cache; } }; @@ -63,39 +61,55 @@ class VariableUri : public VariableImplDyn { } }; -class VariableParent : public VariableImplDyn { +class VariableParent : public VariableImplDyn, public RowUser { public: - VariableParent(const Glib::ustring & src) : VariableImplDyn(src) { } + VariableParent(const Glib::ustring & src, RowUser * dep) : + VariableImplDyn(Glib::ustring(std::find_if(src.begin(), src.end(), isalpha), src.end())) + { + PerRowValues::RowValuesStack::const_iterator r = PerRowValues::Stack().end(); + size_t p = src.length() - source.length(); + while (--p) { + r--; + } + row = *r; + row->use(this); + if (dep) { + row->use(dep); + } + } 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())); + cache = row->getCurrentValue(source); cacheValid = true; } return cache; } + void rowChanged() const + { + cacheValid = false; + } + protected: + const PerRowValues * row; }; -class VariableParse : public VariableImplDyn { +class VariableParse : public VariableImplDyn, public RowUser { public: - VariableParse(const Glib::ustring & src) : VariableImplDyn(src) { } + VariableParse(const Glib::ustring & src) : + VariableImplDyn(src) + { + boost::char_separator<char> sep(" "); + boost::tokenizer<boost::char_separator<char> > tokens(source.raw(), sep); + BOOST_FOREACH(std::string t, tokens) { + vars.push_back(Variable::create(t, this)); + } + } 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); + BOOST_FOREACH(Variable::VariableImplPtr vip, vars) { len += vip->value().length() + 1; - vars.push_back(vip); } cache.reserve(len); BOOST_FOREACH(Variable::VariableImplPtr v, vars) { @@ -108,6 +122,12 @@ class VariableParse : public VariableImplDyn { } return cache; } + void rowChanged() const + { + cacheValid = false; + } + private: + std::list<Variable::VariableImplPtr> vars; }; Variable::Variable(const Glib::ustring & s) : @@ -126,7 +146,7 @@ Variable::Variable(xmlpp::Element * e) : } Variable::VariableImplPtr -Variable::create(const Glib::ustring & s) +Variable::create(const Glib::ustring & s, RowUser * dep) { switch (s[0]) { case '$': // param @@ -134,7 +154,7 @@ Variable::create(const Glib::ustring & s) case '%': // session return VariableImplPtr(new VariableSession(s)); case '^': // parent - return VariableImplPtr(new VariableParent(s)); + return VariableImplPtr(new VariableParent(s, dep)); case '/': // uri return VariableImplPtr(new VariableUri(s)); case '*': // parser |