5 Commits

Author SHA1 Message Date
f2464ed76b Merge branch 'master' of https://git.shstk.ru/SHS/pip 2025-08-14 17:34:21 +03:00
a3615c5666 piDe/SerializeJSON with PIJSON type, some doc 2025-08-14 17:34:12 +03:00
1b3f72d429 add PISystemMonitor measurer signal 2025-08-14 15:57:42 +03:00
04152f05a9 some autogen docs 2025-08-14 14:07:52 +03:00
d95944dcfc PIRegularExpression basic doc 2025-08-14 10:54:37 +03:00
12 changed files with 485 additions and 14 deletions

View File

@@ -341,6 +341,7 @@ void PISystemMonitor::run() {
stat = tstat; stat = tstat;
stat.makeStrings(); stat.makeStrings();
stat_mutex.unlock(); stat_mutex.unlock();
measured();
} }

View File

@@ -242,6 +242,9 @@ public:
//! \~russian //! \~russian
static ullong usedRAM(); static ullong usedRAM();
//! \~english
//! \~russian
EVENT(measured);
private: private:
void run() override; void run() override;

View File

@@ -33,6 +33,8 @@ namespace PIClientServer {
// ServerClient // ServerClient
//! ~english Server-side client implementation
//! ~russian Серверная реализация клиента
class PIP_CLIENT_SERVER_EXPORT ServerClient: public ClientBase { class PIP_CLIENT_SERVER_EXPORT ServerClient: public ClientBase {
friend class Server; friend class Server;
NO_COPY_CLASS(ServerClient); NO_COPY_CLASS(ServerClient);
@@ -41,6 +43,8 @@ public:
ServerClient() {} ServerClient() {}
protected: protected:
//! ~english Called before client destruction
//! ~russian Вызывается перед уничтожением клиента
virtual void aboutDelete() {} virtual void aboutDelete() {}
private: private:
@@ -50,6 +54,8 @@ private:
// Client // Client
//! ~english Client implementation for connecting to servers
//! ~russian Клиентская реализация для подключения к серверам
class PIP_CLIENT_SERVER_EXPORT Client: public ClientBase { class PIP_CLIENT_SERVER_EXPORT Client: public ClientBase {
NO_COPY_CLASS(Client); NO_COPY_CLASS(Client);
@@ -57,6 +63,8 @@ public:
Client(); Client();
~Client(); ~Client();
//! ~english Connects to specified server address
//! ~russian Подключается к указанному адресу сервера
void connect(PINetworkAddress addr); void connect(PINetworkAddress addr);
protected: protected:

View File

@@ -37,6 +37,8 @@ class Server;
class ClientInterface {}; class ClientInterface {};
//! ~english Base class for client-server communication with diagnostics support
//! ~russian Базовый класс для клиент-серверного взаимодействия с поддержкой диагностики
// template<bool EnableDiagnostics = false> // template<bool EnableDiagnostics = false>
class PIP_CLIENT_SERVER_EXPORT ClientBase { class PIP_CLIENT_SERVER_EXPORT ClientBase {
friend class Server; friend class Server;
@@ -46,16 +48,39 @@ public:
ClientBase(); ClientBase();
virtual ~ClientBase(); virtual ~ClientBase();
//! ~english Gets underlying TCP connection
//! ~russian Возвращает TCP-соединение
const PIEthernet * getTCP() const { return tcp; } const PIEthernet * getTCP() const { return tcp; }
//! ~english Closes the connection
//! ~russian Закрывает соединение
void close(); void close();
//! ~english Gracefully stops and waits for completion
//! ~russian Плавно останавливает и ожидает завершения
void stopAndWait(); void stopAndWait();
//! ~english Writes byte array to the connection
//! ~russian Записывает массив байтов в соединение
int write(const void * d, const size_t s); int write(const void * d, const size_t s);
//! ~english Writes byte array to the connection
//! ~russian Записывает массив байтов в соединение
int write(const PIByteArray & ba) { return write(ba.data(), ba.size()); } int write(const PIByteArray & ba) { return write(ba.data(), ba.size()); }
//! ~english Enables diagnostics collection
//! ~russian Включает сбор диагностики
void enableDiagnostics(); void enableDiagnostics();
//! ~english Gets current diagnostics state
//! ~russian Возвращает текущее состояние диагностики
PIDiagnostics::State diagnostics() const; PIDiagnostics::State diagnostics() const;
//! ~english Gets current received packet bytes already received (all bytes count passed in \a receivePacketStart())
//! ~russian Возвращает сколько байт принимаемого пакета получено (общее количество передается в \a receivePacketStart())
int receivePacketProgress() const; int receivePacketProgress() const;
const PIStreamPackerConfig & configuration() const { return stream.configuration(); } const PIStreamPackerConfig & configuration() const { return stream.configuration(); }
@@ -63,10 +88,24 @@ public:
void setConfiguration(const PIStreamPackerConfig & config) { stream.setConfiguration(config); } void setConfiguration(const PIStreamPackerConfig & config) { stream.setConfiguration(config); }
protected: protected:
//! ~english Called when data is received
//! ~russian Вызывается при получении данных
virtual void readed(PIByteArray data) {} virtual void readed(PIByteArray data) {}
//! ~english Called when connection is established
//! ~russian Вызывается при установке соединения
virtual void connected() {} virtual void connected() {}
//! ~english Called when connection is closed
//! ~russian Вызывается при закрытии соединения
virtual void disconnected() {} virtual void disconnected() {}
//! ~english Called when packet receiving starts
//! ~russian Вызывается при начале получения пакета
virtual void receivePacketStart(int size) {} virtual void receivePacketStart(int size) {}
//! ~english Called when packet receiving ends
//! ~russian Вызывается при завершении получения пакета
virtual void receivePacketEnd() {} virtual void receivePacketEnd() {}
void init(); void init();

View File

@@ -38,6 +38,8 @@ namespace PIClientServer {
class ServerClient; class ServerClient;
//! ~english TCP server for client-server communication
//! ~russian TCP сервер для клиент-серверного взаимодействия
class PIP_CLIENT_SERVER_EXPORT Server: public PIStreamPackerConfig { class PIP_CLIENT_SERVER_EXPORT Server: public PIStreamPackerConfig {
friend class ServerClient; friend class ServerClient;
NO_COPY_CLASS(Server); NO_COPY_CLASS(Server);
@@ -46,17 +48,44 @@ public:
Server(); Server();
virtual ~Server(); virtual ~Server();
//! ~english Starts listening on specified address
//! ~russian Начинает прослушивание на указанном адресе
void listen(PINetworkAddress addr); void listen(PINetworkAddress addr);
//! ~english Starts listening on all interfaces
//! ~russian Начинает прослушивание на всех интерфейсах
void listenAll(ushort port) { listen({0, port}); } void listenAll(ushort port) { listen({0, port}); }
//! ~english Stops the server
//! ~russian Останавливает сервер
void stopServer(); void stopServer();
//! ~english Closes all client connections
//! ~russian Закрывает все клиентские соединения
void closeAll(); void closeAll();
//! ~english Gets maximum allowed clients
//! ~russian Возвращает максимальное число клиентов
int getMaxClients() const { return max_clients; } int getMaxClients() const { return max_clients; }
//! ~english Sets maximum allowed clients
//! ~russian Устанавливает максимальное число клиентов
void setMaxClients(int new_max_clients); void setMaxClients(int new_max_clients);
//! ~english Gets current clients count
//! ~russian Возвращает текущее количество клиентов
int clientsCount() const; int clientsCount() const;
//! ~english Executes function for each connected client
//! ~russian Выполняет функцию для каждого подключённого клиента
void forEachClient(std::function<void(ServerClient *)> func); void forEachClient(std::function<void(ServerClient *)> func);
//! ~english Sets factory for creating new client instances
//! ~russian Устанавливает фабрику для создания клиентских экземпляров
void setClientFactory(std::function<ServerClient *()> f) { client_factory = f; } void setClientFactory(std::function<ServerClient *()> f) { client_factory = f; }
private: private:

View File

@@ -13,23 +13,51 @@ public:
}; };
//! ~english Main HTTP client class for performing requests with event callbacks.
//! ~russian Основной класс HTTP-клиента для выполнения запросов с callback-ми событий.
class PIP_HTTP_CLIENT_EXPORT PIHTTPClient: private PIHTTPClientBase { class PIP_HTTP_CLIENT_EXPORT PIHTTPClient: private PIHTTPClientBase {
friend class PIHTTPClientBase; friend class PIHTTPClientBase;
friend class CurlThreadPool; friend class CurlThreadPool;
public: public:
//! ~english Creates a new HTTP request instance with the specified URL, method and message.
//! ~russian Создает новый экземпляр HTTP-запроса с указанным URL, методом и сообщением.
static PIHTTPClient * create(const PIString & url, PIHTTP::Method method = PIHTTP::Method::Get, const PIHTTP::MessageConst & req = {}); static PIHTTPClient * create(const PIString & url, PIHTTP::Method method = PIHTTP::Method::Get, const PIHTTP::MessageConst & req = {});
//! ~english Sets a callback for successful request completion (no parameters).
//! ~russian Устанавливает callback для успешного завершения запроса (без параметров).
PIHTTPClient * onFinish(std::function<void()> f); PIHTTPClient * onFinish(std::function<void()> f);
//! ~english Sets a callback for successful request completion (with response).
//! ~russian Устанавливает callback для успешного завершения запроса (с ответом).
PIHTTPClient * onFinish(std::function<void(const PIHTTP::MessageConst &)> f); PIHTTPClient * onFinish(std::function<void(const PIHTTP::MessageConst &)> f);
//! ~english Sets a callback for request errors (no parameters).
//! ~russian Устанавливает callback для ошибок запроса (без параметров).
PIHTTPClient * onError(std::function<void()> f); PIHTTPClient * onError(std::function<void()> f);
//! ~english Sets a callback for request errors (with error response).
//! ~russian Устанавливает callback для ошибок запроса (с ответом об ошибке).
PIHTTPClient * onError(std::function<void(const PIHTTP::MessageConst &)> f); PIHTTPClient * onError(std::function<void(const PIHTTP::MessageConst &)> f);
//! ~english Sets a callback for request abortion (no parameters).
//! ~russian Устанавливает callback для прерывания запроса (без параметров).
PIHTTPClient * onAbort(std::function<void()> f); PIHTTPClient * onAbort(std::function<void()> f);
//! ~english Sets a callback for request abortion (with abort response).
//! ~russian Устанавливает callback для прерывания запроса (с ответом о прерывании).
PIHTTPClient * onAbort(std::function<void(const PIHTTP::MessageConst &)> f); PIHTTPClient * onAbort(std::function<void(const PIHTTP::MessageConst &)> f);
//! ~english Starts the HTTP request execution.
//! ~russian Начинает выполнение HTTP-запроса.
void start(); void start();
//! ~english Aborts the current HTTP request.
//! ~russian Прерывает текущий HTTP-запрос.
void abort(); void abort();
//! ~english Returns the last error message.
//! ~russian Возвращает последнее сообщение об ошибке.
PIString lastError() const { return last_error; } PIString lastError() const { return last_error; }
private: private:

View File

@@ -9,20 +9,60 @@
namespace PIHTTP { namespace PIHTTP {
//! ~english Immutable HTTP message container with accessors for message components
//! ~russian Контейнер для неизменяемого HTTP-сообщения с методами доступа к компонентам
class PIP_EXPORT MessageConst { class PIP_EXPORT MessageConst {
public: public:
//! ~english Gets the HTTP method used in the message
//! ~russian Возвращает HTTP-метод, использованный в сообщении
PIHTTP::Method method() const { return m_method; } PIHTTP::Method method() const { return m_method; }
//! ~english Gets the HTTP status code
//! ~russian Возвращает HTTP-статус код
PIHTTP::Code code() const { return m_code; } PIHTTP::Code code() const { return m_code; }
//! ~english Checks if status code is informational (1xx)
//! ~russian Проверяет, является ли статус код информационным (1xx)
bool isCodeInformational() const; bool isCodeInformational() const;
//! ~english Checks if status code indicates success (2xx)
//! ~russian Проверяет, указывает ли статус код на успех (2xx)
bool isCodeSuccess() const; bool isCodeSuccess() const;
//! ~english Checks if status code indicates redirection (3xx)
//! ~russian Проверяет, указывает ли статус код на перенаправление (3xx)
bool isCodeRedirection() const; bool isCodeRedirection() const;
//! ~english Checks if status code indicates client error (4xx)
//! ~russian Проверяет, указывает ли статус код на ошибку клиента (4xx)
bool isCodeClientError() const; bool isCodeClientError() const;
//! ~english Checks if status code indicates server error (5xx)
//! ~russian Проверяет, указывает ли статус код на ошибку сервера (5xx)
bool isCodeServerError() const; bool isCodeServerError() const;
//! ~english Checks if status code indicates any error (4xx or 5xx)
//! ~russian Проверяет, указывает ли статус код на любую ошибку (4xx или 5xx)
bool isCodeError() const { return isCodeClientError() || isCodeServerError(); } bool isCodeError() const { return isCodeClientError() || isCodeServerError(); }
//! ~english Gets the request/response path
//! ~russian Возвращает путь запроса/ответа
const PIString & path() const { return m_path; } const PIString & path() const { return m_path; }
//! ~english Gets path components as list
//! ~russian Возвращает компоненты пути в виде списка
PIStringList pathList() const { return m_path.split('/').removeAll({}); } PIStringList pathList() const { return m_path.split('/').removeAll({}); }
//! ~english Gets the message body
//! ~russian Возвращает тело сообщения
const PIByteArray & body() const { return m_body; } const PIByteArray & body() const { return m_body; }
//! ~english Gets all message headers
//! ~russian Возвращает все заголовки сообщения
const PIMap<PIString, PIString> & headers() const { return m_headers; } const PIMap<PIString, PIString> & headers() const { return m_headers; }
//! ~english Gets all message arguments
//! ~russian Возвращает все аргументы сообщения
const PIMap<PIString, PIString> & arguments() const { return m_arguments; } const PIMap<PIString, PIString> & arguments() const { return m_arguments; }
protected: protected:
@@ -35,25 +75,60 @@ protected:
}; };
//! ~english Mutable HTTP message container with modifiers for message components
//! ~russian Контейнер для изменяемого HTTP-сообщения с методами модификации
class PIP_EXPORT MessageMutable: public MessageConst { class PIP_EXPORT MessageMutable: public MessageConst {
public: public:
//! ~english Sets the HTTP method
//! ~russian Устанавливает HTTP-метод
MessageMutable & setMethod(PIHTTP::Method m); MessageMutable & setMethod(PIHTTP::Method m);
//! ~english Sets the HTTP status code
//! ~russian Устанавливает HTTP-статус код
MessageMutable & setCode(PIHTTP::Code c); MessageMutable & setCode(PIHTTP::Code c);
//! ~english Sets the request/response path
//! ~russian Устанавливает путь запроса/ответа
MessageMutable & setPath(PIString p); MessageMutable & setPath(PIString p);
//! ~english Sets the message body
//! ~russian Устанавливает тело сообщения
MessageMutable & setBody(PIByteArray b); MessageMutable & setBody(PIByteArray b);
const PIMap<PIString, PIString> & headers() const { return m_headers; } const PIMap<PIString, PIString> & headers() const { return m_headers; }
const PIMap<PIString, PIString> & arguments() const { return m_arguments; } const PIMap<PIString, PIString> & arguments() const { return m_arguments; }
PIMap<PIString, PIString> & headers() { return m_headers; } PIMap<PIString, PIString> & headers() { return m_headers; }
//! ~english Adds a header to the message
//! ~russian Добавляет заголовок к сообщению
MessageMutable & addHeader(const PIString & header, const PIString & value); MessageMutable & addHeader(const PIString & header, const PIString & value);
//! ~english Removes a header from the message
//! ~russian Удаляет заголовок из сообщения
MessageMutable & removeHeader(const PIString & header); MessageMutable & removeHeader(const PIString & header);
PIMap<PIString, PIString> & arguments() { return m_arguments; } PIMap<PIString, PIString> & arguments() { return m_arguments; }
//! ~english Adds an argument to the message
//! ~russian Добавляет аргумент к сообщению
MessageMutable & addArgument(const PIString & arg, const PIString & value); MessageMutable & addArgument(const PIString & arg, const PIString & value);
//! ~english Removes an argument from the message
//! ~russian Удаляет аргумент из сообщения
MessageMutable & removeArgument(const PIString & arg); MessageMutable & removeArgument(const PIString & arg);
//! ~english Creates message from HTTP status code
//! ~russian Создает сообщение из HTTP-статус кода
static MessageMutable fromCode(PIHTTP::Code c); static MessageMutable fromCode(PIHTTP::Code c);
//! ~english Creates message from HTTP method
//! ~russian Создает сообщение из HTTP-метода
static MessageMutable fromMethod(PIHTTP::Method m); static MessageMutable fromMethod(PIHTTP::Method m);
}; };
//! ~english Gets string representation of HTTP method
//! ~russian Возвращает строковое представление HTTP-метода
PIP_EXPORT const char * methodName(Method m); PIP_EXPORT const char * methodName(Method m);

View File

@@ -7,6 +7,8 @@
struct MicrohttpdServerConnection; struct MicrohttpdServerConnection;
//! ~english Base HTTP server class implementing core functionality
//! ~runnan Базовый класс HTTP сервера, реализующий основную функциональность
class PIP_HTTP_SERVER_EXPORT MicrohttpdServer: public PIObject { class PIP_HTTP_SERVER_EXPORT MicrohttpdServer: public PIObject {
PIOBJECT(MicrohttpdServer) PIOBJECT(MicrohttpdServer)
friend struct MicrohttpdServerConnection; friend struct MicrohttpdServerConnection;
@@ -15,30 +17,75 @@ public:
MicrohttpdServer(); MicrohttpdServer();
virtual ~MicrohttpdServer(); virtual ~MicrohttpdServer();
//! ~english Server configuration options
//! ~russian Опции конфигурации сервера
enum class Option { enum class Option {
ConnectionLimit, // uint ConnectionLimit, //!< ~english Maximum concurrent connections
ConnectionTimeout, // uint, sec //!< ~russian Максимальное количество соединений
HTTPSEnabled, // bool ConnectionTimeout, //!< ~english Connection timeout in seconds
HTTPSMemKey, // const char * to key.pem data //!< ~russian Таймаут соединения в секундах
HTTPSMemCert, // const char * to cert.pem data HTTPSEnabled, //!< ~english Enable HTTPS support
HTTPSKeyPassword // const char * to passwd for key.pem //!< ~russian Включить поддержку HTTPS
HTTPSMemKey, //!< ~english SSL key in memory (PIByteArray)
//!< ~russian SSL ключ в памяти (PIByteArray)
HTTPSMemCert, //!< ~english SSL certificate in memory (PIByteArray)
//!< ~russian SSL сертификат в памяти (PIByteArray)
HTTPSKeyPassword //!< ~english SSL key password (PIByteArray)
//!< ~russian Пароль SSL ключа (PIByteArray)
}; };
//! ~english Sets server option
//! ~russian Устанавливает опцию сервера
void setOption(Option o, PIVariant v); void setOption(Option o, PIVariant v);
//! ~english Sets server favicon
//! ~russian Устанавливает фавикон сервера
void setFavicon(const PIByteArray & im); void setFavicon(const PIByteArray & im);
//! ~english Starts server on specified address
//! ~russian Запускает сервер на указанном адресе
bool listen(PINetworkAddress addr); bool listen(PINetworkAddress addr);
//! ~english Starts server on all interfaces
//! ~russian Запускает сервер на всех интерфейсах
bool listenAll(ushort port) { return listen({0, port}); } bool listenAll(ushort port) { return listen({0, port}); }
//! ~english Checks if server is running
//! ~russian Проверяет, работает ли сервер
bool isListen() const; bool isListen() const;
//! ~english Stops the server
//! ~russian Останавливает сервер
void stop(); void stop();
//! ~english Enables basic authentication
//! ~russian Включает базовую аутентификацию
void enableBasicAuth() { setBasicAuthEnabled(true); } void enableBasicAuth() { setBasicAuthEnabled(true); }
//! ~english Disables basic authentication
//! ~russian Выключает базовую аутентификацию
void disableBasicAuth() { setBasicAuthEnabled(false); } void disableBasicAuth() { setBasicAuthEnabled(false); }
//! ~english Set basic authentication enabled to "yes"
//! ~russian Устанавливает базовую аутентификацию в "yes"
void setBasicAuthEnabled(bool yes) { use_basic_auth = yes; } void setBasicAuthEnabled(bool yes) { use_basic_auth = yes; }
//! ~english Return if basic authentication enabled
//! ~russian Возвращает включена ли базовая аутентификация
bool isBasicAuthEnabled() const { return use_basic_auth; } bool isBasicAuthEnabled() const { return use_basic_auth; }
//! ~english Sets basic authentication realm
//! ~russian Устанавливает область аутентификации
void setBasicAuthRealm(const PIString & r) { realm = r; } void setBasicAuthRealm(const PIString & r) { realm = r; }
//! ~english Sets request processing callback
//! ~russian Устанавливает callback для обработки запросов
void setRequestCallback(std::function<PIHTTP::MessageMutable(const PIHTTP::MessageConst &)> c) { callback = c; } void setRequestCallback(std::function<PIHTTP::MessageMutable(const PIHTTP::MessageConst &)> c) { callback = c; }
//! ~english Sets basic authentication callback
//! ~russian Устанавливает callback для базовой аутентификации
void setBasicAuthCallback(std::function<bool(const PIString &, const PIString &)> c) { callback_auth = c; } void setBasicAuthCallback(std::function<bool(const PIString &, const PIString &)> c) { callback_auth = c; }
private: private:

View File

@@ -3,6 +3,8 @@
#include "microhttpd_server.h" #include "microhttpd_server.h"
//! ~english HTTP server
//! ~russian HTTP сервер
class PIP_HTTP_SERVER_EXPORT PIHTTPServer: public MicrohttpdServer { class PIP_HTTP_SERVER_EXPORT PIHTTPServer: public MicrohttpdServer {
PIOBJECT_SUBCLASS(PIHTTPServer, MicrohttpdServer) PIOBJECT_SUBCLASS(PIHTTPServer, MicrohttpdServer)
@@ -12,24 +14,50 @@ public:
using RequestFunction = std::function<PIHTTP::MessageMutable(const PIHTTP::MessageConst &)>; using RequestFunction = std::function<PIHTTP::MessageMutable(const PIHTTP::MessageConst &)>;
//! ~english Registers handler for specific path and HTTP method
//! ~russian Регистрирует обработчик для указанного пути и HTTP метода
void registerPath(const PIString & path, PIHTTP::Method method, RequestFunction functor); void registerPath(const PIString & path, PIHTTP::Method method, RequestFunction functor);
//! ~english Registers handler for specific path and HTTP method
//! ~russian Регистрирует обработчик для указанного пути и HTTP метода
template<typename T> template<typename T>
void void
registerPath(const PIString & path, PIHTTP::Method method, T * o, PIHTTP::MessageMutable (T::*function)(const PIHTTP::MessageConst &)) { registerPath(const PIString & path, PIHTTP::Method method, T * o, PIHTTP::MessageMutable (T::*function)(const PIHTTP::MessageConst &)) {
registerPath(path, method, [o, function](const PIHTTP::MessageConst & m) { return (o->*function)(m); }); registerPath(path, method, [o, function](const PIHTTP::MessageConst & m) { return (o->*function)(m); });
} }
//! ~english Registers handler for unhandled requests
//! ~russian Регистрирует обработчик для необработанных запросов
void registerUnhandled(RequestFunction functor); void registerUnhandled(RequestFunction functor);
//! ~english Registers handler for unhandled requests
//! ~russian Регистрирует обработчик для необработанных запросов
template<typename T> template<typename T>
void registerUnhandled(T * o, PIHTTP::MessageMutable (T::*function)(const PIHTTP::MessageConst &)) { void registerUnhandled(T * o, PIHTTP::MessageMutable (T::*function)(const PIHTTP::MessageConst &)) {
registerUnhandled([o, function](const PIHTTP::MessageConst & m) { return (o->*function)(m); }); registerUnhandled([o, function](const PIHTTP::MessageConst & m) { return (o->*function)(m); });
} }
//! ~english Unregisters handler for specific path and method
//! ~russian Удаляет обработчик для указанного пути и метода
void unregisterPath(const PIString & path, PIHTTP::Method method); void unregisterPath(const PIString & path, PIHTTP::Method method);
//! ~english Unregisters all handlers for specific path
//! ~russian Удаляет все обработчики для указанного пути
void unregisterPath(const PIString & path); void unregisterPath(const PIString & path);
// void registerBasicAuth() {}
//! ~english Adds header to all server responses
//! ~russian Добавляет заголовок ко всем ответам сервера
void addReplyHeader(const PIString & name, const PIString & value) { reply_headers[name] = value; } void addReplyHeader(const PIString & name, const PIString & value) { reply_headers[name] = value; }
//! ~english Removes header from server responses
//! ~russian Удаляет заголовок из ответов сервера
void removeReplyHeader(const PIString & name) { reply_headers.remove(name); } void removeReplyHeader(const PIString & name) { reply_headers.remove(name); }
//! ~english Clears all custom response headers
//! ~russian Очищает все пользовательские заголовки ответов
void clearReplyHeaders() { reply_headers.clear(); } void clearReplyHeaders() { reply_headers.clear(); }
private: private:

View File

@@ -60,6 +60,9 @@ inline PIJSON piSerializeJSON(const T & v) {
// known types // known types
inline PIJSON piSerializeJSON(const PIJSON & v) {
return v;
}
template<> template<>
inline PIJSON piSerializeJSON(const PIVariant & v) { inline PIJSON piSerializeJSON(const PIVariant & v) {
return PIJSON() = v; return PIJSON() = v;
@@ -248,6 +251,9 @@ inline void piDeserializeJSON(T & v, const PIJSON & js) {
// known types // known types
inline void piDeserializeJSON(PIJSON & v, const PIJSON & js) {
v = js;
}
template<> template<>
inline void piDeserializeJSON(PIVariant & v, const PIJSON & js) { inline void piDeserializeJSON(PIVariant & v, const PIJSON & js) {
v = js.value(); v = js.value();

View File

@@ -28,40 +28,135 @@
#include "pistring.h" #include "pistring.h"
//! \ingroup Text
//! \brief Regular expression class
//! \~english Class for working with regular expressions
//! \~russian Класс для работы с регулярными выражениями
//!
class PIP_EXPORT PIRegularExpression { class PIP_EXPORT PIRegularExpression {
public: public:
//! \brief
//! \~english Options for regular expression matching behavior
//! \~russian Опции поведения регулярного выражения
enum Option { enum Option {
None = 0x0, None = 0x0, /*!< \~english No special options \~russian Без специальных опций */
CaseInsensitive = 0x01, CaseInsensitive = 0x01, /*!< \~english Case insensitive matching \~russian Регистронезависимое сопоставление */
Singleline = 0x02, Singleline = 0x02, /*!< \~english Dot matches newline \~russian Точка соответствует символу новой строки */
Multiline = 0x04, Multiline = 0x04, /*!< \~english ^ and $ match at line boundaries \~russian ^ и $ соответствуют границам строк */
InvertedGreediness = 0x08, InvertedGreediness = 0x08, /*!< \~english Quantifiers are non-greedy by default \~russian Квантификаторы по умолчанию нежадные */
Extended = 0x10 Extended = 0x10 /*!< \~english Extended pattern syntax \~russian Расширенный синтаксис шаблона */
}; };
//! \brief
//! \~english Combination of regular expression options
//! \~russian Комбинация флагов опций регулярного выражения
typedef PIFlags<Option> Options; typedef PIFlags<Option> Options;
//! \brief
//! \~english Creates regular expression with given pattern and options
//! \~russian Создает регулярное выражение с указанным шаблоном и опциями
//! \~english \param pattern Regular expression pattern
//! \~russian \param pattern Шаблон регулярного выражения
//! \~english \param opt Matching options
//! \~russian \param opt Опции сопоставления
PIRegularExpression(const PIString & pattern = {}, Options opt = None); PIRegularExpression(const PIString & pattern = {}, Options opt = None);
//! \brief
//! \~english Creates copy of regular expression
//! \~russian Создает копию регулярного выражения
//! \~english \param o Source regular expression
//! \~russian \param o Исходное регулярное выражение
PIRegularExpression(const PIRegularExpression & o); PIRegularExpression(const PIRegularExpression & o);
//! \brief
//! \~english Assigns regular expression
//! \~russian Присваивает регулярное выражение
//! \~english \param o Source regular expression
//! \~russian \param o Исходное регулярное выражение
PIRegularExpression & operator=(const PIRegularExpression & o); PIRegularExpression & operator=(const PIRegularExpression & o);
//! \brief
//! \~english Destroys regular expression object
//! \~russian Уничтожает объект регулярного выражения
~PIRegularExpression(); ~PIRegularExpression();
//! \brief
//! \~english Class containing regular expression match results
//! \~russian Класс, содержащий результаты сопоставления регулярного выражения
class PIP_EXPORT Matcher { class PIP_EXPORT Matcher {
friend class PIRegularExpression; friend class PIRegularExpression;
public: public:
//! \brief
//! \~english Returns true if match was found
//! \~russian Возвращает true, если совпадение найдено
operator bool() const { return hasMatch(); } operator bool() const { return hasMatch(); }
//! \brief
//! \~english Returns true if match was found
//! \~russian Возвращает true, если совпадение найдено
bool hasMatch() const; bool hasMatch() const;
//! \brief
//! \~english Attempts to find next match in subject string
//! \~russian Пытается найти следующее совпадение в строке
//! \~english \return true if next match was found
//! \~russian \return true, если следующее совпадение найдено
bool next(); bool next();
//! \brief
//! \~english Returns list of all matched strings
//! \~russian Возвращает список всех совпавших строк
PIStringList matchedStrings() const; PIStringList matchedStrings() const;
//! \brief
//! \~english Returns matched substring by index
//! \~russian Возвращает совпавшую подстроку по индексу
//! \~english \param index Capture group index (0 for entire match)
//! \~russian \param index Индекс группы захвата (0 для полного совпадения)
PIString matchedString(int index = 0) const; PIString matchedString(int index = 0) const;
//! \brief
//! \~english Returns start position of matched substring
//! \~russian Возвращает начальную позицию совпавшей подстроки
//! \~english \param index Capture group index (0 for entire match)
//! \~russian \param index Индекс группы захвата (0 для полного совпадения)
int matchedStart(int index = 0) const; int matchedStart(int index = 0) const;
//! \brief
//! \~english Returns length of matched substring
//! \~russian Возвращает длину совпавшей подстроки
//! \~english \param index Capture group index (0 for entire match)
//! \~russian \param index Индекс группы захвата (0 для полного совпадения)
int matchedSize(int index = 0) const; int matchedSize(int index = 0) const;
//! \brief
//! \~english Returns matched substring by group name
//! \~russian Возвращает совпавшую подстроку по имени группы
//! \~english \param gname Capture group name
//! \~russian \param gname Имя группы захвата
PIString matchedString(const PIString & gname) const; PIString matchedString(const PIString & gname) const;
//! \brief
//! \~english Returns start position of named capture group
//! \~russian Возвращает начальную позицию именованной группы захвата
//! \~english \param gname Capture group name
//! \~russian \param gname Имя группы захвата
int matchedStart(const PIString & gname) const; int matchedStart(const PIString & gname) const;
//! \brief
//! \~english Returns length of named capture group match
//! \~russian Возвращает длину совпадения именованной группы захвата
//! \~english \param gname Capture group name
//! \~russian \param gname Имя группы захвата
int matchedSize(const PIString & gname) const; int matchedSize(const PIString & gname) const;
Matcher(Matcher &&) = default; Matcher(Matcher &&) = default;
@@ -87,31 +182,142 @@ public:
size_t start_offset = 0; size_t start_offset = 0;
}; };
//! \brief
//! \~english Returns regular expression pattern
//! \~russian Возвращает шаблон регулярного выражения
PIString pattern() const { return pat_; } PIString pattern() const { return pat_; }
//! \brief
//! \~english Returns regular expression options
//! \~russian Возвращает опции регулярного выражения
Options options() const { return opt_; } Options options() const { return opt_; }
//! \brief
//! \~english Sets regular expression pattern
//! \~russian Устанавливает шаблон регулярного выражения
//! \~english \param pattern New pattern
//! \~russian \param pattern Новый шаблон
void setPattern(const PIString & pattern); void setPattern(const PIString & pattern);
//! \brief
//! \~english Sets regular expression pattern and options
//! \~russian Устанавливает шаблон и опции регулярного выражения
//! \~english \param pattern New pattern
//! \~russian \param pattern Новый шаблон
//! \~english \param opt New options
//! \~russian \param opt Новые опции
void setPattern(const PIString & pattern, Options opt); void setPattern(const PIString & pattern, Options opt);
//! \brief
//! \~english Returns true if regular expression is valid
//! \~russian Возвращает true, если регулярное выражение валидно
bool isValid() const; bool isValid() const;
//! \brief
//! \~english Returns true if regular expression is not valid
//! \~russian Возвращает true, если регулярное выражение невалидно
bool isNotValid() const { return !isValid(); } bool isNotValid() const { return !isValid(); }
//! \brief
//! \~english Returns error description if pattern is invalid
//! \~russian Возвращает описание ошибки, если шаблон невалиден
PIString errorString() const; PIString errorString() const;
//! \brief
//! \~english Returns position of error in pattern
//! \~russian Возвращает позицию ошибки в шаблоне
int errorPosition() const; int errorPosition() const;
//! \~english Gets the number of capture groups in the pattern
//! \~russian Возвращает количество групп захвата в шаблоне
int captureGroupsCount() const; int captureGroupsCount() const;
//! \~english Gets the list of named capture groups
//! \~russian Возвращает список именованных групп захвата
PIStringList captureGroupNames() const; PIStringList captureGroupNames() const;
//! \~english Gets the name of capture group by index
//! \~russian Возвращает имя группы захвата по индексу
//! \~english \param index Group index
//! \~russian \param index Индекс группы
PIString captureGroupName(int index) const; PIString captureGroupName(int index) const;
//! \~english Gets the index of named capture group
//! \~russian Возвращает индекс именованной группы захвата
//! \~english \param gname Group name
//! \~russian \param gname Имя группы
int captureGroupIndex(const PIString & gname) const; int captureGroupIndex(const PIString & gname) const;
//! \~english Matches regular expression against deep copy of subject string
//! \~russian Сопоставляет регулярное выражение с внутренней копией строки
//! \~english \param subject String to match against
//! \~russian \param subject Строка для сопоставления
//! \~english \param offset Starting position for matching
//! \~russian \param offset Начальная позиция для сопоставления
Matcher match(const PIString & subject, size_t offset = 0) const; Matcher match(const PIString & subject, size_t offset = 0) const;
//! \~english Matches regular expression against subject string
//! \~russian Сопоставляет регулярное выражение со строкой
//! \~english \param subject String to match against
//! \~russian \param subject Строка для сопоставления
//! \~english \param offset Starting position for matching
//! \~russian \param offset Начальная позиция для сопоставления
Matcher match(PIString & subject, size_t offset = 0) const; Matcher match(PIString & subject, size_t offset = 0) const;
//! \~english Matches regular expression against subject string
//! \~russian Сопоставляет регулярное выражение со строкой
//! \~english \param subject String to match against
//! \~russian \param subject Строка для сопоставления
//! \~english \param offset Starting position for matching
//! \~russian \param offset Начальная позиция для сопоставления
Matcher match(PIString && subject, size_t offset = 0) const; Matcher match(PIString && subject, size_t offset = 0) const;
//! \~english Prepere match regular expression against deep copy of subject string
//! \~russian Подготавливает сопоставление регулярного выражения с внутренней копией строки
//! \~english \param subject String to match against
//! \~russian \param subject Строка для сопоставления
//! \~english \param offset Starting position for matching
//! \~russian \param offset Начальная позиция для сопоставления
Matcher matchIterator(const PIString & subject, size_t offset = 0) const; Matcher matchIterator(const PIString & subject, size_t offset = 0) const;
//! \~english Prepere match regular expression against subject string
//! \~russian Подготавливает сопоставление регулярного выражения со строкой
//! \~english \param subject String to match against
//! \~russian \param subject Строка для сопоставления
//! \~english \param offset Starting position for matching
//! \~russian \param offset Начальная позиция для сопоставления
Matcher matchIterator(PIString & subject, size_t offset = 0) const; Matcher matchIterator(PIString & subject, size_t offset = 0) const;
//! \~english Prepere match regular expression against subject string
//! \~russian Подготавливает сопоставление регулярного выражения со строкой
//! \~english \param subject String to match against
//! \~russian \param subject Строка для сопоставления
//! \~english \param offset Starting position for matching
//! \~russian \param offset Начальная позиция для сопоставления
Matcher matchIterator(PIString && subject, size_t offset = 0) const; Matcher matchIterator(PIString && subject, size_t offset = 0) const;
//! \~english Creates regular expression from glob pattern
//! \~russian Создает регулярное выражение из glob-шаблона
//! \~english \param pattern Glob pattern
//! \~russian \param pattern Glob-шаблон
//! \~english \param opt Matching options
//! \~russian \param opt Опции сопоставления
static PIRegularExpression fromGlob(const PIString & pattern, Options opt = None); static PIRegularExpression fromGlob(const PIString & pattern, Options opt = None);
//! \~english Creates regular expression from POSIX pattern
//! \~russian Создает регулярное выражение из POSIX-шаблона
//! \~english \param pattern POSIX pattern
//! \~russian \param pattern POSIX-шаблон
//! \~english \param opt Matching options
//! \~russian \param opt Опции сопоставления
static PIRegularExpression fromPOSIX(const PIString & pattern, Options opt = None); static PIRegularExpression fromPOSIX(const PIString & pattern, Options opt = None);
private: private:

View File

@@ -62,7 +62,7 @@ void header() {
piCout << Bold << "PIP Code model generator"; piCout << Bold << "PIP Code model generator";
piCout << Cyan << "Version" << Bold << PIPVersion() << NewLine; piCout << Cyan << "Version" << Bold << PIPVersion() << NewLine;
piCout << Green << Bold << "Usage:" << Default piCout << Green << Bold << "Usage:" << Default
<< "\"pip_cmg [-hHqPpsAMESTG] -o <output_file> [-I<include_dir1>] [-I<include_dir1>] [...] [-D<define1>] [-D<define1>] [...] " << "\"pip_cmg [-hHqPpsAMESTGJ] -o <output_file> [-I<include_dir1>] [-I<include_dir1>] [...] [-D<define1>] [-D<define1>] [...] "
"<file1> [<file2>] [<file3>] [...]\"" "<file1> [<file2>] [<file3>] [...]\""
<< NewLine; << NewLine;
} }
@@ -90,6 +90,7 @@ void usage() {
piCout << "-E " << Green << "- write enums"; piCout << "-E " << Green << "- write enums";
piCout << "-S " << Green << "- write stream operators"; piCout << "-S " << Green << "- write stream operators";
piCout << "-G " << Green << "- write getter functions"; piCout << "-G " << Green << "- write getter functions";
piCout << "-J " << Green << "- write JSON functions";
// piCout << "-T " << Green << "- write text serialize functions"; // piCout << "-T " << Green << "- write text serialize functions";
piCout << "-o <output_file> " << Green piCout << "-o <output_file> " << Green
<< "- output file for code model without extension (e.g. \"ccm\" - files \"ccm.h\" and \"ccm.cpp\" will be created)"; << "- output file for code model without extension (e.g. \"ccm\" - files \"ccm.h\" and \"ccm.cpp\" will be created)";