123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- // -*- mode: c++; tab-width: 4; indent-tabs-mode: t; eval: (progn (c-set-style "stroustrup") (c-set-offset 'innamespace 0)); -*-
- // vi:set ts=4 sts=4 sw=4 noet :
- //
- // Copyright 2010, 2011 wkhtmltopdf authors
- //
- // This file is part of wkhtmltopdf.
- //
- // wkhtmltopdf is free software: you can redistribute it and/or modify
- // it under the terms of the GNU Lesser General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // wkhtmltopdf is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU Lesser General Public License
- // along with wkhtmltopdf. If not, see <http://www.gnu.org/licenses/>.
- #ifndef __REFLECT_HH__
- #define __REFLECT_HH__
- #if defined(_MSC_VER) && _MSC_VER>=1600
- #define typeof decltype
- #endif
- #include "loadsettings.hh"
- #include "websettings.hh"
- #include <QStringList>
- #include <cstring>
- #include "dllbegin.inc"
- namespace wkhtmltopdf {
- namespace settings {
- #define WKHTMLTOPDF_REFLECT(name) ReflectClass::add(#name, new ReflectImpl<typeof(c.name)> (c.name));
- class DLL_LOCAL Reflect {
- public:
- virtual QString get(const char * name) = 0;
- virtual bool set(const char * name, const QString & value) = 0;
- virtual ~Reflect() {};
- };
- class DLL_LOCAL ReflectSimple: public Reflect {
- public:
- virtual QString get() = 0;
- virtual void set(const QString & value, bool * ok) = 0;
- virtual QString get(const char * name) {return name[0]=='\0'?get():QString();}
- virtual bool set(const char * name, const QString & value);
- };
- class DLL_LOCAL ReflectClass: public Reflect {
- public:
- QMap<QString, Reflect *> elms;
- void add(const char * name, Reflect * r) {elms[name] = r;}
- QString get(const char * name);
- bool set(const char * name, const QString & value);
- ~ReflectClass();
- };
- template <typename X>
- class DLL_LOCAL ReflectImpl {
- private:
- ReflectImpl();
- };
- template<>
- struct DLL_LOCAL ReflectImpl<bool>: public ReflectSimple {
- bool & b;
- ReflectImpl(bool & _): b(_) {}
- QString get() {return b?"true":"false";}
- void set(const QString & value, bool * ok) {
- if (value == "true") b=true;
- else if (value == "false") b=false;
- else *ok=false;
- *ok=true;
- }
- };
- template<>
- struct DLL_LOCAL ReflectImpl<QString>: public ReflectSimple {
- QString & s;
- ReflectImpl(QString & _): s(_) {}
- QString get() {return s;}
- void set(const QString & value, bool * ok) {s=value; *ok=true;}
- };
- template<>
- struct DLL_LOCAL ReflectImpl<int>: public ReflectSimple {
- int & i;
- ReflectImpl(int & _): i(_) {}
- QString get() {return QString::number(i);}
- void set(const QString & value, bool * ok) {i = value.toInt(ok);}
- };
- template<>
- struct DLL_LOCAL ReflectImpl<float>: public ReflectSimple {
- float & f;
- ReflectImpl(float & _): f(_) {}
- QString get() {return QString::number(f);}
- void set(const QString & value, bool * ok) {f = value.toDouble(ok);}
- };
- template<>
- struct DLL_LOCAL ReflectImpl< QPair<QString, QString> >: public ReflectSimple {
- QPair<QString, QString> & p;
- ReflectImpl(QPair<QString, QString> & _): p(_) {};
- QString get() {
- return p.first + "\n" + p.second;
- }
- void set(const QString & value, bool * ok) {
- QStringList l = value.split("\n");
- if (l.size() != 2) {*ok=false; return;}
- *ok = true;
- p.first = l[0];
- p.second = l[1];
- }
- };
- template<typename X>
- struct DLL_LOCAL ReflectImpl< QList< X> >: public Reflect {
- QList<X> & l;
- ReflectImpl(QList<X> & _): l(_) {}
- bool parse(const char * name, int & parmsize, int & next, int & elm) {
- elm=-1;
- parmsize = -1;
- if (name[0] == '[') {
- next = 0;
- while (name[next] != '\0' && name[next] != ']') ++next;
- bool ok=true;
- elm = QString::fromLocal8Bit(name+1,next-1).toInt(&ok);
- while (name[next] == ']' || name[next] == '.') ++next;
- return ok;
- }
- parmsize = 0;
- while (name[parmsize] != '\0' && name[parmsize] != '.' && name[parmsize] != '[') ++parmsize;
- next = parmsize;
- if (name[next] == '.') ++next;
- return true;
- }
- virtual QString get(const char * name) {
- int ps, next, elm;
- if (!strcmp(name,"size") || !strcmp(name,"length") || !strcmp(name,"count")) return QString::number(l.size());
- if (!parse(name, ps, next, elm)) return QString();
- if (ps > 0 && !l.isEmpty() && !strncmp(name, "first", ps)) elm = 0;
- if (ps > 0 && !l.isEmpty() && !strncmp(name, "last", ps)) elm = l.size() - 1;
- if (elm < 0 || elm >= l.size()) return QString();
- ReflectImpl<X> impl(l[elm]);
- return static_cast<Reflect*>(&impl)->get(name+next);
- };
- virtual bool set(const char * name, const QString & value) {
- int ps, next, elm;
- if (!strcmp(name,"clear"))
- l.clear();
- else if (!strcmp(name,"append"))
- l.append(X());
- else if (!strcmp(name,"prepend"))
- l.prepend(X());
- else if (!strcmp(name,"delete")) {
- bool ok = true;
- int idx = value.toInt(&ok);
- if (ok && idx >= 0 && idx < l.size()) {
- l.removeAt(idx);
- return true;
- }
- return false;
- }
- else {
- if (!parse(name, ps, next, elm)) return false;
- if (ps > 0 && !l.isEmpty() && !strncmp(name, "first", ps)) elm = 0;
- if (ps > 0 && !l.isEmpty() && !strncmp(name, "last", ps)) elm = l.size() - 1;
- ReflectImpl<X> impl(l[elm]);
- return static_cast<Reflect *>(&impl)->set(name+next, value);
- }
- return true;
- }
- };
- template<>
- struct DLL_LOCAL ReflectImpl<LoadPage::LoadErrorHandling>: public ReflectSimple {
- LoadPage::LoadErrorHandling & l;
- ReflectImpl(LoadPage::LoadErrorHandling & _): l(_) {}
- QString get() {return loadErrorHandlingToStr(l);}
- void set(const QString & value, bool * ok) {l = strToLoadErrorHandling(value.toUtf8().constData(), ok);}
- };
- template<>
- struct DLL_LOCAL ReflectImpl<Proxy>: public ReflectSimple {
- Proxy & p;
- ReflectImpl(Proxy & _): p(_) {}
- QString get() {return proxyToStr(p);}
- void set(const QString & value, bool * ok) {p = strToProxy(value.toUtf8().constData(), ok);}
- };
- template<>
- struct DLL_LOCAL ReflectImpl<PostItem>: public ReflectClass {
- ReflectImpl(PostItem & c) {
- WKHTMLTOPDF_REFLECT(name);
- WKHTMLTOPDF_REFLECT(value);
- WKHTMLTOPDF_REFLECT(file);
- }
- };
- template <>
- struct DLL_LOCAL ReflectImpl<LoadGlobal>: public ReflectClass {
- ReflectImpl(LoadGlobal & c);
- };
- template <>
- struct DLL_LOCAL ReflectImpl<LoadPage>: public ReflectClass {
- ReflectImpl(LoadPage & c);
- };
- template <>
- struct DLL_LOCAL ReflectImpl<Web>: public ReflectClass {
- ReflectImpl(Web & c);
- };
- }
- }
- #include "dllend.inc"
- #endif //__REFLECT_HH__
|