migrate(Lts/Common): apply clang-tidy modernization fixes\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

This commit is contained in:
torsten committed 2026-07-18 16:48:13 +02:00
1 parent 6822817a63
commit acee7b8766
8 files changed
+377 -729

No files matched your search

+8 -13
View File
@@ -4,24 +4,21 @@
#include <QString> #include <QString>
namespace LtsProjectionWorkstation namespace LtsProjectionWorkstation::JsonKeys {
{
namespace JsonKeys
{
inline QString ERROR_MESSAGE() { return QStringLiteral("errorMessage"); } inline QString ERROR_MESSAGE() { return QStringLiteral("errorMessage"); }
inline QString LOGIN_REQUEST() { return QStringLiteral("loginRequest"); } inline QString LOGIN_REQUEST() { return QStringLiteral("loginRequest"); }
inline QString LOGOUT_REQUEST() { return QStringLiteral("logoutRequest"); } inline QString LOGOUT_REQUEST() { return QStringLiteral("logoutRequest"); }
inline QString DISCONNECT_REQUEST() { return QStringLiteral("disconnectRequest"); } inline QString DISCONNECT_REQUEST() {
return QStringLiteral("disconnectRequest");
}
inline QString LOGIN_REPLY() { return QStringLiteral("loginReply"); } inline QString LOGIN_REPLY() { return QStringLiteral("loginReply"); }
inline QString LOGOUT_REPLY() { return QStringLiteral("logoutReply"); } inline QString LOGOUT_REPLY() { return QStringLiteral("logoutReply"); }
inline QString DEDICAED_DISCONNECT() { return QStringLiteral("dedicatedDisconnect"); } inline QString DEDICAED_DISCONNECT() {
return QStringLiteral("dedicatedDisconnect");
}
inline QString USER_ID() { return QStringLiteral("userId"); } inline QString USER_ID() { return QStringLiteral("userId"); }
inline QString USER_PRIORITY() { return QStringLiteral("userPriority"); } inline QString USER_PRIORITY() { return QStringLiteral("userPriority"); }
@@ -35,6 +32,4 @@ inline QString SUCCESS() { return QStringLiteral("success"); }
inline QString SCREENS() { return QStringLiteral("screens"); } inline QString SCREENS() { return QStringLiteral("screens"); }
inline QString SETTINGS_DATA() { return QStringLiteral("settingsData"); } inline QString SETTINGS_DATA() { return QStringLiteral("settingsData"); }
} } // namespace LtsProjectionWorkstation::JsonKeys
}
+30 -57
View File
@@ -1,102 +1,76 @@
#pragma once #pragma once
#include <QObject>
#include <QMetaObject> #include <QMetaObject>
#include <QObject>
#include <QPointer> #include <QPointer>
#include <QtGlobal> #include <QtGlobal>
#include <type_traits> #include <type_traits>
namespace LtsUtils {
namespace LtsUtils class IConnection {
{
class IConnection
{
public: public:
virtual ~IConnection() = default; virtual ~IConnection() = default;
virtual void connect(Qt::ConnectionType = Qt::AutoConnection) = 0; virtual void connect(Qt::ConnectionType = Qt::AutoConnection) = 0;
virtual void disconnect() = 0; virtual void disconnect() = 0;
}; };
class DummyConnection : public IConnection {
class DummyConnection : public IConnection
{
public: public:
void connect(Qt::ConnectionType = Qt::AutoConnection) override {} void connect(Qt::ConnectionType = Qt::AutoConnection) override {}
void disconnect() override {} void disconnect() override {}
}; };
namespace detail {
namespace detail template <class T> struct ExtractClass;
{
template <class T, class Member> struct ExtractClass<Member T::*> {
template<class T>
struct ExtractClass;
template<class T, class Member>
struct ExtractClass<Member T::*>
{
using type = T; using type = T;
}; };
} } // namespace detail
template <class Signal, class Slot> class Connection : public IConnection {
static_assert(std::is_member_function_pointer_v<Signal>,
"Must be a pointer to method");
template<class Signal, class Slot> static_assert(std::is_member_function_pointer_v<Slot>,
class Connection : public IConnection "Must be a pointer to method");
{
static_assert(std::is_member_function_pointer<Signal>::value, "Must be a pointer to method");
static_assert(std::is_member_function_pointer<Slot>::value, "Must be a pointer to method");
using Emitter = typename detail::ExtractClass<Signal>::type; using Emitter = typename detail::ExtractClass<Signal>::type;
using Target = typename detail::ExtractClass<Slot>::type; using Target = typename detail::ExtractClass<Slot>::type;
static_assert(std::is_base_of<QObject, Emitter>::value, "Must be derived from QObject"); static_assert(std::is_base_of_v<QObject, Emitter>,
static_assert(std::is_base_of<QObject, Target>::value, "Must be derived from QObject"); "Must be derived from QObject");
static_assert(std::is_base_of_v<QObject, Target>,
"Must be derived from QObject");
public: public:
Connection(Emitter *emitter, Signal signal, Target *target, Slot slot): Connection(Emitter *emitter, Signal signal, Target *target, Slot slot)
m_emitter(emitter), : m_emitter(emitter), m_signal(signal), m_target(target), m_slot(slot) {
m_signal(signal),
m_target(target),
m_slot(slot)
{
Q_ASSERT(emitter); Q_ASSERT(emitter);
Q_ASSERT(signal); Q_ASSERT(signal);
Q_ASSERT(target); Q_ASSERT(target);
Q_ASSERT(slot); Q_ASSERT(slot);
} }
void connect(Qt::ConnectionType connectionType = Qt::AutoConnection) override void
{ connect(Qt::ConnectionType connectionType = Qt::AutoConnection) override {
Q_ASSERT(!m_connected); Q_ASSERT(!m_connected);
m_connected = true; m_connected = true;
if (!m_emitter || !m_target) if (!m_emitter || !m_target)
return; return;
m_conn = QObject::connect(m_emitter.data(), m_signal, m_target.data(), m_slot, connectionType); m_conn = QObject::connect(m_emitter.data(), m_signal, m_target.data(),
m_slot, connectionType);
Q_ASSERT(m_conn); Q_ASSERT(m_conn);
} }
void disconnect() override void disconnect() override {
{
Q_ASSERT(m_connected); Q_ASSERT(m_connected);
if (m_conn) if (m_conn)
@@ -114,13 +88,12 @@ private:
QMetaObject::Connection m_conn; QMetaObject::Connection m_conn;
}; };
template <class Signal, class Slot>
Connection<Signal, Slot> *
template<class Signal, class Slot> createConnection(typename detail::ExtractClass<Signal>::type *emitter,
Connection<Signal, Slot>* createConnection(typename detail::ExtractClass<Signal>::type *emitter, Signal signal, Signal signal,
typename detail::ExtractClass<Slot>::type *target, Slot slot) typename detail::ExtractClass<Slot>::type *target, Slot slot) {
{
return new Connection<Signal, Slot>(emitter, signal, target, slot); return new Connection<Signal, Slot>(emitter, signal, target, slot);
} }
} } // namespace LtsUtils
+10 -18
View File
@@ -1,43 +1,35 @@
#pragma once #pragma once
#include <QByteArray> #include <QByteArray>
#include <QString> #include <QString>
namespace LtsUtils namespace LtsUtils {
{
template <typename T, typename S> template <typename T, typename S> inline void convert(const S &in, T &out) {
inline void convert(const S &in, T &out) static_assert(!std::is_same_v<S, T>,
{ "Try to convert a type to the same type - is useless");
static_assert(!std::is_same<S, T>::value, "Try to convert a type to the same type - is useless");
out.reserve(static_cast<int>(in.size())); out.reserve(static_cast<int>(in.size()));
std::copy(in.begin(), in.end(), std::back_inserter(out)); std::copy(in.begin(), in.end(), std::back_inserter(out));
} }
template <typename T, typename S> template <typename T, typename S> inline T convert(const S &in) {
inline T convert(const S &in) static_assert(!std::is_same_v<S, T>,
{ "Try to convert a type to the same type - is useless");
static_assert(!std::is_same<S, T>::value, "Try to convert a type to the same type - is useless");
T out; T out;
convert(in, out); convert(in, out);
return out; return out;
} }
template <typename T> inline QByteArray toQByteArray(const T &in) {
template <typename T>
inline QByteArray toQByteArray(const T &in)
{
return convert<QByteArray>(in); return convert<QByteArray>(in);
} }
template <typename T, typename V = typename T::value_type> template <typename T, typename V = typename T::value_type>
bool isInVector(const T &vec, const V &valueToSearch) bool isInVector(const T &vec, const V &valueToSearch) {
{
const auto end = vec.end(); const auto end = vec.end();
return std::find(vec.begin(), end, valueToSearch) != end; return std::find(vec.begin(), end, valueToSearch) != end;
} }
} } // namespace LtsUtils
+178 -355
View File
@@ -1,6 +1,5 @@
#pragma once #pragma once
#include <QJsonArray> #include <QJsonArray>
@@ -8,140 +7,109 @@
#include <QJsonObject> #include <QJsonObject>
#include <QJsonParseError> #include <QJsonParseError>
#include <QJsonValue> #include <QJsonValue>
#include <QVector>
#include <QMap> #include <QMap>
#include <QString> #include <QString>
#include <string> #include <QVector>
#include <vector>
#include <map>
#include <exception>
#include <cstdint> #include <cstdint>
#include <exception>
#include <limits> #include <limits>
#include <map>
#include <string>
#include <utility>
#include <vector>
namespace LtsUtils namespace LtsUtils {
{
class JsonParseError : public std::runtime_error class JsonParseError : public std::runtime_error {
{
public: public:
JsonParseError(const QJsonParseError &err) JsonParseError(const QJsonParseError &err)
: std::runtime_error("json parse error: " + err.errorString().toStdString() + " - at offset " + std::to_string(err.offset)){} : std::runtime_error(
"json parse error: " + err.errorString().toStdString() +
" - at offset " + std::to_string(err.offset)) {}
}; };
class JsonError : public std::runtime_error class JsonError : public std::runtime_error {
{
public: public:
using std::runtime_error::runtime_error; using std::runtime_error::runtime_error;
}; };
class JsonKeyError : public JsonError class JsonKeyError : public JsonError {
{
public: public:
using JsonError::JsonError; using JsonError::JsonError;
}; };
class JsonRangeError : public JsonError class JsonRangeError : public JsonError {
{
public: public:
using JsonError::JsonError; using JsonError::JsonError;
}; };
class JsonTypeError : public JsonError class JsonTypeError : public JsonError {
{
public: public:
using JsonError::JsonError; using JsonError::JsonError;
}; };
class JsonObject {
class JsonObject
{
public: public:
class Key; class Key;
JsonObject() = default; JsonObject() = default;
explicit JsonObject(const QJsonObject &json) explicit JsonObject(const QJsonObject &json)
: m_json(json) : m_json(json), m_jsonIsSet(true) {}
, m_jsonIsSet(true)
{}
explicit JsonObject(QJsonObject &&json) explicit JsonObject(QJsonObject &&json)
: m_json(std::move(json)) : m_json(std::move(json)), m_jsonIsSet(true) {}
, m_jsonIsSet(true)
{}
static inline JsonObject fromJson(const char *json, int len = -1); static inline JsonObject fromJson(const char *json, int len = -1);
static inline JsonObject fromJson(const QByteArray &json) { return fromJson(json.data(), json.size()); } static inline JsonObject fromJson(const QByteArray &json) {
static inline JsonObject fromJson(const std::string &json) { return fromJson(json.c_str(), json.size()); } return fromJson(json.data(), json.size());
}
static inline JsonObject fromJson(const std::string &json) {
return fromJson(json.c_str(), json.size());
}
static inline JsonObject fromJsonSafe(const char *json, int len = -1) noexcept(false); static inline JsonObject fromJsonSafe(const char *json,
static inline JsonObject fromJsonSafe(const QByteArray &json) noexcept(false) { return fromJsonSafe(json.data(), json.size()); } int len = -1) noexcept(false);
static inline JsonObject fromJsonSafe(const std::string &json) noexcept(false) { return fromJsonSafe(json.c_str(), json.size()); } static inline JsonObject
fromJsonSafe(const QByteArray &json) noexcept(false) {
return fromJsonSafe(json.data(), json.size());
}
static inline JsonObject
fromJsonSafe(const std::string &json) noexcept(false) {
return fromJsonSafe(json.c_str(), json.size());
}
template <class T> [[nodiscard]] bool contains(const Key &key) const;
[[nodiscard]] bool isNull(const Key &key) const {
return contains<void>(key);
}
[[nodiscard]] bool isEmpty() const { return m_json.isEmpty(); }
[[nodiscard]] bool isValid() const { return m_jsonIsSet; }
template<class T> template <class T> T value(const Key &key) const noexcept(false);
bool contains(const Key &key) const;
bool isNull(const Key &key) const { return contains<void>(key); } template <class T>
bool isEmpty() const { return m_json.isEmpty(); }
bool isValid() const { return m_jsonIsSet; }
template<class T>
T value(const Key &key) const noexcept(false);
template<class T>
T valueOr(const Key &key, const T &defaultValue) const noexcept(false); T valueOr(const Key &key, const T &defaultValue) const noexcept(false);
template <class T> [[nodiscard]] bool isMap() const;
template <class T> QMap<QString, T> toMap() const noexcept(false);
template <class T> std::map<std::string, T> toStdMap() const;
template<class T> bool operator==(const JsonObject &other) const {
bool isMap() const; return m_json == other.m_json;
}
template<class T>
QMap<QString, T> toMap() const noexcept(false);
template<class T>
std::map<std::string, T> toStdMap() const;
bool operator==(const JsonObject &other) const { return m_json == other.m_json; }
bool operator!=(const JsonObject &other) const { return !(*this == other); } bool operator!=(const JsonObject &other) const { return !(*this == other); }
class Key class Key {
{
public: public:
Key(const QString &s) Key(QString s) : m_s(std::move(s)) {}
: m_s(s)
{}
Key(const std::string &s) Key(const std::string &s) : m_s(QString::fromStdString(s)) {}
: m_s(QString::fromStdString(s))
{}
Key(const char *s) Key(const char *s) : m_s(QString::fromUtf8(s)) {}
: m_s(QString::fromUtf8(s))
{}
operator const QString &() const { return m_s; } operator const QString &() const { return m_s; }
@@ -150,36 +118,38 @@ public:
}; };
operator const QJsonObject &() const { return m_json; } operator const QJsonObject &() const { return m_json; }
const QJsonObject &object() const { return m_json; } [[nodiscard]] const QJsonObject &object() const { return m_json; }
private: private:
bool containsAny(const QString &key) const { return m_json.contains(key); } [[nodiscard]] bool containsAny(const QString &key) const {
return m_json.contains(key);
}
QJsonObject m_json; QJsonObject m_json;
bool m_jsonIsSet = false; bool m_jsonIsSet = false;
}; };
JsonObject JsonObject::fromJson(const char *json, int len) JsonObject JsonObject::fromJson(const char *json, int len) {
{
if (len < 0) if (len < 0)
len = strlen(json); len = strlen(json);
QJsonParseError error; QJsonParseError error;
const auto doc = QJsonDocument::fromJson(QByteArray::fromRawData(json, len), &error); const auto doc =
QJsonDocument::fromJson(QByteArray::fromRawData(json, len), &error);
if (error.error != QJsonParseError::NoError) if (error.error != QJsonParseError::NoError)
return JsonObject(); return {};
if (!doc.isObject()) if (!doc.isObject())
return JsonObject(); return {};
return JsonObject(doc.object()); return JsonObject(doc.object());
} }
JsonObject JsonObject::fromJsonSafe(const char *json, int len) noexcept(false) JsonObject JsonObject::fromJsonSafe(const char *json, int len) noexcept(false) {
{
if (len < 0) if (len < 0)
len = strlen(json); len = strlen(json);
QJsonParseError error; QJsonParseError error;
const auto doc = QJsonDocument::fromJson(QByteArray::fromRawData(json, len), &error); const auto doc =
QJsonDocument::fromJson(QByteArray::fromRawData(json, len), &error);
if (error.error != QJsonParseError::NoError) if (error.error != QJsonParseError::NoError)
throw JsonParseError(error); throw JsonParseError(error);
@@ -189,106 +159,85 @@ JsonObject JsonObject::fromJsonSafe(const char *json, int len) noexcept(false)
return JsonObject(doc.object()); return JsonObject(doc.object());
} }
class JsonArray {
class JsonArray
{
public: public:
JsonArray() = default; JsonArray() = default;
explicit JsonArray(const QJsonArray &json) explicit JsonArray(const QJsonArray &json)
: m_json(json) : m_json(json), m_jsonIsSet(true) {}
, m_jsonIsSet(true)
{}
explicit JsonArray(QJsonArray &&json) explicit JsonArray(QJsonArray &&json)
: m_json(std::move(json)) : m_json(std::move(json)), m_jsonIsSet(true) {}
, m_jsonIsSet(true)
{}
static inline JsonArray fromJson(const char *json, int len = -1); static inline JsonArray fromJson(const char *json, int len = -1);
static inline JsonArray fromJson(const QByteArray &json) { return fromJson(json.data(), json.size()); } static inline JsonArray fromJson(const QByteArray &json) {
static inline JsonArray fromJson(const std::string &json) { return fromJson(json.c_str(), json.size()); } return fromJson(json.data(), json.size());
}
static inline JsonArray fromJson(const std::string &json) {
return fromJson(json.c_str(), json.size());
}
static inline JsonArray fromJsonSafe(const char *json, int len = -1) noexcept(false); static inline JsonArray fromJsonSafe(const char *json,
static inline JsonArray fromJsonSafe(const QByteArray &json) noexcept(false) { return fromJson(json.data(), json.size()); } int len = -1) noexcept(false);
static inline JsonArray fromJsonSafe(const std::string &json) noexcept(false) { return fromJson(json.c_str(), json.size()); } static inline JsonArray fromJsonSafe(const QByteArray &json) noexcept(false) {
return fromJson(json.data(), json.size());
}
static inline JsonArray
fromJsonSafe(const std::string &json) noexcept(false) {
return fromJson(json.c_str(), json.size());
}
[[nodiscard]] int size() const { return m_json.size(); }
[[nodiscard]] bool isEmpty() const { return m_json.isEmpty(); }
[[nodiscard]] bool isValid() const { return m_jsonIsSet; }
int size() const { return m_json.size(); } template <class T>
bool isEmpty() const { return m_json.isEmpty(); } [[nodiscard]] bool contains(int index) const noexcept(false);
bool isValid() const { return m_jsonIsSet; }
[[nodiscard]] bool isNull(int index) const noexcept(false) {
return contains<void>(index);
}
template<class T> template <class T> T at(int index) const noexcept(false);
bool contains(int index) const noexcept(false);
template <class T> [[nodiscard]] bool isVector() const;
bool isNull(int index) const noexcept(false) { return contains<void>(index); } template <class T> QVector<T> toVector() const noexcept(false);
template <class T> std::vector<T> toStdVector() const;
template<class T> bool operator==(const JsonArray &other) const {
T at(int index) const noexcept(false); return m_json == other.m_json;
}
template<class T>
bool isVector() const;
template<class T>
QVector<T> toVector() const noexcept(false);
template<class T>
std::vector<T> toStdVector() const;
bool operator==(const JsonArray &other) const { return m_json == other.m_json; }
bool operator!=(const JsonArray &other) const { return !(*this == other); } bool operator!=(const JsonArray &other) const { return !(*this == other); }
const QJsonArray &operator()() const { return m_json; } const QJsonArray &operator()() const { return m_json; }
private: private:
QJsonArray m_json; QJsonArray m_json;
bool m_jsonIsSet = false; bool m_jsonIsSet = false;
}; };
JsonArray JsonArray::fromJson(const char *json, int len) JsonArray JsonArray::fromJson(const char *json, int len) {
{
if (len < 0) if (len < 0)
len = strlen(json); len = strlen(json);
QJsonParseError error; QJsonParseError error;
QJsonDocument doc = QJsonDocument::fromJson(QByteArray::fromRawData(json, len), &error); QJsonDocument doc =
QJsonDocument::fromJson(QByteArray::fromRawData(json, len), &error);
if (error.error != QJsonParseError::NoError) if (error.error != QJsonParseError::NoError)
return JsonArray(); return {};
if (!doc.isArray()) if (!doc.isArray())
return JsonArray(); return {};
return JsonArray(doc.array()); return JsonArray(doc.array());
} }
JsonArray JsonArray::fromJsonSafe(const char *json, int len) noexcept(false) JsonArray JsonArray::fromJsonSafe(const char *json, int len) noexcept(false) {
{
if (len < 0) if (len < 0)
len = strlen(json); len = strlen(json);
QJsonParseError error; QJsonParseError error;
const auto doc = QJsonDocument::fromJson(QByteArray::fromRawData(json, len), &error); const auto doc =
QJsonDocument::fromJson(QByteArray::fromRawData(json, len), &error);
if (error.error != QJsonParseError::NoError) if (error.error != QJsonParseError::NoError)
throw JsonParseError(error); throw JsonParseError(error);
@@ -298,47 +247,27 @@ JsonArray JsonArray::fromJsonSafe(const char *json, int len) noexcept(false)
return JsonArray(doc.array()); return JsonArray(doc.array());
} }
template <class T> struct JsonValue;
template <class Int> struct JsonLimits {
template<class T>
struct JsonValue;
template<class Int>
struct JsonLimits
{
static constexpr Int lowest() { return std::numeric_limits<Int>::lowest(); } static constexpr Int lowest() { return std::numeric_limits<Int>::lowest(); }
static constexpr Int max() { return std::numeric_limits<Int>::max(); } static constexpr Int max() { return std::numeric_limits<Int>::max(); }
}; };
template <> struct JsonLimits<int64_t> {
static constexpr int64_t lowest() {
template<> return -(static_cast<int64_t>(1) << 53) + 1;
struct JsonLimits<int64_t> }
{
static constexpr int64_t lowest() { return -(static_cast<int64_t>(1) << 53) + 1; }
static constexpr int64_t max() { return (static_cast<int64_t>(1) << 53) - 1; } static constexpr int64_t max() { return (static_cast<int64_t>(1) << 53) - 1; }
}; };
template <> struct JsonLimits<uint64_t> {
template<>
struct JsonLimits<uint64_t>
{
static constexpr uint64_t lowest() { return 0; } static constexpr uint64_t lowest() { return 0; }
static constexpr uint64_t max() { return JsonLimits<int64_t>::max(); } static constexpr uint64_t max() { return JsonLimits<int64_t>::max(); }
}; };
template <class Int> struct JsonIntValue {
static bool matchesType(const QJsonValue &value) {
template<class Int>
struct JsonIntValue
{
static bool matchesType(const QJsonValue &value)
{
if (!value.isDouble()) if (!value.isDouble())
return false; return false;
double val = value.toDouble(); double val = value.toDouble();
@@ -352,163 +281,103 @@ struct JsonIntValue
return val == wholeInt; return val == wholeInt;
} }
static Int value(const QJsonValue &value) noexcept(false) static Int value(const QJsonValue &value) noexcept(false) {
{
if (!matchesType(value)) if (!matchesType(value))
throw JsonTypeError("JSON value not of type Int"); throw JsonTypeError("JSON value not of type Int");
return static_cast<Int>(value.toDouble()); return static_cast<Int>(value.toDouble());
} }
}; };
template <> struct JsonValue<int16_t> : JsonIntValue<int16_t> {};
template <> struct JsonValue<uint16_t> : JsonIntValue<uint16_t> {};
template <> struct JsonValue<int32_t> : JsonIntValue<int32_t> {};
template<> template <> struct JsonValue<uint32_t> : JsonIntValue<uint32_t> {};
struct JsonValue<int16_t> : JsonIntValue<int16_t>
{};
template<> template <> struct JsonValue<int64_t> : JsonIntValue<int64_t> {};
struct JsonValue<uint16_t> : JsonIntValue<uint16_t>
{};
template<> template <> struct JsonValue<uint64_t> : JsonIntValue<uint64_t> {};
struct JsonValue<int32_t> : JsonIntValue<int32_t>
{};
template<> template <> struct JsonValue<double> {
struct JsonValue<uint32_t> : JsonIntValue<uint32_t>
{};
template<>
struct JsonValue<int64_t> : JsonIntValue<int64_t>
{};
template<>
struct JsonValue<uint64_t> : JsonIntValue<uint64_t>
{};
template<>
struct JsonValue<double>
{
static bool matchesType(const QJsonValue &value) { return value.isDouble(); } static bool matchesType(const QJsonValue &value) { return value.isDouble(); }
static double value(const QJsonValue &value) noexcept(false) static double value(const QJsonValue &value) noexcept(false) {
{
if (!matchesType(value)) if (!matchesType(value))
throw JsonTypeError("JSON value not of type Double"); throw JsonTypeError("JSON value not of type Double");
return value.toDouble(); return value.toDouble();
} }
}; };
template <> struct JsonValue<bool> {
template<>
struct JsonValue<bool>
{
static bool matchesType(const QJsonValue &value) { return value.isBool(); } static bool matchesType(const QJsonValue &value) { return value.isBool(); }
static bool value(const QJsonValue &value) noexcept(false) static bool value(const QJsonValue &value) noexcept(false) {
{
if (!matchesType(value)) if (!matchesType(value))
throw JsonTypeError("JSON value not of type Bool"); throw JsonTypeError("JSON value not of type Bool");
return value.toBool(); return value.toBool();
} }
}; };
template <> struct JsonValue<QString> {
template<>
struct JsonValue<QString>
{
static bool matchesType(const QJsonValue &value) { return value.isString(); } static bool matchesType(const QJsonValue &value) { return value.isString(); }
static QString value(const QJsonValue &value) noexcept(false) static QString value(const QJsonValue &value) noexcept(false) {
{
if (!matchesType(value)) if (!matchesType(value))
throw JsonTypeError("JSON value not of type String"); throw JsonTypeError("JSON value not of type String");
return value.toString(); return value.toString();
} }
}; };
template <> struct JsonValue<std::string> {
template<>
struct JsonValue<std::string>
{
static bool matchesType(const QJsonValue &value) { return value.isString(); } static bool matchesType(const QJsonValue &value) { return value.isString(); }
static std::string value(const QJsonValue &value) static std::string value(const QJsonValue &value) {
{
return JsonValue<QString>::value(value).toStdString(); return JsonValue<QString>::value(value).toStdString();
} }
}; };
template <> struct JsonValue<QJsonObject> {
template<>
struct JsonValue<QJsonObject>
{
static bool matchesType(const QJsonValue &value) { return value.isObject(); } static bool matchesType(const QJsonValue &value) { return value.isObject(); }
static QJsonObject value(const QJsonValue &value) noexcept(false) static QJsonObject value(const QJsonValue &value) noexcept(false) {
{
if (!matchesType(value)) if (!matchesType(value))
throw JsonTypeError("JSON value not of type Object"); throw JsonTypeError("JSON value not of type Object");
return value.toObject(); return value.toObject();
} }
}; };
template <> struct JsonValue<JsonObject> {
template<>
struct JsonValue<JsonObject>
{
static bool matchesType(const QJsonValue &value) { return value.isObject(); } static bool matchesType(const QJsonValue &value) { return value.isObject(); }
static JsonObject value(const QJsonValue &value) { return JsonObject(JsonValue<QJsonObject>::value(value)); } static JsonObject value(const QJsonValue &value) {
return JsonObject(JsonValue<QJsonObject>::value(value));
}
}; };
template <> struct JsonValue<void> {
template<>
struct JsonValue<void>
{
static bool matchesType(const QJsonValue &value) { return value.isNull(); } static bool matchesType(const QJsonValue &value) { return value.isNull(); }
}; };
template <> struct JsonValue<QJsonArray> {
template<>
struct JsonValue<QJsonArray>
{
static bool matchesType(const QJsonValue &value) { return value.isArray(); } static bool matchesType(const QJsonValue &value) { return value.isArray(); }
static QJsonArray value(const QJsonValue &value) noexcept(false) static QJsonArray value(const QJsonValue &value) noexcept(false) {
{
if (!matchesType(value)) if (!matchesType(value))
throw JsonTypeError("JSON value not of type Array"); throw JsonTypeError("JSON value not of type Array");
return value.toArray(); return value.toArray();
} }
}; };
template <> struct JsonValue<JsonArray> {
template<>
struct JsonValue<JsonArray>
{
static bool matchesType(const QJsonValue &value) { return value.isArray(); } static bool matchesType(const QJsonValue &value) { return value.isArray(); }
static JsonArray value(const QJsonValue &value) { return JsonArray(JsonValue<QJsonArray>::value(value)); } static JsonArray value(const QJsonValue &value) {
return JsonArray(JsonValue<QJsonArray>::value(value));
}
}; };
template <class T> struct JsonValue<QVector<T>> {
static bool matchesType(const QJsonValue &value) {
template<class T>
struct JsonValue<QVector<T>>
{
static bool matchesType(const QJsonValue &value)
{
if (!value.isArray()) if (!value.isArray())
return false; return false;
@@ -516,37 +385,25 @@ struct JsonValue<QVector<T>>
return array.isVector<T>(); return array.isVector<T>();
} }
static QVector<T> value(const QJsonValue &value) static QVector<T> value(const QJsonValue &value) {
{
const JsonArray array(JsonValue<QJsonArray>::value(value)); const JsonArray array(JsonValue<QJsonArray>::value(value));
return array.toVector<T>(); return array.toVector<T>();
} }
}; };
template <class T> struct JsonValue<std::vector<T>> {
static bool matchesType(const QJsonValue &value) {
template<class T>
struct JsonValue<std::vector<T>>
{
static bool matchesType(const QJsonValue &value)
{
return JsonValue<QVector<T>>::matchesType(value); return JsonValue<QVector<T>>::matchesType(value);
} }
static std::vector<T> value(const QJsonValue &value) static std::vector<T> value(const QJsonValue &value) {
{
const JsonArray array(JsonValue<QJsonArray>::value(value)); const JsonArray array(JsonValue<QJsonArray>::value(value));
return array.toStdVector<T>(); return array.toStdVector<T>();
} }
}; };
template <class T> struct JsonValue<QMap<QString, T>> {
static bool matchesType(const QJsonValue &value) {
template<class T>
struct JsonValue<QMap<QString, T>>
{
static bool matchesType(const QJsonValue &value)
{
if (!value.isObject()) if (!value.isObject())
return false; return false;
@@ -554,72 +411,53 @@ struct JsonValue<QMap<QString, T>>
return obj.isMap<T>(); return obj.isMap<T>();
} }
static QMap<QString, T> value(const QJsonValue &value) static QMap<QString, T> value(const QJsonValue &value) {
{
const JsonObject obj(JsonValue<QJsonObject>::value(value)); const JsonObject obj(JsonValue<QJsonObject>::value(value));
return obj.toMap<T>(); return obj.toMap<T>();
} }
}; };
template <class T> struct JsonValue<std::map<std::string, T>> {
static bool matchesType(const QJsonValue &value) {
template<class T>
struct JsonValue<std::map<std::string, T>>
{
static bool matchesType(const QJsonValue &value)
{
return JsonValue<QMap<QString, T>>::matchesType(value); return JsonValue<QMap<QString, T>>::matchesType(value);
} }
static std::map<std::string, T> value(const QJsonValue &value) static std::map<std::string, T> value(const QJsonValue &value) {
{
const JsonObject obj(JsonValue<QJsonObject>::value(value)); const JsonObject obj(JsonValue<QJsonObject>::value(value));
return obj.toStdMap<T>(); return obj.toStdMap<T>();
} }
}; };
template <class T> bool JsonObject::contains(const Key &key) const {
template<class T>
bool JsonObject::contains(const Key &key) const
{
if (!m_json.contains(key)) if (!m_json.contains(key))
return false; return false;
return JsonValue<T>::matchesType(m_json.value(key)); return JsonValue<T>::matchesType(m_json.value(key));
} }
template<class T> template <class T> T JsonObject::value(const Key &key) const noexcept(false) {
T JsonObject::value(const Key &key) const noexcept(false)
{
if (!containsAny(key)) if (!containsAny(key))
throw JsonKeyError("no element with key: " + static_cast<const QString &>(key).toStdString()); throw JsonKeyError("no element with key: " +
try static_cast<const QString &>(key).toStdString());
{ try {
return JsonValue<T>::value(m_json.value(key)); return JsonValue<T>::value(m_json.value(key));
} } catch (const JsonTypeError &typeError) {
catch(const JsonTypeError &typeError) throw JsonTypeError(std::string(typeError.what()) + " - key: " +
{ static_cast<const QString &>(key).toStdString());
throw JsonTypeError(std::string(typeError.what()) + " - key: " + static_cast<const QString &>(key).toStdString());
} }
} }
template<class T> template <class T>
T JsonObject::valueOr(const Key &key, const T &defaultValue) const T JsonObject::valueOr(const Key &key, const T &defaultValue) const {
{ try {
try
{
return value<T>(key); return value<T>(key);
} }
catch (const JsonKeyError &) catch (const JsonKeyError &) {
{
return defaultValue; return defaultValue;
} }
} }
template<class T> template <class T> bool JsonObject::isMap() const {
bool JsonObject::isMap() const
{
const QStringList keys = m_json.keys(); const QStringList keys = m_json.keys();
for (const auto &key : keys) for (const auto &key : keys)
if (!JsonValue<T>::matchesType(m_json.value(key))) if (!JsonValue<T>::matchesType(m_json.value(key)))
@@ -628,54 +466,41 @@ bool JsonObject::isMap() const
return true; return true;
} }
template<class T> template <class T> QMap<QString, T> JsonObject::toMap() const {
QMap<QString, T> JsonObject::toMap() const
{
QMap<QString, T> result; QMap<QString, T> result;
for (auto current = m_json.begin(); current != m_json.end(); ++current) for (auto current = m_json.begin(); current != m_json.end(); ++current)
result.insert(current.key(), JsonValue<T>::value(current.value())); result.insert(current.key(), JsonValue<T>::value(current.value()));
return result; return result;
} }
template<class T> template <class T> std::map<std::string, T> JsonObject::toStdMap() const {
std::map<std::string, T> JsonObject::toStdMap() const
{
std::map<std::string, T> result; std::map<std::string, T> result;
for (auto current = m_json.begin(); current != m_json.end(); ++current) for (auto current = m_json.begin(); current != m_json.end(); ++current)
result.insert({current.key().toStdString(), JsonValue<T>::value(current.value())}); result.insert(
{current.key().toStdString(), JsonValue<T>::value(current.value())});
return result; return result;
} }
template <class T> bool JsonArray::contains(int index) const noexcept(false) {
template<class T>
bool JsonArray::contains(int index) const noexcept(false)
{
if (index < 0 || index >= m_json.size()) if (index < 0 || index >= m_json.size())
throw JsonRangeError("index out of range: " + std::to_string(index)); throw JsonRangeError("index out of range: " + std::to_string(index));
return JsonValue<T>::matchesType(m_json.at(index)); return JsonValue<T>::matchesType(m_json.at(index));
} }
template<class T> template <class T> T JsonArray::at(int index) const noexcept(false) {
T JsonArray::at(int index) const noexcept(false)
{
if (index < 0 || index >= m_json.size()) if (index < 0 || index >= m_json.size())
throw JsonRangeError("index out of range: " + std::to_string(index)); throw JsonRangeError("index out of range: " + std::to_string(index));
return JsonValue<T>::value(m_json.at(index)); return JsonValue<T>::value(m_json.at(index));
} }
template<class T> template <class T> bool JsonArray::isVector() const {
bool JsonArray::isVector() const
{
for (const QJsonValue &value : m_json) for (const QJsonValue &value : m_json)
if (!JsonValue<T>::matchesType(value)) if (!JsonValue<T>::matchesType(value))
return false; return false;
return true; return true;
} }
template<class T> template <class T> QVector<T> JsonArray::toVector() const {
QVector<T> JsonArray::toVector() const
{
QVector<T> result; QVector<T> result;
result.reserve(m_json.size()); result.reserve(m_json.size());
for (const QJsonValue &value : m_json) for (const QJsonValue &value : m_json)
@@ -683,9 +508,7 @@ QVector<T> JsonArray::toVector() const
return result; return result;
} }
template<class T> template <class T> std::vector<T> JsonArray::toStdVector() const {
std::vector<T> JsonArray::toStdVector() const
{
std::vector<T> result; std::vector<T> result;
result.reserve(m_json.size()); result.reserve(m_json.size());
for (const QJsonValue &value : m_json) for (const QJsonValue &value : m_json)
@@ -693,4 +516,4 @@ std::vector<T> JsonArray::toStdVector() const
return result; return result;
} }
} } // namespace LtsUtils
+8 -19
View File
@@ -1,45 +1,34 @@
#pragma once #pragma once
#include <QString> #include <QString>
#include <cstdint>
#include <map> #include <map>
#include <vector> #include <vector>
#include <cstdint>
namespace LtsUtils namespace LtsUtils {
{
template<typename T, typename C> template <typename T, typename C> class PgArray {
class PgArray
{
public: public:
using Type = T; using Type = T;
using ContainerType = C; using ContainerType = C;
PgArray() = default; PgArray() = default;
Q_DECL_CONSTEXPR explicit PgArray(const C &data) Q_DECL_CONSTEXPR explicit PgArray(const C &data) : m_data(data) {}
: m_data(data)
{}
Q_DECL_CONSTEXPR C operator()()const Q_DECL_CONSTEXPR C operator()() const { return m_data; }
{
return m_data;
}
QString toPgString() const; [[nodiscard]] QString toPgString() const;
static PgArray fromPgString(const QString &str); static PgArray fromPgString(const QString &str);
private: private:
C m_data; C m_data;
}; };
using IntArray = PgArray<int, std::vector<int>>; using IntArray = PgArray<int, std::vector<int>>;
using BigintArray = PgArray<int64_t, std::vector<int64_t>>; using BigintArray = PgArray<int64_t, std::vector<int64_t>>;
using IntArray2D = PgArray<int, std::map<int, int>>; using IntArray2D = PgArray<int, std::map<int, int>>;
using BigintArray2D = PgArray<int64_t, std::map<int64_t, int64_t>>; using BigintArray2D = PgArray<int64_t, std::map<int64_t, int64_t>>;
} } // namespace LtsUtils
+9 -25
View File
@@ -1,15 +1,10 @@
#pragma once #pragma once
#include <QObject> #include <QObject>
namespace LtsUtils {
namespace LtsUtils class PromiseExample1_Class : public QObject {
{
class PromiseExample1_Class : public QObject
{
Q_OBJECT Q_OBJECT
public: public:
using QObject::QObject; using QObject::QObject;
@@ -22,49 +17,38 @@ signals:
void signalDone2(bool didThisWork, int someNumberThatReturns); void signalDone2(bool didThisWork, int someNumberThatReturns);
}; };
class PromiseExample1 : public QObject {
class PromiseExample1 : public QObject
{
Q_OBJECT Q_OBJECT
public: public:
explicit PromiseExample1(QObject *parent = nullptr); explicit PromiseExample1(QObject *parent = nullptr);
bool isSuccess() const { return m_success; } [[nodiscard]] bool isSuccess() const { return m_success; }
private: private:
bool m_success; bool m_success;
}; };
class PromiseExample2 : public QObject {
class PromiseExample2 : public QObject
{
Q_OBJECT Q_OBJECT
public: public:
explicit PromiseExample2(QObject *parent = nullptr); explicit PromiseExample2(QObject *parent = nullptr);
bool isSuccess() const { return m_success; } [[nodiscard]] bool isSuccess() const { return m_success; }
private: private:
bool m_success; bool m_success;
}; };
class PromiseExample3 : public QObject {
class PromiseExample3 : public QObject
{
Q_OBJECT Q_OBJECT
public: public:
explicit PromiseExample3(QObject *parent = nullptr); explicit PromiseExample3(QObject *parent = nullptr);
bool isSuccess() const { return m_success; } [[nodiscard]] bool isSuccess() const { return m_success; }
private: private:
bool m_success; bool m_success;
bool m_alreadyRejected; bool m_alreadyRejected;
}; };
} // namespace LtsUtils
}
+87 -128
View File
@@ -1,20 +1,15 @@
#pragma once #pragma once
#include <QtCore/QByteArray> #include <QtCore/QByteArray>
#include <limits> #include <limits>
namespace LtsUtils namespace LtsUtils {
{
template <typename T> void inline set8Byte(const T in, QByteArray &out) {
static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
template<typename T> "Only integrals allowed for raw byte accessd");
void inline set8Byte(const T in, QByteArray& out)
{
static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "Only integrals allowed for raw byte accessd");
out += (in & 0xFF00000000000000UL) >> 56; out += (in & 0xFF00000000000000UL) >> 56;
out += (in & 0x00FF000000000000UL) >> 48; out += (in & 0x00FF000000000000UL) >> 48;
out += (in & 0x0000FF0000000000UL) >> 40; out += (in & 0x0000FF0000000000UL) >> 40;
@@ -23,35 +18,31 @@ namespace LtsUtils
out += (in & 0x0000000000FF0000UL) >> 16; out += (in & 0x0000000000FF0000UL) >> 16;
out += (in & 0x000000000000FF00UL) >> 8; out += (in & 0x000000000000FF00UL) >> 8;
out += (in & 0x00000000000000FFUL); out += (in & 0x00000000000000FFUL);
} }
template<> template <> void inline set8Byte(const double in, QByteArray &out) {
void inline set8Byte(const double in, QByteArray &out) union hack {
{
union hack
{
double d; double d;
int64_t i; int64_t i;
} h; } h;
h.d = in; h.d = in;
set8Byte(h.i, out); set8Byte(h.i, out);
} }
template<typename T> template <typename T>
bool inline get8Byte(const QByteArray& baData, bool inline get8Byte(const QByteArray &baData, size_t &pos, T &out) {
size_t &pos, static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
T& out) "Only integrals allowed for raw byte accessd");
{ static_assert(sizeof(T) >= 8,
static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "Only integrals allowed for raw byte accessd"); "sizeof(out) is smaller than 8 bytes - will not fit");
static_assert(sizeof(T) >= 8, "sizeof(out) is smaller than 8 bytes - will not fit");
out = T(); out = T();
if(size_t(baData.size()) < pos + 8) if (size_t(baData.size()) < pos + 8)
return false; return false;
const char *data = baData.data() + pos; const char *data = baData.data() + pos;
if(std::numeric_limits<T>::is_signed) if (std::numeric_limits<T>::is_signed)
out |= static_cast<signed long long>(data[0]) << 56; out |= static_cast<signed long long>(data[0]) << 56;
else else
out |= (data[0] & 0xFFULL) << 56; out |= (data[0] & 0xFFULL) << 56;
@@ -66,16 +57,12 @@ namespace LtsUtils
pos += 8; pos += 8;
return true; return true;
} }
template<> template <>
bool inline get8Byte(const QByteArray& baData, bool inline get8Byte(const QByteArray &baData, size_t &pos, double &out) {
size_t &pos,
double& out)
{
out = 0.; out = 0.;
union hack union hack {
{
double d; double d;
int64_t i; int64_t i;
} h; } h;
@@ -83,48 +70,41 @@ namespace LtsUtils
return false; return false;
out = h.d; out = h.d;
return true; return true;
} }
template<typename T> template <typename T> bool inline get8Byte(const QByteArray &data, T &out) {
bool inline get8Byte(const QByteArray& data, T& out)
{
size_t pos = 0; size_t pos = 0;
return get8Byte(data, pos, out); return get8Byte(data, pos, out);
} }
template <typename T> void inline set4Byte(const T in, QByteArray &out) {
template<typename T> static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
void inline set4Byte(const T in, QByteArray& out) "Only integrals allowed for raw byte accessd");
{
static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "Only integrals allowed for raw byte accessd");
out += (in & 0xFF000000) >> 24; out += (in & 0xFF000000) >> 24;
out += (in & 0x00FF0000) >> 16; out += (in & 0x00FF0000) >> 16;
out += (in & 0x0000FF00) >> 8; out += (in & 0x0000FF00) >> 8;
out += (in & 0x000000FF); out += (in & 0x000000FF);
} }
template<> template <> void inline set4Byte(const double in, QByteArray &out) {
void inline set4Byte(const double in, QByteArray& out)
{
int tmp = qRound(in); int tmp = qRound(in);
return set4Byte(tmp, out); return set4Byte(tmp, out);
} }
template<typename T> template <typename T>
bool inline get4Byte(const QByteArray& baData, bool inline get4Byte(const QByteArray &baData, size_t &pos, T &out) {
size_t &pos, static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
T& out) "Only integrals allowed for raw byte accessd");
{ static_assert(sizeof(T) >= 4,
static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "Only integrals allowed for raw byte accessd"); "sizeof(out) is smaller than 4 bytes - will not fit");
static_assert(sizeof(T) >= 4, "sizeof(out) is smaller than 4 bytes - will not fit");
out = T(); out = T();
if(size_t(baData.size()) < pos + 4) if (size_t(baData.size()) < pos + 4)
return false; return false;
const char *data = baData.data() + pos; const char *data = baData.data() + pos;
if(std::numeric_limits<T>::is_signed) if (std::numeric_limits<T>::is_signed)
out |= data[0] << 24; out |= data[0] << 24;
else else
out |= (data[0] & 0xFFU) << 24; out |= (data[0] & 0xFFU) << 24;
@@ -135,53 +115,45 @@ namespace LtsUtils
pos += 4; pos += 4;
return true; return true;
} }
template<> template <>
bool inline get4Byte(const QByteArray& baData, bool inline get4Byte(const QByteArray &baData, size_t &pos, double &out) {
size_t &pos,
double& out)
{
out = 0.; out = 0.;
int tmp; int tmp;
if(!get4Byte(baData, pos, tmp)) if (!get4Byte(baData, pos, tmp))
return false; return false;
out = tmp; out = tmp;
return true; return true;
} }
template<typename T> template <typename T> bool inline get4Byte(const QByteArray &data, T &out) {
bool inline get4Byte(const QByteArray& data, T& out)
{
size_t pos = 0; size_t pos = 0;
return get4Byte(data, pos, out); return get4Byte(data, pos, out);
} }
template <typename T> void inline set3Byte(const T in, QByteArray &out) {
template<typename T> static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
void inline set3Byte(const T in, QByteArray& out) "Only integrals allowed for raw byte accessd");
{
static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "Only integrals allowed for raw byte accessd");
out += (in & 0x00FF0000) >> 16; out += (in & 0x00FF0000) >> 16;
out += (in & 0x0000FF00) >> 8; out += (in & 0x0000FF00) >> 8;
out += (in & 0x000000FF); out += (in & 0x000000FF);
} }
template<typename T> template <typename T>
bool inline get3Byte(const QByteArray& baData, bool inline get3Byte(const QByteArray &baData, size_t &pos, T &out) {
size_t &pos, static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
T& out) "Only integrals allowed for raw byte accessd");
{ static_assert(sizeof(T) >= 3,
static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "Only integrals allowed for raw byte accessd"); "sizeof(out) is smaller than 3 bytes - will not fit");
static_assert(sizeof(T) >= 3, "sizeof(out) is smaller than 3 bytes - will not fit");
out = T(); out = T();
if(size_t(baData.size()) < pos + 3) if (size_t(baData.size()) < pos + 3)
return false; return false;
const char *data = baData.data() + pos; const char *data = baData.data() + pos;
if(std::numeric_limits<T>::is_signed) if (std::numeric_limits<T>::is_signed)
out |= data[0] << 16; out |= data[0] << 16;
else else
out |= (data[0] & 0xFFU) << 16; out |= (data[0] & 0xFFU) << 16;
@@ -191,39 +163,34 @@ namespace LtsUtils
pos += 3; pos += 3;
return true; return true;
} }
template<typename T> template <typename T> bool inline get3Byte(const QByteArray &data, T &out) {
bool inline get3Byte(const QByteArray& data, T& out)
{
size_t pos = 0; size_t pos = 0;
return get3Byte(data, pos, out); return get3Byte(data, pos, out);
} }
template <typename T> void inline set2Byte(const T in, QByteArray &out) {
template<typename T> static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
void inline set2Byte(const T in, QByteArray& out) "Only integrals allowed for raw byte accessd");
{
static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "Only integrals allowed for raw byte accessd");
out += (in & 0x0000FF00) >> 8; out += (in & 0x0000FF00) >> 8;
out += (in & 0x000000FF); out += (in & 0x000000FF);
} }
template<typename T> template <typename T>
bool inline get2Byte(const QByteArray& baData, bool inline get2Byte(const QByteArray &baData, size_t &pos, T &out) {
size_t &pos, static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
T& out) "Only integrals allowed for raw byte accessd");
{ static_assert(sizeof(T) >= 2,
static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "Only integrals allowed for raw byte accessd"); "sizeof(out) is smaller than 2 bytes - will not fit");
static_assert(sizeof(T) >= 2, "sizeof(out) is smaller than 2 bytes - will not fit");
out = T(); out = T();
if(size_t(baData.size()) < pos + 2) if (size_t(baData.size()) < pos + 2)
return false; return false;
const char *data = baData.data() + pos; const char *data = baData.data() + pos;
if(std::numeric_limits<T>::is_signed) if (std::numeric_limits<T>::is_signed)
out |= data[0] << 8; out |= data[0] << 8;
else else
out |= (data[0] & 0xFFU) << 8; out |= (data[0] & 0xFFU) << 8;
@@ -232,38 +199,32 @@ namespace LtsUtils
pos += 2; pos += 2;
return true; return true;
} }
template<typename T> template <typename T> bool inline get2Byte(const QByteArray &data, T &out) {
bool inline get2Byte(const QByteArray& data, T& out)
{
size_t pos = 0; size_t pos = 0;
return get2Byte(data, pos, out); return get2Byte(data, pos, out);
} }
template <typename T> void inline set1Byte(const T in, QByteArray &out) {
template<typename T> static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
void inline set1Byte(const T in, QByteArray& out) "Only integrals allowed for raw byte accessd");
{
static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "Only integrals allowed for raw byte accessd");
unsigned char c = in; unsigned char c = in;
out += c; out += c;
} }
template<typename T> template <typename T>
bool inline get1Byte(const QByteArray& baData, bool inline get1Byte(const QByteArray &baData, size_t &pos, T &out) {
size_t &pos, static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
T& out) "Only integrals allowed for raw byte accessd");
{
static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "Only integrals allowed for raw byte accessd");
out = T(); out = T();
if(size_t(baData.size()) < pos + 1) if (size_t(baData.size()) < pos + 1)
return false; return false;
const char *data = baData.data() + pos; const char *data = baData.data() + pos;
if(std::numeric_limits<T>::is_signed) if (std::numeric_limits<T>::is_signed)
out = (T)(data[0]); out = (T)(data[0]);
else else
out = (T)(data[0] & 0xFF); out = (T)(data[0] & 0xFF);
@@ -271,12 +232,10 @@ namespace LtsUtils
pos += 1; pos += 1;
return true; return true;
} }
template<typename T> template <typename T> bool inline get1Byte(const QByteArray &data, T &out) {
bool inline get1Byte(const QByteArray& data, T& out)
{
size_t pos = 0; size_t pos = 0;
return get1Byte(data, pos, out); return get1Byte(data, pos, out);
}
} }
} // namespace LtsUtils
+47 -114
View File
@@ -6,14 +6,13 @@
extern "C" { extern "C" {
#endif #endif
#define HTTP_PARSER_VERSION_MAJOR 2 #define HTTP_PARSER_VERSION_MAJOR 2
#define HTTP_PARSER_VERSION_MINOR 9 #define HTTP_PARSER_VERSION_MINOR 9
#define HTTP_PARSER_VERSION_PATCH 4 #define HTTP_PARSER_VERSION_PATCH 4
#include <stddef.h> #include <stddef.h>
#if defined(_WIN32) && !defined(__MINGW32__) && \ #if defined(_WIN32) && !defined(__MINGW32__) && \
(!defined(_MSC_VER) || _MSC_VER<1600) && !defined(__WINE__) (!defined(_MSC_VER) || _MSC_VER < 1600) && !defined(__WINE__)
#include <BaseTsd.h> #include <BaseTsd.h>
typedef __int8 int8_t; typedef __int8 int8_t;
typedef unsigned __int8 uint8_t; typedef unsigned __int8 uint8_t;
@@ -27,28 +26,19 @@ typedef unsigned __int64 uint64_t;
#include <stdint.h> #include <stdint.h>
#endif #endif
#ifndef HTTP_PARSER_STRICT #ifndef HTTP_PARSER_STRICT
# define HTTP_PARSER_STRICT 1 #define HTTP_PARSER_STRICT 1
#endif #endif
#ifndef HTTP_MAX_HEADER_SIZE #ifndef HTTP_MAX_HEADER_SIZE
# define HTTP_MAX_HEADER_SIZE (80*1024) #define HTTP_MAX_HEADER_SIZE (80 * 1024)
#endif #endif
typedef struct http_parser http_parser; using http_parser = struct http_parser;
typedef struct http_parser_settings http_parser_settings; using http_parser_settings = struct http_parser_settings;
typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);
typedef int (*http_cb) (http_parser*);
using http_data_cb = int (*)(http_parser *, const char *, size_t);
using http_cb = int (*)(http_parser *);
#define HTTP_STATUS_MAP(XX) \ #define HTTP_STATUS_MAP(XX) \
XX(100, CONTINUE, Continue) \ XX(100, CONTINUE, Continue) \
@@ -57,11 +47,11 @@ typedef int (*http_cb) (http_parser*);
XX(200, OK, OK) \ XX(200, OK, OK) \
XX(201, CREATED, Created) \ XX(201, CREATED, Created) \
XX(202, ACCEPTED, Accepted) \ XX(202, ACCEPTED, Accepted) \
XX(203, NON_AUTHORITATIVE_INFORMATION, Non-Authoritative Information) \ XX(203, NON_AUTHORITATIVE_INFORMATION, Non - Authoritative Information) \
XX(204, NO_CONTENT, No Content) \ XX(204, NO_CONTENT, No Content) \
XX(205, RESET_CONTENT, Reset Content) \ XX(205, RESET_CONTENT, Reset Content) \
XX(206, PARTIAL_CONTENT, Partial Content) \ XX(206, PARTIAL_CONTENT, Partial Content) \
XX(207, MULTI_STATUS, Multi-Status) \ XX(207, MULTI_STATUS, Multi - Status) \
XX(208, ALREADY_REPORTED, Already Reported) \ XX(208, ALREADY_REPORTED, Already Reported) \
XX(226, IM_USED, IM Used) \ XX(226, IM_USED, IM Used) \
XX(300, MULTIPLE_CHOICES, Multiple Choices) \ XX(300, MULTIPLE_CHOICES, Multiple Choices) \
@@ -109,16 +99,13 @@ typedef int (*http_cb) (http_parser*);
XX(507, INSUFFICIENT_STORAGE, Insufficient Storage) \ XX(507, INSUFFICIENT_STORAGE, Insufficient Storage) \
XX(508, LOOP_DETECTED, Loop Detected) \ XX(508, LOOP_DETECTED, Loop Detected) \
XX(510, NOT_EXTENDED, Not Extended) \ XX(510, NOT_EXTENDED, Not Extended) \
XX(511, NETWORK_AUTHENTICATION_REQUIRED, Network Authentication Required) \ XX(511, NETWORK_AUTHENTICATION_REQUIRED, Network Authentication Required)
enum http_status enum http_status {
{
#define XX(num, name, string) HTTP_STATUS_##name = num, #define XX(num, name, string) HTTP_STATUS_##name = num,
HTTP_STATUS_MAP(XX) HTTP_STATUS_MAP(XX)
#undef XX #undef XX
}; };
#define HTTP_METHOD_MAP(XX) \ #define HTTP_METHOD_MAP(XX) \
XX(0, DELETE, DELETE) \ XX(0, DELETE, DELETE) \
@@ -149,7 +136,7 @@ enum http_status
XX(22, CHECKOUT, CHECKOUT) \ XX(22, CHECKOUT, CHECKOUT) \
XX(23, MERGE, MERGE) \ XX(23, MERGE, MERGE) \
\ \
XX(24, MSEARCH, M-SEARCH) \ XX(24, MSEARCH, M - SEARCH) \
XX(25, NOTIFY, NOTIFY) \ XX(25, NOTIFY, NOTIFY) \
XX(26, SUBSCRIBE, SUBSCRIBE) \ XX(26, SUBSCRIBE, SUBSCRIBE) \
XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \ XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \
@@ -162,40 +149,32 @@ enum http_status
XX(31, LINK, LINK) \ XX(31, LINK, LINK) \
XX(32, UNLINK, UNLINK) \ XX(32, UNLINK, UNLINK) \
\ \
XX(33, SOURCE, SOURCE) \ XX(33, SOURCE, SOURCE)
enum http_method enum http_method {
{
#define XX(num, name, string) HTTP_##name = num, #define XX(num, name, string) HTTP_##name = num,
HTTP_METHOD_MAP(XX) HTTP_METHOD_MAP(XX)
#undef XX #undef XX
}; };
enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH }; enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH };
enum flags {
F_CHUNKED = 1 << 0,
enum flags F_CONNECTION_KEEP_ALIVE = 1 << 1,
{ F_CHUNKED = 1 << 0 F_CONNECTION_CLOSE = 1 << 2,
, F_CONNECTION_KEEP_ALIVE = 1 << 1 F_CONNECTION_UPGRADE = 1 << 3,
, F_CONNECTION_CLOSE = 1 << 2 F_TRAILING = 1 << 4,
, F_CONNECTION_UPGRADE = 1 << 3 F_UPGRADE = 1 << 5,
, F_TRAILING = 1 << 4 F_SKIPBODY = 1 << 6,
, F_UPGRADE = 1 << 5 F_CONTENTLENGTH = 1 << 7,
, F_SKIPBODY = 1 << 6 F_TRANSFER_ENCODING = 1 << 8
, F_CONTENTLENGTH = 1 << 7 };
, F_TRANSFER_ENCODING = 1 << 8
};
#define HTTP_ERRNO_MAP(XX) \ #define HTTP_ERRNO_MAP(XX) \
\ \
XX(OK, "success") \ XX(OK, "success") \
\ \
\
XX(CB_message_begin, "the on_message_begin callback failed") \ XX(CB_message_begin, "the on_message_begin callback failed") \
XX(CB_url, "the on_url callback failed") \ XX(CB_url, "the on_url callback failed") \
XX(CB_header_field, "the on_header_field callback failed") \ XX(CB_header_field, "the on_header_field callback failed") \
@@ -207,10 +186,8 @@ enum flags
XX(CB_chunk_header, "the on_chunk_header callback failed") \ XX(CB_chunk_header, "the on_chunk_header callback failed") \
XX(CB_chunk_complete, "the on_chunk_complete callback failed") \ XX(CB_chunk_complete, "the on_chunk_complete callback failed") \
\ \
\
XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \ XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \
XX(HEADER_OVERFLOW, \ XX(HEADER_OVERFLOW, "too many header bytes seen; overflow detected") \
"too many header bytes seen; overflow detected") \
XX(CLOSED_CONNECTION, \ XX(CLOSED_CONNECTION, \
"data received after completed connection: close message") \ "data received after completed connection: close message") \
XX(INVALID_VERSION, "invalid HTTP version") \ XX(INVALID_VERSION, "invalid HTTP version") \
@@ -224,32 +201,21 @@ enum flags
XX(INVALID_FRAGMENT, "invalid fragment") \ XX(INVALID_FRAGMENT, "invalid fragment") \
XX(LF_EXPECTED, "LF character expected") \ XX(LF_EXPECTED, "LF character expected") \
XX(INVALID_HEADER_TOKEN, "invalid character in header") \ XX(INVALID_HEADER_TOKEN, "invalid character in header") \
XX(INVALID_CONTENT_LENGTH, \ XX(INVALID_CONTENT_LENGTH, "invalid character in content-length header") \
"invalid character in content-length header") \ XX(UNEXPECTED_CONTENT_LENGTH, "unexpected content-length header") \
XX(UNEXPECTED_CONTENT_LENGTH, \ XX(INVALID_CHUNK_SIZE, "invalid character in chunk size header") \
"unexpected content-length header") \
XX(INVALID_CHUNK_SIZE, \
"invalid character in chunk size header") \
XX(INVALID_CONSTANT, "invalid constant string") \ XX(INVALID_CONSTANT, "invalid constant string") \
XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\ XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state") \
XX(STRICT, "strict mode assertion failed") \ XX(STRICT, "strict mode assertion failed") \
XX(PAUSED, "parser is paused") \ XX(PAUSED, "parser is paused") \
XX(UNKNOWN, "an unknown error occurred") \ XX(UNKNOWN, "an unknown error occurred") \
XX(INVALID_TRANSFER_ENCODING, \ XX(INVALID_TRANSFER_ENCODING, "request has invalid transfer-encoding")
"request has invalid transfer-encoding") \
#define HTTP_ERRNO_GEN(n, s) HPE_##n, #define HTTP_ERRNO_GEN(n, s) HPE_##n,
enum http_errno { enum http_errno { HTTP_ERRNO_MAP(HTTP_ERRNO_GEN) };
HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
};
#undef HTTP_ERRNO_GEN #undef HTTP_ERRNO_GEN
#define HTTP_PARSER_ERRNO(p) ((enum http_errno)(p)->http_errno)
#define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno)
struct http_parser { struct http_parser {
@@ -264,22 +230,17 @@ struct http_parser {
uint32_t nread; uint32_t nread;
uint64_t content_length; uint64_t content_length;
unsigned short http_major; unsigned short http_major;
unsigned short http_minor; unsigned short http_minor;
unsigned int status_code : 16; unsigned int status_code : 16;
unsigned int method : 8; unsigned int method : 8;
unsigned int http_errno : 7; unsigned int http_errno : 7;
unsigned int upgrade : 1; unsigned int upgrade : 1;
void *data; void *data;
}; };
struct http_parser_settings { struct http_parser_settings {
http_cb on_message_begin; http_cb on_message_begin;
http_data_cb on_url; http_data_cb on_url;
@@ -290,25 +251,20 @@ struct http_parser_settings {
http_data_cb on_body; http_data_cb on_body;
http_cb on_message_complete; http_cb on_message_complete;
http_cb on_chunk_header; http_cb on_chunk_header;
http_cb on_chunk_complete; http_cb on_chunk_complete;
}; };
enum http_parser_url_fields {
enum http_parser_url_fields UF_SCHEMA = 0,
{ UF_SCHEMA = 0 UF_HOST = 1,
, UF_HOST = 1 UF_PORT = 2,
, UF_PORT = 2 UF_PATH = 3,
, UF_PATH = 3 UF_QUERY = 4,
, UF_QUERY = 4 UF_FRAGMENT = 5,
, UF_FRAGMENT = 5 UF_USERINFO = 6,
, UF_USERINFO = 6 UF_MAX = 7
, UF_MAX = 7 };
};
struct http_parser_url { struct http_parser_url {
uint16_t field_set; uint16_t field_set;
@@ -320,58 +276,35 @@ struct http_parser_url {
} field_data[UF_MAX]; } field_data[UF_MAX];
}; };
unsigned long http_parser_version(void); unsigned long http_parser_version(void);
void http_parser_init(http_parser *parser, enum http_parser_type type); void http_parser_init(http_parser *parser, enum http_parser_type type);
void http_parser_settings_init(http_parser_settings *settings); void http_parser_settings_init(http_parser_settings *settings);
size_t http_parser_execute(http_parser *parser, size_t http_parser_execute(http_parser *parser,
const http_parser_settings *settings, const http_parser_settings *settings,
const char *data, const char *data, size_t len);
size_t len);
int http_should_keep_alive(const http_parser *parser); int http_should_keep_alive(const http_parser *parser);
const char *http_method_str(enum http_method m); const char *http_method_str(enum http_method m);
const char *http_status_str(enum http_status s); const char *http_status_str(enum http_status s);
const char *http_errno_name(enum http_errno err); const char *http_errno_name(enum http_errno err);
const char *http_errno_description(enum http_errno err); const char *http_errno_description(enum http_errno err);
void http_parser_url_init(struct http_parser_url *u); void http_parser_url_init(struct http_parser_url *u);
int http_parser_parse_url(const char *buf, size_t buflen, int is_connect,
int http_parser_parse_url(const char *buf, size_t buflen,
int is_connect,
struct http_parser_url *u); struct http_parser_url *u);
void http_parser_pause(http_parser *parser, int paused); void http_parser_pause(http_parser *parser, int paused);
int http_body_is_final(const http_parser *parser); int http_body_is_final(const http_parser *parser);
void http_parser_set_max_header_size(uint32_t size); void http_parser_set_max_header_size(uint32_t size);
#ifdef __cplusplus #ifdef __cplusplus