diff options
author | randomdan <randomdan@localhost> | 2011-02-10 13:41:16 +0000 |
---|---|---|
committer | randomdan <randomdan@localhost> | 2011-02-10 13:41:16 +0000 |
commit | 7e6515ca94d76869e3b8703885e8e1b10790efdd (patch) | |
tree | 8a46eaf2a21b6dd391435879e5beda201a67f730 | |
parent | Fix silly bug loading readonly RDBMS config entries (diff) | |
download | project2-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.jam | 2 | ||||
-rw-r--r-- | project2/fileRows.cpp | 3 | ||||
-rw-r--r-- | project2/fsRows.cpp | 16 | ||||
-rw-r--r-- | project2/genericVisitor.h | 146 | ||||
-rw-r--r-- | project2/procRows.cpp | 3 | ||||
-rw-r--r-- | project2/regexCheck.cpp | 3 | ||||
-rw-r--r-- | project2/sendmailTask.cpp | 7 | ||||
-rw-r--r-- | project2/sessionXml.cpp | 3 | ||||
-rw-r--r-- | project2/sqlCheck.cpp | 4 | ||||
-rw-r--r-- | project2/sqlMergeTask.cpp | 5 | ||||
-rw-r--r-- | project2/sqlRows.cpp | 4 | ||||
-rw-r--r-- | project2/sqlTask.cpp | 4 | ||||
-rw-r--r-- | project2/variableConvert.cpp | 142 | ||||
-rw-r--r-- | project2/variables.cpp | 91 | ||||
-rw-r--r-- | project2/variables.h | 57 | ||||
-rw-r--r-- | project2/xmlPresenter.cpp | 5 | ||||
-rw-r--r-- | project2/xslRows.cpp | 9 |
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(); } |