summaryrefslogtreecommitdiff
path: root/project2/variables.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'project2/variables.cpp')
-rw-r--r--project2/variables.cpp148
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));
+ }
+}
+