summaryrefslogtreecommitdiff
path: root/project2/variables.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'project2/variables.cpp')
-rw-r--r--project2/variables.cpp209
1 files changed, 114 insertions, 95 deletions
diff --git a/project2/variables.cpp b/project2/variables.cpp
index c8b2571..130d210 100644
--- a/project2/variables.cpp
+++ b/project2/variables.cpp
@@ -13,9 +13,35 @@
#include <boost/function.hpp>
#include <boost/bind.hpp>
+class UnknownVariableType : public std::exception { };
+class UnknownVariableSource : public std::exception { };
+class NoVariableDefinition : public std::exception { };
+
+static
+VariableType
+makeVariableType(const Glib::ustring & src, const std::string & type, const std::string & format = std::string())
+{
+ if (type == "stringptr" || type.empty()) return boost::shared_ptr<Glib::ustring>(new Glib::ustring(src));
+ if (type == "string") return src;
+ if (type == "int") return boost::lexical_cast<int>(src);
+ if (type == "uint") return boost::lexical_cast<unsigned int>(src);
+ if (type == "lint") return boost::lexical_cast<long int>(src);
+ if (type == "luint") return boost::lexical_cast<long unsigned int>(src);
+ if (type == "llint") return boost::lexical_cast<long long int>(src);
+ if (type == "lluint") return boost::lexical_cast<long long unsigned int>(src);
+ if (type == "float") return boost::lexical_cast<float>(src);
+ if (type == "double") return boost::lexical_cast<double>(src);
+ if (type == "datetime") return boost::posix_time::time_from_string(src);
+ if (type == "datetimeptr") return boost::shared_ptr<boost::posix_time::ptime>(new boost::posix_time::ptime(boost::posix_time::time_from_string(src)));
+ throw UnknownVariableType();
+}
+
class VariableLiteral : public VariableImpl {
public:
- VariableLiteral(const Glib::ustring & src) : VariableImpl(src), val(src) { }
+ VariableLiteral(const Glib::ustring & src, const std::string & type = std::string()) :
+ val(makeVariableType(src, type))
+ {
+ }
virtual const VariableType & value() const { return val; }
private:
@@ -24,17 +50,31 @@ class VariableLiteral : public VariableImpl {
class VariableImplDyn : public VariableImpl {
public:
- VariableImplDyn(const Glib::ustring & src) : VariableImpl(src), cacheValid(false) { }
+ VariableImplDyn(const xmlpp::Element * e) :
+ cacheValid(false)
+ {
+ try {
+ defaultValue = Variable(e, "default");
+ }
+ catch (NoVariableDefinition) {
+ // That's cool... no default
+ }
+ }
virtual const VariableType & value() const = 0;
protected:
mutable VariableType cache;
mutable bool cacheValid;
+ boost::optional<Variable> defaultValue;
};
class VariableSession : public VariableImplDyn {
public:
- VariableSession(const Glib::ustring & src) : VariableImplDyn(src) { }
+ VariableSession(const xmlpp::Element * e) :
+ VariableImplDyn(e),
+ name(e->get_attribute_value("name"))
+ {
+ }
const VariableType & value() const
{
try {
@@ -44,15 +84,21 @@ class VariableSession : public VariableImplDyn {
if (!defaultValue) {
throw;
}
- cache = *defaultValue;
+ cache = (*defaultValue)();
}
return cache;
}
+ private:
+ const Glib::ustring name;
};
class VariableParam : public VariableImplDyn {
public:
- VariableParam(const Glib::ustring & src) : VariableImplDyn(src) { }
+ VariableParam(const xmlpp::Element * e) :
+ VariableImplDyn(e),
+ name(e->get_attribute_value("name"))
+ {
+ }
const VariableType & value() const
{
if (!cacheValid) {
@@ -63,33 +109,41 @@ class VariableParam : public VariableImplDyn {
if (!defaultValue) {
throw;
}
- cache = *defaultValue;
+ cache = (*defaultValue)();
}
cacheValid = true;
}
return cache;
}
+ private:
+ const Glib::ustring name;
};
class VariableUri : public VariableImplDyn {
public:
- VariableUri(const Glib::ustring & src) : VariableImplDyn(src) { }
+ VariableUri(const xmlpp::Element * e) :
+ VariableImplDyn(e),
+ index(atoi(e->get_attribute_value("index").c_str()))
+ {
+ }
const VariableType & value() const
{
if (!cacheValid) {
try {
- cache = ApplicationEngine::getCurrent()->env()->getParamUri(atoi(name.c_str()));
+ cache = ApplicationEngine::getCurrent()->env()->getParamUri(index);
}
catch (UriElementOutOfRange) {
if (!defaultValue) {
throw;
}
- cache = *defaultValue;
+ cache = (*defaultValue)();
}
cacheValid = true;
}
return cache;
}
+ private:
+ unsigned int index;
};
static void assignHelper(VariableType & dest, const VariableType & src) {
@@ -98,19 +152,21 @@ static void assignHelper(VariableType & dest, const VariableType & src) {
class VariableParent : public VariableImplDyn, public RowUser {
public:
- VariableParent(const Glib::ustring & src, const RowUser * d) :
- VariableImplDyn(src),
+ VariableParent(const xmlpp::Element * e, const RowUser * d) :
+ VariableImplDyn(e),
row(NULL),
- depth(src.find_first_not_of('^')),
- attr(src[depth] == '!'),
+ depth(atoi(e->get_attribute_value("depth").c_str())),
+ attr(e->get_attribute("attribute")),
+ name(attr ? e->get_attribute_value("attribute") : e->get_attribute_value("name")),
dep(d)
{
}
- VariableParent(const Glib::ustring & name, unsigned int d) :
- VariableImplDyn(name),
+ VariableParent(const Glib::ustring & n, bool a, unsigned int d) :
+ VariableImplDyn(NULL),
row(NULL),
depth(d),
- attr(name[0] == '!'),
+ attr(a),
+ name(n),
dep(NULL)
{
}
@@ -146,13 +202,13 @@ class VariableParent : public VariableImplDyn, public RowUser {
if (!defaultValue) {
throw;
}
- cache = *defaultValue;
+ cache = (*defaultValue)();
}
catch (RowSet::FieldDoesNotExist) {
if (!defaultValue) {
throw;
}
- cache = *defaultValue;
+ cache = (*defaultValue)();
}
cacheValid = true;
}
@@ -177,57 +233,57 @@ class VariableParent : public VariableImplDyn, public RowUser {
mutable ConstRowSetPtr row;
const size_t depth;
const bool attr;
+ const Glib::ustring name;
const RowUser * dep;
mutable boost::function2<void, VariableType &, ConstRowSetPtr> getValue;
};
-class VariableParse : public VariableImplDyn, public RowUser {
+class VariableFixed : public VariableImpl {
public:
- VariableParse(const Glib::ustring & src) :
- VariableImplDyn(src)
+ VariableFixed(VariableType v) :
+ var(v)
{
- boost::tokenizer<boost::char_separator<char> > tokens(source.raw(), boost::char_separator<char>(" "));
- BOOST_FOREACH(std::string t, tokens) {
- vars.push_back(Variable::create(t, this));
- }
}
const VariableType & value() const
{
- if (!cacheValid) {
- Glib::ustring newCache;
- BOOST_FOREACH(Variable::VariableImplPtr v, vars) {
- if (newCache.length()) {
- newCache.append(" ");
- }
- typedef Glib::ustring & (Glib::ustring::*appender)(const Glib::ustring &);
- LexicalCall<Glib::ustring, Glib::ustring &>(boost::bind((appender)&Glib::ustring::append, newCache, _1), v->value());
- }
- cache = newCache;
- cacheValid = true;
- }
- return cache;
- }
- void rowChanged() const
- {
- cacheValid = false;
+ return var;
}
private:
- std::list<Variable::VariableImplPtr> vars;
+ VariableType var;
};
-Variable::Variable(const Glib::ustring & s) :
- var(create(s))
-{
-}
-
-Variable::Variable(const xmlpp::Attribute * a) :
- var(create(a->get_value()))
-{
-}
-
-Variable::Variable(const xmlpp::Element * e) :
- var(create(e->get_child_text()->get_content()))
+Variable::Variable(const xmlpp::Element * e, const Glib::ustring & n, bool required, VariableType def)
{
+ xmlpp::Attribute * a = e->get_attribute(n);
+ if (a) {
+ var = new VariableLiteral(a->get_value());
+ return;
+ }
+ xmlpp::Element::NodeList cs = e->get_children(n);
+ if (cs.size() == 1) {
+ const xmlpp::Element * c = dynamic_cast<const xmlpp::Element *>(cs.front());
+ if (c) {
+ Glib::ustring source = c->get_attribute_value("source");
+ if (source == "session")
+ var = new VariableSession(c);
+ else if (source == "parent")
+ var = new VariableParent(c, NULL);
+ else if (source == "uri")
+ var = new VariableUri(c);
+ else if (source == "param")
+ var = new VariableParam(c);
+ else if (source == "literal" || source.empty())
+ var = new VariableLiteral(c->get_attribute_value("value"), c->get_attribute_value("type"));
+ else
+ throw UnknownVariableSource();
+ return;
+ }
+ }
+ if (!required) {
+ var = new VariableFixed(def);
+ return;
+ }
+ throw NoVariableDefinition();
}
Variable::Variable(VariableImpl * v) :
@@ -235,50 +291,13 @@ Variable::Variable(VariableImpl * v) :
{
}
-Variable::VariableImplPtr
-Variable::create(const Glib::ustring & s, RowUser * dep)
+VariableImpl::~VariableImpl()
{
- if (s.empty()) {
- return VariableImplPtr(new VariableLiteral(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, dep));
- case '/': // uri
- return VariableImplPtr(new VariableUri(s));
- case '*': // parser
- return VariableImplPtr(new VariableParse(s.substr(1)));
- case '=': // literal (explicit)
- return VariableImplPtr(new VariableLiteral(s.substr(1)));
- default:
- return VariableImplPtr(new VariableLiteral(s));
- }
}
Variable
-Variable::makeParent(const Glib::ustring & n, unsigned int d)
-{
- return Variable(new VariableParent(n, d));
-}
-
-VariableImpl::VariableImpl(const Glib::ustring & src) :
- source(src)
-{
- Glib::ustring::const_iterator nameStart = std::find_if(source.begin(), source.end(), Glib::Unicode::isalnum);
- Glib::ustring::const_iterator nameEnd = std::find(nameStart, source.end(), '|');
- name = Glib::ustring(nameStart, nameEnd);
- Glib::ustring::const_iterator defaultStart = nameEnd;
- if (defaultStart != source.end()) {
- defaultStart++;
- defaultValue = Glib::ustring(defaultStart, source.end());
- }
-}
-
-VariableImpl::~VariableImpl()
+Variable::makeParent(const Glib::ustring & name, bool attr, unsigned int dep)
{
+ return Variable(new VariableParent(name, attr, dep));
}