mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-11-29 05:48:47 +03:00
commit
83ba59de51
28 changed files with 7973 additions and 522 deletions
|
@ -29,12 +29,11 @@
|
|||
*/
|
||||
|
||||
#include "btjson.h"
|
||||
#include "jsondict.h"
|
||||
#include "jsonlist.h"
|
||||
#include "misc.h"
|
||||
#include "fs_utils.h"
|
||||
#include "qbtsession.h"
|
||||
#include "torrentpersistentdata.h"
|
||||
#include "jsonutils.h"
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
|
||||
#include <QElapsedTimer>
|
||||
|
@ -49,20 +48,20 @@ using namespace libtorrent;
|
|||
static QElapsedTimer cacheTimer; \
|
||||
static bool initialized = false; \
|
||||
if (initialized && !cacheTimer.hasExpired(DUR)) \
|
||||
return VAR.toString(); \
|
||||
return json::toJson(VAR); \
|
||||
initialized = true; \
|
||||
cacheTimer.start(); \
|
||||
VAR.clear()
|
||||
VAR = VARTYPE()
|
||||
|
||||
#define CACHED_VARIABLE_FOR_HASH(VARTYPE, VAR, DUR, HASH) \
|
||||
static VARTYPE VAR; \
|
||||
static QString prev_hash; \
|
||||
static QElapsedTimer cacheTimer; \
|
||||
if (prev_hash == HASH && !cacheTimer.hasExpired(DUR)) \
|
||||
return VAR.toString(); \
|
||||
return json::toJson(VAR); \
|
||||
prev_hash = HASH; \
|
||||
cacheTimer.start(); \
|
||||
VAR.clear()
|
||||
VAR = VARTYPE()
|
||||
|
||||
#else
|
||||
// We don't support caching for Qt < 4.7 at the moment
|
||||
|
@ -122,31 +121,31 @@ static const char KEY_FILE_IS_SEED[] = "is_seed";
|
|||
static const char KEY_TRANSFER_DLSPEED[] = "dl_info";
|
||||
static const char KEY_TRANSFER_UPSPEED[] = "up_info";
|
||||
|
||||
static JsonDict toJson(const QTorrentHandle& h)
|
||||
static QVariantMap toMap(const QTorrentHandle& h)
|
||||
{
|
||||
libtorrent::torrent_status status = h.status(torrent_handle::query_accurate_download_counters);
|
||||
|
||||
JsonDict ret;
|
||||
ret.add(KEY_TORRENT_HASH, h.hash());
|
||||
ret.add(KEY_TORRENT_NAME, h.name());
|
||||
ret.add(KEY_TORRENT_SIZE, misc::friendlyUnit(status.total_wanted)); // FIXME: Should pass as Number, not formatted String (for sorting).
|
||||
ret.add(KEY_TORRENT_PROGRESS, (double)h.progress(status));
|
||||
ret.add(KEY_TORRENT_DLSPEED, misc::friendlyUnit(status.download_payload_rate, true)); // FIXME: Should be passed as a Number
|
||||
ret.add(KEY_TORRENT_UPSPEED, misc::friendlyUnit(status.upload_payload_rate, true)); // FIXME: Should be passed as a Number
|
||||
QVariantMap ret;
|
||||
ret[KEY_TORRENT_HASH] = h.hash();
|
||||
ret[KEY_TORRENT_NAME] = h.name();
|
||||
ret[KEY_TORRENT_SIZE] = misc::friendlyUnit(h.actual_size()); // FIXME: Should pass as Number, not formatted String (for sorting).
|
||||
ret[KEY_TORRENT_PROGRESS] = (double)h.progress(status);
|
||||
ret[KEY_TORRENT_DLSPEED] = misc::friendlyUnit(status.download_payload_rate, true); // FIXME: Should be passed as a Number
|
||||
ret[KEY_TORRENT_UPSPEED] = misc::friendlyUnit(status.upload_payload_rate, true); // FIXME: Should be passed as a Number
|
||||
if (QBtSession::instance()->isQueueingEnabled() && h.queue_position() >= 0)
|
||||
ret.add(KEY_TORRENT_PRIORITY, QString::number(h.queue_position()));
|
||||
ret[KEY_TORRENT_PRIORITY] = QString::number(h.queue_position());
|
||||
else
|
||||
ret.add(KEY_TORRENT_PRIORITY, "*");
|
||||
ret[KEY_TORRENT_PRIORITY] = "*";
|
||||
QString seeds = QString::number(status.num_seeds);
|
||||
if (status.num_complete > 0)
|
||||
seeds += " ("+QString::number(status.num_complete)+")";
|
||||
ret.add(KEY_TORRENT_SEEDS, seeds);
|
||||
ret[KEY_TORRENT_SEEDS] = seeds;
|
||||
QString leechs = QString::number(status.num_peers - status.num_seeds);
|
||||
if (status.num_incomplete > 0)
|
||||
leechs += " ("+QString::number(status.num_incomplete)+")";
|
||||
ret.add(KEY_TORRENT_LEECHS, leechs);
|
||||
ret[KEY_TORRENT_LEECHS] = leechs;
|
||||
const qreal ratio = QBtSession::instance()->getRealRatio(status);
|
||||
ret.add(KEY_TORRENT_RATIO, (ratio > 100.) ? QString::fromUtf8("∞") : misc::accurateDoubleToString(ratio, 1));
|
||||
ret[KEY_TORRENT_RATIO] = (ratio > 100.) ? QString::fromUtf8("∞") : misc::accurateDoubleToString(ratio, 1);
|
||||
QString eta;
|
||||
QString state;
|
||||
if (h.is_paused(status)) {
|
||||
|
@ -179,8 +178,8 @@ static JsonDict toJson(const QTorrentHandle& h)
|
|||
}
|
||||
}
|
||||
}
|
||||
ret.add(KEY_TORRENT_ETA, eta.isEmpty() ? QString::fromUtf8("∞") : eta);
|
||||
ret.add(KEY_TORRENT_STATE, state);
|
||||
ret[KEY_TORRENT_ETA] = eta.isEmpty() ? QString::fromUtf8("∞") : eta;
|
||||
ret[KEY_TORRENT_STATE] = state;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -203,16 +202,16 @@ static JsonDict toJson(const QTorrentHandle& h)
|
|||
* - "eta": Torrent ETA
|
||||
* - "state": Torrent state
|
||||
*/
|
||||
QString btjson::getTorrents()
|
||||
QByteArray btjson::getTorrents()
|
||||
{
|
||||
CACHED_VARIABLE(JsonList, torrent_list, CACHE_DURATION_MS);
|
||||
CACHED_VARIABLE(QVariantList, torrent_list, CACHE_DURATION_MS);
|
||||
std::vector<torrent_handle> torrents = QBtSession::instance()->getTorrents();
|
||||
std::vector<torrent_handle>::const_iterator it = torrents.begin();
|
||||
std::vector<torrent_handle>::const_iterator end = torrents.end();
|
||||
for( ; it != end; ++it) {
|
||||
torrent_list.append(toJson(QTorrentHandle(*it)));
|
||||
torrent_list.append(toMap(QTorrentHandle(*it)));
|
||||
}
|
||||
return torrent_list.toString();
|
||||
return json::toJson(torrent_list);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -225,9 +224,9 @@ QString btjson::getTorrents()
|
|||
* - "num_peers": Tracker peer count
|
||||
* - "msg": Tracker message (last)
|
||||
*/
|
||||
QString btjson::getTrackersForTorrent(const QString& hash)
|
||||
QByteArray btjson::getTrackersForTorrent(const QString& hash)
|
||||
{
|
||||
CACHED_VARIABLE_FOR_HASH(JsonList, tracker_list, CACHE_DURATION_MS, hash);
|
||||
CACHED_VARIABLE_FOR_HASH(QVariantList, tracker_list, CACHE_DURATION_MS, hash);
|
||||
try {
|
||||
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
|
||||
QHash<QString, TrackerInfos> trackers_data = QBtSession::instance()->getTrackersInfo(hash);
|
||||
|
@ -235,9 +234,9 @@ QString btjson::getTrackersForTorrent(const QString& hash)
|
|||
std::vector<announce_entry>::const_iterator it = vect_trackers.begin();
|
||||
std::vector<announce_entry>::const_iterator end = vect_trackers.end();
|
||||
for (; it != end; ++it) {
|
||||
JsonDict tracker_dict;
|
||||
QVariantMap tracker_dict;
|
||||
const QString tracker_url = misc::toQString(it->url);
|
||||
tracker_dict.add(KEY_TRACKER_URL, tracker_url);
|
||||
tracker_dict[KEY_TRACKER_URL] = tracker_url;
|
||||
const TrackerInfos data = trackers_data.value(tracker_url, TrackerInfos(tracker_url));
|
||||
QString status;
|
||||
if (it->verified)
|
||||
|
@ -248,18 +247,18 @@ QString btjson::getTrackersForTorrent(const QString& hash)
|
|||
else
|
||||
status = it->fails > 0 ? tr("Not working") : tr("Not contacted yet");
|
||||
}
|
||||
tracker_dict.add(KEY_TRACKER_STATUS, status);
|
||||
tracker_dict.add(KEY_TRACKER_PEERS, QString::number(trackers_data.value(tracker_url, TrackerInfos(tracker_url)).num_peers));
|
||||
tracker_dict.add(KEY_TRACKER_MSG, data.last_message.trimmed());
|
||||
tracker_dict[KEY_TRACKER_STATUS] = status;
|
||||
tracker_dict[KEY_TRACKER_PEERS] = QString::number(trackers_data.value(tracker_url, TrackerInfos(tracker_url)).num_peers);
|
||||
tracker_dict[KEY_TRACKER_MSG] = data.last_message.trimmed();
|
||||
|
||||
tracker_list.append(tracker_dict);
|
||||
}
|
||||
} catch(const std::exception& e) {
|
||||
qWarning() << Q_FUNC_INFO << "Invalid torrent: " << e.what();
|
||||
return QString();
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
return tracker_list.toString();
|
||||
return json::toJson(tracker_list);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -280,43 +279,42 @@ QString btjson::getTrackersForTorrent(const QString& hash)
|
|||
* - "nb_connections": Torrent connection count
|
||||
* - "share_ratio": Torrent share ratio
|
||||
*/
|
||||
QString btjson::getPropertiesForTorrent(const QString& hash)
|
||||
QByteArray btjson::getPropertiesForTorrent(const QString& hash)
|
||||
{
|
||||
CACHED_VARIABLE_FOR_HASH(JsonDict, data, CACHE_DURATION_MS, hash);
|
||||
CACHED_VARIABLE_FOR_HASH(QVariantMap, data, CACHE_DURATION_MS, hash);
|
||||
try {
|
||||
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
|
||||
|
||||
libtorrent::torrent_status status = h.status(torrent_handle::query_accurate_download_counters);
|
||||
|
||||
if (!status.has_metadata)
|
||||
return QString();
|
||||
return QByteArray();
|
||||
|
||||
// Save path
|
||||
QString save_path = fsutils::toNativePath(TorrentPersistentData::getSavePath(hash));
|
||||
if (save_path.isEmpty())
|
||||
save_path = fsutils::toNativePath(h.save_path());
|
||||
data.add(KEY_PROP_SAVE_PATH, save_path);
|
||||
data.add(KEY_PROP_CREATION_DATE, h.creation_date());
|
||||
data.add(KEY_PROP_PIECE_SIZE, misc::friendlyUnit(h.piece_length()));
|
||||
data.add(KEY_PROP_COMMENT, h.comment());
|
||||
data.add(KEY_PROP_WASTED, misc::friendlyUnit(status.total_failed_bytes + status.total_redundant_bytes));
|
||||
data.add(KEY_PROP_UPLOADED, QString(misc::friendlyUnit(status.all_time_upload) + " (" + misc::friendlyUnit(status.total_payload_upload) + " " + tr("this session") + ")"));
|
||||
data.add(KEY_PROP_DOWNLOADED, QString(misc::friendlyUnit(status.all_time_download) + " (" + misc::friendlyUnit(status.total_payload_download) + " " + tr("this session") + ")"));
|
||||
data.add(KEY_PROP_UP_LIMIT, h.upload_limit() <= 0 ? QString::fromUtf8("∞") : misc::friendlyUnit(h.upload_limit(), true));
|
||||
data.add(KEY_PROP_DL_LIMIT, h.download_limit() <= 0 ? QString::fromUtf8("∞") : misc::friendlyUnit(h.download_limit(), true));
|
||||
data[KEY_PROP_SAVE_PATH] = save_path;
|
||||
data[KEY_PROP_CREATION_DATE] = h.creation_date();
|
||||
data[KEY_PROP_PIECE_SIZE] = misc::friendlyUnit(h.piece_length());
|
||||
data[KEY_PROP_COMMENT] = h.comment();
|
||||
data[KEY_PROP_WASTED] = misc::friendlyUnit(status.total_failed_bytes + status.total_redundant_bytes);
|
||||
data[KEY_PROP_UPLOADED] = QString(misc::friendlyUnit(status.all_time_upload) + " (" + misc::friendlyUnit(status.total_payload_upload) + " " + tr("this session") + ")");
|
||||
data[KEY_PROP_DOWNLOADED] = QString(misc::friendlyUnit(status.all_time_download) + " (" + misc::friendlyUnit(status.total_payload_download) + " " + tr("this session") + ")");
|
||||
data[KEY_PROP_UP_LIMIT] = h.upload_limit() <= 0 ? QString::fromUtf8("∞") : misc::friendlyUnit(h.upload_limit(), true);
|
||||
data[KEY_PROP_DL_LIMIT] = h.download_limit() <= 0 ? QString::fromUtf8("∞") : misc::friendlyUnit(h.download_limit(), true);
|
||||
QString elapsed_txt = misc::userFriendlyDuration(status.active_time);
|
||||
if (h.is_seed(status))
|
||||
elapsed_txt += " ("+tr("Seeded for %1", "e.g. Seeded for 3m10s").arg(misc::userFriendlyDuration(status.seeding_time))+")";
|
||||
data.add(KEY_PROP_TIME_ELAPSED, elapsed_txt);
|
||||
data.add(KEY_PROP_CONNECT_COUNT, QString(QString::number(status.num_connections) + " (" + tr("%1 max", "e.g. 10 max").arg(QString::number(status.connections_limit)) + ")"));
|
||||
data[KEY_PROP_TIME_ELAPSED] = elapsed_txt;
|
||||
data[KEY_PROP_CONNECT_COUNT] = QString(QString::number(status.num_connections) + " (" + tr("%1 max", "e.g. 10 max").arg(QString::number(status.connections_limit)) + ")");
|
||||
const qreal ratio = QBtSession::instance()->getRealRatio(status);
|
||||
data.add(KEY_PROP_RATIO, ratio > 100. ? QString::fromUtf8("∞") : misc::accurateDoubleToString(ratio, 1));
|
||||
data[KEY_PROP_RATIO] = ratio > 100. ? QString::fromUtf8("∞") : misc::accurateDoubleToString(ratio, 1);
|
||||
} catch(const std::exception& e) {
|
||||
qWarning() << Q_FUNC_INFO << "Invalid torrent: " << e.what();
|
||||
return QString();
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
return data.toString();
|
||||
return json::toJson(data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -330,38 +328,38 @@ QString btjson::getPropertiesForTorrent(const QString& hash)
|
|||
* - "priority": File priority
|
||||
* - "is_seed": Flag indicating if torrent is seeding/complete
|
||||
*/
|
||||
QString btjson::getFilesForTorrent(const QString& hash)
|
||||
QByteArray btjson::getFilesForTorrent(const QString& hash)
|
||||
{
|
||||
CACHED_VARIABLE_FOR_HASH(JsonList, file_list, CACHE_DURATION_MS, hash);
|
||||
CACHED_VARIABLE_FOR_HASH(QVariantList, file_list, CACHE_DURATION_MS, hash);
|
||||
try {
|
||||
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
|
||||
if (!h.has_metadata())
|
||||
return QString();
|
||||
return QByteArray();
|
||||
|
||||
const std::vector<int> priorities = h.file_priorities();
|
||||
std::vector<size_type> fp;
|
||||
h.file_progress(fp);
|
||||
for (int i = 0; i < h.num_files(); ++i) {
|
||||
JsonDict file_dict;
|
||||
QVariantMap file_dict;
|
||||
QString fileName = h.filename_at(i);
|
||||
if (fileName.endsWith(".!qB", Qt::CaseInsensitive))
|
||||
fileName.chop(4);
|
||||
file_dict.add(KEY_FILE_NAME, fsutils::toNativePath(fileName));
|
||||
file_dict[KEY_FILE_NAME] = fsutils::toNativePath(fileName);
|
||||
const size_type size = h.filesize_at(i);
|
||||
file_dict.add(KEY_FILE_SIZE, misc::friendlyUnit(size));
|
||||
file_dict.add(KEY_FILE_PROGRESS, (size > 0) ? (fp[i] / (double) size) : 1.);
|
||||
file_dict.add(KEY_FILE_PRIORITY, priorities[i]);
|
||||
file_dict[KEY_FILE_SIZE] = misc::friendlyUnit(size);
|
||||
file_dict[KEY_FILE_PROGRESS] = (size > 0) ? (fp[i] / (double) size) : 1.;
|
||||
file_dict[KEY_FILE_PRIORITY] = priorities[i];
|
||||
if (i == 0)
|
||||
file_dict.add(KEY_FILE_IS_SEED, h.is_seed());
|
||||
file_dict[KEY_FILE_IS_SEED] = h.is_seed();
|
||||
|
||||
file_list.append(file_dict);
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
qWarning() << Q_FUNC_INFO << "Invalid torrent: " << e.what();
|
||||
return QString();
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
return file_list.toString();
|
||||
return json::toJson(file_list);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -372,11 +370,11 @@ QString btjson::getFilesForTorrent(const QString& hash)
|
|||
* - "dl_info": Global download info
|
||||
* - "up_info": Global upload info
|
||||
*/
|
||||
QString btjson::getTransferInfo()
|
||||
QByteArray btjson::getTransferInfo()
|
||||
{
|
||||
CACHED_VARIABLE(JsonDict, info, CACHE_DURATION_MS);
|
||||
CACHED_VARIABLE(QVariantMap, info, CACHE_DURATION_MS);
|
||||
session_status sessionStatus = QBtSession::instance()->getSessionStatus();
|
||||
info.add(KEY_TRANSFER_DLSPEED, tr("D: %1/s - T: %2", "Download speed: x KiB/s - Transferred: x MiB").arg(misc::friendlyUnit(sessionStatus.payload_download_rate)).arg(misc::friendlyUnit(sessionStatus.total_payload_download)));
|
||||
info.add(KEY_TRANSFER_UPSPEED, tr("U: %1/s - T: %2", "Upload speed: x KiB/s - Transferred: x MiB").arg(misc::friendlyUnit(sessionStatus.payload_upload_rate)).arg(misc::friendlyUnit(sessionStatus.total_payload_upload)));
|
||||
return info.toString();
|
||||
info[KEY_TRANSFER_DLSPEED] = tr("D: %1/s - T: %2", "Download speed: x KiB/s - Transferred: x MiB").arg(misc::friendlyUnit(sessionStatus.payload_download_rate)).arg(misc::friendlyUnit(sessionStatus.total_payload_download));
|
||||
info[KEY_TRANSFER_UPSPEED] = tr("U: %1/s - T: %2", "Upload speed: x KiB/s - Transferred: x MiB").arg(misc::friendlyUnit(sessionStatus.payload_upload_rate)).arg(misc::friendlyUnit(sessionStatus.total_payload_upload));
|
||||
return json::toJson(info);
|
||||
}
|
||||
|
|
|
@ -41,11 +41,11 @@ private:
|
|||
btjson() {}
|
||||
|
||||
public:
|
||||
static QString getTorrents();
|
||||
static QString getTrackersForTorrent(const QString& hash);
|
||||
static QString getPropertiesForTorrent(const QString& hash);
|
||||
static QString getFilesForTorrent(const QString& hash);
|
||||
static QString getTransferInfo();
|
||||
static QByteArray getTorrents();
|
||||
static QByteArray getTrackersForTorrent(const QString& hash);
|
||||
static QByteArray getPropertiesForTorrent(const QString& hash);
|
||||
static QByteArray getFilesForTorrent(const QString& hash);
|
||||
static QByteArray getTransferInfo();
|
||||
}; // class btjson
|
||||
|
||||
#endif // BTJSON_H
|
||||
|
|
|
@ -113,7 +113,7 @@ void HttpRequestParser::writeMessage(const QByteArray& ba) {
|
|||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
|
||||
QString tmp(m_data);
|
||||
QUrlQuery query(tmp);
|
||||
QListIterator<QPair<QString, QString> > i(query.queryItems());
|
||||
QListIterator<QPair<QString, QString> > i(query.queryItems(QUrl::FullyDecoded));
|
||||
#else
|
||||
url.setEncodedQuery(m_data);
|
||||
QListIterator<QPair<QString, QString> > i(url.queryItems());
|
||||
|
|
|
@ -1,163 +0,0 @@
|
|||
/*
|
||||
* Bittorrent Client using Qt4 and libtorrent.
|
||||
* Copyright (C) 2006-2012 Ishan Arora and Christophe Dumez
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give permission to
|
||||
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||
* and distribute the linked executables. You must obey the GNU General Public
|
||||
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||
* modify file(s), you may extend this exception to your version of the file(s),
|
||||
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||
* exception statement from your version.
|
||||
*
|
||||
* Contact : chris@qbittorrent.org
|
||||
*/
|
||||
|
||||
#include "json.h"
|
||||
|
||||
#include <QStringList>
|
||||
#include <QVariantMap>
|
||||
|
||||
QString json::toJson(const QVariant& v) {
|
||||
if (v.isNull())
|
||||
return "null";
|
||||
switch(v.type())
|
||||
{
|
||||
case QVariant::Bool:
|
||||
case QVariant::Double:
|
||||
case QVariant::Int:
|
||||
case QVariant::LongLong:
|
||||
case QVariant::UInt:
|
||||
case QVariant::ULongLong:
|
||||
return v.value<QString>();
|
||||
case QVariant::StringList:
|
||||
case QVariant::List: {
|
||||
QStringList strList;
|
||||
foreach (const QVariant &var, v.toList()) {
|
||||
strList << toJson(var);
|
||||
}
|
||||
return "["+strList.join(",")+"]";
|
||||
}
|
||||
case QVariant::String: {
|
||||
QString s = v.value<QString>();
|
||||
QString result = "\"";
|
||||
for (int i=0; i<s.size(); ++i) {
|
||||
const QChar ch = s[i];
|
||||
switch(ch.toLatin1())
|
||||
{
|
||||
case '\b':
|
||||
result += "\\b";
|
||||
break;
|
||||
case '\f':
|
||||
result += "\\f";
|
||||
break;
|
||||
case '\n':
|
||||
result += "\\n";
|
||||
break;
|
||||
case '\r':
|
||||
result += "\\r";
|
||||
break;
|
||||
case '\t':
|
||||
result += "\\t";
|
||||
break;
|
||||
case '\"':
|
||||
case '\\':
|
||||
result += '\\';
|
||||
case '\0':
|
||||
default:
|
||||
result += ch;
|
||||
}
|
||||
}
|
||||
result += "\"";
|
||||
return result;
|
||||
}
|
||||
default:
|
||||
qDebug("Unknown QVariantType: %d", (int)v.type());
|
||||
return "undefined";
|
||||
}
|
||||
}
|
||||
|
||||
QVariantMap json::fromJson(const QString& json) {
|
||||
qDebug("JSON is %s", qPrintable(json));
|
||||
QVariantMap m;
|
||||
if (json.startsWith("{") && json.endsWith("}")) {
|
||||
QStringList couples;
|
||||
QString tmp = "";
|
||||
bool in_list = false;
|
||||
foreach (const QChar &c, json.mid(1, json.length()-2)) {
|
||||
if (c == ',' && !in_list) {
|
||||
couples << tmp;
|
||||
tmp = "";
|
||||
} else {
|
||||
if (c == '[')
|
||||
in_list = true;
|
||||
else if (c == ']')
|
||||
in_list = false;
|
||||
tmp += c;
|
||||
}
|
||||
}
|
||||
if (!tmp.isEmpty()) couples << tmp;
|
||||
|
||||
foreach (const QString &couple, couples) {
|
||||
QStringList parts;
|
||||
int jsonSep = couple.indexOf(":");
|
||||
parts << couple.left(jsonSep);
|
||||
parts << couple.mid(jsonSep + 1);
|
||||
Q_ASSERT(parts.size() == 2);
|
||||
QString key = parts.first();
|
||||
if (key.startsWith("\"") && key.endsWith("\"")) {
|
||||
key = key.mid(1, key.length()-2);
|
||||
}
|
||||
QString value_str = parts.last();
|
||||
QVariant value;
|
||||
if (value_str.startsWith("[") && value_str.endsWith("]")) {
|
||||
value_str = value_str.mid(1, value_str.length()-2);
|
||||
QStringList list_elems = value_str.split(",", QString::SkipEmptyParts);
|
||||
QVariantList varlist;
|
||||
foreach (const QString &list_val, list_elems) {
|
||||
if (list_val.startsWith("\"") && list_val.endsWith("\"")) {
|
||||
varlist << list_val.mid(1, list_val.length()-2).replace("\\n", "\n");
|
||||
} else {
|
||||
if (list_val.compare("false", Qt::CaseInsensitive) == 0)
|
||||
varlist << false;
|
||||
else if (list_val.compare("true", Qt::CaseInsensitive) == 0)
|
||||
varlist << true;
|
||||
else
|
||||
varlist << list_val.toInt();
|
||||
}
|
||||
}
|
||||
value = varlist;
|
||||
} else {
|
||||
if (value_str.startsWith("\"") && value_str.endsWith("\"")) {
|
||||
value_str = value_str.mid(1, value_str.length()-2).replace("\\n", "\n");
|
||||
value = value_str;
|
||||
} else {
|
||||
if (value_str.compare("false", Qt::CaseInsensitive) == 0)
|
||||
value = false;
|
||||
else if (value_str.compare("true", Qt::CaseInsensitive) == 0)
|
||||
value = true;
|
||||
else
|
||||
value = value_str.toInt();
|
||||
}
|
||||
}
|
||||
m.insert(key, value);
|
||||
qDebug("%s:%s", qPrintable(key), qPrintable(value_str));
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
* Bittorrent Client using Qt4 and libtorrent.
|
||||
* Copyright (C) 2012, Christophe Dumez
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give permission to
|
||||
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||
* and distribute the linked executables. You must obey the GNU General Public
|
||||
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||
* modify file(s), you may extend this exception to your version of the file(s),
|
||||
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||
* exception statement from your version.
|
||||
*
|
||||
* Contact : chris@qbittorrent.org
|
||||
*/
|
||||
|
||||
#include "jsondict.h"
|
||||
#include "json.h"
|
||||
|
||||
JsonDict::JsonDict(): m_dirty(false)
|
||||
{
|
||||
}
|
||||
|
||||
void JsonDict::clear()
|
||||
{
|
||||
m_items.clear();
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
void JsonDict::add(const QString& key, const QVariant& value)
|
||||
{
|
||||
m_items.append("\"" + key + "\":" + json::toJson(value));
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
const QString& JsonDict::toString() const
|
||||
{
|
||||
if (m_dirty) {
|
||||
m_json = "{" + m_items.join(",") + "}";
|
||||
m_dirty = false;
|
||||
}
|
||||
return m_json;
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Bittorrent Client using Qt4 and libtorrent.
|
||||
* Copyright (C) 2012, Christophe Dumez
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give permission to
|
||||
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||
* and distribute the linked executables. You must obey the GNU General Public
|
||||
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||
* modify file(s), you may extend this exception to your version of the file(s),
|
||||
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||
* exception statement from your version.
|
||||
*
|
||||
* Contact : chris@qbittorrent.org
|
||||
*/
|
||||
|
||||
#ifndef JSONDICT_H
|
||||
#define JSONDICT_H
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
class JsonDict
|
||||
{
|
||||
public:
|
||||
JsonDict();
|
||||
void clear();
|
||||
void add(const QString& key, const QVariant& value);
|
||||
const QString& toString() const;
|
||||
|
||||
private:
|
||||
mutable bool m_dirty;
|
||||
mutable QString m_json;
|
||||
QStringList m_items;
|
||||
};
|
||||
|
||||
#endif // JSONDICT_H
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* Bittorrent Client using Qt4 and libtorrent.
|
||||
* Copyright (C) 2012, Christophe Dumez
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give permission to
|
||||
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||
* and distribute the linked executables. You must obey the GNU General Public
|
||||
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||
* modify file(s), you may extend this exception to your version of the file(s),
|
||||
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||
* exception statement from your version.
|
||||
*
|
||||
* Contact : chris@qbittorrent.org
|
||||
*/
|
||||
|
||||
#ifndef JSONLIST_H
|
||||
#define JSONLIST_H
|
||||
|
||||
#include <QStringList>
|
||||
#include "jsondict.h"
|
||||
|
||||
class JsonList
|
||||
{
|
||||
public:
|
||||
JsonList();
|
||||
const QString& toString() const;
|
||||
void clear();
|
||||
void append(const QVariant& val);
|
||||
void append(const JsonDict& dict);
|
||||
|
||||
private:
|
||||
mutable bool m_dirty;
|
||||
mutable QString m_json;
|
||||
QStringList m_items;
|
||||
};
|
||||
|
||||
#endif // JSONLIST_H
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Bittorrent Client using Qt4 and libtorrent.
|
||||
* Copyright (C) 2012, Christophe Dumez
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2014 Vladimir Golovnev
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -25,39 +25,42 @@
|
|||
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||
* exception statement from your version.
|
||||
*
|
||||
* Contact : chris@qbittorrent.org
|
||||
* Contact : glassez@yandex.ru
|
||||
*/
|
||||
|
||||
#include "jsonlist.h"
|
||||
#include "json.h"
|
||||
#ifndef JSONUTILS_H
|
||||
#define JSONUTILS_H
|
||||
|
||||
JsonList::JsonList() : m_dirty(false)
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#else
|
||||
#include <QString>
|
||||
#include "qjson/parser.h"
|
||||
#include "qjson/serializer.h"
|
||||
#endif
|
||||
|
||||
namespace json {
|
||||
|
||||
inline QByteArray toJson(const QVariant& var)
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
return QJsonDocument::fromVariant(var).toJson();
|
||||
#else
|
||||
return QJson::Serializer().serialize(var);
|
||||
#endif
|
||||
}
|
||||
|
||||
const QString& JsonList::toString() const
|
||||
inline QVariant fromJson(const QString& json)
|
||||
{
|
||||
if (m_dirty) {
|
||||
m_json = "[" + m_items.join(",") + "]";
|
||||
m_dirty = false;
|
||||
}
|
||||
return m_json;
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
return QJsonDocument::fromJson(json.toUtf8()).toVariant();
|
||||
#else
|
||||
return QJson::Parser().parse(json.toUtf8());
|
||||
#endif
|
||||
}
|
||||
|
||||
void JsonList::clear()
|
||||
{
|
||||
m_items.clear();
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
void JsonList::append(const QVariant& val)
|
||||
{
|
||||
m_items.append(json::toJson(val));
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
void JsonList::append(const JsonDict& dict)
|
||||
{
|
||||
m_items.append(dict.toString());
|
||||
m_dirty = true;
|
||||
}
|
||||
#endif // JSONUTILS_H
|
|
@ -29,9 +29,7 @@
|
|||
*/
|
||||
|
||||
#include "prefjson.h"
|
||||
#include "jsondict.h"
|
||||
#include "preferences.h"
|
||||
#include "json.h"
|
||||
#include "qbtsession.h"
|
||||
#include "scannedfoldersmodel.h"
|
||||
|
||||
|
@ -41,110 +39,111 @@
|
|||
#include <QSslKey>
|
||||
#endif
|
||||
#include <QTranslator>
|
||||
#include "jsonutils.h"
|
||||
|
||||
prefjson::prefjson()
|
||||
{
|
||||
}
|
||||
|
||||
QString prefjson::getPreferences()
|
||||
QByteArray prefjson::getPreferences()
|
||||
{
|
||||
const Preferences pref;
|
||||
JsonDict data;
|
||||
QVariantMap data;
|
||||
// UI
|
||||
data.add("locale", pref.getLocale());
|
||||
data["locale"] = pref.getLocale();
|
||||
// Downloads
|
||||
data.add("save_path", fsutils::toNativePath(pref.getSavePath()));
|
||||
data.add("temp_path_enabled", pref.isTempPathEnabled());
|
||||
data.add("temp_path", fsutils::toNativePath(pref.getTempPath()));
|
||||
QStringList l;
|
||||
data["save_path"] = fsutils::toNativePath(pref.getSavePath());
|
||||
data["temp_path_enabled"] = pref.isTempPathEnabled();
|
||||
data["temp_path"] = fsutils::toNativePath(pref.getTempPath());
|
||||
QVariantList l;
|
||||
foreach (const QString& s, pref.getScanDirs()) {
|
||||
l << fsutils::toNativePath(s);
|
||||
}
|
||||
data.add("scan_dirs", l);
|
||||
data["scan_dirs"] = l;
|
||||
QVariantList var_list;
|
||||
foreach (bool b, pref.getDownloadInScanDirs()) {
|
||||
var_list << b;
|
||||
}
|
||||
data.add("download_in_scan_dirs", var_list);
|
||||
data.add("export_dir_enabled", pref.isTorrentExportEnabled());
|
||||
data.add("export_dir", fsutils::toNativePath(pref.getTorrentExportDir()));
|
||||
data.add("mail_notification_enabled", pref.isMailNotificationEnabled());
|
||||
data.add("mail_notification_email", pref.getMailNotificationEmail());
|
||||
data.add("mail_notification_smtp", pref.getMailNotificationSMTP());
|
||||
data.add("mail_notification_ssl_enabled", pref.getMailNotificationSMTPSSL());
|
||||
data.add("mail_notification_auth_enabled", pref.getMailNotificationSMTPAuth());
|
||||
data.add("mail_notification_username", pref.getMailNotificationSMTPUsername());
|
||||
data.add("mail_notification_password", pref.getMailNotificationSMTPPassword());
|
||||
data.add("autorun_enabled", pref.isAutoRunEnabled());
|
||||
data.add("autorun_program", fsutils::toNativePath(pref.getAutoRunProgram()));
|
||||
data.add("preallocate_all", pref.preAllocateAllFiles());
|
||||
data.add("queueing_enabled", pref.isQueueingSystemEnabled());
|
||||
data.add("max_active_downloads", pref.getMaxActiveDownloads());
|
||||
data.add("max_active_torrents", pref.getMaxActiveTorrents());
|
||||
data.add("max_active_uploads", pref.getMaxActiveUploads());
|
||||
data.add("dont_count_slow_torrents", pref.ignoreSlowTorrentsForQueueing());
|
||||
data.add("incomplete_files_ext", pref.useIncompleteFilesExtension());
|
||||
data["download_in_scan_dirs"] = var_list;
|
||||
data["export_dir_enabled"] = pref.isTorrentExportEnabled();
|
||||
data["export_dir"] = fsutils::toNativePath(pref.getTorrentExportDir());
|
||||
data["mail_notification_enabled"] = pref.isMailNotificationEnabled();
|
||||
data["mail_notification_email"] = pref.getMailNotificationEmail();
|
||||
data["mail_notification_smtp"] = pref.getMailNotificationSMTP();
|
||||
data["mail_notification_ssl_enabled"] = pref.getMailNotificationSMTPSSL();
|
||||
data["mail_notification_auth_enabled"] = pref.getMailNotificationSMTPAuth();
|
||||
data["mail_notification_username"] = pref.getMailNotificationSMTPUsername();
|
||||
data["mail_notification_password"] = pref.getMailNotificationSMTPPassword();
|
||||
data["autorun_enabled"] = pref.isAutoRunEnabled();
|
||||
data["autorun_program"] = fsutils::toNativePath(pref.getAutoRunProgram());
|
||||
data["preallocate_all"] = pref.preAllocateAllFiles();
|
||||
data["queueing_enabled"] = pref.isQueueingSystemEnabled();
|
||||
data["max_active_downloads"] = pref.getMaxActiveDownloads();
|
||||
data["max_active_torrents"] = pref.getMaxActiveTorrents();
|
||||
data["max_active_uploads"] = pref.getMaxActiveUploads();
|
||||
data["dont_count_slow_torrents"] = pref.ignoreSlowTorrentsForQueueing();
|
||||
data["incomplete_files_ext"] = pref.useIncompleteFilesExtension();
|
||||
// Connection
|
||||
data.add("listen_port", pref.getSessionPort());
|
||||
data.add("upnp", pref.isUPnPEnabled());
|
||||
data.add("dl_limit", pref.getGlobalDownloadLimit());
|
||||
data.add("up_limit", pref.getGlobalUploadLimit());
|
||||
data.add("max_connec", pref.getMaxConnecs());
|
||||
data.add("max_connec_per_torrent", pref.getMaxConnecsPerTorrent());
|
||||
data.add("max_uploads_per_torrent", pref.getMaxUploadsPerTorrent());
|
||||
data.add("enable_utp", pref.isuTPEnabled());
|
||||
data.add("limit_utp_rate", pref.isuTPRateLimited());
|
||||
data.add("limit_tcp_overhead", pref.includeOverheadInLimits());
|
||||
data.add("alt_dl_limit", pref.getAltGlobalDownloadLimit());
|
||||
data.add("alt_up_limit", pref.getAltGlobalUploadLimit());
|
||||
data.add("scheduler_enabled", pref.isSchedulerEnabled());
|
||||
data["listen_port"] = pref.getSessionPort();
|
||||
data["upnp"] = pref.isUPnPEnabled();
|
||||
data["dl_limit"] = pref.getGlobalDownloadLimit();
|
||||
data["up_limit"] = pref.getGlobalUploadLimit();
|
||||
data["max_connec"] = pref.getMaxConnecs();
|
||||
data["max_connec_per_torrent"] = pref.getMaxConnecsPerTorrent();
|
||||
data["max_uploads_per_torrent"] = pref.getMaxUploadsPerTorrent();
|
||||
data["enable_utp"] = pref.isuTPEnabled();
|
||||
data["limit_utp_rate"] = pref.isuTPRateLimited();
|
||||
data["limit_tcp_overhead"] = pref.includeOverheadInLimits();
|
||||
data["alt_dl_limit"] = pref.getAltGlobalDownloadLimit();
|
||||
data["alt_up_limit"] = pref.getAltGlobalUploadLimit();
|
||||
data["scheduler_enabled"] = pref.isSchedulerEnabled();
|
||||
const QTime start_time = pref.getSchedulerStartTime();
|
||||
data.add("schedule_from_hour", start_time.hour());
|
||||
data.add("schedule_from_min", start_time.minute());
|
||||
data["schedule_from_hour"] = start_time.hour();
|
||||
data["schedule_from_min"] = start_time.minute();
|
||||
const QTime end_time = pref.getSchedulerEndTime();
|
||||
data.add("schedule_to_hour", end_time.hour());
|
||||
data.add("schedule_to_min", end_time.minute());
|
||||
data.add("scheduler_days", pref.getSchedulerDays());
|
||||
data["schedule_to_hour"] = end_time.hour();
|
||||
data["schedule_to_min"] = end_time.minute();
|
||||
data["scheduler_days"] = pref.getSchedulerDays();
|
||||
// Bittorrent
|
||||
data.add("dht", pref.isDHTEnabled());
|
||||
data.add("dhtSameAsBT", pref.isDHTPortSameAsBT());
|
||||
data.add("dht_port", pref.getDHTPort());
|
||||
data.add("pex", pref.isPeXEnabled());
|
||||
data.add("lsd", pref.isLSDEnabled());
|
||||
data.add("encryption", pref.getEncryptionSetting());
|
||||
data.add("anonymous_mode", pref.isAnonymousModeEnabled());
|
||||
data["dht"] = pref.isDHTEnabled();
|
||||
data["dhtSameAsBT"] = pref.isDHTPortSameAsBT();
|
||||
data["dht_port"] = pref.getDHTPort();
|
||||
data["pex"] = pref.isPeXEnabled();
|
||||
data["lsd"] = pref.isLSDEnabled();
|
||||
data["encryption"] = pref.getEncryptionSetting();
|
||||
data["anonymous_mode"] = pref.isAnonymousModeEnabled();
|
||||
// Proxy
|
||||
data.add("proxy_type", pref.getProxyType());
|
||||
data.add("proxy_ip", pref.getProxyIp());
|
||||
data.add("proxy_port", pref.getProxyPort());
|
||||
data.add("proxy_peer_connections", pref.proxyPeerConnections());
|
||||
data.add("proxy_auth_enabled", pref.isProxyAuthEnabled());
|
||||
data.add("proxy_username", pref.getProxyUsername());
|
||||
data.add("proxy_password", pref.getProxyPassword());
|
||||
data["proxy_type"] = pref.getProxyType();
|
||||
data["proxy_ip"] = pref.getProxyIp();
|
||||
data["proxy_port"] = pref.getProxyPort();
|
||||
data["proxy_peer_connections"] = pref.proxyPeerConnections();
|
||||
data["proxy_auth_enabled"] = pref.isProxyAuthEnabled();
|
||||
data["proxy_username"] = pref.getProxyUsername();
|
||||
data["proxy_password"] = pref.getProxyPassword();
|
||||
// IP Filter
|
||||
data.add("ip_filter_enabled", pref.isFilteringEnabled());
|
||||
data.add("ip_filter_path", fsutils::toNativePath(pref.getFilter()));
|
||||
data["ip_filter_enabled"] = pref.isFilteringEnabled();
|
||||
data["ip_filter_path"] = fsutils::toNativePath(pref.getFilter());
|
||||
// Web UI
|
||||
data.add("web_ui_port", pref.getWebUiPort());
|
||||
data.add("web_ui_username", pref.getWebUiUsername());
|
||||
data.add("web_ui_password", pref.getWebUiPassword());
|
||||
data.add("bypass_local_auth", !pref.isWebUiLocalAuthEnabled());
|
||||
data.add("use_https", pref.isWebUiHttpsEnabled());
|
||||
data.add("ssl_key", QString::fromLatin1(pref.getWebUiHttpsKey()));
|
||||
data.add("ssl_cert", QString::fromLatin1(pref.getWebUiHttpsCertificate()));
|
||||
data["web_ui_port"] = pref.getWebUiPort();
|
||||
data["web_ui_username"] = pref.getWebUiUsername();
|
||||
data["web_ui_password"] = pref.getWebUiPassword();
|
||||
data["bypass_local_auth"] = !pref.isWebUiLocalAuthEnabled();
|
||||
data["use_https"] = pref.isWebUiHttpsEnabled();
|
||||
data["ssl_key"] = QString::fromLatin1(pref.getWebUiHttpsKey());
|
||||
data["ssl_cert"] = QString::fromLatin1(pref.getWebUiHttpsCertificate());
|
||||
// DynDns
|
||||
data.add("dyndns_enabled", pref.isDynDNSEnabled());
|
||||
data.add("dyndns_service", pref.getDynDNSService());
|
||||
data.add("dyndns_username", pref.getDynDNSUsername());
|
||||
data.add("dyndns_password", pref.getDynDNSPassword());
|
||||
data.add("dyndns_domain", pref.getDynDomainName());
|
||||
data["dyndns_enabled"] = pref.isDynDNSEnabled();
|
||||
data["dyndns_service"] = pref.getDynDNSService();
|
||||
data["dyndns_username"] = pref.getDynDNSUsername();
|
||||
data["dyndns_password"] = pref.getDynDNSPassword();
|
||||
data["dyndns_domain"] = pref.getDynDomainName();
|
||||
|
||||
return data.toString();
|
||||
return json::toJson(data);
|
||||
}
|
||||
|
||||
void prefjson::setPreferences(const QString& json)
|
||||
{
|
||||
const QVariantMap m = json::fromJson(json);
|
||||
const QVariantMap m = json::fromJson(json).toMap();
|
||||
|
||||
// UI
|
||||
Preferences pref;
|
||||
|
|
|
@ -39,7 +39,7 @@ private:
|
|||
prefjson();
|
||||
|
||||
public:
|
||||
static QString getPreferences();
|
||||
static QByteArray getPreferences();
|
||||
static void setPreferences(const QString& json);
|
||||
|
||||
};
|
||||
|
|
206
src/webui/qjson/FlexLexer.h
Normal file
206
src/webui/qjson/FlexLexer.h
Normal file
|
@ -0,0 +1,206 @@
|
|||
// -*-C++-*-
|
||||
// FlexLexer.h -- define interfaces for lexical analyzer classes generated
|
||||
// by flex
|
||||
|
||||
// Copyright (c) 1993 The Regents of the University of California.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This code is derived from software contributed to Berkeley by
|
||||
// Kent Williams and Tom Epperly.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
|
||||
// Neither the name of the University nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
|
||||
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
// IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE.
|
||||
|
||||
// This file defines FlexLexer, an abstract class which specifies the
|
||||
// external interface provided to flex C++ lexer objects, and yyFlexLexer,
|
||||
// which defines a particular lexer class.
|
||||
//
|
||||
// If you want to create multiple lexer classes, you use the -P flag
|
||||
// to rename each yyFlexLexer to some other xxFlexLexer. You then
|
||||
// include <FlexLexer.h> in your other sources once per lexer class:
|
||||
//
|
||||
// #undef yyFlexLexer
|
||||
// #define yyFlexLexer xxFlexLexer
|
||||
// #include <FlexLexer.h>
|
||||
//
|
||||
// #undef yyFlexLexer
|
||||
// #define yyFlexLexer zzFlexLexer
|
||||
// #include <FlexLexer.h>
|
||||
// ...
|
||||
|
||||
#ifndef __FLEX_LEXER_H
|
||||
// Never included before - need to define base class.
|
||||
#define __FLEX_LEXER_H
|
||||
|
||||
#include <iostream>
|
||||
# ifndef FLEX_STD
|
||||
# define FLEX_STD std::
|
||||
# endif
|
||||
|
||||
extern "C++" {
|
||||
|
||||
struct yy_buffer_state;
|
||||
typedef int yy_state_type;
|
||||
|
||||
class FlexLexer {
|
||||
public:
|
||||
virtual ~FlexLexer() { }
|
||||
|
||||
const char* YYText() const { return yytext; }
|
||||
int YYLeng() const { return yyleng; }
|
||||
|
||||
virtual void
|
||||
yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0;
|
||||
virtual struct yy_buffer_state*
|
||||
yy_create_buffer( FLEX_STD istream* s, int size ) = 0;
|
||||
virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0;
|
||||
virtual void yyrestart( FLEX_STD istream* s ) = 0;
|
||||
|
||||
virtual int yylex() = 0;
|
||||
|
||||
// Call yylex with new input/output sources.
|
||||
int yylex( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 )
|
||||
{
|
||||
switch_streams( new_in, new_out );
|
||||
return yylex();
|
||||
}
|
||||
|
||||
// Switch to new input/output streams. A nil stream pointer
|
||||
// indicates "keep the current one".
|
||||
virtual void switch_streams( FLEX_STD istream* new_in = 0,
|
||||
FLEX_STD ostream* new_out = 0 ) = 0;
|
||||
|
||||
int lineno() const { return yylineno; }
|
||||
|
||||
int debug() const { return yy_flex_debug; }
|
||||
void set_debug( int flag ) { yy_flex_debug = flag; }
|
||||
|
||||
protected:
|
||||
char* yytext;
|
||||
int yyleng;
|
||||
int yylineno; // only maintained if you use %option yylineno
|
||||
int yy_flex_debug; // only has effect with -d or "%option debug"
|
||||
};
|
||||
|
||||
}
|
||||
#endif // FLEXLEXER_H
|
||||
|
||||
#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce)
|
||||
// Either this is the first time through (yyFlexLexerOnce not defined),
|
||||
// or this is a repeated include to define a different flavor of
|
||||
// yyFlexLexer, as discussed in the flex manual.
|
||||
#define yyFlexLexerOnce
|
||||
|
||||
extern "C++" {
|
||||
|
||||
class yyFlexLexer : public FlexLexer {
|
||||
public:
|
||||
// arg_yyin and arg_yyout default to the cin and cout, but we
|
||||
// only make that assignment when initializing in yylex().
|
||||
yyFlexLexer( FLEX_STD istream* arg_yyin = 0, FLEX_STD ostream* arg_yyout = 0 );
|
||||
|
||||
virtual ~yyFlexLexer();
|
||||
|
||||
void yy_switch_to_buffer( struct yy_buffer_state* new_buffer );
|
||||
struct yy_buffer_state* yy_create_buffer( FLEX_STD istream* s, int size );
|
||||
void yy_delete_buffer( struct yy_buffer_state* b );
|
||||
void yyrestart( FLEX_STD istream* s );
|
||||
|
||||
void yypush_buffer_state( struct yy_buffer_state* new_buffer );
|
||||
void yypop_buffer_state();
|
||||
|
||||
virtual int yylex();
|
||||
virtual void switch_streams( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 );
|
||||
virtual int yywrap();
|
||||
|
||||
protected:
|
||||
virtual int LexerInput( char* buf, int max_size );
|
||||
virtual void LexerOutput( const char* buf, int size );
|
||||
virtual void LexerError( const char* msg );
|
||||
|
||||
void yyunput( int c, char* buf_ptr );
|
||||
int yyinput();
|
||||
|
||||
void yy_load_buffer_state();
|
||||
void yy_init_buffer( struct yy_buffer_state* b, FLEX_STD istream* s );
|
||||
void yy_flush_buffer( struct yy_buffer_state* b );
|
||||
|
||||
int yy_start_stack_ptr;
|
||||
int yy_start_stack_depth;
|
||||
int* yy_start_stack;
|
||||
|
||||
void yy_push_state( int new_state );
|
||||
void yy_pop_state();
|
||||
int yy_top_state();
|
||||
|
||||
yy_state_type yy_get_previous_state();
|
||||
yy_state_type yy_try_NUL_trans( yy_state_type current_state );
|
||||
int yy_get_next_buffer();
|
||||
|
||||
FLEX_STD istream* yyin; // input source for default LexerInput
|
||||
FLEX_STD ostream* yyout; // output sink for default LexerOutput
|
||||
|
||||
// yy_hold_char holds the character lost when yytext is formed.
|
||||
char yy_hold_char;
|
||||
|
||||
// Number of characters read into yy_ch_buf.
|
||||
int yy_n_chars;
|
||||
|
||||
// Points to current character in buffer.
|
||||
char* yy_c_buf_p;
|
||||
|
||||
int yy_init; // whether we need to initialize
|
||||
int yy_start; // start state number
|
||||
|
||||
// Flag which is used to allow yywrap()'s to do buffer switches
|
||||
// instead of setting up a fresh yyin. A bit of a hack ...
|
||||
int yy_did_buffer_switch_on_eof;
|
||||
|
||||
|
||||
size_t yy_buffer_stack_top; /**< index of top of stack. */
|
||||
size_t yy_buffer_stack_max; /**< capacity of stack. */
|
||||
struct yy_buffer_state ** yy_buffer_stack; /**< Stack as an array. */
|
||||
void yyensure_buffer_stack(void);
|
||||
|
||||
// The following are not always needed, but may be depending
|
||||
// on use of certain flex features (like REJECT or yymore()).
|
||||
|
||||
yy_state_type yy_last_accepting_state;
|
||||
char* yy_last_accepting_cpos;
|
||||
|
||||
yy_state_type* yy_state_buf;
|
||||
yy_state_type* yy_state_ptr;
|
||||
|
||||
char* yy_full_match;
|
||||
int* yy_full_state;
|
||||
int yy_full_lp;
|
||||
|
||||
int yy_lp;
|
||||
int yy_looking_for_trail_begin;
|
||||
|
||||
int yy_more_flag;
|
||||
int yy_more_len;
|
||||
int yy_more_offset;
|
||||
int yy_prev_more_offset;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // yyFlexLexer || ! yyFlexLexerOnce
|
||||
|
1103
src/webui/qjson/json_parser.cc
Normal file
1103
src/webui/qjson/json_parser.cc
Normal file
File diff suppressed because it is too large
Load diff
300
src/webui/qjson/json_parser.hh
Normal file
300
src/webui/qjson/json_parser.hh
Normal file
|
@ -0,0 +1,300 @@
|
|||
/* A Bison parser, made by GNU Bison 2.7. */
|
||||
|
||||
/* Skeleton interface for Bison LALR(1) parsers in C++
|
||||
|
||||
Copyright (C) 2002-2012 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
/**
|
||||
** \file json_parser.hh
|
||||
** Define the yy::parser class.
|
||||
*/
|
||||
|
||||
/* C++ LALR(1) parser skeleton written by Akim Demaille. */
|
||||
|
||||
#ifndef YY_YY_JSON_PARSER_HH_INCLUDED
|
||||
# define YY_YY_JSON_PARSER_HH_INCLUDED
|
||||
|
||||
/* "%code requires" blocks. */
|
||||
/* Line 33 of lalr1.cc */
|
||||
#line 26 "json_parser.yy"
|
||||
|
||||
#include "parser_p.h"
|
||||
#include "json_scanner.h"
|
||||
#include "qjson_debug.h"
|
||||
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QVariant>
|
||||
|
||||
#include <limits>
|
||||
|
||||
class JSonScanner;
|
||||
|
||||
namespace QJson {
|
||||
class Parser;
|
||||
}
|
||||
|
||||
#define YYERROR_VERBOSE 1
|
||||
|
||||
Q_DECLARE_METATYPE(QVector<QVariant>*)
|
||||
Q_DECLARE_METATYPE(QVariantMap*)
|
||||
|
||||
|
||||
/* Line 33 of lalr1.cc */
|
||||
#line 72 "json_parser.hh"
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include "stack.hh"
|
||||
#include "location.hh"
|
||||
|
||||
/* Enabling traces. */
|
||||
#ifndef YYDEBUG
|
||||
# define YYDEBUG 1
|
||||
#endif
|
||||
|
||||
|
||||
namespace yy {
|
||||
/* Line 33 of lalr1.cc */
|
||||
#line 88 "json_parser.hh"
|
||||
|
||||
/// A Bison parser.
|
||||
class json_parser
|
||||
{
|
||||
public:
|
||||
/// Symbol semantic values.
|
||||
#ifndef YYSTYPE
|
||||
typedef int semantic_type;
|
||||
#else
|
||||
typedef YYSTYPE semantic_type;
|
||||
#endif
|
||||
/// Symbol locations.
|
||||
typedef location location_type;
|
||||
/// Tokens.
|
||||
struct token
|
||||
{
|
||||
/* Tokens. */
|
||||
enum yytokentype {
|
||||
END = 0,
|
||||
CURLY_BRACKET_OPEN = 1,
|
||||
CURLY_BRACKET_CLOSE = 2,
|
||||
SQUARE_BRACKET_OPEN = 3,
|
||||
SQUARE_BRACKET_CLOSE = 4,
|
||||
COLON = 5,
|
||||
COMMA = 6,
|
||||
NUMBER = 7,
|
||||
TRUE_VAL = 8,
|
||||
FALSE_VAL = 9,
|
||||
NULL_VAL = 10,
|
||||
STRING = 11,
|
||||
INVALID = 12
|
||||
};
|
||||
|
||||
};
|
||||
/// Token type.
|
||||
typedef token::yytokentype token_type;
|
||||
|
||||
/// Build a parser object.
|
||||
json_parser (QJson::ParserPrivate* driver_yyarg);
|
||||
virtual ~json_parser ();
|
||||
|
||||
/// Parse.
|
||||
/// \returns 0 iff parsing succeeded.
|
||||
virtual int parse ();
|
||||
|
||||
#if YYDEBUG
|
||||
/// The current debugging stream.
|
||||
std::ostream& debug_stream () const;
|
||||
/// Set the current debugging stream.
|
||||
void set_debug_stream (std::ostream &);
|
||||
|
||||
/// Type for debugging levels.
|
||||
typedef int debug_level_type;
|
||||
/// The current debugging level.
|
||||
debug_level_type debug_level () const;
|
||||
/// Set the current debugging level.
|
||||
void set_debug_level (debug_level_type l);
|
||||
#endif
|
||||
|
||||
private:
|
||||
/// Report a syntax error.
|
||||
/// \param loc where the syntax error is found.
|
||||
/// \param msg a description of the syntax error.
|
||||
virtual void error (const location_type& loc, const std::string& msg);
|
||||
|
||||
/// Generate an error message.
|
||||
/// \param state the state where the error occurred.
|
||||
/// \param tok the lookahead token.
|
||||
virtual std::string yysyntax_error_ (int yystate, int tok);
|
||||
|
||||
#if YYDEBUG
|
||||
/// \brief Report a symbol value on the debug stream.
|
||||
/// \param yytype The token type.
|
||||
/// \param yyvaluep Its semantic value.
|
||||
/// \param yylocationp Its location.
|
||||
virtual void yy_symbol_value_print_ (int yytype,
|
||||
const semantic_type* yyvaluep,
|
||||
const location_type* yylocationp);
|
||||
/// \brief Report a symbol on the debug stream.
|
||||
/// \param yytype The token type.
|
||||
/// \param yyvaluep Its semantic value.
|
||||
/// \param yylocationp Its location.
|
||||
virtual void yy_symbol_print_ (int yytype,
|
||||
const semantic_type* yyvaluep,
|
||||
const location_type* yylocationp);
|
||||
#endif
|
||||
|
||||
|
||||
/// State numbers.
|
||||
typedef int state_type;
|
||||
/// State stack type.
|
||||
typedef stack<state_type> state_stack_type;
|
||||
/// Semantic value stack type.
|
||||
typedef stack<semantic_type> semantic_stack_type;
|
||||
/// location stack type.
|
||||
typedef stack<location_type> location_stack_type;
|
||||
|
||||
/// The state stack.
|
||||
state_stack_type yystate_stack_;
|
||||
/// The semantic value stack.
|
||||
semantic_stack_type yysemantic_stack_;
|
||||
/// The location stack.
|
||||
location_stack_type yylocation_stack_;
|
||||
|
||||
/// Whether the given \c yypact_ value indicates a defaulted state.
|
||||
/// \param yyvalue the value to check
|
||||
static bool yy_pact_value_is_default_ (int yyvalue);
|
||||
|
||||
/// Whether the given \c yytable_ value indicates a syntax error.
|
||||
/// \param yyvalue the value to check
|
||||
static bool yy_table_value_is_error_ (int yyvalue);
|
||||
|
||||
/// Internal symbol numbers.
|
||||
typedef unsigned char token_number_type;
|
||||
/* Tables. */
|
||||
/// For a state, the index in \a yytable_ of its portion.
|
||||
static const signed char yypact_[];
|
||||
static const signed char yypact_ninf_;
|
||||
|
||||
/// For a state, default reduction number.
|
||||
/// Unless\a yytable_ specifies something else to do.
|
||||
/// Zero means the default is an error.
|
||||
static const unsigned char yydefact_[];
|
||||
|
||||
static const signed char yypgoto_[];
|
||||
static const signed char yydefgoto_[];
|
||||
|
||||
/// What to do in a state.
|
||||
/// \a yytable_[yypact_[s]]: what to do in state \a s.
|
||||
/// - if positive, shift that token.
|
||||
/// - if negative, reduce the rule which number is the opposite.
|
||||
/// - if zero, do what YYDEFACT says.
|
||||
static const unsigned char yytable_[];
|
||||
static const signed char yytable_ninf_;
|
||||
|
||||
static const signed char yycheck_[];
|
||||
|
||||
/// For a state, its accessing symbol.
|
||||
static const unsigned char yystos_[];
|
||||
|
||||
/// For a rule, its LHS.
|
||||
static const unsigned char yyr1_[];
|
||||
/// For a rule, its RHS length.
|
||||
static const unsigned char yyr2_[];
|
||||
|
||||
/// Convert the symbol name \a n to a form suitable for a diagnostic.
|
||||
static std::string yytnamerr_ (const char *n);
|
||||
|
||||
|
||||
/// For a symbol, its name in clear.
|
||||
static const char* const yytname_[];
|
||||
#if YYDEBUG
|
||||
/// A type to store symbol numbers and -1.
|
||||
typedef signed char rhs_number_type;
|
||||
/// A `-1'-separated list of the rules' RHS.
|
||||
static const rhs_number_type yyrhs_[];
|
||||
/// For each rule, the index of the first RHS symbol in \a yyrhs_.
|
||||
static const unsigned char yyprhs_[];
|
||||
/// For each rule, its source line number.
|
||||
static const unsigned char yyrline_[];
|
||||
/// For each scanner token number, its symbol number.
|
||||
static const unsigned short int yytoken_number_[];
|
||||
/// Report on the debug stream that the rule \a r is going to be reduced.
|
||||
virtual void yy_reduce_print_ (int r);
|
||||
/// Print the state stack on the debug stream.
|
||||
virtual void yystack_print_ ();
|
||||
|
||||
/* Debugging. */
|
||||
int yydebug_;
|
||||
std::ostream* yycdebug_;
|
||||
#endif
|
||||
|
||||
/// Convert a scanner token number \a t to a symbol number.
|
||||
token_number_type yytranslate_ (int t);
|
||||
|
||||
/// \brief Reclaim the memory associated to a symbol.
|
||||
/// \param yymsg Why this token is reclaimed.
|
||||
/// If null, do not display the symbol, just free it.
|
||||
/// \param yytype The symbol type.
|
||||
/// \param yyvaluep Its semantic value.
|
||||
/// \param yylocationp Its location.
|
||||
inline void yydestruct_ (const char* yymsg,
|
||||
int yytype,
|
||||
semantic_type* yyvaluep,
|
||||
location_type* yylocationp);
|
||||
|
||||
/// Pop \a n symbols the three stacks.
|
||||
inline void yypop_ (unsigned int n = 1);
|
||||
|
||||
/* Constants. */
|
||||
static const int yyeof_;
|
||||
/* LAST_ -- Last index in TABLE_. */
|
||||
static const int yylast_;
|
||||
static const int yynnts_;
|
||||
static const int yyempty_;
|
||||
static const int yyfinal_;
|
||||
static const int yyterror_;
|
||||
static const int yyerrcode_;
|
||||
static const int yyntokens_;
|
||||
static const unsigned int yyuser_token_number_max_;
|
||||
static const token_number_type yyundef_token_;
|
||||
|
||||
/* User arguments. */
|
||||
QJson::ParserPrivate* driver;
|
||||
};
|
||||
|
||||
} // yy
|
||||
/* Line 33 of lalr1.cc */
|
||||
#line 297 "json_parser.hh"
|
||||
|
||||
|
||||
|
||||
#endif /* !YY_YY_JSON_PARSER_HH_INCLUDED */
|
4513
src/webui/qjson/json_scanner.cc
Normal file
4513
src/webui/qjson/json_scanner.cc
Normal file
File diff suppressed because it is too large
Load diff
82
src/webui/qjson/json_scanner.cpp
Normal file
82
src/webui/qjson/json_scanner.cpp
Normal file
|
@ -0,0 +1,82 @@
|
|||
/* This file is part of QJson
|
||||
*
|
||||
* Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com>
|
||||
* Copyright (C) 2013 Silvio Moioli <silvio@moioli.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License version 2.1, as published by the Free Software Foundation.
|
||||
*
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#include "json_scanner.cc"
|
||||
|
||||
#include "qjson_debug.h"
|
||||
#include "json_scanner.h"
|
||||
#include "json_parser.hh"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QRegExp>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
||||
JSonScanner::JSonScanner(QIODevice* io)
|
||||
: m_allowSpecialNumbers(false),
|
||||
m_io (io),
|
||||
m_criticalError(false),
|
||||
m_C_locale(QLocale::C)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
JSonScanner::~JSonScanner()
|
||||
{
|
||||
}
|
||||
|
||||
void JSonScanner::allowSpecialNumbers(bool allow) {
|
||||
m_allowSpecialNumbers = allow;
|
||||
}
|
||||
|
||||
int JSonScanner::yylex(YYSTYPE* yylval, yy::location *yylloc) {
|
||||
m_yylval = yylval;
|
||||
m_yylloc = yylloc;
|
||||
m_yylloc->step();
|
||||
int result = yylex();
|
||||
|
||||
if (m_criticalError) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int JSonScanner::LexerInput(char* buf, int max_size) {
|
||||
if (!m_io->isOpen()) {
|
||||
qCritical() << "JSonScanner::yylex - io device is not open";
|
||||
m_criticalError = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int readBytes = m_io->read(buf, max_size);
|
||||
if(readBytes < 0) {
|
||||
qCritical() << "JSonScanner::yylex - error while reading from io device";
|
||||
m_criticalError = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return readBytes;
|
||||
}
|
||||
|
||||
|
66
src/webui/qjson/json_scanner.h
Normal file
66
src/webui/qjson/json_scanner.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/* This file is part of QJson
|
||||
*
|
||||
* Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License version 2.1, as published by the Free Software Foundation.
|
||||
*
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _JSON_SCANNER
|
||||
#define _JSON_SCANNER
|
||||
|
||||
#include <QtCore/QIODevice>
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtCore/QLocale>
|
||||
|
||||
#define YYSTYPE QVariant
|
||||
|
||||
// Only include FlexLexer.h if it hasn't been already included
|
||||
#if ! defined(yyFlexLexerOnce)
|
||||
#include <FlexLexer.h>
|
||||
#endif
|
||||
|
||||
#include "parser_p.h"
|
||||
|
||||
|
||||
|
||||
namespace yy {
|
||||
class location;
|
||||
int yylex(YYSTYPE *yylval, yy::location *yylloc, QJson::ParserPrivate* driver);
|
||||
}
|
||||
|
||||
class JSonScanner : public yyFlexLexer
|
||||
{
|
||||
public:
|
||||
explicit JSonScanner(QIODevice* io);
|
||||
~JSonScanner();
|
||||
|
||||
void allowSpecialNumbers(bool allow);
|
||||
|
||||
int yylex(YYSTYPE* yylval, yy::location *yylloc);
|
||||
int yylex();
|
||||
int LexerInput(char* buf, int max_size);
|
||||
protected:
|
||||
bool m_allowSpecialNumbers;
|
||||
QIODevice* m_io;
|
||||
|
||||
YYSTYPE* m_yylval;
|
||||
yy::location* m_yylloc;
|
||||
bool m_criticalError;
|
||||
QString m_currentString;
|
||||
QLocale m_C_locale;
|
||||
};
|
||||
|
||||
#endif
|
181
src/webui/qjson/location.hh
Normal file
181
src/webui/qjson/location.hh
Normal file
|
@ -0,0 +1,181 @@
|
|||
/* A Bison parser, made by GNU Bison 2.7. */
|
||||
|
||||
/* Locations for Bison parsers in C++
|
||||
|
||||
Copyright (C) 2002-2007, 2009-2012 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
/**
|
||||
** \file location.hh
|
||||
** Define the yy::location class.
|
||||
*/
|
||||
|
||||
#ifndef YY_YY_LOCATION_HH_INCLUDED
|
||||
# define YY_YY_LOCATION_HH_INCLUDED
|
||||
|
||||
# include "position.hh"
|
||||
|
||||
|
||||
namespace yy {
|
||||
/* Line 166 of location.cc */
|
||||
#line 47 "location.hh"
|
||||
|
||||
/// Abstract a location.
|
||||
class location
|
||||
{
|
||||
public:
|
||||
|
||||
/// Construct a location from \a b to \a e.
|
||||
location (const position& b, const position& e)
|
||||
: begin (b)
|
||||
, end (e)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a 0-width location in \a p.
|
||||
explicit location (const position& p = position ())
|
||||
: begin (p)
|
||||
, end (p)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a 0-width location in \a f, \a l, \a c.
|
||||
explicit location (std::string* f,
|
||||
unsigned int l = 1u,
|
||||
unsigned int c = 1u)
|
||||
: begin (f, l, c)
|
||||
, end (f, l, c)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// Initialization.
|
||||
void initialize (std::string* f = YY_NULL,
|
||||
unsigned int l = 1u,
|
||||
unsigned int c = 1u)
|
||||
{
|
||||
begin.initialize (f, l, c);
|
||||
end = begin;
|
||||
}
|
||||
|
||||
/** \name Line and Column related manipulators
|
||||
** \{ */
|
||||
public:
|
||||
/// Reset initial location to final location.
|
||||
void step ()
|
||||
{
|
||||
begin = end;
|
||||
}
|
||||
|
||||
/// Extend the current location to the COUNT next columns.
|
||||
void columns (unsigned int count = 1)
|
||||
{
|
||||
end += count;
|
||||
}
|
||||
|
||||
/// Extend the current location to the COUNT next lines.
|
||||
void lines (unsigned int count = 1)
|
||||
{
|
||||
end.lines (count);
|
||||
}
|
||||
/** \} */
|
||||
|
||||
|
||||
public:
|
||||
/// Beginning of the located region.
|
||||
position begin;
|
||||
/// End of the located region.
|
||||
position end;
|
||||
};
|
||||
|
||||
/// Join two location objects to create a location.
|
||||
inline const location operator+ (const location& begin, const location& end)
|
||||
{
|
||||
location res = begin;
|
||||
res.end = end.end;
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Add two location objects.
|
||||
inline const location operator+ (const location& begin, unsigned int width)
|
||||
{
|
||||
location res = begin;
|
||||
res.columns (width);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Add and assign a location.
|
||||
inline location& operator+= (location& res, unsigned int width)
|
||||
{
|
||||
res.columns (width);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Compare two location objects.
|
||||
inline bool
|
||||
operator== (const location& loc1, const location& loc2)
|
||||
{
|
||||
return loc1.begin == loc2.begin && loc1.end == loc2.end;
|
||||
}
|
||||
|
||||
/// Compare two location objects.
|
||||
inline bool
|
||||
operator!= (const location& loc1, const location& loc2)
|
||||
{
|
||||
return !(loc1 == loc2);
|
||||
}
|
||||
|
||||
/** \brief Intercept output stream redirection.
|
||||
** \param ostr the destination output stream
|
||||
** \param loc a reference to the location to redirect
|
||||
**
|
||||
** Avoid duplicate information.
|
||||
*/
|
||||
template <typename YYChar>
|
||||
inline std::basic_ostream<YYChar>&
|
||||
operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)
|
||||
{
|
||||
position last = loc.end - 1;
|
||||
ostr << loc.begin;
|
||||
if (last.filename
|
||||
&& (!loc.begin.filename
|
||||
|| *loc.begin.filename != *last.filename))
|
||||
ostr << '-' << last;
|
||||
else if (loc.begin.line != last.line)
|
||||
ostr << '-' << last.line << '.' << last.column;
|
||||
else if (loc.begin.column != last.column)
|
||||
ostr << '-' << last.column;
|
||||
return ostr;
|
||||
}
|
||||
|
||||
|
||||
} // yy
|
||||
/* Line 296 of location.cc */
|
||||
#line 180 "location.hh"
|
||||
|
||||
#endif /* !YY_YY_LOCATION_HH_INCLUDED */
|
141
src/webui/qjson/parser.cpp
Normal file
141
src/webui/qjson/parser.cpp
Normal file
|
@ -0,0 +1,141 @@
|
|||
/* This file is part of QJson
|
||||
*
|
||||
* Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License version 2.1, as published by the Free Software Foundation.
|
||||
*
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "parser.h"
|
||||
#include "parser_p.h"
|
||||
#include "json_parser.hh"
|
||||
#include "json_scanner.h"
|
||||
|
||||
#include <QtCore/QBuffer>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QTextStream>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
using namespace QJson;
|
||||
|
||||
ParserPrivate::ParserPrivate() :
|
||||
m_scanner(0)
|
||||
{
|
||||
m_specialNumbersAllowed = false;
|
||||
reset();
|
||||
}
|
||||
|
||||
ParserPrivate::~ParserPrivate()
|
||||
{
|
||||
if (m_scanner)
|
||||
delete m_scanner;
|
||||
}
|
||||
|
||||
void ParserPrivate::setError(QString errorMsg, int errorLine) {
|
||||
m_error = true;
|
||||
m_errorMsg = errorMsg;
|
||||
m_errorLine = errorLine;
|
||||
}
|
||||
|
||||
void ParserPrivate::reset()
|
||||
{
|
||||
m_error = false;
|
||||
m_errorLine = 0;
|
||||
m_errorMsg.clear();
|
||||
if (m_scanner) {
|
||||
delete m_scanner;
|
||||
m_scanner = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Parser::Parser() :
|
||||
d(new ParserPrivate)
|
||||
{
|
||||
}
|
||||
|
||||
Parser::~Parser()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
QVariant Parser::parse (QIODevice* io, bool* ok)
|
||||
{
|
||||
d->reset();
|
||||
|
||||
if (!io->isOpen()) {
|
||||
if (!io->open(QIODevice::ReadOnly)) {
|
||||
if (ok != 0)
|
||||
*ok = false;
|
||||
qCritical ("Error opening device");
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
if (!io->isReadable()) {
|
||||
if (ok != 0)
|
||||
*ok = false;
|
||||
qCritical ("Device is not readable");
|
||||
io->close();
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if (io->atEnd()) {
|
||||
if (ok != 0)
|
||||
*ok = false;
|
||||
d->setError(QLatin1String("No data"), 0);
|
||||
io->close();
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
d->m_scanner = new JSonScanner (io);
|
||||
d->m_scanner->allowSpecialNumbers(d->m_specialNumbersAllowed);
|
||||
yy::json_parser parser(d);
|
||||
parser.parse();
|
||||
|
||||
delete d->m_scanner;
|
||||
d->m_scanner = 0;
|
||||
|
||||
if (ok != 0)
|
||||
*ok = !d->m_error;
|
||||
|
||||
io->close();
|
||||
return d->m_result;
|
||||
}
|
||||
|
||||
QVariant Parser::parse(const QByteArray& jsonString, bool* ok) {
|
||||
QBuffer buffer;
|
||||
buffer.open(QBuffer::ReadWrite);
|
||||
buffer.write(jsonString);
|
||||
buffer.seek(0);
|
||||
return parse (&buffer, ok);
|
||||
}
|
||||
|
||||
QString Parser::errorString() const
|
||||
{
|
||||
return d->m_errorMsg;
|
||||
}
|
||||
|
||||
int Parser::errorLine() const
|
||||
{
|
||||
return d->m_errorLine;
|
||||
}
|
||||
|
||||
void QJson::Parser::allowSpecialNumbers(bool allowSpecialNumbers) {
|
||||
d->m_specialNumbersAllowed = allowSpecialNumbers;
|
||||
}
|
||||
|
||||
bool Parser::specialNumbersAllowed() const {
|
||||
return d->m_specialNumbersAllowed;
|
||||
}
|
99
src/webui/qjson/parser.h
Normal file
99
src/webui/qjson/parser.h
Normal file
|
@ -0,0 +1,99 @@
|
|||
/* This file is part of QJson
|
||||
*
|
||||
* Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License version 2.1, as published by the Free Software Foundation.
|
||||
*
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef QJSON_PARSER_H
|
||||
#define QJSON_PARSER_H
|
||||
|
||||
#include "qjson_export.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QIODevice;
|
||||
class QVariant;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
/**
|
||||
* Namespace used by QJson
|
||||
*/
|
||||
namespace QJson {
|
||||
|
||||
class ParserPrivate;
|
||||
|
||||
/**
|
||||
* @brief Main class used to convert JSON data to QVariant objects
|
||||
*/
|
||||
class QJSON_EXPORT Parser
|
||||
{
|
||||
public:
|
||||
Parser();
|
||||
~Parser();
|
||||
|
||||
/**
|
||||
* Read JSON string from the I/O Device and converts it to a QVariant object
|
||||
* @param io Input output device
|
||||
* @param ok if a conversion error occurs, *ok is set to false; otherwise *ok is set to true.
|
||||
* @returns a QVariant object generated from the JSON string
|
||||
*/
|
||||
QVariant parse(QIODevice* io, bool* ok = 0);
|
||||
|
||||
/**
|
||||
* This is a method provided for convenience.
|
||||
* @param jsonData data containing the JSON object representation
|
||||
* @param ok if a conversion error occurs, *ok is set to false; otherwise *ok is set to true.
|
||||
* @returns a QVariant object generated from the JSON string
|
||||
* @sa errorString
|
||||
* @sa errorLine
|
||||
*/
|
||||
QVariant parse(const QByteArray& jsonData, bool* ok = 0);
|
||||
|
||||
/**
|
||||
* This method returns the error message
|
||||
* @returns a QString object containing the error message of the last parse operation
|
||||
* @sa errorLine
|
||||
*/
|
||||
QString errorString() const;
|
||||
|
||||
/**
|
||||
* This method returns line number where the error occurred
|
||||
* @returns the line number where the error occurred
|
||||
* @sa errorString
|
||||
*/
|
||||
int errorLine() const;
|
||||
|
||||
/**
|
||||
* Sets whether special numbers (Infinity, -Infinity, NaN) are allowed as an extension to
|
||||
* the standard
|
||||
* @param allowSpecialNumbers new value of whether special numbers are allowed
|
||||
* @sa specialNumbersAllowed
|
||||
*/
|
||||
void allowSpecialNumbers(bool allowSpecialNumbers);
|
||||
|
||||
/**
|
||||
* @returns whether special numbers (Infinity, -Infinity, NaN) are allowed
|
||||
* @sa allowSpecialNumbers
|
||||
*/
|
||||
bool specialNumbersAllowed() const;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(Parser)
|
||||
ParserPrivate* const d;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // QJSON_PARSER_H
|
57
src/webui/qjson/parser_p.h
Normal file
57
src/webui/qjson/parser_p.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/* This file is part of QJson
|
||||
*
|
||||
* Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com>
|
||||
* Copyright (C) 2009 Michael Leupold <lemma@confuego.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License version 2.1, as published by the Free Software Foundation.
|
||||
*
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef QJSON_PARSER_P_H
|
||||
#define QJSON_PARSER_P_H
|
||||
|
||||
#include "parser.h"
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QVariant>
|
||||
|
||||
class JSonScanner;
|
||||
|
||||
namespace yy {
|
||||
class json_parser;
|
||||
}
|
||||
|
||||
namespace QJson {
|
||||
|
||||
class ParserPrivate
|
||||
{
|
||||
public:
|
||||
ParserPrivate();
|
||||
~ParserPrivate();
|
||||
|
||||
void reset();
|
||||
|
||||
void setError(QString errorMsg, int line);
|
||||
|
||||
JSonScanner* m_scanner;
|
||||
bool m_error;
|
||||
int m_errorLine;
|
||||
QString m_errorMsg;
|
||||
QVariant m_result;
|
||||
bool m_specialNumbersAllowed;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // QJSON_PARSER_H
|
172
src/webui/qjson/position.hh
Normal file
172
src/webui/qjson/position.hh
Normal file
|
@ -0,0 +1,172 @@
|
|||
/* A Bison parser, made by GNU Bison 2.7. */
|
||||
|
||||
/* Positions for Bison parsers in C++
|
||||
|
||||
Copyright (C) 2002-2007, 2009-2012 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
/**
|
||||
** \file position.hh
|
||||
** Define the yy::position class.
|
||||
*/
|
||||
|
||||
#ifndef YY_YY_POSITION_HH_INCLUDED
|
||||
# define YY_YY_POSITION_HH_INCLUDED
|
||||
|
||||
# include <algorithm> // std::max
|
||||
# include <iostream>
|
||||
# include <string>
|
||||
|
||||
# ifndef YY_NULL
|
||||
# if defined __cplusplus && 201103L <= __cplusplus
|
||||
# define YY_NULL nullptr
|
||||
# else
|
||||
# define YY_NULL 0
|
||||
# endif
|
||||
# endif
|
||||
|
||||
|
||||
namespace yy {
|
||||
/* Line 36 of location.cc */
|
||||
#line 57 "position.hh"
|
||||
/// Abstract a position.
|
||||
class position
|
||||
{
|
||||
public:
|
||||
|
||||
/// Construct a position.
|
||||
explicit position (std::string* f = YY_NULL,
|
||||
unsigned int l = 1u,
|
||||
unsigned int c = 1u)
|
||||
: filename (f)
|
||||
, line (l)
|
||||
, column (c)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// Initialization.
|
||||
void initialize (std::string* fn = YY_NULL,
|
||||
unsigned int l = 1u,
|
||||
unsigned int c = 1u)
|
||||
{
|
||||
filename = fn;
|
||||
line = l;
|
||||
column = c;
|
||||
}
|
||||
|
||||
/** \name Line and Column related manipulators
|
||||
** \{ */
|
||||
/// (line related) Advance to the COUNT next lines.
|
||||
void lines (int count = 1)
|
||||
{
|
||||
column = 1u;
|
||||
line += count;
|
||||
}
|
||||
|
||||
/// (column related) Advance to the COUNT next columns.
|
||||
void columns (int count = 1)
|
||||
{
|
||||
column = std::max (1u, column + count);
|
||||
}
|
||||
/** \} */
|
||||
|
||||
/// File name to which this position refers.
|
||||
std::string* filename;
|
||||
/// Current line number.
|
||||
unsigned int line;
|
||||
/// Current column number.
|
||||
unsigned int column;
|
||||
};
|
||||
|
||||
/// Add and assign a position.
|
||||
inline position&
|
||||
operator+= (position& res, const int width)
|
||||
{
|
||||
res.columns (width);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Add two position objects.
|
||||
inline const position
|
||||
operator+ (const position& begin, const int width)
|
||||
{
|
||||
position res = begin;
|
||||
return res += width;
|
||||
}
|
||||
|
||||
/// Add and assign a position.
|
||||
inline position&
|
||||
operator-= (position& res, const int width)
|
||||
{
|
||||
return res += -width;
|
||||
}
|
||||
|
||||
/// Add two position objects.
|
||||
inline const position
|
||||
operator- (const position& begin, const int width)
|
||||
{
|
||||
return begin + -width;
|
||||
}
|
||||
|
||||
/// Compare two position objects.
|
||||
inline bool
|
||||
operator== (const position& pos1, const position& pos2)
|
||||
{
|
||||
return (pos1.line == pos2.line
|
||||
&& pos1.column == pos2.column
|
||||
&& (pos1.filename == pos2.filename
|
||||
|| (pos1.filename && pos2.filename
|
||||
&& *pos1.filename == *pos2.filename)));
|
||||
}
|
||||
|
||||
/// Compare two position objects.
|
||||
inline bool
|
||||
operator!= (const position& pos1, const position& pos2)
|
||||
{
|
||||
return !(pos1 == pos2);
|
||||
}
|
||||
|
||||
/** \brief Intercept output stream redirection.
|
||||
** \param ostr the destination output stream
|
||||
** \param pos a reference to the position to redirect
|
||||
*/
|
||||
template <typename YYChar>
|
||||
inline std::basic_ostream<YYChar>&
|
||||
operator<< (std::basic_ostream<YYChar>& ostr, const position& pos)
|
||||
{
|
||||
if (pos.filename)
|
||||
ostr << *pos.filename << ':';
|
||||
return ostr << pos.line << '.' << pos.column;
|
||||
}
|
||||
|
||||
|
||||
} // yy
|
||||
/* Line 148 of location.cc */
|
||||
#line 172 "position.hh"
|
||||
#endif /* !YY_YY_POSITION_HH_INCLUDED */
|
19
src/webui/qjson/qjson.pri
Normal file
19
src/webui/qjson/qjson.pri
Normal file
|
@ -0,0 +1,19 @@
|
|||
INCLUDEPATH += $$PWD
|
||||
|
||||
HEADERS += $$PWD/FlexLexer.h \
|
||||
$$PWD/stack.hh \
|
||||
$$PWD/position.hh \
|
||||
$$PWD/location.hh \
|
||||
$$PWD/json_parser.hh \
|
||||
$$PWD/json_scanner.h \
|
||||
$$PWD/parser.h \
|
||||
$$PWD/parser_p.h \
|
||||
$$PWD_debug.h \
|
||||
$$PWD_export.h \
|
||||
$$PWD/serializer.h
|
||||
|
||||
SOURCES += $$PWD/json_parser.cc \
|
||||
$$PWD/json_scanner.cc \
|
||||
$$PWD/json_scanner.cpp \
|
||||
$$PWD/parser.cpp \
|
||||
$$PWD/serializer.cpp
|
34
src/webui/qjson/qjson_debug.h
Normal file
34
src/webui/qjson/qjson_debug.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/* This file is part of qjson
|
||||
*
|
||||
* Copyright (C) 2009 Michael Leupold <lemma@confuego.org>
|
||||
* Copyright (C) 2013 Silvio Moioli <silvio@moioli.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License version 2.1, as published by the Free Software Foundation.
|
||||
*
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef QJSON_DEBUG_H
|
||||
#define QJSON_DEBUG_H
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
// define qjsonDebug()
|
||||
#ifdef QJSON_VERBOSE_DEBUG_OUTPUT
|
||||
inline QDebug qjsonDebug() { return QDebug(QtDebugMsg); }
|
||||
#else
|
||||
#define qjsonDebug() if(false) QDebug(QtDebugMsg)
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Bittorrent Client using Qt4 and libtorrent.
|
||||
* Copyright (C) 2006-2012 Ishan Arora and Christophe Dumez
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2014 Vladimir Golovnev
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -25,20 +25,13 @@
|
|||
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||
* exception statement from your version.
|
||||
*
|
||||
* Contact : chris@qbittorrent.org
|
||||
* Contact : glassez@yandex.ru
|
||||
*/
|
||||
|
||||
#ifndef QJSON_EXPORT_H
|
||||
#define QJSON_EXPORT_H
|
||||
|
||||
#ifndef JSON_H
|
||||
#define JSON_H
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
namespace json {
|
||||
|
||||
QString toJson(const QVariant& v);
|
||||
QVariantMap fromJson(const QString& json);
|
||||
|
||||
} // namespace json
|
||||
#include <qglobal.h>
|
||||
#define QJSON_EXPORT
|
||||
|
||||
#endif
|
444
src/webui/qjson/serializer.cpp
Normal file
444
src/webui/qjson/serializer.cpp
Normal file
|
@ -0,0 +1,444 @@
|
|||
/* This file is part of qjson
|
||||
*
|
||||
* Copyright (C) 2009 Till Adam <adam@kde.org>
|
||||
* Copyright (C) 2009 Flavio Castelli <flavio@castelli.name>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License version 2.1, as published by the Free Software Foundation.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "serializer.h"
|
||||
|
||||
#include <QtCore/QDataStream>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVariant>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#ifdef Q_OS_SOLARIS
|
||||
# ifndef isinf
|
||||
# include <ieeefp.h>
|
||||
# define isinf(x) (!finite((x)) && (x)==(x))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER // using MSVC compiler
|
||||
#include <float.h>
|
||||
#endif
|
||||
|
||||
using namespace QJson;
|
||||
|
||||
class Serializer::SerializerPrivate {
|
||||
public:
|
||||
SerializerPrivate() :
|
||||
specialNumbersAllowed(false),
|
||||
indentMode(QJson::IndentNone),
|
||||
doublePrecision(6) {
|
||||
errorMessage.clear();
|
||||
}
|
||||
QString errorMessage;
|
||||
bool specialNumbersAllowed;
|
||||
IndentMode indentMode;
|
||||
int doublePrecision;
|
||||
QByteArray buildIndent(int spaces);
|
||||
QByteArray serialize( const QVariant &v, bool *ok, int indentLevel = 0);
|
||||
QString sanitizeString( QString str );
|
||||
QByteArray join( const QList<QByteArray>& list, const QByteArray& sep );
|
||||
};
|
||||
|
||||
QByteArray Serializer::SerializerPrivate::join( const QList<QByteArray>& list, const QByteArray& sep ) {
|
||||
QByteArray res;
|
||||
Q_FOREACH( const QByteArray& i, list ) {
|
||||
if ( !res.isEmpty() )
|
||||
res += sep;
|
||||
res += i;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
QByteArray Serializer::SerializerPrivate::serialize( const QVariant &v, bool *ok, int indentLevel)
|
||||
{
|
||||
QByteArray str;
|
||||
|
||||
if ( ! v.isValid() ) { // invalid or null?
|
||||
str = "null";
|
||||
} else if (( v.type() == QVariant::List ) || ( v.type() == QVariant::StringList )){ // an array or a stringlist?
|
||||
const QVariantList list = v.toList();
|
||||
QList<QByteArray> values;
|
||||
Q_FOREACH( const QVariant& var, list )
|
||||
{
|
||||
QByteArray serializedValue;
|
||||
|
||||
serializedValue = serialize( var, ok, indentLevel+1);
|
||||
|
||||
if ( !*ok ) {
|
||||
break;
|
||||
}
|
||||
switch(indentMode) {
|
||||
case QJson::IndentFull :
|
||||
case QJson::IndentMedium :
|
||||
case QJson::IndentMinimum :
|
||||
values << serializedValue;
|
||||
break;
|
||||
case QJson::IndentCompact :
|
||||
case QJson::IndentNone :
|
||||
default:
|
||||
values << serializedValue.trimmed();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (indentMode == QJson::IndentMedium || indentMode == QJson::IndentFull ) {
|
||||
QByteArray indent = buildIndent(indentLevel);
|
||||
str = indent + "[\n" + join( values, ",\n" ) + "\n" + indent + "]";
|
||||
}
|
||||
else if (indentMode == QJson::IndentMinimum) {
|
||||
QByteArray indent = buildIndent(indentLevel);
|
||||
str = indent + "[\n" + join( values, ",\n" ) + "\n" + indent + "]";
|
||||
}
|
||||
else if (indentMode == QJson::IndentCompact) {
|
||||
str = "[" + join( values, "," ) + "]";
|
||||
}
|
||||
else {
|
||||
str = "[ " + join( values, ", " ) + " ]";
|
||||
}
|
||||
|
||||
} else if ( v.type() == QVariant::Map ) { // variant is a map?
|
||||
const QVariantMap vmap = v.toMap();
|
||||
QMapIterator<QString, QVariant> it( vmap );
|
||||
|
||||
if (indentMode == QJson::IndentMinimum) {
|
||||
QByteArray indent = buildIndent(indentLevel);
|
||||
str = indent + "{ ";
|
||||
}
|
||||
else if (indentMode == QJson::IndentMedium || indentMode == QJson::IndentFull) {
|
||||
QByteArray indent = buildIndent(indentLevel);
|
||||
QByteArray nextindent = buildIndent(indentLevel + 1);
|
||||
str = indent + "{\n" + nextindent;
|
||||
}
|
||||
else if (indentMode == QJson::IndentCompact) {
|
||||
str = "{";
|
||||
}
|
||||
else {
|
||||
str = "{ ";
|
||||
}
|
||||
|
||||
QList<QByteArray> pairs;
|
||||
while ( it.hasNext() ) {
|
||||
it.next();
|
||||
indentLevel++;
|
||||
QByteArray serializedValue = serialize( it.value(), ok, indentLevel);
|
||||
indentLevel--;
|
||||
if ( !*ok ) {
|
||||
break;
|
||||
}
|
||||
QByteArray key = sanitizeString( it.key() ).toUtf8();
|
||||
QByteArray value = serializedValue.trimmed();
|
||||
if (indentMode == QJson::IndentCompact) {
|
||||
pairs << key + ":" + value;
|
||||
} else {
|
||||
pairs << key + " : " + value;
|
||||
}
|
||||
}
|
||||
|
||||
if (indentMode == QJson::IndentFull) {
|
||||
QByteArray indent = buildIndent(indentLevel + 1);
|
||||
str += join( pairs, ",\n" + indent);
|
||||
}
|
||||
else if (indentMode == QJson::IndentCompact) {
|
||||
str += join( pairs, "," );
|
||||
}
|
||||
else {
|
||||
str += join( pairs, ", " );
|
||||
}
|
||||
|
||||
if (indentMode == QJson::IndentMedium || indentMode == QJson::IndentFull) {
|
||||
QByteArray indent = buildIndent(indentLevel);
|
||||
str += "\n" + indent + "}";
|
||||
}
|
||||
else if (indentMode == QJson::IndentCompact) {
|
||||
str += "}";
|
||||
}
|
||||
else {
|
||||
str += " }";
|
||||
}
|
||||
|
||||
} else if ( v.type() == QVariant::Hash ) { // variant is a hash?
|
||||
const QVariantHash vhash = v.toHash();
|
||||
QHashIterator<QString, QVariant> it( vhash );
|
||||
|
||||
if (indentMode == QJson::IndentMinimum) {
|
||||
QByteArray indent = buildIndent(indentLevel);
|
||||
str = indent + "{ ";
|
||||
}
|
||||
else if (indentMode == QJson::IndentMedium || indentMode == QJson::IndentFull) {
|
||||
QByteArray indent = buildIndent(indentLevel);
|
||||
QByteArray nextindent = buildIndent(indentLevel + 1);
|
||||
str = indent + "{\n" + nextindent;
|
||||
}
|
||||
else if (indentMode == QJson::IndentCompact) {
|
||||
str = "{";
|
||||
}
|
||||
else {
|
||||
str = "{ ";
|
||||
}
|
||||
|
||||
QList<QByteArray> pairs;
|
||||
while ( it.hasNext() ) {
|
||||
it.next();
|
||||
|
||||
QByteArray serializedValue = serialize( it.value(), ok, indentLevel + 1);
|
||||
|
||||
if ( !*ok ) {
|
||||
break;
|
||||
}
|
||||
QByteArray key = sanitizeString( it.key() ).toUtf8();
|
||||
QByteArray value = serializedValue.trimmed();
|
||||
if (indentMode == QJson::IndentCompact) {
|
||||
pairs << key + ":" + value;
|
||||
} else {
|
||||
pairs << key + " : " + value;
|
||||
}
|
||||
}
|
||||
|
||||
if (indentMode == QJson::IndentFull) {
|
||||
QByteArray indent = buildIndent(indentLevel + 1);
|
||||
str += join( pairs, ",\n" + indent);
|
||||
}
|
||||
else if (indentMode == QJson::IndentCompact) {
|
||||
str += join( pairs, "," );
|
||||
}
|
||||
else {
|
||||
str += join( pairs, ", " );
|
||||
}
|
||||
|
||||
if (indentMode == QJson::IndentMedium || indentMode == QJson::IndentFull) {
|
||||
QByteArray indent = buildIndent(indentLevel);
|
||||
str += "\n" + indent + "}";
|
||||
}
|
||||
else if (indentMode == QJson::IndentCompact) {
|
||||
str += "}";
|
||||
}
|
||||
else {
|
||||
str += " }";
|
||||
}
|
||||
|
||||
} else {
|
||||
// Add indent, we may need to remove it later for some layouts
|
||||
switch(indentMode) {
|
||||
case QJson::IndentFull :
|
||||
case QJson::IndentMedium :
|
||||
case QJson::IndentMinimum :
|
||||
str += buildIndent(indentLevel);
|
||||
break;
|
||||
case QJson::IndentCompact :
|
||||
case QJson::IndentNone :
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (( v.type() == QVariant::String ) || ( v.type() == QVariant::ByteArray )) { // a string or a byte array?
|
||||
str = sanitizeString( v.toString() ).toUtf8();
|
||||
} else if (( v.type() == QVariant::Double) || ((QMetaType::Type)v.type() == QMetaType::Float)) { // a double or a float?
|
||||
const double value = v.toDouble();
|
||||
#if defined _WIN32 && !defined(Q_OS_SYMBIAN)
|
||||
const bool special = _isnan(value) || !_finite(value);
|
||||
#elif defined(Q_OS_SYMBIAN) || defined(Q_OS_ANDROID) || defined(Q_OS_BLACKBERRY) || defined(Q_OS_SOLARIS)
|
||||
const bool special = isnan(value) || isinf(value);
|
||||
#else
|
||||
const bool special = std::isnan(value) || std::isinf(value);
|
||||
#endif
|
||||
if (special) {
|
||||
if (specialNumbersAllowed) {
|
||||
#if defined _WIN32 && !defined(Q_OS_SYMBIAN)
|
||||
if (_isnan(value)) {
|
||||
#elif defined(Q_OS_SYMBIAN) || defined(Q_OS_ANDROID) || defined(Q_OS_BLACKBERRY) || defined(Q_OS_SOLARIS)
|
||||
if (isnan(value)) {
|
||||
#else
|
||||
if (std::isnan(value)) {
|
||||
#endif
|
||||
str += "NaN";
|
||||
} else {
|
||||
if (value<0) {
|
||||
str += '-';
|
||||
}
|
||||
str += "Infinity";
|
||||
}
|
||||
} else {
|
||||
errorMessage += QLatin1String("Attempt to write NaN or infinity, which is not supported by json\n");
|
||||
*ok = false;
|
||||
}
|
||||
} else {
|
||||
str = QByteArray::number( value , 'g', doublePrecision);
|
||||
if( ! str.contains( "." ) && ! str.contains( "e" ) ) {
|
||||
str += ".0";
|
||||
}
|
||||
}
|
||||
} else if ( v.type() == QVariant::Bool ) { // boolean value?
|
||||
str += ( v.toBool() ? "true" : "false" );
|
||||
} else if ( v.type() == QVariant::ULongLong ) { // large unsigned number?
|
||||
str += QByteArray::number( v.value<qulonglong>() );
|
||||
} else if ( v.type() == QVariant::UInt ) { // unsigned int number?
|
||||
str += QByteArray::number( v.value<quint32>() );
|
||||
} else if ( v.canConvert<qlonglong>() ) { // any signed number?
|
||||
str += QByteArray::number( v.value<qlonglong>() );
|
||||
} else if ( v.canConvert<int>() ) { // unsigned short number?
|
||||
str += QByteArray::number( v.value<int>() );
|
||||
} else if ( v.canConvert<QString>() ){ // can value be converted to string?
|
||||
// this will catch QDate, QDateTime, QUrl, ...
|
||||
str += sanitizeString( v.toString() ).toUtf8();
|
||||
//TODO: catch other values like QImage, QRect, ...
|
||||
} else {
|
||||
*ok = false;
|
||||
errorMessage += QLatin1String("Cannot serialize ");
|
||||
errorMessage += v.toString();
|
||||
errorMessage += QLatin1String(" because type ");
|
||||
errorMessage += QLatin1String(v.typeName());
|
||||
errorMessage += QLatin1String(" is not supported by QJson\n");
|
||||
}
|
||||
}
|
||||
if ( *ok )
|
||||
{
|
||||
return str;
|
||||
}
|
||||
else
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
QByteArray Serializer::SerializerPrivate::buildIndent(int spaces)
|
||||
{
|
||||
QByteArray indent;
|
||||
if (spaces < 0) {
|
||||
spaces = 0;
|
||||
}
|
||||
for (int i = 0; i < spaces; i++ ) {
|
||||
indent += " ";
|
||||
}
|
||||
return indent;
|
||||
}
|
||||
|
||||
QString Serializer::SerializerPrivate::sanitizeString( QString str )
|
||||
{
|
||||
str.replace( QLatin1String( "\\" ), QLatin1String( "\\\\" ) );
|
||||
|
||||
// escape unicode chars
|
||||
QString result;
|
||||
const ushort* unicode = str.utf16();
|
||||
unsigned int i = 0;
|
||||
|
||||
while ( unicode[ i ] ) {
|
||||
if ( unicode[ i ] < 128 ) {
|
||||
result.append( QChar( unicode[ i ] ) );
|
||||
}
|
||||
else {
|
||||
QString hexCode = QString::number( unicode[ i ], 16 ).rightJustified( 4,
|
||||
QLatin1Char('0') );
|
||||
|
||||
result.append( QLatin1String ("\\u") ).append( hexCode );
|
||||
}
|
||||
++i;
|
||||
}
|
||||
str = result;
|
||||
|
||||
str.replace( QLatin1String( "\"" ), QLatin1String( "\\\"" ) );
|
||||
str.replace( QLatin1String( "\b" ), QLatin1String( "\\b" ) );
|
||||
str.replace( QLatin1String( "\f" ), QLatin1String( "\\f" ) );
|
||||
str.replace( QLatin1String( "\n" ), QLatin1String( "\\n" ) );
|
||||
str.replace( QLatin1String( "\r" ), QLatin1String( "\\r" ) );
|
||||
str.replace( QLatin1String( "\t" ), QLatin1String( "\\t" ) );
|
||||
|
||||
return QString( QLatin1String( "\"%1\"" ) ).arg( str );
|
||||
}
|
||||
|
||||
Serializer::Serializer()
|
||||
: d( new SerializerPrivate )
|
||||
{
|
||||
}
|
||||
|
||||
Serializer::~Serializer() {
|
||||
delete d;
|
||||
}
|
||||
|
||||
void Serializer::serialize( const QVariant& v, QIODevice* io, bool* ok)
|
||||
{
|
||||
Q_ASSERT( io );
|
||||
*ok = true;
|
||||
|
||||
if (!io->isOpen()) {
|
||||
if (!io->open(QIODevice::WriteOnly)) {
|
||||
d->errorMessage = QLatin1String("Error opening device");
|
||||
*ok = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!io->isWritable()) {
|
||||
d->errorMessage = QLatin1String("Device is not readable");
|
||||
io->close();
|
||||
*ok = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const QByteArray str = serialize( v, ok);
|
||||
if (*ok && (io->write(str) != str.count())) {
|
||||
*ok = false;
|
||||
d->errorMessage = QLatin1String("Something went wrong while writing to IO device");
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray Serializer::serialize( const QVariant &v)
|
||||
{
|
||||
bool ok;
|
||||
|
||||
return serialize(v, &ok);
|
||||
}
|
||||
|
||||
QByteArray Serializer::serialize( const QVariant &v, bool *ok)
|
||||
{
|
||||
bool _ok = true;
|
||||
d->errorMessage.clear();
|
||||
|
||||
if (ok) {
|
||||
*ok = true;
|
||||
} else {
|
||||
ok = &_ok;
|
||||
}
|
||||
|
||||
return d->serialize(v, ok);
|
||||
}
|
||||
|
||||
void QJson::Serializer::allowSpecialNumbers(bool allow) {
|
||||
d->specialNumbersAllowed = allow;
|
||||
}
|
||||
|
||||
bool QJson::Serializer::specialNumbersAllowed() const {
|
||||
return d->specialNumbersAllowed;
|
||||
}
|
||||
|
||||
void QJson::Serializer::setIndentMode(IndentMode mode) {
|
||||
d->indentMode = mode;
|
||||
}
|
||||
|
||||
void QJson::Serializer::setDoublePrecision(int precision) {
|
||||
d->doublePrecision = precision;
|
||||
}
|
||||
|
||||
IndentMode QJson::Serializer::indentMode() const {
|
||||
return d->indentMode;
|
||||
}
|
||||
|
||||
QString QJson::Serializer::errorMessage() const {
|
||||
return d->errorMessage;
|
||||
}
|
||||
|
230
src/webui/qjson/serializer.h
Normal file
230
src/webui/qjson/serializer.h
Normal file
|
@ -0,0 +1,230 @@
|
|||
/* This file is part of qjson
|
||||
*
|
||||
* Copyright (C) 2009 Till Adam <adam@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License version 2.1, as published by the Free Software Foundation.
|
||||
*
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef QJSON_SERIALIZER_H
|
||||
#define QJSON_SERIALIZER_H
|
||||
|
||||
#include "qjson_export.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QIODevice;
|
||||
class QString;
|
||||
class QVariant;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace QJson {
|
||||
/**
|
||||
@brief How the indentation should work.
|
||||
\verbatim
|
||||
none (default) :
|
||||
{ "foo" : 0, "foo1" : 1, "foo2" : [ { "bar" : 1, "foo" : 0, "foobar" : 0 }, { "bar" : 1, "foo" : 1, "foobar" : 1 } ], "foo3" : [ 1, 2, 3, 4, 5, 6 ] }
|
||||
|
||||
compact :
|
||||
{"foo":0,"foo1":1,"foo2":[{"bar":1,"foo":0,"foobar":0},{"bar":1,"foo":1,"foobar":1}],"foo3":[1,2,3,4,5,6]}
|
||||
|
||||
minimum :
|
||||
{ "foo" : 0, "foo1" : 1, "foo2" : [
|
||||
{ "bar" : 1, "foo" : 0, "foobar" : 0 },
|
||||
{ "bar" : 1, "foo" : 1, "foobar" : 1 }
|
||||
], "foo3" : [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6
|
||||
] }
|
||||
|
||||
medium :
|
||||
{
|
||||
"foo" : 0, "foo1" : 1, "foo2" : [
|
||||
{
|
||||
"bar" : 1, "foo" : 0, "foobar" : 0
|
||||
},
|
||||
{
|
||||
"bar" : 1, "foo" : 1, "foobar" : 1
|
||||
}
|
||||
], "foo3" : [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6
|
||||
]
|
||||
}
|
||||
|
||||
full :
|
||||
{
|
||||
"foo" : 0,
|
||||
"foo1" : 1,
|
||||
"foo2" : [
|
||||
{
|
||||
"bar" : 1,
|
||||
"foo" : 0,
|
||||
"foobar" : 0
|
||||
},
|
||||
{
|
||||
"bar" : 1,
|
||||
"foo" : 1,
|
||||
"foobar" : 1
|
||||
}
|
||||
],
|
||||
"foo3" : [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
\endverbatim
|
||||
*/
|
||||
enum IndentMode {
|
||||
IndentNone,
|
||||
IndentCompact,
|
||||
IndentMinimum,
|
||||
IndentMedium,
|
||||
IndentFull
|
||||
};
|
||||
/**
|
||||
* @brief Main class used to convert QVariant objects to JSON data.
|
||||
*
|
||||
* QVariant objects are converted to a string containing the JSON data.
|
||||
*
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* \code
|
||||
* QVariantList people;
|
||||
*
|
||||
* QVariantMap bob;
|
||||
* bob.insert("Name", "Bob");
|
||||
* bob.insert("Phonenumber", 123);
|
||||
*
|
||||
* QVariantMap alice;
|
||||
* alice.insert("Name", "Alice");
|
||||
* alice.insert("Phonenumber", 321);
|
||||
*
|
||||
* people << bob << alice;
|
||||
*
|
||||
* QJson::Serializer serializer;
|
||||
* bool ok;
|
||||
* QByteArray json = serializer.serialize(people, &ok);
|
||||
*
|
||||
* if (ok) {
|
||||
* qDebug() << json;
|
||||
* } else {
|
||||
* qCritical() << "Something went wrong:" << serializer.errorMessage();
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* The output will be:
|
||||
*
|
||||
* \code
|
||||
* "[ { "Name" : "Bob", "Phonenumber" : 123 },
|
||||
* { "Name" : "Alice", "Phonenumber" : 321 } ]"
|
||||
* \endcode
|
||||
*
|
||||
* It's possible to tune the indentation level of the resulting string. \sa setIndentMode
|
||||
*/
|
||||
class QJSON_EXPORT Serializer {
|
||||
public:
|
||||
Serializer();
|
||||
~Serializer();
|
||||
|
||||
/**
|
||||
* This method generates a textual JSON representation and outputs it to the
|
||||
* passed in I/O Device.
|
||||
* @param variant The JSON document in its in-memory representation as generated by the
|
||||
* parser.
|
||||
* @param out Input output device
|
||||
* @param ok if a conversion error occurs, *ok is set to false; otherwise *ok is set to true
|
||||
*/
|
||||
void serialize( const QVariant& variant, QIODevice* out, bool* ok);
|
||||
|
||||
/**
|
||||
* This is a method provided for convenience. It turns the passed in in-memory
|
||||
* representation of the JSON document into a textual one, which is returned.
|
||||
* If the returned string is empty, the document was empty. If it was null, there
|
||||
* was a parsing error.
|
||||
*
|
||||
* @param variant The JSON document in its in-memory representation as generated by the
|
||||
* parser.
|
||||
*
|
||||
* \deprecated This method is going to be removed with the next major release of QJson.
|
||||
*/
|
||||
QByteArray serialize( const QVariant& variant);
|
||||
|
||||
/**
|
||||
* This is a method provided for convenience. It turns the passed in in-memory
|
||||
* representation of the JSON document into a textual one, which is returned.
|
||||
* If the returned string is empty, the document was empty. If it was null, there
|
||||
* was a parsing error.
|
||||
*
|
||||
* @param variant The JSON document in its in-memory representation as generated by the
|
||||
* parser.
|
||||
* @param ok if a conversion error occurs, *ok is set to false; otherwise *ok is set to true
|
||||
*/
|
||||
QByteArray serialize( const QVariant& variant, bool *ok);
|
||||
|
||||
/**
|
||||
* Allow or disallow writing of NaN and/or Infinity (as an extension to QJson)
|
||||
*/
|
||||
void allowSpecialNumbers(bool allow);
|
||||
|
||||
/**
|
||||
* Is Nan and/or Infinity allowed?
|
||||
*/
|
||||
bool specialNumbersAllowed() const;
|
||||
|
||||
/**
|
||||
* set output indentation mode as defined in QJson::IndentMode
|
||||
*/
|
||||
void setIndentMode(IndentMode mode = QJson::IndentNone);
|
||||
|
||||
|
||||
/**
|
||||
* set double precision used while converting Double
|
||||
* \sa QByteArray::number
|
||||
*/
|
||||
void setDoublePrecision(int precision);
|
||||
|
||||
/**
|
||||
* Returns one of the indentation modes defined in QJson::IndentMode
|
||||
*/
|
||||
IndentMode indentMode() const;
|
||||
|
||||
/**
|
||||
* Returns the error message
|
||||
*/
|
||||
QString errorMessage() const;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(Serializer)
|
||||
class SerializerPrivate;
|
||||
SerializerPrivate* const d;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // QJSON_SERIALIZER_H
|
133
src/webui/qjson/stack.hh
Normal file
133
src/webui/qjson/stack.hh
Normal file
|
@ -0,0 +1,133 @@
|
|||
/* A Bison parser, made by GNU Bison 2.7. */
|
||||
|
||||
/* Stack handling for Bison parsers in C++
|
||||
|
||||
Copyright (C) 2002-2012 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
/**
|
||||
** \file stack.hh
|
||||
** Define the yy::stack class.
|
||||
*/
|
||||
|
||||
#ifndef YY_YY_STACK_HH_INCLUDED
|
||||
# define YY_YY_STACK_HH_INCLUDED
|
||||
|
||||
# include <deque>
|
||||
|
||||
|
||||
namespace yy {
|
||||
/* Line 34 of stack.hh */
|
||||
#line 47 "stack.hh"
|
||||
template <class T, class S = std::deque<T> >
|
||||
class stack
|
||||
{
|
||||
public:
|
||||
// Hide our reversed order.
|
||||
typedef typename S::reverse_iterator iterator;
|
||||
typedef typename S::const_reverse_iterator const_iterator;
|
||||
|
||||
stack () : seq_ ()
|
||||
{
|
||||
}
|
||||
|
||||
stack (unsigned int n) : seq_ (n)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
T&
|
||||
operator [] (unsigned int i)
|
||||
{
|
||||
return seq_[i];
|
||||
}
|
||||
|
||||
inline
|
||||
const T&
|
||||
operator [] (unsigned int i) const
|
||||
{
|
||||
return seq_[i];
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
push (const T& t)
|
||||
{
|
||||
seq_.push_front (t);
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
pop (unsigned int n = 1)
|
||||
{
|
||||
for (; n; --n)
|
||||
seq_.pop_front ();
|
||||
}
|
||||
|
||||
inline
|
||||
unsigned int
|
||||
height () const
|
||||
{
|
||||
return seq_.size ();
|
||||
}
|
||||
|
||||
inline const_iterator begin () const { return seq_.rbegin (); }
|
||||
inline const_iterator end () const { return seq_.rend (); }
|
||||
|
||||
private:
|
||||
S seq_;
|
||||
};
|
||||
|
||||
/// Present a slice of the top of a stack.
|
||||
template <class T, class S = stack<T> >
|
||||
class slice
|
||||
{
|
||||
public:
|
||||
slice (const S& stack, unsigned int range)
|
||||
: stack_ (stack)
|
||||
, range_ (range)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
const T&
|
||||
operator [] (unsigned int i) const
|
||||
{
|
||||
return stack_[range_ - i];
|
||||
}
|
||||
|
||||
private:
|
||||
const S& stack_;
|
||||
unsigned int range_;
|
||||
};
|
||||
|
||||
} // yy
|
||||
/* Line 116 of stack.hh */
|
||||
#line 132 "stack.hh"
|
||||
|
||||
#endif /* !YY_YY_STACK_HH_INCLUDED */
|
|
@ -4,26 +4,26 @@ HEADERS += $$PWD/httpserver.h \
|
|||
$$PWD/httpconnection.h \
|
||||
$$PWD/httprequestparser.h \
|
||||
$$PWD/httpresponsegenerator.h \
|
||||
$$PWD/json.h \
|
||||
$$PWD/jsonlist.h \
|
||||
$$PWD/jsondict.h \
|
||||
$$PWD/btjson.h \
|
||||
$$PWD/prefjson.h \
|
||||
$$PWD/httpheader.h \
|
||||
$$PWD/httprequestheader.h \
|
||||
$$PWD/httpresponseheader.h
|
||||
$$PWD/httpresponseheader.h \
|
||||
$$PWD/jsonutils.h
|
||||
|
||||
SOURCES += $$PWD/httpserver.cpp \
|
||||
$$PWD/httpconnection.cpp \
|
||||
$$PWD/httprequestparser.cpp \
|
||||
$$PWD/httpresponsegenerator.cpp \
|
||||
$$PWD/jsonlist.cpp \
|
||||
$$PWD/jsondict.cpp \
|
||||
$$PWD/btjson.cpp \
|
||||
$$PWD/json.cpp \
|
||||
$$PWD/prefjson.cpp \
|
||||
$$PWD/httpheader.cpp \
|
||||
$$PWD/httprequestheader.cpp \
|
||||
$$PWD/httpresponseheader.cpp
|
||||
|
||||
# QJson JSON parser/serializer for using with Qt4
|
||||
lessThan(QT_MAJOR_VERSION, 5) {
|
||||
include(qjson/qjson.pri)
|
||||
}
|
||||
|
||||
RESOURCES += $$PWD/webui.qrc
|
||||
|
|
Loading…
Reference in a new issue