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
+1216 -1568

No files matched your search

+35 -40
View File
@@ -1,40 +1,35 @@
#pragma once #pragma once
#include <QString> #include <QString>
namespace LtsProjectionWorkstation namespace LtsProjectionWorkstation::JsonKeys {
{
namespace JsonKeys inline QString ERROR_MESSAGE() { return QStringLiteral("errorMessage"); }
{
inline QString LOGIN_REQUEST() { return QStringLiteral("loginRequest"); }
inline QString ERROR_MESSAGE() { return QStringLiteral("errorMessage"); } inline QString LOGOUT_REQUEST() { return QStringLiteral("logoutRequest"); }
inline QString DISCONNECT_REQUEST() {
return QStringLiteral("disconnectRequest");
inline QString LOGIN_REQUEST() { return QStringLiteral("loginRequest"); } }
inline QString LOGOUT_REQUEST() { return QStringLiteral("logoutRequest"); }
inline QString DISCONNECT_REQUEST() { return QStringLiteral("disconnectRequest"); } inline QString LOGIN_REPLY() { return QStringLiteral("loginReply"); }
inline QString LOGOUT_REPLY() { return QStringLiteral("logoutReply"); }
inline QString DEDICAED_DISCONNECT() {
return QStringLiteral("dedicatedDisconnect");
inline QString LOGIN_REPLY() { return QStringLiteral("loginReply"); } }
inline QString LOGOUT_REPLY() { return QStringLiteral("logoutReply"); }
inline QString DEDICAED_DISCONNECT() { return QStringLiteral("dedicatedDisconnect"); } inline QString USER_ID() { return QStringLiteral("userId"); }
inline QString USER_PRIORITY() { return QStringLiteral("userPriority"); }
inline QString EXERCISE_ID() { return QStringLiteral("exerciseId"); }
inline QString USER_ID() { return QStringLiteral("userId"); } inline QString NAME() { return QStringLiteral("name"); }
inline QString USER_PRIORITY() { return QStringLiteral("userPriority"); } inline QString PORT() { return QStringLiteral("port"); }
inline QString EXERCISE_ID() { return QStringLiteral("exerciseId"); } inline QString WIDTH() { return QStringLiteral("width"); }
inline QString NAME() { return QStringLiteral("name"); } inline QString HEIGHT() { return QStringLiteral("height"); }
inline QString PORT() { return QStringLiteral("port"); } inline QString REASON() { return QStringLiteral("reason"); }
inline QString WIDTH() { return QStringLiteral("width"); } inline QString SUCCESS() { return QStringLiteral("success"); }
inline QString HEIGHT() { return QStringLiteral("height"); } inline QString SCREENS() { return QStringLiteral("screens"); }
inline QString REASON() { return QStringLiteral("reason"); } inline QString SETTINGS_DATA() { return QStringLiteral("settingsData"); }
inline QString SUCCESS() { return QStringLiteral("success"); }
inline QString SCREENS() { return QStringLiteral("screens"); } } // namespace LtsProjectionWorkstation::JsonKeys
inline QString SETTINGS_DATA() { return QStringLiteral("settingsData"); }
}
}
+99 -126
View File
@@ -1,126 +1,99 @@
#pragma once
#pragma once
#include <QMetaObject>
#include <QObject> #include <QObject>
#include <QMetaObject> #include <QPointer>
#include <QPointer> #include <QtGlobal>
#include <QtGlobal> #include <type_traits>
#include <type_traits>
namespace LtsUtils {
namespace LtsUtils class IConnection {
{ public:
virtual ~IConnection() = default;
virtual void connect(Qt::ConnectionType = Qt::AutoConnection) = 0;
virtual void disconnect() = 0;
class IConnection };
{
public: class DummyConnection : public IConnection {
virtual ~IConnection() = default; public:
virtual void connect(Qt::ConnectionType = Qt::AutoConnection) = 0; void connect(Qt::ConnectionType = Qt::AutoConnection) override {}
virtual void disconnect() = 0; void disconnect() override {}
}; };
namespace detail {
template <class T> struct ExtractClass;
class DummyConnection : public IConnection
{ template <class T, class Member> struct ExtractClass<Member T::*> {
public: using type = T;
void connect(Qt::ConnectionType = Qt::AutoConnection) override {} };
void disconnect() override {}
}; } // namespace detail
template <class Signal, class Slot> class Connection : public IConnection {
namespace detail static_assert(std::is_member_function_pointer_v<Signal>,
{ "Must be a pointer to method");
static_assert(std::is_member_function_pointer_v<Slot>,
"Must be a pointer to method");
template<class T> using Emitter = typename detail::ExtractClass<Signal>::type;
struct ExtractClass; using Target = typename detail::ExtractClass<Slot>::type;
static_assert(std::is_base_of_v<QObject, Emitter>,
"Must be derived from QObject");
template<class T, class Member> static_assert(std::is_base_of_v<QObject, Target>,
struct ExtractClass<Member T::*> "Must be derived from QObject");
{
using type = T; public:
}; Connection(Emitter *emitter, Signal signal, Target *target, Slot slot)
: m_emitter(emitter), m_signal(signal), m_target(target), m_slot(slot) {
} Q_ASSERT(emitter);
Q_ASSERT(signal);
Q_ASSERT(target);
Q_ASSERT(slot);
}
template<class Signal, class Slot>
class Connection : public IConnection void
{ connect(Qt::ConnectionType connectionType = Qt::AutoConnection) override {
static_assert(std::is_member_function_pointer<Signal>::value, "Must be a pointer to method"); Q_ASSERT(!m_connected);
static_assert(std::is_member_function_pointer<Slot>::value, "Must be a pointer to method");
m_connected = true;
using Emitter = typename detail::ExtractClass<Signal>::type;
using Target = typename detail::ExtractClass<Slot>::type; if (!m_emitter || !m_target)
return;
static_assert(std::is_base_of<QObject, Emitter>::value, "Must be derived from QObject");
static_assert(std::is_base_of<QObject, Target>::value, "Must be derived from QObject"); m_conn = QObject::connect(m_emitter.data(), m_signal, m_target.data(),
m_slot, connectionType);
public: Q_ASSERT(m_conn);
Connection(Emitter *emitter, Signal signal, Target *target, Slot slot): }
m_emitter(emitter),
m_signal(signal), void disconnect() override {
m_target(target), Q_ASSERT(m_connected);
m_slot(slot)
{ if (m_conn)
Q_ASSERT(emitter); QObject::disconnect(m_conn);
Q_ASSERT(signal);
Q_ASSERT(target); m_connected = false;
Q_ASSERT(slot); }
}
private:
void connect(Qt::ConnectionType connectionType = Qt::AutoConnection) override bool m_connected{false};
{ QPointer<Emitter> m_emitter;
Q_ASSERT(!m_connected); Signal m_signal;
QPointer<Target> m_target;
m_connected = true; Slot m_slot;
QMetaObject::Connection m_conn;
};
if (!m_emitter || !m_target) template <class Signal, class Slot>
return; Connection<Signal, Slot> *
createConnection(typename detail::ExtractClass<Signal>::type *emitter,
m_conn = QObject::connect(m_emitter.data(), m_signal, m_target.data(), m_slot, connectionType); Signal signal,
Q_ASSERT(m_conn); typename detail::ExtractClass<Slot>::type *target, Slot slot) {
} return new Connection<Signal, Slot>(emitter, signal, target, slot);
}
void disconnect() override
{ } // namespace LtsUtils
Q_ASSERT(m_connected);
if (m_conn)
QObject::disconnect(m_conn);
m_connected = false;
}
private:
bool m_connected{false};
QPointer<Emitter> m_emitter;
Signal m_signal;
QPointer<Target> m_target;
Slot m_slot;
QMetaObject::Connection m_conn;
};
template<class Signal, class Slot>
Connection<Signal, Slot>* createConnection(typename detail::ExtractClass<Signal>::type *emitter, Signal signal,
typename detail::ExtractClass<Slot>::type *target, Slot slot)
{
return new Connection<Signal, Slot>(emitter, signal, target, slot);
}
}
+35 -43
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> inline void convert(const S &in, T &out) {
static_assert(!std::is_same_v<S, T>,
template <typename T, typename S> "Try to convert a type to the same type - is useless");
inline void convert(const S &in, T &out) out.reserve(static_cast<int>(in.size()));
{ std::copy(in.begin(), in.end(), std::back_inserter(out));
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()));
std::copy(in.begin(), in.end(), std::back_inserter(out)); template <typename T, typename S> 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");
template <typename T, typename S> T out;
inline T convert(const S &in) convert(in, out);
{ return out;
static_assert(!std::is_same<S, T>::value, "Try to convert a type to the same type - is useless"); }
T out;
convert(in, out); template <typename T> inline QByteArray toQByteArray(const T &in) {
return out; return convert<QByteArray>(in);
} }
template <typename T, typename V = typename T::value_type>
template <typename T> bool isInVector(const T &vec, const V &valueToSearch) {
inline QByteArray toQByteArray(const T &in) const auto end = vec.end();
{ return std::find(vec.begin(), end, valueToSearch) != end;
return convert<QByteArray>(in); }
}
} // namespace LtsUtils
template <typename T, typename V = typename T::value_type>
bool isInVector(const T &vec, const V &valueToSearch)
{
const auto end = vec.end();
return std::find(vec.begin(), end, valueToSearch) != end;
}
}
+519 -696
View File
File diff suppressed because it is too large. Load diff
+34 -45
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> class PgArray {
public:
template<typename T, typename C> using Type = T;
class PgArray using ContainerType = C;
{
public: PgArray() = default;
using Type = T; Q_DECL_CONSTEXPR explicit PgArray(const C &data) : m_data(data) {}
using ContainerType = C;
Q_DECL_CONSTEXPR C operator()() const { return m_data; }
PgArray() = default;
Q_DECL_CONSTEXPR explicit PgArray(const C &data) [[nodiscard]] QString toPgString() const;
: m_data(data) static PgArray fromPgString(const QString &str);
{}
private:
Q_DECL_CONSTEXPR C operator()()const C m_data;
{ };
return m_data;
} using IntArray = PgArray<int, std::vector<int>>;
using BigintArray = PgArray<int64_t, std::vector<int64_t>>;
QString toPgString() const;
static PgArray fromPgString(const QString &str); using IntArray2D = PgArray<int, std::map<int, int>>;
private: using BigintArray2D = PgArray<int64_t, std::map<int64_t, int64_t>>;
C m_data;
}; } // namespace LtsUtils
using IntArray = PgArray<int, std::vector<int>>;
using BigintArray = PgArray<int64_t, std::vector<int64_t>>;
using IntArray2D = PgArray<int, std::map<int, int>>;
using BigintArray2D = PgArray<int64_t, std::map<int64_t, int64_t>>;
}
+54 -70
View File
@@ -1,70 +1,54 @@
#pragma once #pragma once
#include <QObject>
#include <QObject>
namespace LtsUtils {
namespace LtsUtils class PromiseExample1_Class : public QObject {
{ Q_OBJECT
public:
using QObject::QObject;
class PromiseExample1_Class : public QObject
{ void doSomethingAsync1();
Q_OBJECT void doSomethingAsync2();
public:
using QObject::QObject; signals:
void signalDone1(bool didThisWork);
void doSomethingAsync1(); void signalDone2(bool didThisWork, int someNumberThatReturns);
void doSomethingAsync2(); };
signals: class PromiseExample1 : public QObject {
void signalDone1(bool didThisWork); Q_OBJECT
void signalDone2(bool didThisWork, int someNumberThatReturns); public:
}; explicit PromiseExample1(QObject *parent = nullptr);
[[nodiscard]] bool isSuccess() const { return m_success; }
class PromiseExample1 : public QObject
{ private:
Q_OBJECT bool m_success;
public: };
explicit PromiseExample1(QObject *parent = nullptr);
class PromiseExample2 : public QObject {
bool isSuccess() const { return m_success; } Q_OBJECT
public:
private: explicit PromiseExample2(QObject *parent = nullptr);
bool m_success;
}; [[nodiscard]] bool isSuccess() const { return m_success; }
private:
bool m_success;
};
class PromiseExample2 : public QObject
{ class PromiseExample3 : public QObject {
Q_OBJECT Q_OBJECT
public: public:
explicit PromiseExample2(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;
};
} // namespace LtsUtils
class PromiseExample3 : public QObject
{
Q_OBJECT
public:
explicit PromiseExample3(QObject *parent = nullptr);
bool isSuccess() const { return m_success; }
private:
bool m_success;
bool m_alreadyRejected;
};
}
+241 -282
View File
@@ -1,282 +1,241 @@
#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>,
"Only integrals allowed for raw byte accessd");
out += (in & 0xFF00000000000000UL) >> 56;
template<typename T> out += (in & 0x00FF000000000000UL) >> 48;
void inline set8Byte(const T in, QByteArray& out) out += (in & 0x0000FF0000000000UL) >> 40;
{ out += (in & 0x000000FF00000000UL) >> 32;
static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "Only integrals allowed for raw byte accessd"); out += (in & 0x00000000FF000000UL) >> 24;
out += (in & 0xFF00000000000000UL) >> 56; out += (in & 0x0000000000FF0000UL) >> 16;
out += (in & 0x00FF000000000000UL) >> 48; out += (in & 0x000000000000FF00UL) >> 8;
out += (in & 0x0000FF0000000000UL) >> 40; out += (in & 0x00000000000000FFUL);
out += (in & 0x000000FF00000000UL) >> 32; }
out += (in & 0x00000000FF000000UL) >> 24;
out += (in & 0x0000000000FF0000UL) >> 16; template <> void inline set8Byte(const double in, QByteArray &out) {
out += (in & 0x000000000000FF00UL) >> 8; union hack {
out += (in & 0x00000000000000FFUL); double d;
} int64_t i;
} h;
template<> h.d = in;
void inline set8Byte(const double in, QByteArray &out) set8Byte(h.i, out);
{ }
union hack
{ template <typename T>
double d; bool inline get8Byte(const QByteArray &baData, size_t &pos, T &out) {
int64_t i; static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
} h; "Only integrals allowed for raw byte accessd");
h.d = in; static_assert(sizeof(T) >= 8,
set8Byte(h.i, out); "sizeof(out) is smaller than 8 bytes - will not fit");
} out = T();
template<typename T> if (size_t(baData.size()) < pos + 8)
bool inline get8Byte(const QByteArray& baData, return false;
size_t &pos,
T& out) const char *data = baData.data() + pos;
{
static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "Only integrals allowed for raw byte accessd"); if (std::numeric_limits<T>::is_signed)
static_assert(sizeof(T) >= 8, "sizeof(out) is smaller than 8 bytes - will not fit"); out |= static_cast<signed long long>(data[0]) << 56;
out = T(); else
out |= (data[0] & 0xFFULL) << 56;
if(size_t(baData.size()) < pos + 8) out |= (data[1] & 0xFFULL) << 48;
return false; out |= (data[2] & 0xFFULL) << 40;
out |= (data[3] & 0xFFULL) << 32;
const char *data = baData.data() + pos; out |= (data[4] & 0xFFULL) << 24;
out |= (data[5] & 0xFFULL) << 16;
if(std::numeric_limits<T>::is_signed) out |= (data[6] & 0xFFULL) << 8;
out |= static_cast<signed long long>(data[0]) << 56; out |= (data[7] & 0xFFULL);
else
out |= (data[0] & 0xFFULL) << 56; pos += 8;
out |= (data[1] & 0xFFULL) << 48;
out |= (data[2] & 0xFFULL) << 40; return true;
out |= (data[3] & 0xFFULL) << 32; }
out |= (data[4] & 0xFFULL) << 24;
out |= (data[5] & 0xFFULL) << 16; template <>
out |= (data[6] & 0xFFULL) << 8; bool inline get8Byte(const QByteArray &baData, size_t &pos, double &out) {
out |= (data[7] & 0xFFULL); out = 0.;
union hack {
pos += 8; double d;
int64_t i;
return true; } h;
} if (!get8Byte(baData, pos, h.i))
return false;
template<> out = h.d;
bool inline get8Byte(const QByteArray& baData, return true;
size_t &pos, }
double& out)
{ template <typename T> bool inline get8Byte(const QByteArray &data, T &out) {
out = 0.; size_t pos = 0;
union hack return get8Byte(data, pos, out);
{ }
double d;
int64_t i; template <typename T> void inline set4Byte(const T in, QByteArray &out) {
} h; static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
if (!get8Byte(baData, pos, h.i)) "Only integrals allowed for raw byte accessd");
return false; out += (in & 0xFF000000) >> 24;
out = h.d; out += (in & 0x00FF0000) >> 16;
return true; out += (in & 0x0000FF00) >> 8;
} out += (in & 0x000000FF);
}
template<typename T>
bool inline get8Byte(const QByteArray& data, T& out) template <> void inline set4Byte(const double in, QByteArray &out) {
{ int tmp = qRound(in);
size_t pos = 0; return set4Byte(tmp, out);
return get8Byte(data, pos, out); }
}
template <typename T>
bool inline get4Byte(const QByteArray &baData, size_t &pos, T &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(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");
out += (in & 0xFF000000) >> 24; out = T();
out += (in & 0x00FF0000) >> 16;
out += (in & 0x0000FF00) >> 8; if (size_t(baData.size()) < pos + 4)
out += (in & 0x000000FF); return false;
}
const char *data = baData.data() + pos;
template<>
void inline set4Byte(const double in, QByteArray& out) if (std::numeric_limits<T>::is_signed)
{ out |= data[0] << 24;
int tmp = qRound(in); else
return set4Byte(tmp, out); out |= (data[0] & 0xFFU) << 24;
} out |= (data[1] & 0xFFU) << 16;
out |= (data[2] & 0xFFU) << 8;
template<typename T> out |= (data[3] & 0xFFU);
bool inline get4Byte(const QByteArray& baData,
size_t &pos, pos += 4;
T& out)
{ return true;
static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "Only integrals allowed for raw byte accessd"); }
static_assert(sizeof(T) >= 4, "sizeof(out) is smaller than 4 bytes - will not fit");
out = T(); template <>
bool inline get4Byte(const QByteArray &baData, size_t &pos, double &out) {
if(size_t(baData.size()) < pos + 4) out = 0.;
return false; int tmp;
if (!get4Byte(baData, pos, tmp))
const char *data = baData.data() + pos; return false;
out = tmp;
if(std::numeric_limits<T>::is_signed) return true;
out |= data[0] << 24; }
else
out |= (data[0] & 0xFFU) << 24; template <typename T> bool inline get4Byte(const QByteArray &data, T &out) {
out |= (data[1] & 0xFFU) << 16; size_t pos = 0;
out |= (data[2] & 0xFFU) << 8; return get4Byte(data, pos, out);
out |= (data[3] & 0xFFU); }
pos += 4; template <typename T> void inline set3Byte(const T in, QByteArray &out) {
static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
return true; "Only integrals allowed for raw byte accessd");
} out += (in & 0x00FF0000) >> 16;
out += (in & 0x0000FF00) >> 8;
template<> out += (in & 0x000000FF);
bool inline get4Byte(const QByteArray& baData, }
size_t &pos,
double& out) template <typename T>
{ bool inline get3Byte(const QByteArray &baData, size_t &pos, T &out) {
out = 0.; static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
int tmp; "Only integrals allowed for raw byte accessd");
if(!get4Byte(baData, pos, tmp)) static_assert(sizeof(T) >= 3,
return false; "sizeof(out) is smaller than 3 bytes - will not fit");
out = tmp; out = T();
return true;
} if (size_t(baData.size()) < pos + 3)
return false;
template<typename T>
bool inline get4Byte(const QByteArray& data, T& out) const char *data = baData.data() + pos;
{
size_t pos = 0; if (std::numeric_limits<T>::is_signed)
return get4Byte(data, pos, out); out |= data[0] << 16;
} else
out |= (data[0] & 0xFFU) << 16;
out |= (data[1] & 0xFFU) << 8;
template<typename T> out |= (data[2] & 0xFFU);
void inline set3Byte(const T in, QByteArray& out)
{ pos += 3;
static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "Only integrals allowed for raw byte accessd");
out += (in & 0x00FF0000) >> 16; return true;
out += (in & 0x0000FF00) >> 8; }
out += (in & 0x000000FF);
} template <typename T> bool inline get3Byte(const QByteArray &data, T &out) {
size_t pos = 0;
template<typename T> return get3Byte(data, pos, out);
bool inline get3Byte(const QByteArray& baData, }
size_t &pos,
T& out) template <typename T> void inline set2Byte(const T in, QByteArray &out) {
{ static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "Only integrals allowed for raw byte accessd"); "Only integrals allowed for raw byte accessd");
static_assert(sizeof(T) >= 3, "sizeof(out) is smaller than 3 bytes - will not fit"); out += (in & 0x0000FF00) >> 8;
out = T(); out += (in & 0x000000FF);
}
if(size_t(baData.size()) < pos + 3)
return false; template <typename T>
bool inline get2Byte(const QByteArray &baData, size_t &pos, T &out) {
const char *data = baData.data() + pos; static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
"Only integrals allowed for raw byte accessd");
if(std::numeric_limits<T>::is_signed) static_assert(sizeof(T) >= 2,
out |= data[0] << 16; "sizeof(out) is smaller than 2 bytes - will not fit");
else out = T();
out |= (data[0] & 0xFFU) << 16;
out |= (data[1] & 0xFFU) << 8; if (size_t(baData.size()) < pos + 2)
out |= (data[2] & 0xFFU); return false;
pos += 3; const char *data = baData.data() + pos;
return true; if (std::numeric_limits<T>::is_signed)
} out |= data[0] << 8;
else
template<typename T> out |= (data[0] & 0xFFU) << 8;
bool inline get3Byte(const QByteArray& data, T& out) out |= data[1] & 0xFFU;
{
size_t pos = 0; pos += 2;
return get3Byte(data, pos, out);
} return true;
}
template<typename T> template <typename T> bool inline get2Byte(const QByteArray &data, T &out) {
void inline set2Byte(const T in, QByteArray& out) size_t pos = 0;
{ return get2Byte(data, pos, out);
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 & 0x000000FF); template <typename T> void inline set1Byte(const T in, QByteArray &out) {
} static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
"Only integrals allowed for raw byte accessd");
template<typename T> unsigned char c = in;
bool inline get2Byte(const QByteArray& baData, out += c;
size_t &pos, }
T& out)
{ template <typename T>
static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "Only integrals allowed for raw byte accessd"); bool inline get1Byte(const QByteArray &baData, size_t &pos, T &out) {
static_assert(sizeof(T) >= 2, "sizeof(out) is smaller than 2 bytes - will not fit"); static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
out = T(); "Only integrals allowed for raw byte accessd");
out = T();
if(size_t(baData.size()) < pos + 2)
return false; if (size_t(baData.size()) < pos + 1)
return false;
const char *data = baData.data() + pos;
const char *data = baData.data() + pos;
if(std::numeric_limits<T>::is_signed)
out |= data[0] << 8; if (std::numeric_limits<T>::is_signed)
else out = (T)(data[0]);
out |= (data[0] & 0xFFU) << 8; else
out |= data[1] & 0xFFU; out = (T)(data[0] & 0xFF);
pos += 2; pos += 1;
return true; return true;
} }
template<typename T> template <typename T> bool inline get1Byte(const QByteArray &data, T &out) {
bool inline get2Byte(const QByteArray& data, T& out) size_t pos = 0;
{ return get1Byte(data, pos, out);
size_t pos = 0; }
return get2Byte(data, pos, out); } // namespace LtsUtils
}
template<typename T>
void inline set1Byte(const T in, QByteArray& out)
{
static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "Only integrals allowed for raw byte accessd");
unsigned char c = in;
out += c;
}
template<typename T>
bool inline get1Byte(const QByteArray& baData,
size_t &pos,
T& out)
{
static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "Only integrals allowed for raw byte accessd");
out = T();
if(size_t(baData.size()) < pos + 1)
return false;
const char *data = baData.data() + pos;
if(std::numeric_limits<T>::is_signed)
out = (T)(data[0]);
else
out = (T)(data[0] & 0xFF);
pos += 1;
return true;
}
template<typename T>
bool inline get1Byte(const QByteArray& data, T& out)
{
size_t pos = 0;
return get1Byte(data, pos, out);
}
}
+199 -266
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,351 +26,285 @@ 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;
using http_data_cb = int (*)(http_parser *, const char *, size_t);
using http_cb = int (*)(http_parser *);
#define HTTP_STATUS_MAP(XX) \
XX(100, CONTINUE, Continue) \
XX(101, SWITCHING_PROTOCOLS, Switching Protocols) \
XX(102, PROCESSING, Processing) \
XX(200, OK, OK) \
XX(201, CREATED, Created) \
XX(202, ACCEPTED, Accepted) \
XX(203, NON_AUTHORITATIVE_INFORMATION, Non - Authoritative Information) \
XX(204, NO_CONTENT, No Content) \
XX(205, RESET_CONTENT, Reset Content) \
XX(206, PARTIAL_CONTENT, Partial Content) \
XX(207, MULTI_STATUS, Multi - Status) \
XX(208, ALREADY_REPORTED, Already Reported) \
XX(226, IM_USED, IM Used) \
XX(300, MULTIPLE_CHOICES, Multiple Choices) \
XX(301, MOVED_PERMANENTLY, Moved Permanently) \
XX(302, FOUND, Found) \
XX(303, SEE_OTHER, See Other) \
XX(304, NOT_MODIFIED, Not Modified) \
XX(305, USE_PROXY, Use Proxy) \
XX(307, TEMPORARY_REDIRECT, Temporary Redirect) \
XX(308, PERMANENT_REDIRECT, Permanent Redirect) \
XX(400, BAD_REQUEST, Bad Request) \
XX(401, UNAUTHORIZED, Unauthorized) \
XX(402, PAYMENT_REQUIRED, Payment Required) \
XX(403, FORBIDDEN, Forbidden) \
XX(404, NOT_FOUND, Not Found) \
XX(405, METHOD_NOT_ALLOWED, Method Not Allowed) \
XX(406, NOT_ACCEPTABLE, Not Acceptable) \
XX(407, PROXY_AUTHENTICATION_REQUIRED, Proxy Authentication Required) \
XX(408, REQUEST_TIMEOUT, Request Timeout) \
XX(409, CONFLICT, Conflict) \
XX(410, GONE, Gone) \
XX(411, LENGTH_REQUIRED, Length Required) \
XX(412, PRECONDITION_FAILED, Precondition Failed) \
XX(413, PAYLOAD_TOO_LARGE, Payload Too Large) \
XX(414, URI_TOO_LONG, URI Too Long) \
XX(415, UNSUPPORTED_MEDIA_TYPE, Unsupported Media Type) \
XX(416, RANGE_NOT_SATISFIABLE, Range Not Satisfiable) \
XX(417, EXPECTATION_FAILED, Expectation Failed) \
XX(421, MISDIRECTED_REQUEST, Misdirected Request) \
XX(422, UNPROCESSABLE_ENTITY, Unprocessable Entity) \
XX(423, LOCKED, Locked) \
XX(424, FAILED_DEPENDENCY, Failed Dependency) \
XX(426, UPGRADE_REQUIRED, Upgrade Required) \
XX(428, PRECONDITION_REQUIRED, Precondition Required) \
XX(429, TOO_MANY_REQUESTS, Too Many Requests) \
XX(431, REQUEST_HEADER_FIELDS_TOO_LARGE, Request Header Fields Too Large) \
XX(451, UNAVAILABLE_FOR_LEGAL_REASONS, Unavailable For Legal Reasons) \
XX(500, INTERNAL_SERVER_ERROR, Internal Server Error) \
XX(501, NOT_IMPLEMENTED, Not Implemented) \
XX(502, BAD_GATEWAY, Bad Gateway) \
XX(503, SERVICE_UNAVAILABLE, Service Unavailable) \
XX(504, GATEWAY_TIMEOUT, Gateway Timeout) \
XX(505, HTTP_VERSION_NOT_SUPPORTED, HTTP Version Not Supported) \
XX(506, VARIANT_ALSO_NEGOTIATES, Variant Also Negotiates) \
XX(507, INSUFFICIENT_STORAGE, Insufficient Storage) \
XX(508, LOOP_DETECTED, Loop Detected) \
XX(510, NOT_EXTENDED, Not Extended) \
XX(511, NETWORK_AUTHENTICATION_REQUIRED, Network Authentication Required)
enum http_status {
typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);
typedef int (*http_cb) (http_parser*);
#define HTTP_STATUS_MAP(XX) \
XX(100, CONTINUE, Continue) \
XX(101, SWITCHING_PROTOCOLS, Switching Protocols) \
XX(102, PROCESSING, Processing) \
XX(200, OK, OK) \
XX(201, CREATED, Created) \
XX(202, ACCEPTED, Accepted) \
XX(203, NON_AUTHORITATIVE_INFORMATION, Non-Authoritative Information) \
XX(204, NO_CONTENT, No Content) \
XX(205, RESET_CONTENT, Reset Content) \
XX(206, PARTIAL_CONTENT, Partial Content) \
XX(207, MULTI_STATUS, Multi-Status) \
XX(208, ALREADY_REPORTED, Already Reported) \
XX(226, IM_USED, IM Used) \
XX(300, MULTIPLE_CHOICES, Multiple Choices) \
XX(301, MOVED_PERMANENTLY, Moved Permanently) \
XX(302, FOUND, Found) \
XX(303, SEE_OTHER, See Other) \
XX(304, NOT_MODIFIED, Not Modified) \
XX(305, USE_PROXY, Use Proxy) \
XX(307, TEMPORARY_REDIRECT, Temporary Redirect) \
XX(308, PERMANENT_REDIRECT, Permanent Redirect) \
XX(400, BAD_REQUEST, Bad Request) \
XX(401, UNAUTHORIZED, Unauthorized) \
XX(402, PAYMENT_REQUIRED, Payment Required) \
XX(403, FORBIDDEN, Forbidden) \
XX(404, NOT_FOUND, Not Found) \
XX(405, METHOD_NOT_ALLOWED, Method Not Allowed) \
XX(406, NOT_ACCEPTABLE, Not Acceptable) \
XX(407, PROXY_AUTHENTICATION_REQUIRED, Proxy Authentication Required) \
XX(408, REQUEST_TIMEOUT, Request Timeout) \
XX(409, CONFLICT, Conflict) \
XX(410, GONE, Gone) \
XX(411, LENGTH_REQUIRED, Length Required) \
XX(412, PRECONDITION_FAILED, Precondition Failed) \
XX(413, PAYLOAD_TOO_LARGE, Payload Too Large) \
XX(414, URI_TOO_LONG, URI Too Long) \
XX(415, UNSUPPORTED_MEDIA_TYPE, Unsupported Media Type) \
XX(416, RANGE_NOT_SATISFIABLE, Range Not Satisfiable) \
XX(417, EXPECTATION_FAILED, Expectation Failed) \
XX(421, MISDIRECTED_REQUEST, Misdirected Request) \
XX(422, UNPROCESSABLE_ENTITY, Unprocessable Entity) \
XX(423, LOCKED, Locked) \
XX(424, FAILED_DEPENDENCY, Failed Dependency) \
XX(426, UPGRADE_REQUIRED, Upgrade Required) \
XX(428, PRECONDITION_REQUIRED, Precondition Required) \
XX(429, TOO_MANY_REQUESTS, Too Many Requests) \
XX(431, REQUEST_HEADER_FIELDS_TOO_LARGE, Request Header Fields Too Large) \
XX(451, UNAVAILABLE_FOR_LEGAL_REASONS, Unavailable For Legal Reasons) \
XX(500, INTERNAL_SERVER_ERROR, Internal Server Error) \
XX(501, NOT_IMPLEMENTED, Not Implemented) \
XX(502, BAD_GATEWAY, Bad Gateway) \
XX(503, SERVICE_UNAVAILABLE, Service Unavailable) \
XX(504, GATEWAY_TIMEOUT, Gateway Timeout) \
XX(505, HTTP_VERSION_NOT_SUPPORTED, HTTP Version Not Supported) \
XX(506, VARIANT_ALSO_NEGOTIATES, Variant Also Negotiates) \
XX(507, INSUFFICIENT_STORAGE, Insufficient Storage) \
XX(508, LOOP_DETECTED, Loop Detected) \
XX(510, NOT_EXTENDED, Not Extended) \
XX(511, NETWORK_AUTHENTICATION_REQUIRED, Network Authentication Required) \
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) \
XX(0, DELETE, DELETE) \
XX(1, GET, GET) \
XX(2, HEAD, HEAD) \
XX(3, POST, POST) \
XX(4, PUT, PUT) \
\
XX(5, CONNECT, CONNECT) \
XX(6, OPTIONS, OPTIONS) \
XX(7, TRACE, TRACE) \
\
XX(8, COPY, COPY) \
XX(9, LOCK, LOCK) \
XX(10, MKCOL, MKCOL) \
XX(11, MOVE, MOVE) \
XX(12, PROPFIND, PROPFIND) \
XX(13, PROPPATCH, PROPPATCH) \
XX(14, SEARCH, SEARCH) \
XX(15, UNLOCK, UNLOCK) \
XX(16, BIND, BIND) \
XX(17, REBIND, REBIND) \
XX(18, UNBIND, UNBIND) \
XX(19, ACL, ACL) \
\
XX(20, REPORT, REPORT) \
XX(21, MKACTIVITY, MKACTIVITY) \
XX(22, CHECKOUT, CHECKOUT) \
XX(23, MERGE, MERGE) \
\
XX(24, MSEARCH, M - SEARCH) \
XX(25, NOTIFY, NOTIFY) \
XX(26, SUBSCRIBE, SUBSCRIBE) \
XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \
\
XX(28, PATCH, PATCH) \
XX(29, PURGE, PURGE) \
\
XX(30, MKCALENDAR, MKCALENDAR) \
\
XX(31, LINK, LINK) \
XX(32, UNLINK, UNLINK) \
\
XX(33, SOURCE, SOURCE)
enum http_method {
#define HTTP_METHOD_MAP(XX) \
XX(0, DELETE, DELETE) \
XX(1, GET, GET) \
XX(2, HEAD, HEAD) \
XX(3, POST, POST) \
XX(4, PUT, PUT) \
\
XX(5, CONNECT, CONNECT) \
XX(6, OPTIONS, OPTIONS) \
XX(7, TRACE, TRACE) \
\
XX(8, COPY, COPY) \
XX(9, LOCK, LOCK) \
XX(10, MKCOL, MKCOL) \
XX(11, MOVE, MOVE) \
XX(12, PROPFIND, PROPFIND) \
XX(13, PROPPATCH, PROPPATCH) \
XX(14, SEARCH, SEARCH) \
XX(15, UNLOCK, UNLOCK) \
XX(16, BIND, BIND) \
XX(17, REBIND, REBIND) \
XX(18, UNBIND, UNBIND) \
XX(19, ACL, ACL) \
\
XX(20, REPORT, REPORT) \
XX(21, MKACTIVITY, MKACTIVITY) \
XX(22, CHECKOUT, CHECKOUT) \
XX(23, MERGE, MERGE) \
\
XX(24, MSEARCH, M-SEARCH) \
XX(25, NOTIFY, NOTIFY) \
XX(26, SUBSCRIBE, SUBSCRIBE) \
XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \
\
XX(28, PATCH, PATCH) \
XX(29, PURGE, PURGE) \
\
XX(30, MKCALENDAR, MKCALENDAR) \
\
XX(31, LINK, LINK) \
XX(32, UNLINK, UNLINK) \
\
XX(33, SOURCE, SOURCE) \
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,
F_CONNECTION_KEEP_ALIVE = 1 << 1,
F_CONNECTION_CLOSE = 1 << 2,
F_CONNECTION_UPGRADE = 1 << 3,
F_TRAILING = 1 << 4,
F_UPGRADE = 1 << 5,
F_SKIPBODY = 1 << 6,
F_CONTENTLENGTH = 1 << 7,
F_TRANSFER_ENCODING = 1 << 8
};
#define HTTP_ERRNO_MAP(XX) \
enum flags \
{ F_CHUNKED = 1 << 0 XX(OK, "success") \
, F_CONNECTION_KEEP_ALIVE = 1 << 1 \
, F_CONNECTION_CLOSE = 1 << 2 XX(CB_message_begin, "the on_message_begin callback failed") \
, F_CONNECTION_UPGRADE = 1 << 3 XX(CB_url, "the on_url callback failed") \
, F_TRAILING = 1 << 4 XX(CB_header_field, "the on_header_field callback failed") \
, F_UPGRADE = 1 << 5 XX(CB_header_value, "the on_header_value callback failed") \
, F_SKIPBODY = 1 << 6 XX(CB_headers_complete, "the on_headers_complete callback failed") \
, F_CONTENTLENGTH = 1 << 7 XX(CB_body, "the on_body callback failed") \
, F_TRANSFER_ENCODING = 1 << 8 XX(CB_message_complete, "the on_message_complete callback failed") \
}; XX(CB_status, "the on_status callback failed") \
XX(CB_chunk_header, "the on_chunk_header callback failed") \
XX(CB_chunk_complete, "the on_chunk_complete callback failed") \
\
XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \
#define HTTP_ERRNO_MAP(XX) \ XX(HEADER_OVERFLOW, "too many header bytes seen; overflow detected") \
\ XX(CLOSED_CONNECTION, \
XX(OK, "success") \ "data received after completed connection: close message") \
\ XX(INVALID_VERSION, "invalid HTTP version") \
\ XX(INVALID_STATUS, "invalid HTTP status code") \
XX(CB_message_begin, "the on_message_begin callback failed") \ XX(INVALID_METHOD, "invalid HTTP method") \
XX(CB_url, "the on_url callback failed") \ XX(INVALID_URL, "invalid URL") \
XX(CB_header_field, "the on_header_field callback failed") \ XX(INVALID_HOST, "invalid host") \
XX(CB_header_value, "the on_header_value callback failed") \ XX(INVALID_PORT, "invalid port") \
XX(CB_headers_complete, "the on_headers_complete callback failed") \ XX(INVALID_PATH, "invalid path") \
XX(CB_body, "the on_body callback failed") \ XX(INVALID_QUERY_STRING, "invalid query string") \
XX(CB_message_complete, "the on_message_complete callback failed") \ XX(INVALID_FRAGMENT, "invalid fragment") \
XX(CB_status, "the on_status callback failed") \ XX(LF_EXPECTED, "LF character expected") \
XX(CB_chunk_header, "the on_chunk_header callback failed") \ XX(INVALID_HEADER_TOKEN, "invalid character in header") \
XX(CB_chunk_complete, "the on_chunk_complete callback failed") \ XX(INVALID_CONTENT_LENGTH, "invalid character in content-length header") \
\ XX(UNEXPECTED_CONTENT_LENGTH, "unexpected content-length header") \
\ XX(INVALID_CHUNK_SIZE, "invalid character in chunk size header") \
XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \ XX(INVALID_CONSTANT, "invalid constant string") \
XX(HEADER_OVERFLOW, \ XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state") \
"too many header bytes seen; overflow detected") \ XX(STRICT, "strict mode assertion failed") \
XX(CLOSED_CONNECTION, \ XX(PAUSED, "parser is paused") \
"data received after completed connection: close message") \ XX(UNKNOWN, "an unknown error occurred") \
XX(INVALID_VERSION, "invalid HTTP version") \ XX(INVALID_TRANSFER_ENCODING, "request has invalid transfer-encoding")
XX(INVALID_STATUS, "invalid HTTP status code") \
XX(INVALID_METHOD, "invalid HTTP method") \
XX(INVALID_URL, "invalid URL") \
XX(INVALID_HOST, "invalid host") \
XX(INVALID_PORT, "invalid port") \
XX(INVALID_PATH, "invalid path") \
XX(INVALID_QUERY_STRING, "invalid query string") \
XX(INVALID_FRAGMENT, "invalid fragment") \
XX(LF_EXPECTED, "LF character expected") \
XX(INVALID_HEADER_TOKEN, "invalid character in header") \
XX(INVALID_CONTENT_LENGTH, \
"invalid character in content-length header") \
XX(UNEXPECTED_CONTENT_LENGTH, \
"unexpected content-length header") \
XX(INVALID_CHUNK_SIZE, \
"invalid character in chunk size header") \
XX(INVALID_CONSTANT, "invalid constant string") \
XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\
XX(STRICT, "strict mode assertion failed") \
XX(PAUSED, "parser is paused") \
XX(UNKNOWN, "an unknown error occurred") \
XX(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 {
unsigned int type : 2; unsigned int type : 2;
unsigned int flags : 8; unsigned int flags : 8;
unsigned int state : 7; unsigned int state : 7;
unsigned int header_state : 7; unsigned int header_state : 7;
unsigned int index : 5; unsigned int index : 5;
unsigned int extra_flags : 2; unsigned int extra_flags : 2;
unsigned int lenient_http_headers : 1; unsigned int lenient_http_headers : 1;
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;
http_data_cb on_status; http_data_cb on_status;
http_data_cb on_header_field; http_data_cb on_header_field;
http_data_cb on_header_value; http_data_cb on_header_value;
http_cb on_headers_complete; http_cb on_headers_complete;
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;
uint16_t port; uint16_t port;
struct { struct {
uint16_t off; uint16_t off;
uint16_t len; uint16_t len;
} 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