summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2011-02-10 13:41:16 +0000
committerrandomdan <randomdan@localhost>2011-02-10 13:41:16 +0000
commit7e6515ca94d76869e3b8703885e8e1b10790efdd (patch)
tree8a46eaf2a21b6dd391435879e5beda201a67f730
parentFix silly bug loading readonly RDBMS config entries (diff)
downloadproject2-7e6515ca94d76869e3b8703885e8e1b10790efdd.tar.bz2
project2-7e6515ca94d76869e3b8703885e8e1b10790efdd.tar.xz
project2-7e6515ca94d76869e3b8703885e8e1b10790efdd.zip
Get rid of that stupid LexicalCall and it's messy templates (what WAS I thinking?)
And replace it with a VariableType that wraps the boost::variant and is implicitly convertable to useful things (may need extending in time)
-rw-r--r--project2/Jamfile.jam2
-rw-r--r--project2/fileRows.cpp3
-rw-r--r--project2/fsRows.cpp16
-rw-r--r--project2/genericVisitor.h146
-rw-r--r--project2/procRows.cpp3
-rw-r--r--project2/regexCheck.cpp3
-rw-r--r--project2/sendmailTask.cpp7
-rw-r--r--project2/sessionXml.cpp3
-rw-r--r--project2/sqlCheck.cpp4
-rw-r--r--project2/sqlMergeTask.cpp5
-rw-r--r--project2/sqlRows.cpp4
-rw-r--r--project2/sqlTask.cpp4
-rw-r--r--project2/variableConvert.cpp142
-rw-r--r--project2/variables.cpp91
-rw-r--r--project2/variables.h57
-rw-r--r--project2/xmlPresenter.cpp5
-rw-r--r--project2/xslRows.cpp9
17 files changed, 286 insertions, 218 deletions
diff --git a/project2/Jamfile.jam b/project2/Jamfile.jam
index 040991e..cdba0d3 100644
--- a/project2/Jamfile.jam
+++ b/project2/Jamfile.jam
@@ -49,7 +49,7 @@ lib p2uuid :
lib p2common :
appEngine.cpp dataSource.cpp environment.cpp fileStarGlibIoChannel.cpp iHaveParameters.cpp
iterate.cpp paramChecker.cpp presenter.cpp rawView.cpp dumpTask.cpp logger.cpp
- sourceObject.cpp task.cpp variables.cpp view.cpp xmlObjectLoader.cpp exceptions.cpp
+ sourceObject.cpp task.cpp variables.cpp variableConvert.cpp view.cpp xmlObjectLoader.cpp exceptions.cpp
sessionClearTask.cpp session.cpp sessionSetTask.cpp commonObjects.cpp xmlPresenter.cpp
rowView.cpp rowSet.cpp rowUser.cpp rowProcessor.cpp config.cpp
:
diff --git a/project2/fileRows.cpp b/project2/fileRows.cpp
index 036cf4c..78a61a5 100644
--- a/project2/fileRows.cpp
+++ b/project2/fileRows.cpp
@@ -2,7 +2,6 @@
#include "rowProcessor.h"
#include "xmlObjectLoader.h"
#include "exceptions.h"
-#include "genericVisitor.h"
#include <boost/algorithm/string/predicate.hpp>
ElementLoaderImpl<FileRows> filerowsLoader("filerows");
@@ -172,7 +171,7 @@ FileRows::addColumn(const Glib::ustring & rawtok) const
FileStarChannel
FileRows::doOpen() const
{
- FILE * f = LexicalCall<const char *, FILE *>(boost::bind(&fopen, _1, "r"), path());
+ FILE * f = fopen(path(), "r");
if (!f) {
throw FileNotReadable();
}
diff --git a/project2/fsRows.cpp b/project2/fsRows.cpp
index 1b2d2ce..ca901c8 100644
--- a/project2/fsRows.cpp
+++ b/project2/fsRows.cpp
@@ -3,7 +3,6 @@
#include "xmlObjectLoader.h"
#include "rowProcessor.h"
#include "exceptions.h"
-#include "genericVisitor.h"
#include <boost/filesystem/operations.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/split.hpp>
@@ -13,6 +12,7 @@
#include <pwd.h>
#include <grp.h>
#include <stdio.h>
+#include <boost/date_time/posix_time/posix_time.hpp>
typedef boost::filesystem::basic_directory_iterator<FsRows::Path> DirEnt;
@@ -136,9 +136,13 @@ FsRows::setFilter(const Glib::ustring &)
}
FsRows::Path
-normalisePath(FsRows::Path & p)
+normalisePath(const std::string & p)
{
- return (p / ".").remove_filename();
+ // Ensure there is a trailing /
+ if (*p.rend() != '/') {
+ return p + "/";
+ }
+ return p;
}
void
@@ -146,14 +150,12 @@ FsRows::execute(const RowProcessor * rp) const
{
rowNum = 1;
depth = 0;
- fsRoot = LexicalCall<Path, Path>(boost::bind(&normalisePath, _1), rp->getParameter("root"));
- // Ensure there is a trailing /
+ fsRoot = normalisePath(rp->getParameter("root"));
specs.clear();
SpecSpec s;
typedef SpecSpec & (*splitter)(SpecSpec &, const Glib::ustring &, bool (*)(gunichar), boost::algorithm::token_compress_mode_type);
splitter split = &boost::algorithm::split;
- LexicalCall<Glib::ustring, void>(boost::bind(split, boost::ref(s), _1, Glib::Unicode::isspace, boost::algorithm::token_compress_on),
- rp->getParameter("spec"));
+ split(s, rp->getParameter("spec"), Glib::Unicode::isspace, boost::algorithm::token_compress_on);
for (SpecSpec::const_iterator sf = s.begin(); sf != s.end(); ) {
const Glib::ustring & name = (*sf++);
if (name == "-name") {
diff --git a/project2/genericVisitor.h b/project2/genericVisitor.h
deleted file mode 100644
index ce45f3f..0000000
--- a/project2/genericVisitor.h
+++ /dev/null
@@ -1,146 +0,0 @@
-#ifndef GENERIC_VISITOR_H
-#define GENERIC_VISITOR_H
-
-#include <boost/lexical_cast.hpp>
-#include <boost/function.hpp>
-#include <boost/bind.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
-
-namespace LexicalVisitorHelper {
- template <typename T, typename S, typename R>
- class lexical_run {
- public:
- R operator()(const boost::function1<R, T> & func, const S & i) const
- {
- return func(boost::lexical_cast<T>(i));
- }
- };
- template <typename T, typename R>
- class lexical_run<T, T, R> {
- public:
- R operator()(const boost::function1<R, T> & func, const T & i) const
- {
- return func(i);
- }
- };
- template <typename S, typename R>
- class lexical_run<const unsigned char *, S, R> {
- public:
- R operator()(const boost::function1<R, const unsigned char *> & func, const S & i) const
- {
- return func(reinterpret_cast<const unsigned char *>(boost::lexical_cast<Glib::ustring>(i).c_str()));
- }
- };
- template <typename S, typename R>
- class lexical_run<const char *, S, R> {
- public:
- R operator()(const boost::function1<R, const char *> & func, const S & i) const
- {
- return func(boost::lexical_cast<Glib::ustring>(i).c_str());
- }
- };
- template <typename R>
- class lexical_run<const unsigned char *, Glib::ustring, R> {
- public:
- R operator()(const boost::function1<R, const unsigned char *> & func, const Glib::ustring & i) const
- {
- return func(reinterpret_cast<const unsigned char *>(i.c_str()));
- }
- };
- template <typename R>
- class lexical_run<const char *, Glib::ustring, R> {
- public:
- R operator()(const boost::function1<R, const char *> & func, const Glib::ustring & i) const
- {
- return func(i.c_str());
- }
- };
- template <typename R>
- class lexical_run<Glib::ustring, boost::shared_ptr<const boost::posix_time::ptime>, R> {
- public:
- R operator()(const boost::function1<R, Glib::ustring> & func, const boost::shared_ptr<const boost::posix_time::ptime> & i) const
- {
- return func(boost::posix_time::to_iso_extended_string(*i));
- }
- };
- template <typename R>
- class lexical_run<Glib::ustring, const boost::posix_time::ptime, R> {
- public:
- R operator()(const boost::function1<R, Glib::ustring> & func, const boost::posix_time::ptime & i) const
- {
- return func(boost::posix_time::to_iso_extended_string(i));
- }
- };
- template <typename T, typename S, typename R>
- class lexical_run<T, boost::shared_ptr<const S>, R> {
- public:
- R operator()(const boost::function1<R, T> & func, const boost::shared_ptr<const S> & i) const
- {
- return func(boost::lexical_cast<T>(*i));
- }
- };
- template <typename S, typename R>
- class lexical_run<const char *, boost::shared_ptr<const S>, R> {
- public:
- R operator()(const boost::function1<R, const char *> & func, const boost::shared_ptr<const S> & i) const
- {
- return func(boost::lexical_cast<Glib::ustring>(*i).c_str());
- }
- };
- template <typename S, typename R>
- class lexical_run<const unsigned char *, boost::shared_ptr<const S>, R> {
- public:
- R operator()(const boost::function1<R, const unsigned char *> & func, const boost::shared_ptr<const S> & i) const
- {
- return func(reinterpret_cast<const unsigned char *>(boost::lexical_cast<Glib::ustring>(*i).c_str()));
- }
- };
- template <typename T, typename R>
- class lexical_run<T, boost::shared_ptr<const T>, R> {
- public:
- R operator()(const boost::function1<R, T> & func, const boost::shared_ptr<const T> & i) const
- {
- return func(*i);
- }
- };
- template <typename R>
- class lexical_run<const char *, boost::shared_ptr<const Glib::ustring>, R> {
- public:
- R operator()(const boost::function1<R, const char *> & func, const boost::shared_ptr<const Glib::ustring> & i) const
- {
- return func(i->c_str());
- }
- };
- template <typename R>
- class lexical_run<const unsigned char *, boost::shared_ptr<const Glib::ustring>, R> {
- public:
- R operator()(const boost::function1<R, const unsigned char *> & func, const boost::shared_ptr<const Glib::ustring> & i) const
- {
- return func(reinterpret_cast<const unsigned char *>(i->c_str()));
- }
- };
-
- template <typename T, typename R>
- class LexicalVisitor : public boost::static_visitor<R> {
- public:
- typedef boost::function1<R, T> Func;
- LexicalVisitor(Func f) : func(f) {
- }
- template <typename S>
- R operator()(const S & i) const {
- return lexical_run<T, S, R>()(func, i);
- }
- private:
- Func func;
- };
-}
-
-template <typename P, typename R>
-R LexicalCall(const boost::function1<R, P> & f, const VariableType & s)
-{
- return boost::apply_visitor<const LexicalVisitorHelper::LexicalVisitor<P, R>, const VariableType &>(
- LexicalVisitorHelper::LexicalVisitor<P, R>(f), s);
-}
-
-#endif
-
diff --git a/project2/procRows.cpp b/project2/procRows.cpp
index 53a71b0..c3ae6aa 100644
--- a/project2/procRows.cpp
+++ b/project2/procRows.cpp
@@ -1,6 +1,5 @@
#include "procRows.h"
#include "xmlObjectLoader.h"
-#include "genericVisitor.h"
#include <stdexcept>
ElementLoaderImpl<ProcRows> procrowsLoader("procrows");
@@ -26,7 +25,7 @@ ProcRows::loadComplete(const CommonObjects *)
FileStarChannel
ProcRows::doOpen() const
{
- FILE * f = LexicalCall<const char *, FILE *>(boost::bind(&popen, _1, "re"), path());
+ FILE * f = popen(path(), "re");
if (!f) {
throw SubProcessFailedToStart();
}
diff --git a/project2/regexCheck.cpp b/project2/regexCheck.cpp
index 5921a06..0412145 100644
--- a/project2/regexCheck.cpp
+++ b/project2/regexCheck.cpp
@@ -1,7 +1,6 @@
#include "regexCheck.h"
#include "xmlObjectLoader.h"
#include "commonObjects.h"
-#include "genericVisitor.h"
#include <boost/regex.hpp>
ElementLoaderImpl<RegexCheck> regexCheckLoader("regexcheck");
@@ -26,7 +25,7 @@ RegexCheck::loadComplete(const CommonObjects *)
bool
RegexCheck::performCheck() const
{
- return LexicalCall<Glib::ustring, bool>(boost::bind(&RegexCheck::checkString, this, _1), applyTo());
+ return checkString(applyTo());
}
bool
diff --git a/project2/sendmailTask.cpp b/project2/sendmailTask.cpp
index 7e0f25f..7e2242b 100644
--- a/project2/sendmailTask.cpp
+++ b/project2/sendmailTask.cpp
@@ -2,7 +2,6 @@
#include <boost/foreach.hpp>
#include "xmlObjectLoader.h"
#include "xmlPresenter.h"
-#include "genericVisitor.h"
#include <libxslt/transform.h>
#include <misc.h>
#include <stdexcept>
@@ -73,7 +72,7 @@ class Header : public SendMailTask::MailPart {
header(h), value(v) {
}
const char * write(char ** buf, int * len) {
- LexicalCall<const char *, void>(boost::bind(&Header::writeText, this, buf, len, _1), value);
+ writeText(buf, len, value);
return (const char *)*buf;
}
private:
@@ -171,9 +170,9 @@ SendMailTask::execute() const
// Write email
smtp_session_t session = smtp_create_session();
smtp_message_t message = smtp_add_message(session);
- LexicalCall<const char *, void>(boost::bind(&smtp_set_server, session, _1), server());
+ smtp_set_server(session, server());
smtp_set_header(message, "To", NULL, NULL);
- LexicalCall<const char *, void>(boost::bind(&smtp_add_recipient, message, _1), to());
+ smtp_add_recipient(message, to());
smtp_set_messagecb(message, writeMailWrapper, (SendMailTask*)this);
if (!smtp_start_session(session)) {
char buf[BUFSIZ];
diff --git a/project2/sessionXml.cpp b/project2/sessionXml.cpp
index f7ff7c4..3281a81 100644
--- a/project2/sessionXml.cpp
+++ b/project2/sessionXml.cpp
@@ -1,6 +1,5 @@
#include "sessionXml.h"
#include "uuid.h"
-#include "genericVisitor.h"
#include <libxml++/nodes/element.h>
#include <libxml++/parsers/domparser.h>
#include <libxml++/nodes/textnode.h>
@@ -71,7 +70,7 @@ SessionContainerXml::CleanUp()
sess->set_attribute("expires", boost::lexical_cast<Glib::ustring>(currentSession->expires));
BOOST_FOREACH(const SessionXml::Values::value_type & nvp, currentSession->vars) {
xmlpp::Element * v = sess->add_child("var");
- LexicalCall<Glib::ustring, void>(boost::bind(&xmlpp::Element::add_child_text, v, _1), nvp.second);
+ v->add_child_text(nvp.second);
v->set_attribute("name", nvp.first);
}
doc->write_to_file(xmlFile);
diff --git a/project2/sqlCheck.cpp b/project2/sqlCheck.cpp
index fc8f4bc..c8d5a23 100644
--- a/project2/sqlCheck.cpp
+++ b/project2/sqlCheck.cpp
@@ -6,7 +6,6 @@
#include <boost/regex.hpp>
#include "commonObjects.h"
#include "sqlVariableBinder.h"
-#include "genericVisitor.h"
ElementLoaderImpl<SqlCheck> sqlCheckLoader("sqlcheck");
@@ -30,8 +29,7 @@ SqlCheck::~SqlCheck()
void
SqlCheck::loadComplete(const CommonObjects * co)
{
- query = LexicalCall<std::string, const RdbmsDataSource *>(boost::bind(
- &CommonObjects::dataSource<RdbmsDataSource>, co, _1), dataSource)->getReadonly().newSelectCommand(sql);
+ query = co->dataSource<RdbmsDataSource>(dataSource())->getReadonly().newSelectCommand(sql);
}
class HandleDoCompare : public DB::HandleField {
diff --git a/project2/sqlMergeTask.cpp b/project2/sqlMergeTask.cpp
index f59cc97..12e8a48 100644
--- a/project2/sqlMergeTask.cpp
+++ b/project2/sqlMergeTask.cpp
@@ -3,7 +3,6 @@
#include "rdbmsDataSource.h"
#include "exceptions.h"
#include "sqlVariableBinder.h"
-#include "genericVisitor.h"
#include <misc.h>
#include <stdio.h>
#include <stdexcept>
@@ -89,7 +88,7 @@ SqlMergeTask::~SqlMergeTask()
void
SqlMergeTask::loadComplete(const CommonObjects * co)
{
- destdb = &LexicalCall<std::string, const RdbmsDataSource *>(boost::bind(&CommonObjects::dataSource<RdbmsDataSource>, co, _1), dataSource)->getWritable();
+ destdb = &co->dataSource<RdbmsDataSource>(dataSource())->getWritable();
insCmd = insertCommand();
BOOST_FOREACH(const Iterates::value_type & i, sources) {
attach(i.second, insCmd);
@@ -128,7 +127,7 @@ SqlMergeTask::execute() const
BOOST_FOREACH(const Keys::value_type & k, keys) {
tp.addKey(k);
}
- LexicalCall<const char *, void>(boost::bind(&TablePatch::patch, tp, _1, patchOrder.c_str()), updateWhere());
+ tp.patch(updateWhere(), patchOrder.c_str());
dropTempTable();
}
diff --git a/project2/sqlRows.cpp b/project2/sqlRows.cpp
index 94f9fc1..ebd0a4b 100644
--- a/project2/sqlRows.cpp
+++ b/project2/sqlRows.cpp
@@ -9,8 +9,8 @@
#include "xmlObjectLoader.h"
#include "commonObjects.h"
#include "sqlVariableBinder.h"
-#include "genericVisitor.h"
#include <boost/date_time/gregorian/gregorian_types.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
ElementLoaderImpl<SqlRows> sqlviewLoader("sqlrows");
@@ -31,7 +31,7 @@ SqlRows::~SqlRows()
void
SqlRows::loadComplete(const CommonObjects * co)
{
- db = LexicalCall<std::string, const RdbmsDataSource *>(boost::bind(&CommonObjects::dataSource<RdbmsDataSource>, co, _1), dataSource);
+ db = co->dataSource<RdbmsDataSource>(dataSource());
}
void
diff --git a/project2/sqlTask.cpp b/project2/sqlTask.cpp
index 341dbb9..543dd41 100644
--- a/project2/sqlTask.cpp
+++ b/project2/sqlTask.cpp
@@ -5,7 +5,6 @@
#include "rdbmsDataSource.h"
#include "commonObjects.h"
#include "sqlVariableBinder.h"
-#include "genericVisitor.h"
ElementLoaderImpl<SqlTask> sqltaskLoader("sqltask");
@@ -27,8 +26,7 @@ SqlTask::~SqlTask()
void
SqlTask::loadComplete(const CommonObjects * co)
{
- modify = LexicalCall<std::string, const RdbmsDataSource *>(boost::bind(
- &CommonObjects::dataSource<RdbmsDataSource>, co, _1), dataSource)->getWritable().newModifyCommand(sql);
+ modify = co->dataSource<RdbmsDataSource>(dataSource())->getWritable().newModifyCommand(sql);
}
void
diff --git a/project2/variableConvert.cpp b/project2/variableConvert.cpp
new file mode 100644
index 0000000..a084639
--- /dev/null
+++ b/project2/variableConvert.cpp
@@ -0,0 +1,142 @@
+#include "variables.h"
+#include <boost/lexical_cast.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+template <typename T>
+void
+deleter(const void * t)
+{
+ delete static_cast<const T *>(t);
+}
+
+template <typename T>
+const T *
+set(const VariableType * var, const T * t, VariableType::Freer f = deleter<T>)
+{
+ if (var->freer) { var->freer(var->convertCache); }
+ var->convertCache = t;
+ var->freer = f;
+ return t;
+}
+template <typename T>
+const T *
+set(const VariableType * var, const T * t)
+{
+ return set(var, t, deleter<T>);
+}
+
+// Convert to Glib::ustring
+class ConvertVisitorGlibUstring : public boost::static_visitor<const Glib::ustring &> {
+ public:
+ ConvertVisitorGlibUstring(const VariableType * v) : var(v) {
+ }
+ const Glib::ustring & operator()(const Glib::ustring & r) const {
+ return *set(var, &r, NULL);
+ }
+ const Glib::ustring & operator()(const boost::shared_ptr<const Glib::ustring> & r) const {
+ return *set(var, r.get(), NULL);
+ }
+ const Glib::ustring & operator()(const boost::posix_time::ptime & r) const {
+ return *set(var, new Glib::ustring(boost::posix_time::to_iso_extended_string(r)));
+ }
+ const Glib::ustring & operator()(const boost::shared_ptr<const boost::posix_time::ptime> & r) const {
+ return *set(var, new Glib::ustring(boost::posix_time::to_iso_extended_string(*r)));
+ }
+ template <typename T>
+ const Glib::ustring & operator()(const T & r) const {
+ return *set(var, new Glib::ustring(boost::lexical_cast<Glib::ustring>(r)));
+ }
+ private:
+ const VariableType * var;
+};
+// Convert to STL std::string
+class ConvertVisitorStdString : public boost::static_visitor<const std::string &> {
+ public:
+ ConvertVisitorStdString(const VariableType * v) : var(v) {
+ }
+ const std::string & operator()(const Glib::ustring & r) const {
+ return *set(var, new std::string(r));
+ }
+ const std::string & operator()(const boost::shared_ptr<const Glib::ustring> & r) const {
+ return *set(var, new std::string(*r));
+ }
+ const std::string & operator()(const boost::posix_time::ptime & r) const {
+ return *set(var, new std::string(boost::posix_time::to_iso_extended_string(r)));
+ }
+ const std::string & operator()(const boost::shared_ptr<const boost::posix_time::ptime> & r) const {
+ return *set(var, new std::string(boost::posix_time::to_iso_extended_string(*r)));
+ }
+ template <typename T>
+ const std::string & operator()(const T & r) const {
+ return *set(var, new std::string(boost::lexical_cast<std::string>(r)));
+ }
+ private:
+ const VariableType * var;
+};
+// Convert to char * (with std::string storage)
+class ConvertVisitorCharStar : public boost::static_visitor<const char *> {
+ public:
+ ConvertVisitorCharStar(const VariableType * v) : var(v) {
+ }
+ const char * operator()(const Glib::ustring & r) const {
+ return set(var, &r, NULL)->c_str();
+ }
+ const char * operator()(const boost::shared_ptr<const Glib::ustring> & r) const {
+ return set(var, r.get(), NULL)->c_str();
+ }
+ const char * operator()(const boost::posix_time::ptime & r) const {
+ return set(var, new std::string(boost::posix_time::to_iso_extended_string(r)))->c_str();
+ }
+ const char * operator()(const boost::shared_ptr<const boost::posix_time::ptime> & r) const {
+ return set(var, new std::string(boost::posix_time::to_iso_extended_string(*r)))->c_str();
+ }
+ template <typename T>
+ const char * operator()(const T & r) const {
+ return set(var, new std::string(boost::lexical_cast<std::string>(r)))->c_str();
+ }
+ private:
+ const VariableType * var;
+};
+// Convert to unsigned char * (with std::basic_string<unsigned char> storage / std::string)
+class ConvertVisitorUCharStar : public boost::static_visitor<const unsigned char *> {
+ public:
+ ConvertVisitorUCharStar(const VariableType * v) : var(v) {
+ }
+ const unsigned char * operator()(const Glib::ustring & r) const {
+ return reinterpret_cast<const unsigned char *>(set(var, &r, NULL)->c_str());
+ }
+ const unsigned char * operator()(const boost::shared_ptr<const Glib::ustring> & r) const {
+ return reinterpret_cast<const unsigned char *>(set(var, r.get(), NULL)->c_str());
+ }
+ const unsigned char * operator()(const boost::posix_time::ptime & r) const {
+ return reinterpret_cast<const unsigned char *>(
+ set(var, new std::string(boost::posix_time::to_iso_extended_string(r)))->c_str());
+ }
+ const unsigned char * operator()(const boost::shared_ptr<const boost::posix_time::ptime> & r) const {
+ return reinterpret_cast<const unsigned char *>(
+ set(var, new std::string(boost::posix_time::to_iso_extended_string(*r)))->c_str());
+ }
+ template <typename T>
+ const unsigned char * operator()(const T & r) const {
+ return set(var, new std::basic_string<unsigned char>(boost::lexical_cast<std::basic_string<unsigned char> >(r)))->c_str();
+ }
+ private:
+ const VariableType * var;
+};
+VariableType::operator const Glib::ustring &() const
+{
+ return boost::apply_visitor(ConvertVisitorGlibUstring(this), *this);
+}
+VariableType::operator const std::string &() const
+{
+ return boost::apply_visitor(ConvertVisitorStdString(this), *this);
+}
+VariableType::operator const char *() const
+{
+ return boost::apply_visitor(ConvertVisitorCharStar(this), *this);
+}
+VariableType::operator const unsigned char *() const
+{
+ return boost::apply_visitor(ConvertVisitorUCharStar(this), *this);
+}
+
diff --git a/project2/variables.cpp b/project2/variables.cpp
index 32a1a15..c5907ed 100644
--- a/project2/variables.cpp
+++ b/project2/variables.cpp
@@ -3,7 +3,6 @@
#include "appEngine.h"
#include "session.h"
#include "rowUser.h"
-#include "genericVisitor.h"
#include <libxml++/nodes/textnode.h>
#include <stdexcept>
#include <boost/tokenizer.hpp>
@@ -11,30 +10,94 @@
#include <boost/algorithm/string/predicate.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
class UnknownVariableType : public std::exception { };
class UnknownVariableSource : public std::exception { };
class NoVariableDefinition : public std::exception { };
+enum VT_typeID {
+ DefaultType,
+ StringPtr,
+ String,
+ Int,
+ UInt,
+ LInt,
+ LUInt,
+ LLInt,
+ LLUInt,
+ Float,
+ Double,
+ DateTime,
+ DateTimePtr,
+};
+
static
VariableType
-makeVariableType(const Glib::ustring & src, const std::string & type, const std::string & format = std::string())
+makeVariableType(const Glib::ustring & src, const std::string & type, const VT_typeID format = DefaultType)
{
- 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)));
+ switch (format) {
+ case DefaultType:
+ case StringPtr:
+ return boost::shared_ptr<Glib::ustring>(new Glib::ustring(src));
+ case String:
+ return src;
+ case Int:
+ return boost::lexical_cast<int>(src);
+ case UInt:
+ return boost::lexical_cast<unsigned int>(src);
+ case LInt:
+ return boost::lexical_cast<long int>(src);
+ case LUInt:
+ return boost::lexical_cast<long unsigned int>(src);
+ case LLInt:
+ return boost::lexical_cast<long long int>(src);
+ case LLUInt:
+ return boost::lexical_cast<long long unsigned int>(src);
+ case Float:
+ return boost::lexical_cast<float>(src);
+ case Double:
+ return boost::lexical_cast<double>(src);
+ case DateTime:
+ return boost::posix_time::time_from_string(src);
+ case DateTimePtr:
+ return boost::shared_ptr<boost::posix_time::ptime>(new boost::posix_time::ptime(boost::posix_time::time_from_string(src)));
+ }
throw UnknownVariableType();
}
+VariableType::VariableType() :
+ _VT(),
+ convertCache(NULL),
+ freer(NULL)
+{
+}
+
+VariableType::VariableType(const VariableType & vt) :
+ _VT(*((const _VT *)&vt)),
+ convertCache(NULL),
+ freer(NULL)
+{
+}
+
+VariableType::~VariableType()
+{
+ if (freer && convertCache) {
+ freer(convertCache);
+ }
+}
+
+void
+VariableType::operator=(const VariableType & vt)
+{
+ if (freer && convertCache) {
+ freer(convertCache);
+ }
+ freer = NULL;
+ convertCache = NULL;
+ _VT::operator=(*((const _VT *)&vt));
+}
+
class VariableLiteral : public VariableImpl {
public:
VariableLiteral(const Glib::ustring & src, const std::string & type = std::string()) :
diff --git a/project2/variables.h b/project2/variables.h
index 2cccd5e..7303e5a 100644
--- a/project2/variables.h
+++ b/project2/variables.h
@@ -14,24 +14,45 @@
class RowUser;
typedef boost::variant<
- // Strings
- Glib::ustring,
- boost::shared_ptr<const Glib::ustring>,
- // Numbers
- long long unsigned int,
- long unsigned int,
- unsigned int,
- short unsigned int,
- long long int,
- long int,
- int,
- short int,
- double,
- float,
- // DateTimes
- boost::posix_time::ptime,
- boost::shared_ptr<const boost::posix_time::ptime>
- > VariableType;
+ // Strings
+ Glib::ustring,
+ boost::shared_ptr<const Glib::ustring>,
+ // Numbers
+ long long unsigned int,
+ long unsigned int,
+ unsigned int,
+ short unsigned int,
+ long long int,
+ long int,
+ int,
+ short int,
+ double,
+ float,
+ // DateTimes
+ boost::posix_time::ptime,
+ boost::shared_ptr<const boost::posix_time::ptime>
+ > _VT;
+
+class VariableType : public _VT {
+ public:
+ typedef void(*Freer)(const void*);
+ template<typename T>
+ VariableType(const T & t) : _VT(t), convertCache(NULL), freer(NULL) { }
+ VariableType();
+ VariableType(const VariableType &);
+ ~VariableType();
+ void operator=(const VariableType &);
+
+ operator const Glib::ustring &() const;
+ operator const std::string &() const;
+ operator const char *() const;
+ operator const unsigned char *() const;
+
+ private:
+ template <typename T> friend const T * set(const VariableType * var, const T * t, Freer);
+ mutable const void * convertCache;
+ mutable Freer freer;
+};
class VariableImpl : public virtual IntrusivePtrBase {
public:
diff --git a/project2/xmlPresenter.cpp b/project2/xmlPresenter.cpp
index 46b1ef1..32d28cb 100644
--- a/project2/xmlPresenter.cpp
+++ b/project2/xmlPresenter.cpp
@@ -1,5 +1,4 @@
#include "xmlPresenter.h"
-#include "genericVisitor.h"
XmlPresenter::~XmlPresenter()
{
@@ -39,13 +38,13 @@ XmlPresenter::pushSub(const Glib::ustring & name, const Glib::ustring & ns) cons
void
XmlPresenter::addAttr(const Glib::ustring & name, const Glib::ustring & ns, const VariableType & value) const
{
- LexicalCall<Glib::ustring, void>(boost::bind(&xmlpp::Element::set_attribute, nodeStack.back(), name, _1, ns), value);
+ nodeStack.back()->set_attribute(name, value);
}
void
XmlPresenter::setText(const VariableType & value) const
{
- LexicalCall<Glib::ustring, void>(boost::bind(&xmlpp::Element::set_child_text, nodeStack.back(), _1), value);
+ nodeStack.back()->set_child_text(value);
}
void
diff --git a/project2/xslRows.cpp b/project2/xslRows.cpp
index 0b981aa..f15f38f 100644
--- a/project2/xslRows.cpp
+++ b/project2/xslRows.cpp
@@ -3,7 +3,6 @@
#include "xml.h"
#include "exceptions.h"
#include "xmlObjectLoader.h"
-#include "genericVisitor.h"
#include <boost/lexical_cast.hpp>
#include <libxml/HTMLparser.h>
#include <libxml/xpath.h>
@@ -104,7 +103,7 @@ XslRows::execute(const RowProcessor * rp) const
{
typedef boost::shared_ptr<xmlXPathObject> xmlXPathObjectSPtr;
typedef boost::shared_ptr<xmlXPathContext> xmlXPathContextSPtr;
- xmlDocPtr doc = LexicalCall<Glib::ustring, xmlDocPtr>(boost::bind(&XslRows::getDocument, this, _1), url());
+ xmlDocPtr doc = getDocument(url());
xmlXPathContextSPtr xpathCtx = xmlXPathContextSPtr(xmlXPathNewContext(doc), xmlXPathFreeContext);
if (!xpathCtx) {
throw XpathInitError();
@@ -112,8 +111,7 @@ XslRows::execute(const RowProcessor * rp) const
BOOST_FOREACH(const Namespaces::value_type & ns, namespaces) {
xmlXPathRegisterNs(xpathCtx.get(), BAD_CAST ns.first.c_str(), BAD_CAST ns.second.c_str());
}
- xmlXPathObjectSPtr xpathObj = xmlXPathObjectSPtr(
- LexicalCall<const xmlChar *, xmlXPathObjectPtr>(boost::bind(&xmlXPathEvalExpression, _1, xpathCtx.get()), fv->root()), xmlXPathFreeObject);
+ xmlXPathObjectSPtr xpathObj = xmlXPathObjectSPtr(xmlXPathEvalExpression(fv->root(), xpathCtx.get()));
if (!xpathObj || !xpathObj->nodesetval) {
throw XpathEvalError();
}
@@ -123,8 +121,7 @@ XslRows::execute(const RowProcessor * rp) const
xpathCtx->node = rowRoot;
values.clear();
BOOST_FOREACH(const FilterView::XPaths::value_type & xp, fv->xpaths) {
- xmlXPathObjectSPtr xpathObjI = xmlXPathObjectSPtr(LexicalCall<const xmlChar *, xmlXPathObjectPtr>(
- boost::bind(&xmlXPathEvalExpression, _1, xpathCtx.get()), xp.second()), xmlXPathFreeObject);
+ xmlXPathObjectSPtr xpathObjI = xmlXPathObjectSPtr(xmlXPathEvalExpression(xp.second(), xpathCtx.get()), xmlXPathFreeObject);
if (!xpathObjI) {
throw XpathEvalError();
}