From ca3c009de293bed788fa02a15c202747bf70a9f6 Mon Sep 17 00:00:00 2001 From: randomdan Date: Thu, 29 Jul 2010 23:51:40 +0000 Subject: Add optional support for default values for variables --- project2/appEngine.h | 2 ++ project2/cgiEnvironment.cpp | 12 +++++-- project2/cgiEnvironment.h | 2 +- project2/environment.cpp | 2 +- project2/environment.h | 2 +- project2/perRowValues.h | 2 ++ project2/session.h | 1 + project2/sessionShm.cpp | 6 +++- project2/variables.cpp | 77 ++++++++++++++++++++++++++++++++++++++------- project2/variables.h | 5 ++- 10 files changed, 93 insertions(+), 18 deletions(-) diff --git a/project2/appEngine.h b/project2/appEngine.h index 7f37cfd..54a8cec 100644 --- a/project2/appEngine.h +++ b/project2/appEngine.h @@ -8,6 +8,8 @@ class ApplicationEngine { public: + class UriElementOutOfRange : std::exception { }; + class ParamNotFound : std::exception { }; class DataSourceNotFound : std::exception { }; class DataSourceNotCompatible : std::exception { }; diff --git a/project2/cgiEnvironment.cpp b/project2/cgiEnvironment.cpp index fe38f57..2faf165 100644 --- a/project2/cgiEnvironment.cpp +++ b/project2/cgiEnvironment.cpp @@ -1,4 +1,5 @@ #include "cgiEnvironment.h" +#include "appEngine.h" #include #include #include @@ -21,14 +22,21 @@ CgiEnvironment::~CgiEnvironment() } Glib::ustring -CgiEnvironment::getParamUri(const std::string & p) const +CgiEnvironment::getParamUri(unsigned int p) const { - return elems[atoi(p.c_str())]; + if (p >= elems.size()) { + throw ApplicationEngine::UriElementOutOfRange(); + } + return elems[p]; } Glib::ustring CgiEnvironment::getParamQuery(const std::string & p) const { + cgicc::const_form_iterator i = cgi->getElement(p); + if (i == cgi->getElements().end()) { + throw ApplicationEngine::ParamNotFound(); + } return (*cgi)(p); } diff --git a/project2/cgiEnvironment.h b/project2/cgiEnvironment.h index 7df65c9..c01d50d 100644 --- a/project2/cgiEnvironment.h +++ b/project2/cgiEnvironment.h @@ -15,7 +15,7 @@ class CgiEnvironment : public Environment, public cgicc::CgiEnvironment { CgiEnvironment(cgicc::Cgicc *); virtual ~CgiEnvironment(); - Glib::ustring getParamUri(const std::string & idx) const; + Glib::ustring getParamUri(unsigned int idx) const; Glib::ustring getParamQuery(const std::string & idx) const; std::string getServerName() const { return cgicc::CgiEnvironment::getServerName(); } std::string getScriptName() const { return cgicc::CgiEnvironment::getScriptName(); } diff --git a/project2/environment.cpp b/project2/environment.cpp index 9e4d9f0..c0cc0fa 100644 --- a/project2/environment.cpp +++ b/project2/environment.cpp @@ -9,7 +9,7 @@ Environment::~Environment() } Glib::ustring -Environment::getParamUri(const std::string &) const +Environment::getParamUri(unsigned int) const { throw ParameterTypeNotSupported(); } diff --git a/project2/environment.h b/project2/environment.h index 2925f13..a8c6396 100644 --- a/project2/environment.h +++ b/project2/environment.h @@ -11,7 +11,7 @@ class Environment { Environment(); virtual ~Environment() = 0; - virtual Glib::ustring getParamUri(const std::string & idx) const = 0; + virtual Glib::ustring getParamUri(unsigned int idx) const = 0; virtual Glib::ustring getParamQuery(const std::string & idx) const = 0; virtual std::string getServerName() const = 0; diff --git a/project2/perRowValues.h b/project2/perRowValues.h index 26a0a6b..cee7e07 100644 --- a/project2/perRowValues.h +++ b/project2/perRowValues.h @@ -15,6 +15,8 @@ class RowUser { class PerRowValues { public: + class ParentOutOfRange : public std::exception { }; + class FieldDoesNotExist : public std::exception { }; typedef std::vector RowValuesStack; PerRowValues(); virtual ~PerRowValues() = 0; diff --git a/project2/session.h b/project2/session.h index de31626..8dc1b8b 100644 --- a/project2/session.h +++ b/project2/session.h @@ -8,6 +8,7 @@ class Session { public: + class VariableNotFound : public std::exception { }; typedef std::map Values; Session(); diff --git a/project2/sessionShm.cpp b/project2/sessionShm.cpp index c9f748c..e4c9d16 100644 --- a/project2/sessionShm.cpp +++ b/project2/sessionShm.cpp @@ -100,7 +100,11 @@ SessionShmData::~SessionShmData() Glib::ustring SessionShm::GetValue(const Glib::ustring & name) const { - return data->svs.find(name.c_str())->second.c_str(); + SessionShmData::SessionValues::const_iterator i = data->svs.find(name.c_str()); + if (i == data->svs.end()) { + throw Session::VariableNotFound(); + } + return i->second.c_str(); } void diff --git a/project2/variables.cpp b/project2/variables.cpp index 9aa1a5b..07d30aa 100644 --- a/project2/variables.cpp +++ b/project2/variables.cpp @@ -30,7 +30,15 @@ class VariableSession : public VariableImplDyn { VariableSession(const Glib::ustring & src) : VariableImplDyn(src) { } const Glib::ustring & value() const { - cache = ApplicationEngine::getCurrent()->session()->GetValue(source.substr(1)); + try { + cache = ApplicationEngine::getCurrent()->session()->GetValue(name); + } + catch (Session::VariableNotFound) { + if (!defaultValue) { + throw; + } + cache = *defaultValue; + } return cache; } }; @@ -41,7 +49,15 @@ class VariableParam : public VariableImplDyn { const Glib::ustring & value() const { if (!cacheValid) { - cache = ApplicationEngine::getCurrent()->env()->getParamQuery(source.substr(1)); + try { + cache = ApplicationEngine::getCurrent()->env()->getParamQuery(name); + } + catch (ApplicationEngine::ParamNotFound) { + if (!defaultValue) { + throw; + } + cache = *defaultValue; + } cacheValid = true; } return cache; @@ -54,7 +70,15 @@ class VariableUri : public VariableImplDyn { const Glib::ustring & value() const { if (!cacheValid) { - cache = ApplicationEngine::getCurrent()->env()->getParamUri(source.substr(1)); + try { + cache = ApplicationEngine::getCurrent()->env()->getParamUri(atoi(name.c_str())); + } + catch (ApplicationEngine::UriElementOutOfRange) { + if (!defaultValue) { + throw; + } + cache = *defaultValue; + } cacheValid = true; } return cache; @@ -73,16 +97,33 @@ class VariableParent : public VariableImplDyn, public RowUser { const Glib::ustring & value() const { if (!cacheValid) { - if (!row) { - PerRowValues::RowValuesStack::const_reverse_iterator r = PerRowValues::Stack().rbegin(); - for (size_t p = depth; --p; r++) ; - row = *r; - row->use(this); - if (dep) { - row->use(dep); + try { + if (!row) { + PerRowValues::RowValuesStack::const_reverse_iterator r = PerRowValues::Stack().rbegin(); + for (size_t p = depth; --p; r++) ; + if (r == PerRowValues::Stack().rend()) { + throw PerRowValues::ParentOutOfRange(); + } + row = *r; + row->use(this); + if (dep) { + row->use(dep); + } } + cache = row->getCurrentValue(source); + } + catch (PerRowValues::ParentOutOfRange) { + if (!defaultValue) { + throw; + } + cache = *defaultValue; + } + catch (PerRowValues::FieldDoesNotExist) { + if (!defaultValue) { + throw; + } + cache = *defaultValue; } - cache = row->getCurrentValue(source); cacheValid = true; } return cache; @@ -170,3 +211,17 @@ Variable::create(const Glib::ustring & s, RowUser * dep) } } +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++; + Glib::ustring::const_iterator defaultEnd = source.end(); + defaultValue = Glib::ustring(defaultStart, defaultEnd); + } +} + diff --git a/project2/variables.h b/project2/variables.h index 3387a0a..ae3d3c6 100644 --- a/project2/variables.h +++ b/project2/variables.h @@ -2,6 +2,7 @@ #define VARIABLES_H #include +#include #include #include #include @@ -13,8 +14,10 @@ class VariableImpl { virtual const Glib::ustring & value() const = 0; protected: - VariableImpl(const Glib::ustring & src) : source(src) { } + VariableImpl(const Glib::ustring & src); const Glib::ustring source; + Glib::ustring name; + boost::optional defaultValue; }; class Variable { -- cgit v1.2.3