mirror of
https://github.com/pocoproject/poco.git
synced 2025-11-25 06:36:37 +01:00
502 lines
13 KiB
C++
502 lines
13 KiB
C++
//
|
|
// Template.cpp
|
|
//
|
|
// $Id: //poco/Main/WebWidgets/src/Template.cpp#2 $
|
|
//
|
|
// Library: WebWidgets
|
|
// Package: Templates
|
|
// Module: Template
|
|
//
|
|
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
|
// and Contributors.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person or organization
|
|
// obtaining a copy of the software and accompanying documentation covered by
|
|
// this license (the "Software") to use, reproduce, display, distribute,
|
|
// execute, and transmit the Software, and to prepare derivative works of the
|
|
// Software, and to permit third-parties to whom the Software is furnished to
|
|
// do so, all subject to the following:
|
|
//
|
|
// The copyright notices in the Software and this entire statement, including
|
|
// the above license grant, this restriction and the following disclaimer,
|
|
// must be included in all copies of the Software, in whole or in part, and
|
|
// all derivative works of the Software, unless such copies or derivative
|
|
// works are solely in the form of machine-executable object code generated by
|
|
// a source language processor.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
// DEALINGS IN THE SOFTWARE.
|
|
//
|
|
|
|
|
|
#include "Poco/WebWidgets/Template.h"
|
|
#include <cctype>
|
|
|
|
|
|
namespace Poco {
|
|
namespace WebWidgets {
|
|
|
|
|
|
Template::Template(const std::string& templateStr):
|
|
View(typeid(Template)),
|
|
_templateStr(templateStr),
|
|
_maxWildCard(0),
|
|
_values()
|
|
{
|
|
_maxWildCard = detectMaxWildCard();
|
|
_values.resize(_maxWildCard);
|
|
}
|
|
|
|
|
|
Template::Template(const std::string& templateStr, const std::vector<Poco::Any>& values):
|
|
View(typeid(Template)),
|
|
_templateStr(templateStr),
|
|
_maxWildCard(values.size()),
|
|
_values()
|
|
{
|
|
poco_assert (values.size() == detectMaxWildCard());
|
|
_values.resize(_maxWildCard);
|
|
|
|
for (std::size_t i = 0; i < values.size(); ++i)
|
|
bind(i, values[i]);
|
|
}
|
|
|
|
|
|
Template::Template(const std::string& templateStr, const std::type_info& type):
|
|
View(type),
|
|
_templateStr(templateStr),
|
|
_values()
|
|
{
|
|
_maxWildCard = detectMaxWildCard();
|
|
_values.resize(_maxWildCard);
|
|
}
|
|
|
|
|
|
Template::~Template()
|
|
{
|
|
}
|
|
|
|
|
|
std::size_t Template::detectMaxWildCard() const
|
|
{
|
|
// search for strings %num, take care of %%!
|
|
bool inPercent = false;
|
|
std::size_t maxVal(0);
|
|
std::size_t curVal(0);
|
|
std::size_t cnt(0);
|
|
for (std::size_t i = 0; i < _templateStr.size(); ++i)
|
|
{
|
|
char c = _templateStr[i];
|
|
if (inPercent)
|
|
{
|
|
if (c == '%')
|
|
{
|
|
if (cnt == 0) { // %%
|
|
inPercent = false;
|
|
curVal = 0;
|
|
}
|
|
else
|
|
{
|
|
// we read %123%
|
|
if (curVal+1 > maxVal)
|
|
maxVal = curVal+1;
|
|
// we remain within inPercent
|
|
curVal = 0;
|
|
cnt = 0;
|
|
}
|
|
}
|
|
else if(isdigit(c))
|
|
{
|
|
curVal*=10;
|
|
curVal += (c-'0');
|
|
++cnt;
|
|
}
|
|
else
|
|
{
|
|
inPercent = false;
|
|
if (curVal+1 > maxVal)
|
|
maxVal = curVal+1;
|
|
// we remain within inPercent
|
|
curVal = 0;
|
|
cnt = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (c == '%')
|
|
{
|
|
inPercent = true;
|
|
curVal = 0;
|
|
cnt = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
return maxVal;
|
|
}
|
|
|
|
|
|
void Template::parse(const RenderContext& ctx, std::ostream& out) const
|
|
{
|
|
bool inPercent = false;
|
|
std::size_t curVal(0);
|
|
std::size_t cnt(0);
|
|
|
|
for (std::size_t i = 0; i < _templateStr.size(); ++i)
|
|
{
|
|
char c = _templateStr[i];
|
|
if (inPercent)
|
|
{
|
|
if (c == '%')
|
|
{
|
|
if (cnt == 0) { // %%
|
|
inPercent = false;
|
|
curVal = 0;
|
|
out << "%";
|
|
}
|
|
else
|
|
{
|
|
// we read %123%
|
|
const Poco::Any& val = _values[curVal];
|
|
write(ctx, out, val);
|
|
// we remain within inPercent
|
|
curVal = 0;
|
|
cnt = 0;
|
|
}
|
|
}
|
|
else if(isdigit(c))
|
|
{
|
|
curVal*=10;
|
|
curVal += (c-'0');
|
|
++cnt;
|
|
}
|
|
else
|
|
{
|
|
// we read neither percent nor number
|
|
inPercent = false;
|
|
if (cnt > 0)
|
|
write(ctx, out, _values[curVal]);
|
|
else
|
|
out << "%";
|
|
out.put(c);
|
|
curVal = 0;
|
|
cnt = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (c == '%')
|
|
{
|
|
inPercent = true;
|
|
curVal = 0;
|
|
cnt = 0;
|
|
}
|
|
else
|
|
out.put(c);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void Template::bind(std::size_t num, int val)
|
|
{
|
|
_values[num] = val;
|
|
}
|
|
|
|
|
|
void Template::bind(std::size_t num, float val)
|
|
{
|
|
_values[num] = val;
|
|
}
|
|
|
|
|
|
void Template::bind(std::size_t num, double val)
|
|
{
|
|
_values[num] = val;
|
|
}
|
|
|
|
|
|
void Template::bind(std::size_t num, char val)
|
|
{
|
|
_values[num] = val;
|
|
}
|
|
|
|
|
|
void Template::bind(std::size_t num, bool val)
|
|
{
|
|
_values[num] = val;
|
|
}
|
|
|
|
|
|
void Template::bind(std::size_t num, const std::string& val)
|
|
{
|
|
_values[num] = val;
|
|
}
|
|
|
|
|
|
void Template::bind(std::size_t num, const char* pVal)
|
|
{
|
|
std::string val(pVal);
|
|
bind(num, val);
|
|
}
|
|
|
|
|
|
void Template::bind(std::size_t num, Renderable* pVal)
|
|
{
|
|
poco_check_ptr (pVal);
|
|
_values[num] = pVal;
|
|
}
|
|
|
|
|
|
void Template::bind(std::size_t num, const Any& val)
|
|
{
|
|
const std::type_info& type = val.type();
|
|
if (type == typeid(Renderable*))
|
|
{
|
|
Any cpy = val;
|
|
Renderable* pRend = AnyCast<Renderable*>(cpy);
|
|
if (pRend)
|
|
bind(num, pRend);
|
|
}
|
|
else if (type == typeid(Renderable::Ptr))
|
|
{
|
|
Any cpy = val;
|
|
Renderable::Ptr pRend = AnyCast<Renderable::Ptr>(cpy);
|
|
if (pRend)
|
|
bindPtr(num, pRend);
|
|
}
|
|
else if (type == typeid(std::string))
|
|
bind(num, RefAnyCast<std::string>(val));
|
|
else if (type == typeid(const char*))
|
|
bind(num, RefAnyCast<const char*>(val));
|
|
else if (type == typeid(int))
|
|
bind(num, AnyCast<int>(val));
|
|
else if (type == typeid(float))
|
|
bind(num, AnyCast<float>(val));
|
|
else if (type == typeid(double))
|
|
bind(num, AnyCast<double>(val));
|
|
else if (type == typeid(bool))
|
|
bind(num, AnyCast<bool>(val));
|
|
else if (type == typeid(std::vector<Poco::Any>))
|
|
bind(num, RefAnyCast<std::vector<Poco::Any> >(val));
|
|
else if (type == typeid(Poco::AutoPtr<Renderable>))
|
|
bindPtr(num, RefAnyCast<Poco::AutoPtr<Renderable> >(val));
|
|
else if (type == typeid(Poco::AutoPtr<Getter>))
|
|
bindPtr(num, RefAnyCast<Poco::AutoPtr<Getter> >(val));
|
|
else if (type == typeid(Poco::SharedPtr<std::vector<Poco::Any> >))
|
|
bindPtr(num, RefAnyCast<Poco::SharedPtr<std::vector<Poco::Any> > >(val));
|
|
else if (type == typeid(Poco::SharedPtr<std::vector<float> >))
|
|
bindPtr(num, RefAnyCast<Poco::SharedPtr<std::vector<float> > >(val));
|
|
else if (type == typeid(Poco::SharedPtr<std::vector<double> >))
|
|
bindPtr(num, RefAnyCast<Poco::SharedPtr<std::vector<double> > >(val));
|
|
else if (type == typeid(Poco::SharedPtr<std::vector<char> >))
|
|
bindPtr(num, RefAnyCast<Poco::SharedPtr<std::vector<char> > >(val));
|
|
else if (type == typeid(Poco::SharedPtr<std::vector<bool> >))
|
|
bindPtr(num, RefAnyCast<Poco::SharedPtr<std::vector<bool> > >(val));
|
|
else if (type == typeid(Poco::SharedPtr<std::vector<Renderable::Ptr> >))
|
|
bindPtr(num, RefAnyCast<Poco::SharedPtr<std::vector<Renderable::Ptr> > >(val));
|
|
else if (type == typeid(Poco::SharedPtr<std::vector<std::string> >))
|
|
bindPtr(num, RefAnyCast<Poco::SharedPtr<std::vector<std::string> > >(val));
|
|
else if (type == typeid(Poco::SharedPtr<std::vector<Getter::Ptr> >))
|
|
bindPtr(num, RefAnyCast<Poco::SharedPtr<std::vector<Getter::Ptr> > >(val));
|
|
else if (type == typeid(Poco::SharedPtr<int>))
|
|
bindPtr(num, RefAnyCast<Poco::SharedPtr<int> >(val));
|
|
else if (type == typeid(Poco::SharedPtr<float>))
|
|
bindPtr(num, RefAnyCast<Poco::SharedPtr<float> >(val));
|
|
else if (type == typeid(Poco::SharedPtr<double>))
|
|
bindPtr(num, RefAnyCast<Poco::SharedPtr<double> >(val));
|
|
else if (type == typeid(Poco::SharedPtr<char>))
|
|
bindPtr(num, RefAnyCast<Poco::SharedPtr<char> >(val));
|
|
else if (type == typeid(Poco::SharedPtr<bool>))
|
|
bindPtr(num, RefAnyCast<Poco::SharedPtr<bool> >(val));
|
|
else if (type == typeid(Poco::SharedPtr<std::string>))
|
|
bindPtr(num, RefAnyCast<Poco::SharedPtr<std::string> >(val));
|
|
else if (type == typeid(Poco::SharedPtr<Poco::Any>))
|
|
bindPtr(num, RefAnyCast<Poco::SharedPtr<Poco::Any> >(val));
|
|
else /* if (type == typeid(char)) */
|
|
bind(num, AnyCast<char>(val));
|
|
}
|
|
|
|
|
|
void Template::write(const RenderContext& ctx, std::ostream& out, const Any& val) const
|
|
{
|
|
if (val.empty())
|
|
return;
|
|
const std::type_info& type = val.type();
|
|
if (type == typeid(Renderable*))
|
|
{
|
|
Any cpy = val;
|
|
Renderable* pRend = AnyCast<Renderable*>(cpy);
|
|
if (pRend)
|
|
pRend->renderHead(ctx, out);
|
|
}
|
|
else if (type == typeid(Renderable::Ptr))
|
|
{
|
|
Any cpy = val;
|
|
Renderable::Ptr pRend = AnyCast<Renderable::Ptr>(cpy);
|
|
if (pRend)
|
|
pRend->renderHead(ctx, out);
|
|
}
|
|
else if (type == typeid(std::string))
|
|
out << RefAnyCast<std::string>(val);
|
|
else if (type == typeid(int))
|
|
out << AnyCast<int>(val);
|
|
else if (type == typeid(float))
|
|
out << AnyCast<float>(val);
|
|
else if (type == typeid(double))
|
|
out << AnyCast<double>(val);
|
|
else if (type == typeid(bool))
|
|
out << (AnyCast<bool>(val)?"true":"false");
|
|
else if (type == typeid(SharedPtr<std::string>))
|
|
out << *AnyCast<SharedPtr<std::string> >(val);
|
|
else if (type == typeid(SharedPtr<int>))
|
|
out << *AnyCast<SharedPtr<int> >(val);
|
|
else if (type == typeid(SharedPtr<float>))
|
|
out << *AnyCast<SharedPtr<float> >(val);
|
|
else if (type == typeid(SharedPtr<double>))
|
|
out << *AnyCast<SharedPtr<double> >(val);
|
|
else if (type == typeid(SharedPtr<bool>))
|
|
out << (*AnyCast<SharedPtr<bool> >(val)?"true":"false");
|
|
else if (type == typeid(Getter::Ptr))
|
|
{
|
|
Getter::Ptr pGet =AnyCast<Getter::Ptr>(val);
|
|
write(ctx, out, pGet->get());
|
|
}
|
|
else if (type == typeid(std::vector<Poco::Any>))
|
|
writeVector(ctx, out, RefAnyCast<std::vector<Poco::Any> >(val));
|
|
else if (type == typeid(Poco::SharedPtr<std::vector<Poco::Any> >))
|
|
writeVector(ctx, out, *RefAnyCast<Poco::SharedPtr<std::vector<Poco::Any> > >(val));
|
|
else if (type == typeid(Poco::SharedPtr<std::vector<float> >))
|
|
writeVector(ctx, out, *RefAnyCast<Poco::SharedPtr<std::vector<float> > >(val));
|
|
else if (type == typeid(Poco::SharedPtr<std::vector<double> >))
|
|
writeVector(ctx, out, *RefAnyCast<Poco::SharedPtr<std::vector<double> > >(val));
|
|
else if (type == typeid(Poco::SharedPtr<std::vector<char> >))
|
|
writeVector(ctx, out, *RefAnyCast<Poco::SharedPtr<std::vector<char> > >(val));
|
|
else if (type == typeid(Poco::SharedPtr<std::vector<bool> >))
|
|
writeVector(ctx, out, *RefAnyCast<Poco::SharedPtr<std::vector<bool> > >(val));
|
|
else if (type == typeid(Poco::SharedPtr<std::vector<Renderable::Ptr> >))
|
|
writeVector(ctx, out, *RefAnyCast<Poco::SharedPtr<std::vector<Renderable::Ptr> > >(val));
|
|
else if (type == typeid(Poco::SharedPtr<std::vector<std::string> >))
|
|
writeVector(ctx, out, *RefAnyCast<Poco::SharedPtr<std::vector<std::string> > >(val));
|
|
else if (type == typeid(Poco::SharedPtr<std::vector<Getter::Ptr> >))
|
|
writeVector(ctx, out, *RefAnyCast<Poco::SharedPtr<std::vector<Getter::Ptr> > >(val));
|
|
else /* if (type == typeid(char)) */
|
|
out << AnyCast<char>(val);
|
|
}
|
|
|
|
|
|
void Template::bind(std::size_t num, const std::vector<Poco::Any>& val)
|
|
{
|
|
_values[num] = val;
|
|
}
|
|
|
|
|
|
void Template::bindPtr(std::size_t num, Poco::AutoPtr<Renderable> pRend)
|
|
{
|
|
_values[num] = pRend;
|
|
}
|
|
|
|
|
|
void Template::bindPtr(std::size_t num, Poco::AutoPtr<Getter> pRend)
|
|
{
|
|
_values[num] = pRend;
|
|
}
|
|
|
|
|
|
void Template::bindPtr(std::size_t num, Poco::SharedPtr<std::vector<Poco::Any> > pVal)
|
|
{
|
|
_values[num] = pVal;
|
|
}
|
|
|
|
|
|
void Template::bindPtr(std::size_t num, Poco::SharedPtr<std::vector<float> > pVal)
|
|
{
|
|
_values[num] = pVal;
|
|
}
|
|
|
|
|
|
void Template::bindPtr(std::size_t num, Poco::SharedPtr<std::vector<double> > pVal)
|
|
{
|
|
_values[num] = pVal;
|
|
}
|
|
|
|
|
|
void Template::bindPtr(std::size_t num, Poco::SharedPtr<std::vector<char> > pVal)
|
|
{
|
|
_values[num] = pVal;
|
|
}
|
|
|
|
|
|
void Template::bindPtr(std::size_t num, Poco::SharedPtr<std::vector<bool> > pVal)
|
|
{
|
|
_values[num] = pVal;
|
|
}
|
|
|
|
|
|
void Template::bindPtr(std::size_t num, Poco::SharedPtr<std::vector<Renderable::Ptr> > pVal)
|
|
{
|
|
_values[num] = pVal;
|
|
}
|
|
|
|
|
|
void Template::bindPtr(std::size_t num, Poco::SharedPtr<std::vector<std::string> > pVal)
|
|
{
|
|
_values[num] = pVal;
|
|
}
|
|
|
|
|
|
void Template::bindPtr(std::size_t num, Poco::SharedPtr<std::vector<Getter::Ptr> > pVal)
|
|
{
|
|
_values[num] = pVal;
|
|
}
|
|
|
|
|
|
void Template::bindPtr(std::size_t num, Poco::SharedPtr<int> pVal)
|
|
{
|
|
_values[num] = pVal;
|
|
}
|
|
|
|
|
|
void Template::bindPtr(std::size_t num, Poco::SharedPtr<float> pVal)
|
|
{
|
|
_values[num] = pVal;
|
|
}
|
|
|
|
|
|
void Template::bindPtr(std::size_t num, Poco::SharedPtr<double> pVal)
|
|
{
|
|
_values[num] = pVal;
|
|
}
|
|
|
|
|
|
void Template::bindPtr(std::size_t num, Poco::SharedPtr<char> pVal)
|
|
{
|
|
_values[num] = pVal;
|
|
}
|
|
|
|
|
|
void Template::bindPtr(std::size_t num, Poco::SharedPtr<bool> pVal)
|
|
{
|
|
_values[num] = pVal;
|
|
}
|
|
|
|
|
|
void Template::bindPtr(std::size_t num, Poco::SharedPtr<std::string> pVal)
|
|
{
|
|
_values[num] = pVal;
|
|
}
|
|
|
|
|
|
void Template::bindPtr(std::size_t num, Poco::SharedPtr<Poco::Any> pVal)
|
|
{
|
|
_values[num] = pVal;
|
|
}
|
|
|
|
|
|
} } // namespace Poco::WebWidgets
|