merged AI doc, some new pages

This commit is contained in:
2026-03-12 14:46:57 +03:00
parent 07ae277f9e
commit ed13838237
206 changed files with 14088 additions and 5152 deletions

View File

@@ -1,9 +1,8 @@
/*! \file pibasetransfer.h
* \ingroup IO
* \~\brief
* \~english Base class for reliable send and receive data in fixed packets with error correction, pause and resume
* \~russian Базовый класс для надежного обмена данными с помощью фиксированных пакетов с коррекцией ошибок и паузой
*/
//! \~\file pibasetransfer.h
//! \~\ingroup IO-Utils
//! \~\brief
//! \~english Base class for reliable packet sessions with acknowledgements, pause and resume
//! \~russian Базовый класс для надежных пакетных сессий с подтверждениями, паузой и продолжением
/*
PIP - Platform Independent Primitives
Base class for reliable send and receive data in fixed packets with error correction, pause and resume
@@ -29,78 +28,276 @@
#include "picrc.h"
#include "pidiagnostics.h"
//! \~\ingroup IO-Utils
//! \~\brief
//! \~english Base transport for reliable fixed-size packet exchange over an external channel.
//! \~russian Базовый транспорт для надежного обмена пакетами фиксированного размера через внешний канал.
//! \~\details
//! \~english This class provides a foundation for reliable data transfer with features like error correction, pause/resume functionality,
//! and packet-based communication.
//! \~russian Этот класс предоставляет основу для надежной передачи данных с возможностью коррекции ошибок, паузы/возобновления и пакетной
//! коммуникации.
class PIP_EXPORT PIBaseTransfer: public PIObject {
PIOBJECT_SUBCLASS(PIBaseTransfer, PIObject);
public:
//! \~english Constructs transfer with default packet size, timeout and diagnostics.
//! \~russian Создает передачу с размером пакета, таймаутом и диагностикой по умолчанию.
PIBaseTransfer();
//! \~english Stops active transfer state and owned diagnostics.
//! \~russian Останавливает активное состояние передачи и встроенную диагностику.
~PIBaseTransfer();
#pragma pack(push, 1)
//! \~english Common header placed before every protocol packet.
//! \~russian Общий заголовок, размещаемый перед каждым пакетом протокола.
struct PIP_EXPORT PacketHeader {
//! \~english Packet signature used to recognize transfer packets.
//! \~russian Сигнатура пакета, используемая для распознавания пакетов передачи.
uint sig;
//! \~english Packet type from the transfer protocol.
//! \~russian Тип пакета из протокола передачи.
int type; // PacketType
//! \~english Session identifier for current transfer exchange.
//! \~russian Идентификатор сессии текущего обмена.
int session_id;
//! \~english Sequential packet identifier inside the session.
//! \~russian Последовательный идентификатор пакета внутри сессии.
uint id;
//! \~english CRC calculated for the packet payload.
//! \~russian CRC, вычисленная для полезной нагрузки пакета.
uint crc;
//! \~english Returns whether the packet signature matches \a packetSignature().
//! \~russian Возвращает, совпадает ли сигнатура пакета с \a packetSignature().
bool check_sig() { return (sig == signature); }
};
//! \~english Logical fragment description used to split data into packets.
//! \~russian Описание логического фрагмента, используемое для разбиения данных на пакеты.
struct PIP_EXPORT Part {
//! \~english Constructs part metadata for item "id_", fragment size "size_" and offset "start_".
//! \~russian Создает метаданные части для элемента "id_", размера фрагмента "size_" и смещения "start_".
Part(uint id_ = 0, ullong size_ = 0, ullong start_ = 0): id(id_), size(size_), start(start_) {}
//! \~english Identifier of the logical item being transferred.
//! \~russian Идентификатор логического элемента, который передается.
uint id;
//! \~english Size of this fragment in bytes.
//! \~russian Размер этого фрагмента в байтах.
ullong size;
//! \~english Byte offset of this fragment inside the logical item.
//! \~russian Смещение этого фрагмента в байтах внутри логического элемента.
ullong start;
};
#pragma pack(pop)
//! \~english Requests cancellation of the current send session.
//! \~russian Запрашивает отмену текущей сессии отправки.
void stopSend();
//! \~english Requests cancellation of the current receive session.
//! \~russian Запрашивает отмену текущей сессии приема.
void stopReceive();
//! \~english Returns whether a send session is active.
//! \~russian Возвращает, активна ли сессия отправки.
bool isSending() const { return is_sending; }
//! \~english Returns whether a receive session is active.
//! \~russian Возвращает, активна ли сессия приема.
bool isReceiving() const { return is_receiving; }
//! \~english Returns whether the transfer is currently paused.
//! \~russian Возвращает, находится ли передача сейчас на паузе.
bool isPause() const { return is_pause; }
//! \~english Switches current session between paused and resumed states.
//! \~russian Переключает текущую сессию между состояниями паузы и продолжения.
void setPause(bool pause_);
//! \~english Sets maximum encoded packet size in bytes.
//! \~russian Устанавливает максимальный размер кодированного пакета в байтах.
void setPacketSize(int size) { packet_size = size; }
//! \~english Returns maximum encoded packet size in bytes.
//! \~russian Возвращает максимальный размер кодированного пакета в байтах.
int packetSize() const { return packet_size; }
//! \~english Sets session timeout in seconds for start negotiation, acknowledgements and pause recovery.
//! \~russian Устанавливает таймаут сессии в секундах для согласования старта, подтверждений и восстановления после паузы.
void setTimeout(double sec);
//! \~english Returns session timeout in seconds.
//! \~russian Возвращает таймаут сессии в секундах.
double timeout() const { return timeout_; }
//! \~english Enables or disables CRC validation for data packets.
//! \~russian Включает или выключает проверку CRC для пакетов данных.
void setCRCEnabled(bool en = true) { crc_enabled = en; }
//! \~english Returns whether CRC validation is enabled.
//! \~russian Возвращает, включена ли проверка CRC.
bool isCRCEnabled() const { return crc_enabled; }
//! \~english Returns short textual state of the current session.
//! \~russian Возвращает краткое текстовое состояние текущей сессии.
PIString stateString() const { return state_string; }
//! \~english Returns a map of successfully received or transmitted packets for the current session.
//! \~russian Возвращает карту успешно принятых или переданных пакетов для текущей сессии.
PIString packetMap() const { return pm_string; }
//! \~english Returns total number of bytes planned for the current session.
//! \~russian Возвращает общее число байтов, запланированных для текущей сессии.
llong bytesAll() const { return bytes_all; }
//! \~english Returns number of bytes already processed in the current session.
//! \~russian Возвращает число байтов, уже обработанных в текущей сессии.
llong bytesCur() const { return bytes_cur; }
//! \~english Get diagnostics object
//! \~russian Получить объект диагностики
//! \~\return
//! \~english Diagnostic object reference
//! \~russian Ссылка на объект диагностики
const PIDiagnostics & diagnostic() { return diag; }
//! \~english Returns the packet signature constant used by the protocol.
//! \~russian Возвращает константу сигнатуры пакета, используемую протоколом.
static uint packetSignature() { return signature; }
//! \~\handlers
//! \~\{
//! \~\fn void received(PIByteArray data)
//! \~english Processes a single encoded packet received from an external transport.
//! \~russian Обрабатывает один закодированный пакет, полученный от внешнего транспорта.
//! \~\note
//! \~english This handler must be called when data is received by an external transport.
//! \~russian Этот обработчик необходимо вызывать при получении данных внешним транспортом.
EVENT_HANDLER1(void, received, PIByteArray, data);
//! \~\fn void stop()
//! \~english Stops both sending and receiving sides of the current session.
//! \~russian Останавливает и отправку, и прием текущей сессии.
//! \~\note
//! \~english Equivalent to calling both `stopSend()` and `stopReceive()`.
//! \~russian Эквивалентно вызову `stopSend()` и `stopReceive()`.
EVENT_HANDLER(void, stop) {
stopSend();
stopReceive();
}
//! \~\fn void pause()
//! \~english Switches current session to paused state.
//! \~russian Переводит текущую сессию в состояние паузы.
//! \~\note
//! \~english Triggers the `paused()` signal.
//! \~russian Генерирует событие `paused()`.
EVENT_HANDLER(void, pause) { setPause(true); }
//! \~\fn void resume()
//! \~english Resumes the current paused session.
//! \~russian Продолжает текущую приостановленную сессию.
//! \~\note
//! \~english Triggers the `resumed()` signal.
//! \~russian Генерирует событие `resumed()`.
EVENT_HANDLER(void, resume) { setPause(false); }
//! \~\}
//! \~\events
//! \~\{
//! \~\fn void receiveStarted()
//! \~english Emitted when a receive session is accepted and initialized.
//! \~russian Генерируется, когда сессия приема принята и инициализирована.
//! \~\note
//! \~english Triggered by internal logic after receiving a valid `pt_Start` packet.
//! \~russian Генерируется внутренней логикой после получения корректного пакета типа `pt_Start`.
EVENT(receiveStarted);
//! \~\fn void paused()
//! \~english Emitted when the transfer enters paused state.
//! \~russian Генерируется, когда передача переходит в состояние паузы.
//! \~\note
//! \~english Triggered when `pause` handler is invoked (e.g., via `setPause(true)` or incoming `pt_Pause`).
//! \~russian Генерируется при вызове обработчика `pause` (например, через `setPause(true)` или получении `pt_Pause`).
EVENT(paused);
//! \~\fn void resumed()
//! \~english Emitted when the transfer leaves paused state.
//! \~russian Генерируется, когда передача выходит из состояния паузы.
//! \~\note
//! \~english Triggered when `resume` handler is invoked (e.g., via `setPause(false)` or incoming `pt_Start` during pause).
//! \~russian Генерируется при вызове обработчика `resume` (например, через `setPause(false)` или получении `pt_Start` во время
//! паузы).
EVENT(resumed);
//! \~\fn void receiveFinished(bool ok)
//! \~english Emitted when the receive session finishes with result "ok".
//! \~russian Генерируется, когда сессия приема завершается с результатом "ok".
//! \~\param ok
//! \~english `true` if all packets were received and verified, `false` on error or interruption.
//! \~russian `true`, если все пакеты получены и проверены, `false` — при ошибке или прерывании.
EVENT1(receiveFinished, bool, ok);
//! \~\fn void sendStarted()
//! \~english Emitted when a prepared send session starts.
//! \~russian Генерируется при запуске подготовленной сессии отправки.
//! \~\note
//! \~english Triggered after `buildSession()` and before the first packet is sent.
//! \~russian Генерируется после `buildSession()` и до отправки первого пакета.
EVENT(sendStarted);
//! \~\fn void sendFinished(bool ok)
//! \~english Emitted when the send session finishes with result "ok".
//! \~russian Генерируется, когда сессия отправки завершается с результатом "ok".
//! \~\param ok
//! \~english `true` if all packets were sent and acknowledged, `false` on error or timeout.
//! \~russian `true`, если все пакеты отправлены и подтверждены, `false` — при ошибке или таймауте.
EVENT1(sendFinished, bool, ok);
//! \~\fn void sendRequest(PIByteArray &data)
//! \~english Emitted for every encoded packet that must be written to the external transport.
//! \~russian Генерируется для каждого закодированного пакета, который нужно записать во внешний транспорт.
//! \~\param data
//! \~english Encoded packet including protocol header and payload.
//! \~russian Закодированный пакет, включая заголовок протокола и полезную нагрузку.
//! \~\note
//! \~english The external transport should send this data.
//! \~russian Внешний транспорт должен отправить эти данные.
EVENT1(sendRequest, PIByteArray &, data);
//! \~\}
protected:
//! \~english Builds session packet layout for logical parts in "parts".
//! \~russian Формирует раскладку пакетов сессии для логических частей из "parts".
void buildSession(PIVector<Part> parts);
//! \~english Returns payload bytes for one requested logical fragment.
//! \~russian Возвращает байты полезной нагрузки для одного запрошенного логического фрагмента.
virtual PIByteArray buildPacket(Part fi) = 0;
//! \~english Consumes one received logical fragment and optional custom packet header.
//! \~russian Обрабатывает один принятый логический фрагмент и необязательный пользовательский заголовок пакета.
virtual void receivePart(Part fi, PIByteArray ba, PIByteArray pheader) = 0;
//! \~english Called after a new receive session is accepted and initialized.
//! \~russian Вызывается после принятия и инициализации новой сессии приема.
virtual void beginReceive() { ; }
//! \~english Custom header
//! \~russian Пользовательский заголовок
virtual PIByteArray customHeader() { return PIByteArray(); }
//! \~english Runs the prepared send session until success, failure or cancellation.
//! \~russian Выполняет подготовленную сессию отправки до успеха, ошибки или отмены.
bool send_process();
uint packet_header_size, part_header_size;
@@ -156,33 +353,48 @@ private:
};
//! \~english Binary stream write operator for PacketHeader
//! \~russian Оператор записи в бинарный поток для PacketHeader
BINARY_STREAM_WRITE(PIBaseTransfer::PacketHeader) {
s << v.sig << v.type << v.session_id << v.id << v.crc;
return s;
}
//! \~english Binary stream read operator for PacketHeader
//! \~russian Оператор чтения из бинарного потока для PacketHeader
BINARY_STREAM_READ(PIBaseTransfer::PacketHeader) {
s >> v.sig >> v.type >> v.session_id >> v.id >> v.crc;
return s;
}
//! \~english Binary stream write operator for Part
//! \~russian Оператор записи в бинарный поток для Part
BINARY_STREAM_WRITE(PIBaseTransfer::Part) {
s << v.id << v.size << v.start;
return s;
}
//! \~english Binary stream read operator for Part
//! \~russian Оператор чтения из бинарного потока для Part
BINARY_STREAM_READ(PIBaseTransfer::Part) {
s >> v.id >> v.size >> v.start;
return s;
}
//! \~english Binary stream write operator for StartRequest
//! \~russian Оператор записи в бинарный поток для StartRequest
BINARY_STREAM_WRITE(PIBaseTransfer::StartRequest) {
s << v.packets << v.size;
return s;
}
//! \~english Binary stream read operator for StartRequest
//! \~russian Оператор чтения из бинарного потока для StartRequest
BINARY_STREAM_READ(PIBaseTransfer::StartRequest) {
s >> v.packets >> v.size;
return s;
}
//! \~\relatesalso PICout
//! \~english Writes Part to \a PICout.
//! \~russian Выводит Part в \a PICout.
inline PICout operator<<(PICout s, const PIBaseTransfer::Part & v) {
s.saveAndSetControls(0);
s << "Part(\"" << v.id << "\", " << PIString::readableSize(v.start) << " b | " << PIString::readableSize(v.size) << " b)";

View File

@@ -1,9 +1,8 @@
/*! \file pibroadcast.h
* \ingroup IO-Utils
* \~\brief
* \~english Broadcast for all interfaces, including loopback
* \~russian Широкое вещание на все интерфейсы, включая loopback
*/
//! \~\file pibroadcast.h
//! \~\ingroup IO-Utils
//! \~\brief
//! \~english Multi-interface UDP broadcast, multicast and loopback helper
//! \~russian Вспомогательный класс для UDP broadcast, multicast и loopback на нескольких интерфейсах
/*
PIP - Platform Independent Primitives
Broadcast for all interfaces, including loopback
@@ -31,106 +30,140 @@
#include "pip_io_utils_export.h"
//! \~\ingroup IO-Utils
//! \~\brief
//! \~english Multi-channel sender and receiver over multicast, broadcast and loopback endpoints.
//! \~russian Многоканальный отправитель и приемник через multicast-, broadcast- и loopback-конечные точки.
class PIP_IO_UTILS_EXPORT PIBroadcast
: public PIThread
, public PIEthUtilBase {
PIOBJECT_SUBCLASS(PIBroadcast, PIThread);
public:
//! %PIBroadcast channels, can be used independently
//! \~english Transport channels that may be enabled independently.
//! \~russian Транспортные каналы, которые можно включать независимо.
enum Channel {
Multicast /** Use multicast addresses */ = 0x01,
Broadcast /** Use broadcast addresses */ = 0x02,
Loopback /** Use loopback addresses */ = 0x04,
All /** Use all channels */ = 0xFFFF,
Multicast = 0x01 /** \~english Use multicast addresses \~russian Использовать multicast-адреса */,
Broadcast = 0x02 /** \~english Use broadcast addresses \~russian Использовать broadcast-адреса */,
Loopback = 0x04 /** \~english Use loopback addresses \~russian Использовать loopback-адреса */,
All = 0xFFFF /** \~english Use all channels \~russian Использовать все каналы */
};
//! \~english Bitmask of enabled \a Channel values.
//! \~russian Битовая маска включенных значений \a Channel.
typedef PIFlags<Channel> Channels;
/** Contructs %PIBroadcast, if \"send_only\" not set
* all PIEthernets will be binded to receive data
* */
//! \~english Constructs broadcaster, optionally in send-only mode.
//! \~russian Создает broadcaster, при необходимости в режиме только отправки.
//! \~\details
//! \~english
//! When "send_only" is false, receive sockets are initialized too.
//! \~russian
//! Если "send_only" равно false, также инициализируются приемные сокеты.
PIBroadcast(bool send_only = false);
//! \~english Destroys broadcaster and owned transport endpoints.
//! \~russian Уничтожает broadcaster и принадлежащие ему транспортные конечные точки.
~PIBroadcast();
//! Set channels to \"ch\" and queue to reinit
//! \~english Sets enabled channels and schedules reinitialization.
//! \~russian Устанавливает включенные каналы и планирует переинициализацию.
void setChannels(Channels ch);
//! Returns channels
//! \~english Returns enabled channels.
//! \~russian Возвращает включенные каналы.
Channels channels() const { return _channels; }
//! Returns if is send_only
//! \~english Returns whether this instance is send-only.
//! \~russian Возвращает, работает ли экземпляр только на отправку.
bool isSendOnly() const { return _send_only; }
//! Set multicast IP to \"mg\" and queue to reinit
//! \~english Sets multicast group IP and schedules reinitialization.
//! \~russian Устанавливает IP multicast-группы и планирует переинициализацию.
void setMulticastGroup(const PIString & mg);
//! Returns multicast IP
//! \~english Returns multicast group IP.
//! \~russian Возвращает IP multicast-группы.
PIString multicastGroup() const { return mcast_address.ipString(); }
//! Set multicast port to \"port\" and queue to reinit
//! \~english Sets multicast port and schedules reinitialization.
//! \~russian Устанавливает multicast-порт и планирует переинициализацию.
void setMulticastPort(ushort port);
//! Returns multicast port
//! \~english Returns multicast port.
//! \~russian Возвращает multicast-порт.
ushort multicastPort() const { return mcast_address.port(); }
//! Set multicast address to \"addr\" and queue to reinit
//! \~english Sets full multicast address and schedules reinitialization.
//! \~russian Устанавливает полный multicast-адрес и планирует переинициализацию.
void setMulticastAddress(const PINetworkAddress & addr);
//! Returns multicast address
//! \~english Returns multicast endpoint address.
//! \~russian Возвращает адрес multicast-конечной точки.
PINetworkAddress multicastAddress() const { return mcast_address; }
//! Set broadcast port to \"port\" and queue to reinit
//! \~english Sets broadcast port and schedules reinitialization.
//! \~russian Устанавливает broadcast-порт и планирует переинициализацию.
void setBroadcastPort(ushort port);
//! Returns broadcast port
//! \~english Returns broadcast port.
//! \~russian Возвращает broadcast-порт.
ushort broadcastPort() { return bcast_port; }
//! Set loopback start port to \"port\" and queue to reinit
//! \~english Sets first loopback port and schedules reinitialization.
//! \~russian Устанавливает первый loopback-порт и планирует переинициализацию.
void setLoopbackPort(ushort port);
//! Returns loopback start port
//! \~english Returns first loopback port.
//! \~russian Возвращает первый loopback-порт.
ushort loopbackPort() { return lo_port; }
//! Set loopback ports count to \"count\" and queue to reinit
//! \~english Sets number of loopback ports and schedules reinitialization.
//! \~russian Устанавливает число loopback-портов и планирует переинициализацию.
void setLoopbackPortsCount(int count);
//! Returns loopback ports count
//! \~english Returns number of loopback ports.
//! \~russian Возвращает число loopback-портов.
int loopbackPortsCount() const { return lo_pcnt; }
//! If not send_only starts all threaded reads
//! \~english Starts receiving on all initialized channels.
//! \~russian Запускает прием на всех инициализированных каналах.
void startRead();
//! Stop all threaded reads
//! \~english Stops receiving on all initialized channels.
//! \~russian Останавливает прием на всех инициализированных каналах.
void stopRead();
//! Reinit all PIEthernets with current \a PIEthernet::allAddresses()
//! \~english Rebuilds transport endpoints for current \a PIEthernet::allAddresses().
//! \~russian Пересоздает транспортные конечные точки для текущего списка \a PIEthernet::allAddresses().
void reinit();
//! Send packet
//! \~english Sends one packet through all enabled channels.
//! \~russian Отправляет один пакет через все включенные каналы.
void send(const PIByteArray & data);
EVENT1(receiveEvent, PIByteArray, data);
//! \events
//! \{
//! \fn void receiveEvent(PIByteArray data)
//! \brief Raise on packet received
//! \~english Emitted when a packet is received on any active channel.
//! \~russian Генерируется при получении пакета на любом активном канале.
EVENT1(receiveEvent, PIByteArray, data);
//! \}
protected:
//! Called when packet received
//! \~english Called when a packet is received.
//! \~russian Вызывается при получении пакета.
virtual void received(PIByteArray data) {}
//! Called when addresses are changed
//! \~english Called after local interface address list changes.
//! \~russian Вызывается после изменения списка адресов локальных интерфейсов.
virtual void addressesChanged() {}
private:

View File

@@ -1,10 +1,8 @@
/*! \file piconnection.h
* \brief
* \ingroup IO-Utils
* \~\brief
* \~english Complex I/O point
* \~russian Составное устройство ввода/вывода
*/
//! \~\file piconnection.h
//! \~\ingroup IO-Utils
//! \~\brief
//! \~english Connection routing helper built on shared devices and packet filters
//! \~russian Вспомогательный класс маршрутизации поверх общих устройств и пакетных фильтров
/*
PIP - Platform Independent Primitives
Complex I/O point
@@ -32,267 +30,389 @@
class PIConfig;
//! \~\ingroup IO-Utils
//! \~\brief
//! \~english Routes data between shared devices, packet extractors, channels and periodic senders.
//! \~russian Маршрутизирует данные между общими устройствами, извлекателями пакетов, каналами и периодическими отправителями.
//!
//! \~\details
//! \~english
//! %PIConnection uses a process-wide device pool so several connections can
//! share the same physical device. Raw device data may be forwarded into named
//! filters, routed through channels, monitored with diagnostics and emitted by
//! periodic senders.
//! \~russian
//! %PIConnection использует общий для процесса пул устройств, поэтому несколько
//! соединений могут разделять одно физическое устройство. Сырые данные
//! устройств могут передаваться в именованные фильтры, маршрутизироваться по
//! каналам, контролироваться диагностикой и отправляться периодическими
//! отправителями.
class PIP_EXPORT PIConnection: public PIObject {
PIOBJECT_SUBCLASS(PIConnection, PIObject);
public:
//! Constructs connection with name "name", or with default name = "connection"
//! \~english Constructs an empty connection with name "name".
//! \~russian Создает пустое соединение с именем "name".
PIConnection(const PIString & name = PIStringAscii("connection"));
//! Constructs connection and configure it from config file "config" from section "name"
//! \~english Constructs a connection and immediately configures it from section "name" of file "config".
//! \~russian Создает соединение и сразу настраивает его из секции "name" файла "config".
PIConnection(const PIString & config, const PIString & name);
//! Constructs connection and configure it from config content "string" from section "name"
//! \~english Constructs a connection and immediately configures it from section "name" stored in "string".
//! \~russian Создает соединение и сразу настраивает его из секции "name", хранящейся в "string".
PIConnection(PIString * string, const PIString & name);
//! \~english Releases all bindings owned by this connection.
//! \~russian Освобождает все привязки, принадлежащие этому соединению.
~PIConnection();
/*! \brief Configure connection from config file "config" from section "name". Returns if configuration was successful
* \details \b Warning: all devices, filters and channels removed before configure! */
//! \~english Reconfigures the connection from section "name" of file "config".
//! \~russian Перенастраивает соединение из секции "name" файла "config".
//! \~\details
//! \~english \b Warning: all devices, filters and channels removed before configure!
//! \~russian \b Внимание: все устройства, фильтры и каналы удаляются перед настройкой!
bool configureFromConfig(const PIString & config, const PIString & name = PIStringAscii("connection"));
/*! \brief Configure connection from config content "string" from section "name". Returns if configuration was successful
* \details \b Warning: all devices, filters and channels removed before configure! */
//! \~english Reconfigures the connection from section "name" stored in "string".
//! \~russian Перенастраивает соединение из секции "name", хранящейся в "string".
//! \~\details
//! \~english \b Warning: all devices, filters and channels removed before configure!
//! \~russian \b Внимание: все устройства, фильтры и каналы удаляются перед настройкой!
bool configureFromString(PIString * string, const PIString & name = PIStringAscii("connection"));
//! Returns config file section of current connection configuration
//! \~english Serializes current connection state into one configuration section.
//! \~russian Сериализует текущее состояние соединения в одну секцию конфигурации.
PIString makeConfig() const;
/*! \brief Add device with full path "full_path", open mode "mode" to Device pool and connection
* \details Returns pointer to device or null if device can not be created. If "start" is true,
* read thread is started immediately. Else, you can start read thread with functions \a startThreadedRead()
* or \a startAllThreadedReads(). By default, read thread doesn`t start */
//! \~english Adds device "full_path" to the shared device pool and binds it to this connection.
//! \~russian Добавляет устройство "full_path" в общий пул устройств и привязывает его к этому соединению.
//! \~\details
//! \~english Returns the shared device instance or \c nullptr when creation fails. When "start" is \b true, threaded read starts
//! immediately.
//! \~russian Возвращает общий экземпляр устройства или \c nullptr, если создание не удалось. Если "start" равно \b true, потоковое
//! чтение запускается сразу.
PIIODevice * addDevice(const PIString & full_path, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite, bool start = false);
//! \~english Assigns alias "name" to device "dev" inside this connection.
//! \~russian Назначает устройству "dev" псевдоним "name" внутри этого соединения.
void setDeviceName(PIIODevice * dev, const PIString & name);
//! \~english Returns all aliases assigned to device "dev" in this connection.
//! \~russian Возвращает все псевдонимы устройства "dev" в этом соединении.
PIStringList deviceNames(const PIIODevice * dev) const;
/*! \brief Remove device with full path "full_path" from connection
* \details Returns if device was removed. If there is no connection bounded to this device,
* it will be removed from Device pool */
//! \~english Unbinds device "full_path" from this connection.
//! \~russian Отвязывает устройство "full_path" от этого соединения.
//! \~\details
//! \~english The shared device object is deleted from the pool only when no connections still use it.
//! \~russian Общий объект устройства удаляется из пула только тогда, когда им больше не пользуется ни одно соединение.
bool removeDevice(const PIString & full_path);
/*! \brief Remove all device from connection
* \details If there is no connection bounded to there devices, they removed from Device pool */
//! \~english Removes all devices currently bound to this connection.
//! \~russian Удаляет все устройства, привязанные к этому соединению.
//! \~\details
//! \~english Devices remain in the shared pool while they are still referenced by other connections.
//! \~russian Устройства остаются в общем пуле, пока на них ссылаются другие соединения.
void removeAllDevices();
//! Returns device with full path "full_path" or null if there is no such device
//! \~english Returns bound device by normalized full path.
//! \~russian Возвращает привязанное устройство по нормализованному полному пути.
PIIODevice * deviceByFullPath(const PIString & full_path) const;
//! Returns device with name "name" or null if there is no such device
//! \~english Returns bound device by alias.
//! \~russian Возвращает привязанное устройство по псевдониму.
PIIODevice * deviceByName(const PIString & name) const;
//! Returns all devices bounded to this connection
//! \~english Returns all devices currently bound to this connection.
//! \~russian Возвращает все устройства, привязанные к этому соединению.
PIVector<PIIODevice *> boundedDevices() const;
/*! \brief Add filter with name "name" to device with full path "full_path_name" or filter "full_path_name"
* \details If there is no filter with name "name", connection create new with split mode "mode" and bound
* to it device "full_path_name" or filter "full_path_name". If filter with name "name" already exists,
* device "full_path_name" or filter "full_path_name" add to this filter.
* This function returns PIPacketExtractor * assosiated with this filter
* \n \b Attention! "mode" is altual olny if new filter was created! */
//! \~english Creates or reuses filter "name" and binds source "full_path_name" to it.
//! \~russian Создает или повторно использует фильтр "name" и привязывает к нему источник "full_path_name".
//! \~\details
//! \~english If there is no filter with name "name", connection create new with split mode "mode" and bound
//! to it device "full_path_name" or filter "full_path_name". If filter with name "name" already exists,
//! device "full_path_name" or filter "full_path_name" add to this filter.
//! This function returns PIPacketExtractor * assosiated with this filter.
//! \~russian Если фильтра с именем "name" не существует, соединение создаст новый фильтр с режимом разделения "mode"
//! и привяжет к нему устройство "full_path_name" или фильтр "full_path_name". Если фильтр с именем "name" уже существует,
//! устройство "full_path_name" или фильтр "full_path_name" добавляется к этому фильтру.
//! Эта функция возвращает PIPacketExtractor *, связанный с этим фильтром.
//! \~\note
//! \~english \b Attention! "mode" is altual olny if new filter was created!
//! \~russian \b Внимание! "mode" актуален только если был создан новый фильтр!
//! \~\sa PIPacketExtractor
PIPacketExtractor *
addFilter(const PIString & name, const PIString & full_path_name, PIPacketExtractor::SplitMode mode = PIPacketExtractor::None);
//! Add filter with name "name" to device "dev"
//! \~english Creates or reuses filter "name" and binds device "dev" to it.
//! \~russian Создает или повторно использует фильтр "name" и привязывает к нему устройство "dev".
PIPacketExtractor *
addFilter(const PIString & name, const PIIODevice * dev, PIPacketExtractor::SplitMode mode = PIPacketExtractor::None) {
return addFilter(name, devFPath(dev), mode);
}
//! Add filter with "filter" to device "dev"
//! \~english Binds existing extractor object "filter" to source "full_path_name".
//! \~russian Привязывает существующий объект извлекателя "filter" к источнику "full_path_name".
PIPacketExtractor * addFilter(PIPacketExtractor * filter, const PIString & full_path_name);
//! Add filter with "filter" to device "dev"
//! \~english Binds existing extractor object "filter" to device "dev".
//! \~russian Привязывает существующий объект извлекателя "filter" к устройству "dev".
PIPacketExtractor * addFilter(PIPacketExtractor * filter, const PIIODevice * dev) { return addFilter(filter, devFPath(dev)); }
/*! \brief Remove from filter with name "name" device with full path "full_path_name" or filter "full_path_name"
* \details If there is no devices bounded to this filter, it will be removed. Returns if device was removed */
//! \~english Unbinds source "full_path_name" from filter "name".
//! \~russian Отвязывает источник "full_path_name" от фильтра "name".
//! \~\details
//! \~english Removes the filter itself when it no longer has any bound sources.
//! \~russian Удаляет сам фильтр, когда у него больше не остается привязанных источников.
bool removeFilter(const PIString & name, const PIString & full_path_name);
//! Remove from filter with name "name" device or filter "dev"
//! \~english Unbinds device or upstream filter "dev" from filter "name".
//! \~russian Отвязывает устройство или вышестоящий фильтр "dev" от фильтра "name".
bool removeFilter(const PIString & name, const PIIODevice * dev);
//! Remove filter with name "name". Returns if filter was removed
//! \~english Removes filter "name" together with all its bindings.
//! \~russian Удаляет фильтр "name" вместе со всеми его привязками.
bool removeFilter(const PIString & name);
//! Remove all filters from connection
//! \~english Removes all filters from this connection.
//! \~russian Удаляет все фильтры из этого соединения.
void removeAllFilters();
//! Returns all filters of connection
//! \~english Returns all filters owned by this connection.
//! \~russian Возвращает все фильтры, принадлежащие этому соединению.
PIVector<PIPacketExtractor *> filters() const;
//! Returns all filter names of connection
//! \~english Returns names of all filters owned by this connection.
//! \~russian Возвращает имена всех фильтров, принадлежащих этому соединению.
PIStringList filterNames() const;
//! Returns PIPacketExtractor * assosiated with filter "name" or null if there is no such filter
//! \~english Returns filter "name" or \c nullptr when it does not exist.
//! \~russian Возвращает фильтр "name" или \c nullptr, если такого фильтра нет.
PIPacketExtractor * filter(const PIString & name) const;
//! Returns all devices bounded to filter "name"
//! \~english Returns all sources currently bound to filter "name".
//! \~russian Возвращает все источники, привязанные к фильтру "name".
PIVector<PIIODevice *> filterBoundedDevices(const PIString & name) const;
/*! \brief Add to connection channel from "name_from" to "name_to"
* \details "name_from" and "name_to" can be full pathes of devices or device names or filter names.
* Returns \b false if there if no such device or filter, else create channel and returns \b true */
//! \~english Adds a routing channel from "name_from" to "name_to".
//! \~russian Добавляет канал маршрутизации от "name_from" к "name_to".
//! \~\details
//! \~english Both endpoints may reference a device full path, a device alias or a filter name.
//! \~russian Оба конца канала могут ссылаться на полный путь устройства, псевдоним устройства или имя фильтра.
bool addChannel(const PIString & name_from, const PIString & name_to);
//! Add to connection channel from "name_from" to "dev_to"
//! \~english Adds a routing channel from "name_from" to device "dev_to".
//! \~russian Добавляет канал маршрутизации от "name_from" к устройству "dev_to".
bool addChannel(const PIString & name_from, const PIIODevice * dev_to) { return addChannel(name_from, devFPath(dev_to)); }
//! Add to connection channel from "dev_from" to "name_to"
//! \~english Adds a routing channel from device "dev_from" to "name_to".
//! \~russian Добавляет канал маршрутизации от устройства "dev_from" к "name_to".
bool addChannel(const PIIODevice * dev_from, const PIString & name_to) { return addChannel(devFPath(dev_from), name_to); }
//! Add to connection channel from "dev_from" to "dev_to"
//! \~english Adds a routing channel from device "dev_from" to device "dev_to".
//! \~russian Добавляет канал маршрутизации от устройства "dev_from" к устройству "dev_to".
bool addChannel(const PIIODevice * dev_from, const PIIODevice * dev_to) { return addChannel(devFPath(dev_from), devFPath(dev_to)); }
/*! \brief Remove from connection channel from "name_from" to "name_to"
* \details "name_from" and "name_to" can be full pathes of devices or filter names.
* Returns \b false if there if no such device or filter, else remove channel and returns \b true */
//! \~english Removes routing channel from "name_from" to "name_to".
//! \~russian Удаляет канал маршрутизации от "name_from" к "name_to".
bool removeChannel(const PIString & name_from, const PIString & name_to);
//! Remove from connection channel from "name_from" to "dev_to"
//! \~english Removes routing channel from "name_from" to device "dev_to".
//! \~russian Удаляет канал маршрутизации от "name_from" к устройству "dev_to".
bool removeChannel(const PIString & name_from, const PIIODevice * dev_to) { return removeChannel(name_from, devFPath(dev_to)); }
//! Remove from connection channel from "dev_from" to "name_to"
//! \~english Removes routing channel from device "dev_from" to "name_to".
//! \~russian Удаляет канал маршрутизации от устройства "dev_from" к "name_to".
bool removeChannel(const PIIODevice * dev_from, const PIString & name_to) { return removeChannel(devFPath(dev_from), name_to); }
//! Remove from connection channel from "dev_from" to "dev_to"
//! \~english Removes routing channel from device "dev_from" to device "dev_to".
//! \~russian Удаляет канал маршрутизации от устройства "dev_from" к устройству "dev_to".
bool removeChannel(const PIIODevice * dev_from, const PIIODevice * dev_to) {
return removeChannel(devFPath(dev_from), devFPath(dev_to));
}
/*! \brief Remove from connection all channels from "name_from"
* \details "name_from" can be full path of device or filter name.
* Returns \b false if there if no such device or filter, else remove channels and returns \b true */
//! \~english Removes all outgoing channels starting from "name_from".
//! \~russian Удаляет все исходящие каналы, начинающиеся в "name_from".
bool removeChannel(const PIString & name_from);
//! Remove from connection all channels from "dev_from"
//! \~english Removes all outgoing channels starting from device "dev_from".
//! \~russian Удаляет все исходящие каналы, начинающиеся от устройства "dev_from".
bool removeChannel(const PIIODevice * dev_from) { return removeChannel(devFPath(dev_from)); }
//! Remove from connection all channels
//! \~english Removes all routing channels from this connection.
//! \~russian Удаляет все каналы маршрутизации из этого соединения.
void removeAllChannels();
//! Returns all channels of this connection as full pathes or filter names pair array (from, to)
//! \~english Returns all routing channels as source and destination pairs.
//! \~russian Возвращает все каналы маршрутизации как пары источника и назначения.
PIVector<PIPair<PIString, PIString>> channels() const;
/*! \brief Add to connection sender with name "name" device with full path "full_path"
* \details If there is no sender with name "name", connection create new, bound
* to it device "full_path_name" and start sender timer with frequency "frequency".
* If sender with name "name" already exists, device "full_path_name" add to this sender
* If "start" is true, sender is started immediately. Else, you can start sender with
* functions \a startSender()
* \n \b Attention! "frequency" is actual olny if new sender was created! */
//! \~english Creates or reuses sender "name" and binds device "full_path_name" to it.
//! \~russian Создает или повторно использует отправитель "name" и привязывает к нему устройство "full_path_name".
//! \~\details
//! \~english If there is no sender with name "name", connection create new, bound
//! to it device "full_path_name" and start sender timer with frequency "frequency".
//! If sender with name "name" already exists, device "full_path_name" add to this sender
//! If "start" is true, sender is started immediately. Else, you can start sender with
//! functions \a startSender().
//! \~russian Если отправителя с именем "name" не существует, соединение создаст новый отправитель, привяжет
//! к нему устройство "full_path_name" и запускает таймер отправителя с частотой "frequency".
//! Если отправитель с именем "name" уже существует, устройство "full_path_name" добавляется к этому отправителю
//! Если "start" равно true, отправитель запускается немедленно. В противном случае можно запустить отправителя с помощью
//! функций \a startSender().
//! \~\note
//! \~english \b Attention! "frequency" is actual olny if new sender was created!
//! \~russian \b Внимание! "frequency" актуален только если был создан новый отправитель!
//! \~\sa startSender()
void addSender(const PIString & name, const PIString & full_path_name, float frequency, bool start = false);
//! Add to connection sender with name "name" device "dev"
//! \~english Creates or reuses sender "name" and binds device "dev" to it.
//! \~russian Создает или повторно использует отправитель "name" и привязывает к нему устройство "dev".
void addSender(const PIString & name, const PIIODevice * dev, float frequency, bool start = false) {
addSender(name, devFPath(dev), frequency, start);
}
/*! \brief Remove from sender with name "name" device with full path "full_path_name"
* \details If there is no devices bounded to this sender, it will be removed. Returns if sender was removed */
//! \~english Unbinds device "full_path_name" from sender "name".
//! \~russian Отвязывает устройство "full_path_name" от отправителя "name".
//! \~\details
//! \~english If there is no devices bounded to this sender, it will be removed. Returns if sender was removed.
//! \~russian Если к этому отправителю не привязано устройств, он будет удален. Возвращает успешность удаления отправителя.
bool removeSender(const PIString & name, const PIString & full_path_name);
//! Remove from sender with name "name" device "dev"
//! \~english Unbinds device "dev" from sender "name".
//! \~russian Отвязывает устройство "dev" от отправителя "name".
bool removeSender(const PIString & name, const PIIODevice * dev) { return removeSender(name, devFPath(dev)); }
//! Remove sender with name "name", returns if sender was removed
//! \~english Removes sender "name" together with its timer state.
//! \~russian Удаляет отправитель "name" вместе с состоянием его таймера.
bool removeSender(const PIString & name);
//! Set sender "name" fixed send data "data", returns if sender exists
//! \~english Assigns fixed payload "data" to sender "name".
//! \~russian Назначает фиксированную нагрузку "data" отправителю "name".
bool setSenderFixedData(const PIString & name, const PIByteArray & data);
//! Remove sender "name" fixed send data, returns if sender exists
//! \~english Clears fixed payload for sender "name".
//! \~russian Очищает фиксированную нагрузку отправителя "name".
bool clearSenderFixedData(const PIString & name);
//! Returns sender "name" fixed send data
//! \~english Returns fixed payload configured for sender "name".
//! \~russian Возвращает фиксированную нагрузку, настроенную для отправителя "name".
PIByteArray senderFixedData(const PIString & name) const;
//! Returns sender "name" timer frequency, -1 if there is no such sender, or 0 if sender is not started yet
//! \~english Returns sender timer frequency.
//! \~russian Возвращает частоту таймера отправителя.
//! \~\details
//! \~english Returns -1 when the sender does not exist and 0 when it exists but is not running.
//! \~russian Возвращает -1, если отправителя не существует, и 0, если он существует, но не запущен.
float senderFrequency(const PIString & name) const;
//! Remove from connection all senders
//! \~english Removes all senders from this connection.
//! \~russian Удаляет все отправители из этого соединения.
void removeAllSenders();
//! Start read thread of device with full path "full_path"
//! \~english Starts threaded read for source "full_path_name".
//! \~russian Запускает потоковое чтение для источника "full_path_name".
void startThreadedRead(const PIString & full_path_name);
//! Start read thread of device "dev"
//! \~english Starts threaded read for device "dev".
//! \~russian Запускает потоковое чтение для устройства "dev".
void startThreadedRead(const PIIODevice * dev) { startThreadedRead(devFPath(dev)); }
//! Start read threads of all Device pool device
//! \~english Starts threaded read for all devices bound to the shared pool.
//! \~russian Запускает потоковое чтение для всех устройств, привязанных к общему пулу.
void startAllThreadedReads();
//! Start sender "name" timer
//! \~english Starts sender timer "name".
//! \~russian Запускает таймер отправителя "name".
void startSender(const PIString & name);
//! Start all senders timers
//! \~english Starts all sender timers.
//! \~russian Запускает таймеры всех отправителей.
void startAllSenders();
//! Start all read threads and senders
//! \~english Starts all threaded reads and all senders.
//! \~russian Запускает все потоковые чтения и все отправители.
void start() {
startAllThreadedReads();
startAllSenders();
}
//! Stop read thread of device with full path "full_path"
//! \~english Stops threaded read for source "full_path_name".
//! \~russian Останавливает потоковое чтение для источника "full_path_name".
void stopThreadedRead(const PIString & full_path_name);
//! Stop read thread of device "dev"
//! \~english Stops threaded read for device "dev".
//! \~russian Останавливает потоковое чтение для устройства "dev".
void stopThreadedRead(const PIIODevice * dev) { stopThreadedRead(devFPath(dev)); }
//! Stop read threads of all Device pool device
//! \~english Stops threaded read for all bound devices.
//! \~russian Останавливает потоковое чтение для всех привязанных устройств.
void stopAllThreadedReads();
//! Stop sender "name" timer
//! \~english Stops sender timer "name".
//! \~russian Останавливает таймер отправителя "name".
void stopSender(const PIString & name);
//! Stop all senders timers
//! \~english Stops all sender timers.
//! \~russian Останавливает таймеры всех отправителей.
void stopAllSenders();
//! Stop all read threads and senders
//! \~english Stops all threaded reads and all senders.
//! \~russian Останавливает все потоковые чтения и все отправители.
void stop() {
stopAllThreadedReads();
stopAllSenders();
}
//! Stop connection and remove all devices
//! \~english Stops the connection and removes all bound devices.
//! \~russian Останавливает соединение и удаляет все привязанные устройства.
void destroy() {
stop();
removeAllDevices();
}
//! Returns if there are no devices in this connection
//! \~english Returns whether the connection currently has no bound devices.
//! \~russian Возвращает, нет ли сейчас у соединения привязанных устройств.
bool isEmpty() const { return device_modes.isEmpty(); }
//! Returns PIDiagnostics * assosiated with device with full path "full_path_name", name "full_path_name" or filter "full_path_name"
//! \~english Returns diagnostics object for device or filter "full_path_name".
//! \~russian Возвращает объект диагностики для устройства или фильтра "full_path_name".
PIDiagnostics * diagnostic(const PIString & full_path_name) const;
//! Returns PIDiagnostics * assosiated with device or filter "dev"
//! \~english Returns diagnostics object associated with device or filter "dev".
//! \~russian Возвращает объект диагностики, связанный с устройством или фильтром "dev".
PIDiagnostics * diagnostic(const PIIODevice * dev) const { return diags_.value(const_cast<PIIODevice *>(dev), 0); }
//! Write data "data" to device with full path "full_path" and returns result of \a write() function of device
//! \~english Writes "data" to device resolved by full path "full_path".
//! \~russian Записывает "data" в устройство, найденное по полному пути "full_path".
int writeByFullPath(const PIString & full_path, const PIByteArray & data);
//! Write data "data" to device with name "name" and returns result of \a write() function of device
//! \~english Writes "data" to device resolved by alias "name".
//! \~russian Записывает "data" в устройство, найденное по псевдониму "name".
int writeByName(const PIString & name, const PIByteArray & data);
//! Write data "data" to device "dev" and returns result of \a write() function of device
//! \~english Writes "data" directly to device "dev".
//! \~russian Записывает "data" непосредственно в устройство "dev".
int write(PIIODevice * dev, const PIByteArray & data);
//! Returns all connections in application
//! \~english Returns all currently alive %PIConnection objects.
//! \~russian Возвращает все существующие в приложении объекты %PIConnection.
static PIVector<PIConnection *> allConnections();
//! Returns all devices in Device pool
//! \~english Returns all devices currently stored in the shared device pool.
//! \~russian Возвращает все устройства, которые сейчас хранятся в общем пуле устройств.
static PIVector<PIIODevice *> allDevices();
//! Set Device pool fake mode to \"yes\" and returns previous mode
//! \~english Enables or disables shared device-pool fake mode and returns previous state.
//! \~russian Включает или выключает режим имитации общего пула устройств и возвращает предыдущее состояние.
static bool setFakeMode(bool yes);
//! Returns if Device pool works in fake mode
//! \~english Returns whether the shared device pool works in fake mode.
//! \~russian Возвращает, работает ли общий пул устройств в режиме имитации.
static bool isFakeMode();
class PIP_EXPORT DevicePool: public PIThread {
@@ -310,6 +430,7 @@ public:
void init();
PIIODevice *
addDevice(PIConnection * parent, const PIString & fp, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite, bool start = true);
bool removeDevice(PIConnection * parent, const PIString & fp);
void unboundConnection(PIConnection * parent);
PIIODevice * device(const PIString & fp) const;
@@ -336,32 +457,38 @@ public:
bool fake;
};
EVENT2(dataReceivedEvent, const PIString &, from, const PIByteArray &, data);
EVENT2(packetReceivedEvent, const PIString &, from, const PIByteArray &, data);
EVENT3(qualityChanged, const PIIODevice *, dev, PIDiagnostics::Quality, new_quality, PIDiagnostics::Quality, old_quality);
//! \events
//! \{
//! \fn void dataReceivedEvent(const PIString & from, const PIByteArray & data)
//! \brief Raise on data received from device with full path "from"
//! \~english Emitted when raw data is received from source "from".
//! \~russian Генерируется при получении сырых данных от источника "from".
EVENT2(dataReceivedEvent, const PIString &, from, const PIByteArray &, data);
//! \fn void packetReceivedEvent(const PIString & from, const PIByteArray & data)
//! \brief Raise on packet received from filter with name "from"
//! \~english Emitted when filter "from" produces a packet.
//! \~russian Генерируется, когда фильтр "from" выдает пакет.
EVENT2(packetReceivedEvent, const PIString &, from, const PIByteArray &, data);
//! \fn void qualityChanged(const PIIODevice * device, PIDiagnostics::Quality new_quality, PIDiagnostics::Quality old_quality)
//! \brief Raise on diagnostic quality of device "device" changed from "old_quality" to "new_quality"
//! \~english Emitted when diagnostics quality of "device" changes.
//! \~russian Генерируется при изменении качества диагностики устройства "device".
EVENT3(qualityChanged, const PIIODevice *, dev, PIDiagnostics::Quality, new_quality, PIDiagnostics::Quality, old_quality);
//! \}
protected:
//! Executes on data received from device with full path "from"
//! \~english Called after raw data is received from source "from".
//! \~russian Вызывается после получения сырых данных от источника "from".
virtual void dataReceived(const PIString & from, const PIByteArray & data) {}
//! Executes on packet received from filter with name "from"
//! \~english Called after filter "from" produces a packet.
//! \~russian Вызывается после того, как фильтр "from" выдает пакет.
virtual void packetReceived(const PIString & from, const PIByteArray & data) {}
//! You should returns data for sender "sender_name"
//! \~english Returns dynamic payload for sender "sender_name".
//! \~russian Возвращает динамическую нагрузку для отправителя "sender_name".
virtual PIByteArray senderData(const PIString & sender_name);
private:
@@ -408,7 +535,6 @@ private:
void __DevicePool_threadReadDP(void * ddp);
extern PIP_EXPORT PIConnection::DevicePool * __device_pool__;
class PIP_EXPORT __DevicePoolContainer__ {

View File

@@ -1,9 +1,8 @@
/*! \file pidatatransfer.h
* \ingroup IO
* \~\brief
* \~english Class for send and receive PIByteArray via \a PIBaseTransfer
* \~russian Класс для отправки и приема PIByteArray с помощью \a PIBaseTransfer
*/
//! \~\ingroup IO-Utils
//! \~\file pidatatransfer.h
//! \~\brief
//! \~english Class for send and receive PIByteArray via \a PIBaseTransfer
//! \~russian Класс для отправки и приема PIByteArray с помощью \a PIBaseTransfer
/*
PIP - Platform Independent Primitives
Class for send and receive PIByteArray via PIBaseTransfer
@@ -29,14 +28,32 @@
#include "pibasetransfer.h"
//! \~\ingroup IO-Utils
//! \~\brief
//! \~english Class for send and receive PIByteArray via \a PIBaseTransfer
//! \~russian Класс для отправки и приема PIByteArray с помощью \a PIBaseTransfer
//! \~\sa PIBaseTransfer
class PIP_EXPORT PIDataTransfer: public PIBaseTransfer {
PIOBJECT_SUBCLASS(PIDataTransfer, PIBaseTransfer);
public:
//! \~english Constructs byte-array transfer.
//! \~russian Создает передачу массива байтов.
PIDataTransfer() { ; }
//! \~english Destructor
//! \~russian Деструктор
~PIDataTransfer() { ; }
//! \~english Send data
//! \~russian Отправить данные
bool send(const PIByteArray & ba);
//! \~english Get received data
//! \~russian Получить принятые данные
//! \~\note
//! \~english The data will be valid only after the successful completion of receiving \a receiveFinished.
//! \~russian Данные будут валидные только после успешного завершения приёма \a receiveFinished.
const PIByteArray & data() { return data_; }
private:

View File

@@ -1,9 +1,8 @@
/*! \file pidiagnostics.h
* \ingroup IO
* \~\brief
* \~english Connection quality diagnostics
* \~russian Диагностика качества связи
*/
//! \~\file pidiagnostics.h
//! \~\ingroup IO-Utils
//! \~\brief
//! \~english Connection quality diagnostics
//! \~russian Диагностика качества связи
/*
PIP - Platform Independent Primitives
Speed and quality in/out diagnostics
@@ -30,6 +29,13 @@
#include "pitimer.h"
//! \~\ingroup IO-Utils
//! \brief
//! \~english Connection diagnostics for packet frequency, throughput and receive quality
//! \~russian Диагностика соединения для частоты пакетов, пропускной способности и качества приема
//! \details
//! \~english This class provides connection quality diagnostics based on packet reception statistics
//! \~russian Класс обеспечивает диагностику качества связи на основе статистики приема пакетов
class PIP_EXPORT PIDiagnostics: public PITimer {
PIOBJECT_SUBCLASS(PIDiagnostics, PITimer);
friend class PIConnection;
@@ -37,95 +43,162 @@ class PIP_EXPORT PIDiagnostics: public PITimer {
public:
NO_COPY_CLASS(PIDiagnostics);
//! Constructs an empty diagnostics and if "start_" start it
//! \~english Constructs diagnostics and optionally starts periodic evaluation immediately.
//! \~russian Создает диагностику и при необходимости сразу запускает периодическую оценку.
PIDiagnostics(bool start_ = true);
//! \~english Stops diagnostics updates.
//! \~russian Останавливает обновление диагностики.
virtual ~PIDiagnostics();
//! Connection quality
//! \~english Receive quality estimated from recent packet history.
//! \~russian Качество приема, оцениваемое по недавней истории пакетов.
enum Quality {
Unknown /** Unknown, no one packet received yet */ = 1,
Failure /** No connection, no one correct packet received for last period */ = 2,
Bad /** Bad connection, correct packets received <= 20% */ = 3,
Average /** Average connection, correct packets received > 20% and <= 80% */ = 4,
Good /** Good connection, correct packets received > 80% */ = 5
Unknown = 1 /** \~english No receive history yet \~russian История приема еще отсутствует */,
Failure = 2 /** \~english No correct packets in the recent window \~russian В недавнем окне нет корректных пакетов */,
Bad = 3 /** \~english Correct packets are at most 20 percent \~russian Корректных пакетов не более 20 процентов */,
Average =
4 /** \~english Correct packets are above 20 and up to 80 percent \~russian Корректных пакетов больше 20 и до 80 процентов */
,
Good = 5 /** \~english Correct packets are above 80 percent \~russian Корректных пакетов больше 80 процентов */
};
//! Information about current diagnostics state
//! \~english Snapshot of current counters and derived statistics.
//! \~russian Снимок текущих счетчиков и производных статистик.
struct PIP_EXPORT State {
//! \~english Constructs zeroed state with formatted speed strings.
//! \~russian Создает обнуленное состояние с отформатированными строками скоростей.
State();
//! \~english Latest receive frequency for the current timer interval.
//! \~russian Последняя частота приема для текущего интервала таймера.
float immediate_freq = 0.f;
//! \~english Averaged receive frequency over the disconnect window.
//! \~russian Усредненная частота приема по окну отключения.
float integral_freq = 0.f;
//! \~english Number of correct received packets per second.
//! \~russian Число корректно принятых пакетов в секунду.
ullong received_packets_per_sec = 0ull;
//! \~english Total number of correct received packets.
//! \~russian Общее число корректно принятых пакетов.
ullong received_packets = 0ull;
//! \~english Total number of incorrect received packets.
//! \~russian Общее число некорректно принятых пакетов.
ullong received_packets_wrong = 0ull;
//! \~english Number of received bytes per second.
//! \~russian Число принятых байтов в секунду.
ullong received_bytes_per_sec = 0ull;
//! \~english Total number of correctly received bytes.
//! \~russian Общее число корректно принятых байтов.
ullong received_bytes = 0ull;
//! \~english Total number of bytes from incorrect packets.
//! \~russian Общее число байтов из некорректных пакетов.
ullong received_bytes_wrong = 0ull;
//! \~english Number of sent packets per second.
//! \~russian Число отправленных пакетов в секунду.
ullong sended_packets_per_sec = 0ull;
//! \~english Total number of sent packets.
//! \~russian Общее число отправленных пакетов.
ullong sended_packets = 0ull;
//! \~english Number of sent bytes per second.
//! \~russian Число отправленных байтов в секунду.
ullong sended_bytes_per_sec = 0ull;
//! \~english Total number of sent bytes.
//! \~russian Общее число отправленных байтов.
ullong sended_bytes = 0ull;
//! \~english Human-readable receive speed string.
//! \~russian Строка скорости приема в человекочитаемом виде.
PIString receive_speed;
//! \~english Human-readable send speed string.
//! \~russian Строка скорости отправки в человекочитаемом виде.
PIString send_speed;
//! \~english Current receive quality category.
//! \~russian Текущая категория качества приема.
PIDiagnostics::Quality quality = PIDiagnostics::Unknown;
};
//! Returns current state
//! \~english Returns a thread-safe snapshot of current diagnostics state.
//! \~russian Возвращает потокобезопасный снимок текущего состояния диагностики.
PIDiagnostics::State state() const;
//! Returns period of full disconnect in seconds and period of averaging frequency
//! \~english Returns the disconnect timeout and averaging window.
//! \~russian Возвращает таймаут отключения и окно усреднения.
PISystemTime disconnectTimeout() const { return disconn_; }
//! Returns period of full disconnect in seconds and period of averaging frequency
//! \~english Sets the disconnect timeout in seconds.
//! \~russian Устанавливает таймаут отключения в секундах.
void setDisconnectTimeout(float s) DEPRECATEDM("use setDisconnectTimeout(PISystemTime)") {
setDisconnectTimeout(PISystemTime::fromSeconds(s));
}
//! Returns period of full disconnect and period of averaging frequency
//! \~english Sets the disconnect timeout and averaging window.
//! \~russian Устанавливает таймаут отключения и окно усреднения.
void setDisconnectTimeout(PISystemTime tm) { setProperty("disconnectTimeout", tm); }
//! Returns connection quality
//! \~english Returns current receive quality.
//! \~russian Возвращает текущее качество приема.
PIDiagnostics::Quality quality() const;
//! Returns receive speed in format "n {B|kB|MB|GB|TB}/s"
//! \~english Returns formatted receive throughput string.
//! \~russian Возвращает строку отформатированной скорости приема.
PIString receiveSpeed() const;
//! Returns send speed in format "n {B|kB|MB|GB|TB}/s"
//! \~english Returns formatted send throughput string.
//! \~russian Возвращает строку отформатированной скорости отправки.
PIString sendSpeed() const;
EVENT_HANDLER0(void, start);
EVENT_HANDLER1(void, start, PISystemTime, interval);
EVENT_HANDLER0(void, reset);
EVENT_HANDLER1(void, received, int, size) { received(size, true); }
EVENT_HANDLER2(void, received, int, size, bool, correct);
EVENT_HANDLER1(void, sended, int, size);
EVENT2(qualityChanged, PIDiagnostics::Quality, new_quality, PIDiagnostics::Quality, old_quality);
//! \handlers
//! \{
//! \fn void start(double msecs = 1000.)
//! \brief Start diagnostics evaluations with period "msecs" milliseconds
//! \fn void start()
//! \~english Starts periodic diagnostics evaluation with the default interval.
//! \~russian Запускает периодическую оценку диагностики с интервалом по умолчанию.
EVENT_HANDLER0(void, start);
//! \fn void start(PISystemTime interval)
//! \~english Starts periodic diagnostics evaluation with interval "interval".
//! \~russian Запускает периодическую оценку диагностики с интервалом "interval".
EVENT_HANDLER1(void, start, PISystemTime, interval);
//! \fn void reset()
//! \brief Reset diagnostics counters
//! \~english Resets counters, rolling history and derived statistics.
//! \~russian Сбрасывает счетчики, скользящую историю и производные статистики.
EVENT_HANDLER0(void, reset);
//! \fn void received(int size, bool correct = true)
//! \brief Notify diagnostics about "correct" corected received packet
//! \~english Notifies diagnostics about one received packet of size "size".
//! \~russian Уведомляет диагностику об одном принятом пакете размером "size".
EVENT_HANDLER1(void, received, int, size) { received(size, true); }
EVENT_HANDLER2(void, received, int, size, bool, correct);
//! \fn void sended(int size)
//! \brief Notify diagnostics about sended packet
//! \~english Notifies diagnostics about one sent packet of size "size".
//! \~russian Уведомляет диагностику об одном отправленном пакете размером "size".
EVENT_HANDLER1(void, sended, int, size);
//! \}
//! \events
//! \{
//! \fn void qualityChanged(PIDiagnostics::Quality new_quality, PIDiagnostics::Quality old_quality)
//! \brief Raise on change receive quality from "old_quality" to "new_quality"
//! \~english Emitted when receive quality changes from "old_quality" to "new_quality".
//! \~russian Генерируется при изменении качества приема с "old_quality" на "new_quality".
EVENT2(qualityChanged, PIDiagnostics::Quality, new_quality, PIDiagnostics::Quality, old_quality);
//! \}

View File

@@ -1,9 +1,8 @@
/*! \file piethutilbase.h
* \ingroup IO-Utils
* \~\brief
* \~english Base class for ethernet utils
* \~russian Базовый класс для утилит ethernet
*/
//! \~\file piethutilbase.h
//! \~\ingroup IO-Utils
//! \~\brief
//! \~english Base helper for optional crypt layer in IO-Utils transports
//! \~russian Базовый помощник для необязательного слоя шифрования в транспортах IO-Utils
/*
PIP - Platform Independent Primitives
Base class for ethernet utils
@@ -29,45 +28,67 @@
#include "pibytearray.h"
#include "pip_io_utils_export.h"
//! \~\ingroup IO-Utils
//! \~\brief
//! \~english Base helper that adds optional packet encryption to transport utilities.
//! \~russian Базовый помощник, добавляющий необязательное шифрование пакетов в транспортные утилиты.
class PIP_IO_UTILS_EXPORT PIEthUtilBase {
public:
//! \~english Constructs helper with crypt layer disabled.
//! \~russian Создает помощник с выключенным слоем шифрования.
PIEthUtilBase();
//! \~english Destroys the crypt helper.
//! \~russian Уничтожает помощник шифрования.
~PIEthUtilBase();
//! Set crypt layer enabled
//! \~english Enables or disables the crypt layer.
//! \~russian Включает или выключает слой шифрования.
void setCryptEnabled(bool on);
//! Enable crypt layer
//! \~english Enables the crypt layer.
//! \~russian Включает слой шифрования.
void cryptEnable();
//! Disable crypt layer
//! \~english Disables the crypt layer.
//! \~russian Выключает слой шифрования.
void cryptDisable();
//! Returns if crypt layer enabled
//! \~english Returns whether the crypt layer is enabled.
//! \~russian Возвращает, включен ли слой шифрования.
bool isCryptEnabled() const;
//! Set crypt layer key to \"k\"
//! \~english Sets crypt key "k" and enables the crypt layer.
//! \~russian Устанавливает ключ шифрования "k" и включает слой шифрования.
void setCryptKey(const PIByteArray & k);
//! Generate crypt layer key by \a PICrypt::hash and
//! set crypt layer enabled
//! \~english Generates crypt key from passphrase "k" and enables the crypt layer.
//! \~russian Генерирует ключ шифрования из парольной фразы "k" и включает слой шифрования.
void createCryptKey(const PIString & k);
//! Returns crypt layer key
//! \~english Returns current crypt key.
//! \~russian Возвращает текущий ключ шифрования.
PIByteArray cryptKey() const;
//! \brief Returns addition size for crypted data.
//! \~english Returns extra size added by encryption.
//! \~russian Возвращает дополнительный размер, добавляемый шифрованием.
static size_t cryptSizeAddition();
protected:
/*! \brief Returns encrypted data if layer enabled,
* otherwise returns unchanged \"data\" */
//! \~english Encrypts "data" when the crypt layer is enabled.
//! \~russian Шифрует "data", если слой шифрования включен.
PIByteArray cryptData(const PIByteArray & data);
/*! \brief Returns decrypted data if layer enabled,
* otherwise returns unchanged \"data\". If decryption
* was unsuccessfull returns empty %PIByteArray. */
//! \~english Decrypts "data" when the crypt layer is enabled.
//! \~russian Дешифрует "data", если слой шифрования включен.
//! \~\details
//! \~english
//! Returns decrypted data if layer enabled, otherwise returns unchanged "data". If decryption was unsuccessful returns empty
//! %PIByteArray
//! \~russian
//! Возвращает расшифрованные данные, если слой включен, иначе возвращает неизмененные "data". Если расшифровка неуспешна, возвращает
//! пустой %PIByteArray
PIByteArray decryptData(const PIByteArray & data);
private:

View File

@@ -1,9 +1,11 @@
/*! \file pifiletransfer.h
* \ingroup IO
* \~\brief
* \~english Class for send and receive files and directories via \a PIBaseTransfer
* \~russian Класс для отправки и приема файлов и папок с помощью \a PIBaseTransfer
*/
//! \~\file pifiletransfer.h
//! \~\ingroup IO-Utils
//! \~\brief
//! \~english Class for sending and receiving files and directories via \a PIBaseTransfer
//! \~russian Класс для отправки и приема файлов и папок с помощью \a PIBaseTransfer
//! \~\details
//! \~english PIFileTransfer provides functionality for transferring files and directories over a network using PIBaseTransfer protocol
//! \~russian PIFileTransfer предоставляет функциональность для передачи файлов и папок по сети с использованием протокола PIBaseTransfer
/*
PIP - Platform Independent Primitives
Class for send and receive files and directories via PIBaseTransfer
@@ -31,35 +33,72 @@
#define __PIFILETRANSFER_VERSION 2
//! \~\ingroup IO-Utils
//! \~\brief
//! \~english Class for sending and receiving files and directories via \a PIBaseTransfer
//! \~russian Класс для отправки и приема файлов и папок с помощью \a PIBaseTransfer
class PIP_EXPORT PIFileTransfer: public PIBaseTransfer {
PIOBJECT_SUBCLASS(PIFileTransfer, PIBaseTransfer);
public:
//! \~english Constructs empty file transfer
//! \~russian Создает пустой transfer файлов
PIFileTransfer();
//! \~english Destructor
//! \~russian Деструктор
~PIFileTransfer();
//! \~english Stage of the file-transfer protocol.
//! \~russian Этап протокола передачи файлов.
enum StepType {
pft_None,
pft_Description,
pft_Data
pft_None /** \~english No active stage \~russian Активный этап отсутствует */,
pft_Description /** \~english Exchange file list and metadata \~russian Обмен списком файлов и метаданными */,
pft_Data /** \~english Exchange file data blocks \~russian Обмен блоками данных файлов */
};
//! \~english File-system entry description extended with destination relative path.
//! \~russian Описание элемента файловой системы, расширенное относительным путем назначения.
struct PIP_EXPORT PFTFileInfo: public PIFile::FileInfo {
//! \~english Constructs transferable file info from base \a PIFile::FileInfo.
//! \~russian Создает передаваемое описание файла из базового \a PIFile::FileInfo.
PFTFileInfo(const PIFile::FileInfo & fi = PIFile::FileInfo()): PIFile::FileInfo(fi) {}
//! \~english Relative destination path on the receiver side.
//! \~russian Относительный путь назначения на стороне приемника.
PIString dest_path;
};
#pragma pack(push, 1)
//! \~english Custom packet header used by the file-transfer protocol.
//! \~russian Пользовательский заголовок пакета, используемый протоколом передачи файлов.
struct PIP_EXPORT PFTHeader {
union {
struct {
//! \~english Three-byte protocol signature "PFT".
//! \~russian Трехбайтовая сигнатура протокола "PFT".
char sig[3]; // PFT
//! \~english Protocol version stored in the packet.
//! \~russian Версия протокола, сохраненная в пакете.
uchar version;
};
//! \~english Raw 32-bit representation of signature and version.
//! \~russian Сырое 32-битное представление сигнатуры и версии.
uint raw_sig;
};
int step; // PacketType
//! \~english Current transfer step from \a StepType.
//! \~russian Текущий этап передачи из \a StepType.
int step;
//! \~english File-transfer session identifier.
//! \~russian Идентификатор сессии передачи файлов.
int session_id;
//! \~english Check if signature is valid
//! \~russian Проверка валидности сигнатуры
bool check_sig() {
if (sig[0] != sign[0] || sig[1] != sign[1] || sig[2] != sign[2] || version != __PIFILETRANSFER_VERSION) return false;
return true;
@@ -67,31 +106,100 @@ public:
};
#pragma pack(pop)
//! \~english Sends one file-system entry identified by "file".
//! \~russian Отправляет один элемент файловой системы, заданный "file".
bool send(const PIFile & file);
//! \~english Sends one file or directory by path.
//! \~russian Отправляет один файл или каталог по пути.
bool send(const PIString & file);
//! \~english Sends all files or directories listed in "files".
//! \~russian Отправляет все файлы или каталоги из списка "files".
bool send(const PIStringList & files);
//! \~english Sends one file-system entry described by "entry".
//! \~russian Отправляет один элемент файловой системы, описанный "entry".
bool send(PIFile::FileInfo entry) { return send(PIVector<PIFile::FileInfo>() << entry); }
//! \~english Sends file entries from "entries", recursively expanding directories.
//! \~russian Отправляет элементы файловой системы из "entries", рекурсивно раскрывая каталоги.
bool send(PIVector<PIFile::FileInfo> entries);
//! \~english Sets destination directory used for received files.
//! \~russian Устанавливает каталог назначения для принимаемых файлов.
void setDirectory(const PIDir & d) { dir = d; }
//! \~english Sets destination directory used for received files by path.
//! \~russian Устанавливает каталог назначения для принимаемых файлов по пути.
//! \~russian Установить директорию по пути
void setDirectory(const PIString & path) { dir.setDir(path); }
//! \~english Returns destination directory used for received files.
//! \~russian Возвращает каталог назначения для принимаемых файлов.
PIDir directory() const { return dir; }
//! \~english Returns whether the overall file transfer workflow is active.
//! \~russian Возвращает, активен ли общий процесс передачи файлов.
bool isStarted() const { return started_; }
//! \~english Returns current file path or scanning status string.
//! \~russian Возвращает путь текущего файла или строку состояния сканирования.
PIString curFile() const;
//! \~english Returns total size of the current file being processed.
//! \~russian Возвращает общий размер текущего обрабатываемого файла.
llong bytesFileAll() const { return bytes_file_all; }
//! \~english Returns processed size of the current file being processed.
//! \~russian Возвращает уже обработанный объем текущего файла.
llong bytesFileCur() const { return bytes_file_cur; }
//! \~english Get pointer to current file name
//! \~russian Получить указатель на имя текущего файла
const PIString * curFile_ptr() const { return &cur_file_string; }
//! \~english Get pointer to total bytes of current file
//! \~russian Получить указатель на общее количество байт текущего файла
const llong * bytesFileAll_ptr() const { return &bytes_file_all; }
//! \~english Get pointer to current bytes of current file
//! \~russian Получить указатель на текущие байты текущего файла
const llong * bytesFileCur_ptr() const { return &bytes_file_cur; }
//! \events
//! \{
//! \~\fn void receiveFilesStarted()
//! \~english Emitted when a new incoming file-transfer workflow starts.
//! \~russian Генерируется при запуске нового входящего процесса передачи файлов.
EVENT(receiveFilesStarted);
//! \~\fn void receiveFilesFinished(bool ok)
//! \~english Emitted when receiving files finishes with result "ok".
//! \~russian Генерируется, когда прием файлов завершается с результатом "ok".
EVENT1(receiveFilesFinished, bool, ok);
//! \~\fn void sendFilesStarted()
//! \~english Emitted when preparing and sending files starts.
//! \~russian Генерируется при начале подготовки и отправки файлов.
EVENT(sendFilesStarted);
//! \~\fn void sendFilesFinished(bool ok)
//! \~english Emitted when sending files finishes with result "ok".
//! \~russian Генерируется, когда отправка файлов завершается с результатом "ok".
EVENT1(sendFilesFinished, bool, ok);
//! \~\fn void receiveFilesRequest(PIStringList files, llong total_bytes, bool * ok)
//! \~english Emitted after the description phase so user code can accept or reject the incoming file set.
//! \~russian Генерируется после фазы описания, чтобы пользовательский код мог принять или отклонить входящий набор файлов.
EVENT3(receiveFilesRequest, PIStringList, files, llong, total_bytes, bool *, ok);
//! \}
private:
static const char sign[];
PIVector<PFTFileInfo> files_;
@@ -115,26 +223,37 @@ private:
EVENT_HANDLER1(void, receive_finished, bool, ok);
};
//! \~english Binary stream write operator for PFTHeader
//! \~russian Оператор записи в бинарный поток для PFTHeader
BINARY_STREAM_WRITE(PIFileTransfer::PFTHeader) {
s << v.raw_sig << v.step << v.session_id;
return s;
}
//! \~english Binary stream read operator for PFTHeader
//! \~russian Оператор чтения из бинарного потока для PFTHeader
BINARY_STREAM_READ(PIFileTransfer::PFTHeader) {
s >> v.raw_sig >> v.step >> v.session_id;
return s;
}
//! \~english Binary stream write operator for PFTFileInfo
//! \~russian Оператор записи в бинарный поток для PFTFileInfo
BINARY_STREAM_WRITE(PIFileTransfer::PFTFileInfo) {
s << v.dest_path << v.size << v.time_access << v.time_modification << v.flags << v.id_user << v.id_group << v.perm_user.raw
<< v.perm_group.raw << v.perm_other.raw;
return s;
}
//! \~english Binary stream read operator for PFTFileInfo
//! \~russian Оператор чтения из бинарного потока для PFTFileInfo
BINARY_STREAM_READ(PIFileTransfer::PFTFileInfo) {
s >> v.dest_path >> v.size >> v.time_access >> v.time_modification >> v.flags >> v.id_user >> v.id_group >> v.perm_user.raw >>
v.perm_group.raw >> v.perm_other.raw;
return s;
}
//! \~\relatesalso PICout
//! \~english Output \a PICout operator for PFTFileInfo
//! \~russian Оператор вывода в \a PICout для PFTFileInfo
inline PICout operator<<(PICout s, const PIFileTransfer::PFTFileInfo & v) {
s.saveAndSetControls(0);
s << "FileInfo(\"" << v.dest_path << "\", " << PIString::readableSize(v.size) << ", " << v.perm_user.toString() << " "

View File

@@ -1,3 +1,12 @@
//! \~\file piioutilsmodule.h
//! \~\ingroup IO-Utils
//! \~\brief
//! \~english Public include header for the IO-Utils module
//! \~russian Публичный заголовок подключения модуля IO-Utils
//!
//! \~\details
//! \~english Includes the public connection, transfer, packing, and parsing utility headers.
//! \~russian Подключает публичные заголовки соединений, передачи данных, упаковки и утилит разбора.
/*
PIP - Platform Independent Primitives
Module includes
@@ -18,8 +27,8 @@
*/
//! \defgroup IO-Utils IO-Utils
//! \~\brief
//! \~english Complex channel transport
//! \~russian Сложный канальный транспорт
//! \~english Packetized transport, transfer helpers and connection utilities
//! \~russian Пакетизированный транспорт, вспомогательные классы передачи и утилиты соединений
//!
//! \~\details
//! \~english \section cmake_module_IO_Utils Building with CMake
@@ -32,12 +41,18 @@
//!
//! \~english \par Common
//! \~russian \par Общее
//!
//! \~english
//! These files provides complex transport over ethernet
//!
//! The module combines packet framing, connection helpers, transfer helpers
//! and parsing utilities built on top of PIP I/O devices.
//! \~russian
//! Эти файлы обеспечивают сложный транспорт поверх ethernet
//! Модуль объединяет пакетирование потока, вспомогательные классы соединений,
//! передачи данных и утилиты разбора поверх устройств ввода-вывода PIP.
//! \~russian Заголовочный файл модуля утилит ввода-вывода
//! \details
//! \~english This module provides comprehensive I/O utilities including file transfer, connection management, packet extraction, and
//! diagnostics.
//! \~russian Этот модуль предоставляет комплексные утилиты ввода-вывода, включая передачу файлов, управление подключениями, извлечение
//! пакетов и диагностику.
//!
//! \~\authors
//! \~english

View File

@@ -1,9 +1,8 @@
/*! \file pipackedtcp.h
* \ingroup IO-Utils
* \~\brief
* \~english Ethernet device
* \~russian Устройство Ethernet
*/
//! \~\file pipackedtcp.h
//! \~\ingroup IO-Utils
//! \~\brief
//! \~english Packet-oriented TCP device built on top of %PIStreamPacker
//! \~russian Пакетно-ориентированное TCP-устройство на основе %PIStreamPacker
/*
PIP - Platform Independent Primitives
Ethernet, UDP/TCP Broadcast/Multicast
@@ -34,36 +33,72 @@
class PIEthernet;
//! \~\ingroup IO-Utils
//! \~\brief
//! \~english TCP device wrapper that exposes framed packets through the %PIIODevice API.
//! \~russian Обертка над TCP-устройством, предоставляющая кадрированные пакеты через API %PIIODevice.
//! \details
//! \~english
//! The %PIPackedTCP class provides a TCP client/server device with automatic data packing/unpacking using PIStreamPacker. It
//! supports both client and server roles with reliable byte-stream transmission over TCP connections.
//! \~russian
//! Класс %PIPackedTCP предоставляет устройство TCP клиент/сервер с автоматической упаковкой/распаковкой данных с использованием
//! PIStreamPacker. Поддерживает обе роли: клиент и сервер с надежной передачей байтовых потоков по TCP соединениям.
class PIP_IO_UTILS_EXPORT PIPackedTCP: public PIIODevice {
PIIODEVICE(PIPackedTCP, "ptcp");
public:
//! \brief Role of %PIPackedTCP
//! \~english Operating role of %PIPackedTCP.
//! \~russian Роль работы %PIPackedTCP.
enum Role {
Client /** TCP client */,
Server /** TCP server for one client */
Client /** \~english TCP client side \~russian Сторона TCP-клиента */,
Server /** \~english TCP server for one client \~russian TCP-сервер для одного клиента */
};
//! Contructs %PIPackedTCP with "role" and "addr" address
//! \~english Constructs %PIPackedTCP with role "role" and endpoint "addr".
//! \~russian Создает %PIPackedTCP с ролью "role" и конечной точкой "addr".
explicit PIPackedTCP(Role role = Client, const PINetworkAddress & addr = {});
//! \~english Destroys the packed TCP device.
//! \~russian Уничтожает устройство пакетированного TCP.
virtual ~PIPackedTCP();
//! Set server address for Server role or connect address for Client
//! \~english Sets listen address for server mode or remote address for client mode.
//! \~russian Устанавливает адрес прослушивания для режима сервера или удаленный адрес для режима клиента.
void setAddress(const PINetworkAddress & addr);
//! \~english Returns true if the TCP connection is established and active
//! \~russian Возвращает true если TCP соединение установлено и активно
bool isConnected() const;
//! \~english Returns true if the device is currently attempting to establish a TCP connection
//! \~russian Возвращает true если устройство в данный момент пытается установить TCP соединение
bool isConnecting() const;
//! Returns read address in format "i.i.i.i:p"
//! \~english Returns configured endpoint address.
//! \~russian Возвращает настроенный адрес конечной точки.
PINetworkAddress address() const { return m_addr; }
//! Returns %PIEthernet type
//! \~english Returns current operating role.
//! \~russian Возвращает текущую рабочую роль.
Role role() const { return m_role; }
//! \events
//! \{
//! \fn void connected()
//! \~english Emitted when client connection becomes ready or a server accepts a client.
//! \~russian Генерируется, когда клиентское подключение готово или сервер принимает клиента.
EVENT0(connected);
//! \fn void disconnected()
//! \~english Emitted when active TCP connection is lost or closed.
//! \~russian Генерируется при потере или закрытии активного TCP-соединения.
EVENT0(disconnected);
//! \}
protected:
void init();

View File

@@ -1,9 +1,8 @@
/*! \file pipacketextractor.h
* \ingroup IO
* \~\brief
* \~english Packets extractor
* \~russian Извлекатель пакетов
*/
//! \~\file pipacketextractor.h
//! \~\ingroup IO-Utils
//! \~\brief
//! \~english Packet extraction helper for byte-stream devices
//! \~russian Вспомогательный класс выделения пакетов для потоковых устройств
/*
PIP - Platform Independent Primitives
Packets extractor
@@ -28,125 +27,188 @@
#include "piiodevice.h"
/// TODO: написать документацию, тут ничего не понятно
/// Pass SourceHeaderPtr, ReceivedHeaderPtr, HeaderSize.
/// Return size of payload if packet is correct, or -1 if incorrect.
//! \~english Callback for header validation and payload size detection. Receives source header, received header and header size. Returns
//! payload size or -1 when the header does not match.
//! \~russian Callback для проверки заголовка и определения размера полезной нагрузки. Принимает ожидаемый заголовок, полученный заголовок и
//! размер заголовка. Возвращает размер полезной нагрузки или -1, если заголовок не совпал.
typedef std::function<int(const uchar *, const uchar *, int)> PacketExtractorHeaderFunc;
/// Pass ReceivedDataPtr, DataSize.
/// Return true if packet is correct, false otherwise.
//! \~english Callback for payload validation. Receives payload pointer and payload size. Returns \b true when the payload should be
//! accepted.
//! \~russian Callback для проверки полезной нагрузки. Принимает указатель на полезную нагрузку и ее размер. Возвращает \b true, если
//! нагрузка должна быть принята.
typedef std::function<bool(const uchar *, int)> PacketExtractorPayloadFunc;
/// Pass SourceFooterPtr, ReceivedFooterPtr, FooterSize.
/// Return true if packet is correct, false otherwise.
//! \~english Callback for footer validation. Receives source footer, received footer and footer size. Returns \b true when the footer
//! matches.
//! \~russian Callback для проверки конца пакета. Принимает ожидаемое окончание пакета, полученное окончание и размер окончания. Возвращает
//! \b true, если окончание совпало.
typedef std::function<bool(const uchar *, const uchar *, int)> PacketExtractorFooterFunc;
//! \~\ingroup IO-Utils
//! \~\brief
//! \~english Extracts packets from data produced by a child %PIIODevice.
//! \~russian Выделяет пакеты из данных, поступающих от дочернего %PIIODevice.
//! \details
//! \~english The PIPacketExtractor class provides packet recognition from data stream using various algorithms.
//! \~russian Класс PIPacketExtractor предоставляет распознавание пакетов из потока данных с использованием различных алгоритмов.
class PIP_EXPORT PIPacketExtractor: public PIIODevice {
PIIODEVICE(PIPacketExtractor, "pckext");
friend class PIConnection;
public:
//! Extract algorithms
//! \~english Packet splitting modes.
//! \~russian Режимы выделения пакетов.
enum SplitMode {
None /** No data processing */,
Header /** Detect packets with \a header() and following \a payloadSize() */,
Footer /** Detect packets with \a footer() and leading \a payloadSize() */,
HeaderAndFooter /** Detect packets with \a header() and \a footer() without \a payloadSize() */,
Size /** Detect packets with \a packetSize() */,
Timeout /** Wait for first read, then read for \a timeout() */
None /** \~english Accept every read chunk as a packet \~russian Считать каждый прочитанный блок отдельным пакетом */,
Header /** \~english Search for \a header() and use configured payload size or callback result \~russian Искать \a header() и
использовать настроенный размер полезной нагрузки или результат callback */
,
Footer /** \~english Use fixed payload size and validate trailing \a footer() \~russian Использовать фиксированный размер полезной
нагрузки и проверять завершающий \a footer() */
,
HeaderAndFooter /** \~english Search for packets bounded by \a header() and \a footer() \~russian Искать пакеты, ограниченные \a
header() и \a footer() */
,
Size /** \~english Treat \a payloadSize() as full packet size \~russian Использовать \a payloadSize() как полный размер пакета */,
Timeout /** \~english Collect bytes until \a timeout() expires after the first read \~russian Накопить байты до истечения \a
timeout() после первого чтения */
};
//! Contructs extractor with child device "device_" and extract algorithm "mode"
//! \~english Constructs extractor bound to "device_" and configured with split mode "mode".
//! \~russian Создает извлекатель, привязанный к "device_", и настраивает режим выделения "mode".
explicit PIPacketExtractor(PIIODevice * device_ = nullptr, SplitMode mode = None);
//! \~english Stops extractor background activity and destroys the object.
//! \~russian Останавливает фоновую работу извлекателя и уничтожает объект.
virtual ~PIPacketExtractor() { stop(); }
//! Returns child %device
//! \~english Returns the current child device.
//! \~russian Возвращает текущее дочернее устройство.
PIIODevice * device() { return dev; }
//! Set child %device to "device_"
//! \~english Replaces the child device with "device_".
//! \~russian Заменяет дочернее устройство на "device_".
void setDevice(PIIODevice * device_);
//! \~english Returns unread bytes currently available from the child device.
//! \~russian Возвращает число непрочитанных байтов, доступных в дочернем устройстве.
ssize_t bytesAvailable() const override;
//! \~english Sets custom header validation callback.
//! \~russian Устанавливает пользовательский callback проверки заголовка.
void setHeaderCheckSlot(PacketExtractorHeaderFunc f) { func_header = f; }
//! \~english Sets custom payload validation callback.
//! \~russian Устанавливает пользовательский callback проверки полезной нагрузки.
void setPayloadCheckSlot(PacketExtractorPayloadFunc f) { func_payload = f; }
//! \~english Sets custom footer validation callback.
//! \~russian Устанавливает пользовательский callback проверки окончания пакета.
void setFooterCheckSlot(PacketExtractorFooterFunc f) { func_footer = f; }
//! Set extract algorithm
//! \~english Switches packet extraction to mode "mode".
//! \~russian Переключает выделение пакетов в режим "mode".
void setSplitMode(SplitMode mode) { setProperty("splitMode", int(mode)); }
//! Set payload size, used for PIPacketExtractor::Header and PIPacketExtractor::Footer algorithms
//! \~english Sets fixed payload size used by the size-based extraction modes.
//! \~russian Устанавливает фиксированный размер полезной нагрузки для режимов с известным размером.
void setPayloadSize(int size);
//! Set header data, used for PIPacketExtractor::Header and PIPacketExtractor::HeaderAndFooter algorithms
//! \~english Sets reference header bytes.
//! \~russian Устанавливает эталонные байты заголовка.
void setHeader(const PIByteArray & data);
//! Set footer data, used for PIPacketExtractor::Footer and PIPacketExtractor::HeaderAndFooter algorithms
//! \~english Sets reference footer bytes.
//! \~russian Устанавливает эталонные байты окончания пакета.
void setFooter(const PIByteArray & data);
//! Set timeout, used for PIPacketExtractor::Timeout algorithm
//! \~english Sets accumulation timeout for \a Timeout mode.
//! \~russian Устанавливает тайм-аут накопления для режима \a Timeout.
void setTimeout(PISystemTime tm) { setProperty("timeout", tm); }
//! Returns current extract algorithm
//! \~english Returns current packet splitting mode.
//! \~russian Возвращает текущий режим выделения пакетов.
SplitMode splitMode() const { return mode_; }
//! Returns current payload size, used for PIPacketExtractor::Header and PIPacketExtractor::Footer and PIPacketExtractor::Size
//! algorithms
//! \~english Returns configured payload size.
//! \~russian Возвращает настроенный размер полезной нагрузки.
int payloadSize() const { return dataSize; }
//! Returns current header data, used for PIPacketExtractor::Header and PIPacketExtractor::HeaderAndFooter algorithms
//! \~english Returns configured reference header.
//! \~russian Возвращает настроенный эталонный заголовок.
PIByteArray header() const { return src_header; }
//! Returns current footer data, used for PIPacketExtractor::Footer and PIPacketExtractor::HeaderAndFooter algorithms
//! \~english Returns configured reference footer.
//! \~russian Возвращает настроенное эталонное окончание пакета.
PIByteArray footer() const { return src_footer; }
//! Returns current timeout in milliseconds, used for PIPacketExtractor::Timeout algorithm
//! \~english Returns timeout used by \a Timeout mode.
//! \~russian Возвращает тайм-аут, используемый режимом \a Timeout.
PISystemTime timeout() const { return time_; }
//! Returns missed by validating functions bytes count
//! \~english Returns number of bytes skipped during resynchronization.
//! \~russian Возвращает число байтов, пропущенных при ресинхронизации.
ullong missedBytes() const { return missed; }
//! Add data to extractor, raise \a packetReceived() if packet is ready
//! \~english Feeds raw bytes into the extractor.
//! \~russian Передает сырые байты в извлекатель.
//! \~english Emits \a packetReceived() when a complete packet is recognized.
//! \~russian Генерирует \a packetReceived(), когда распознан полный пакет.
void appendData(const uchar * d, int s) { threadedRead(d, s); }
//! Add data to extractor, raise \a packetReceived() if packet is ready
//! \~english Feeds byte-array data into the extractor.
//! \~russian Передает массив байтов в извлекатель.
//! \~english Emits \a packetReceived() when a complete packet is recognized.
//! \~russian Генерирует \a packetReceived(), когда распознан полный пакет.
void appendData(const PIByteArray & data) { threadedRead(data.data(), data.size_s()); }
EVENT2(packetReceived, const uchar *, data, int, size);
//! \events
//! \{
//! \fn void packetReceived(const uchar * data, int size)
//! \brief Raise on successfull \a packetValidate() function
//! \~english Emitted when the current input chunk passes the configured extraction rules.
//! \~russian Генерируется, когда текущие входные данные проходят настроенные правила выделения.
EVENT2(packetReceived, const uchar *, data, int, size);
//! \}
protected:
/** \brief Function to validate header
* \param src Your header content
* \param rec Received header
* \param size Header size
* \details Default implementation returns by-byte "src" with "rec" compare result */
//! \~english Validates packet header and optionally returns payload size.
//! \~russian Проверяет заголовок пакета и при необходимости возвращает размер полезной нагрузки.
//! \~\details
//! \~english
//! The default implementation compares "src" and "rec" byte by byte and
//! returns the configured \a payloadSize() on success.
//! \~russian
//! Реализация по умолчанию побайтно сравнивает "src" и "rec" и при успехе
//! возвращает настроенный \a payloadSize().
virtual int validateHeader(const uchar * src, const uchar * rec, int size);
/** \brief Function to validate footer
* \param src Your footer content
* \param rec Received footer
* \param size Footer size
* \details Default implementation returns by-byte "src" with "rec" compare result */
//! \~english Validates packet footer.
//! \~russian Проверяет окончание пакета.
//! \~english The default implementation compares "src" and "rec" byte by byte.
//! \~russian Реализация по умолчанию побайтно сравнивает "src" и "rec".
virtual bool validateFooter(const uchar * src, const uchar * rec, int size);
/** \brief Function to validate payload
* \param rec Received payload
* \param size payload size
* \details Default implementation returns \b true */
//! \~english Validates packet payload.
//! \~russian Проверяет полезную нагрузку пакета.
//! \~english The default implementation accepts any payload.
//! \~russian Реализация по умолчанию принимает любую полезную нагрузку.
virtual bool validatePayload(const uchar * rec, int size);
private:
void construct();
void propertyChanged(const char *) override;

View File

@@ -1,9 +1,8 @@
/*! \file piparsehelper.h
* \ingroup IO
* \~\brief
* \~english Helper class to automate structs receive
* \~russian Класс для автоматизации приема структур
*/
//! \~\file piparsehelper.h
//! \~\ingroup IO-Utils
//! \~\brief
//! \~english Key-dispatch helper for deserializing packets into callbacks
//! \~russian Вспомогательный класс диспетчеризации по ключу для десериализации пакетов в обработчики
/*
PIP - Platform Independent Primitives
Helper class to automate structs receive
@@ -30,60 +29,45 @@
#include "pip_io_utils_export.h"
/** \class PIParseHelper
* \brief Helper class to automate structs receive
*
*
* \section PIParseHelper_synopsis Synopsis
* This class helps to deserialize and invoke neccessarily methods.
*
* Data packets with header and various data types can be automated by this class.
* Every key value mapped to object member function, lambda-function or functor.
*
* This class can remove \b switch-case with deserialization code and
* replace it with several \a assign() calls, binded to ready-to-use event handlers.
* Moreover data type automatic takes from event handler or lambda argument. One should
* only make \"PIByteArray & operator <<()\" with used types, deserialization will be
* performed by %PIParseHelper.
*
*
* \section PIParseHelper_usage Usage
*
* Create instance of %PIParseHelper, or subclass.
*
* In \a assign() methods you can use object member function, lambda-function
* or functor with 0 or 1 arguments,
*
*
* \section PIParseHelper_lambda Lambda-functions
* \code assign(1, [this](const SomeStruct & s){}) \endcode
*
*
* \section PIParseHelper_examples Examples
* First example describes subclass variant. As one can see, it`s a single place to change
* type of received data - event handler argument.
* \snippet piparsehelper.cpp 0
*
* Second example show separate variant:
* \snippet piparsehelper.cpp 1
*
**/
//! \~\ingroup IO-Utils
//! \~\brief
//! \~english Maps packet keys to handlers and deserializes payloads before invocation.
//! \~russian Связывает ключи пакетов с обработчиками и десериализует полезную нагрузку перед вызовом.
//! \~\details
//! \~english
//! %PIParseHelper helps replace manual switch-based packet dispatch with a set of
//! \a assign() calls. Handlers may be plain callbacks, functors or object member functions.
//! Payload types are restored from %PIByteArray by the selected handler signature.
//! \n
//! \n Example:
//! \~russian
//! %PIParseHelper помогает заменить ручную диспетчеризацию пакетов через switch
//! набором вызовов \a assign(). Обработчиками могут быть обычные callback-функции,
//! функторы или методы объекта. Тип полезной нагрузки восстанавливается из %PIByteArray
//! по сигнатуре выбранного обработчика.
//! \n
//! \n Пример:
//!
//! \~\snippet piparsehelper.cpp 0
//! \~\snippet piparsehelper.cpp 1
template<typename Key>
class PIParseHelper {
public:
//! \brief Construct %PIParseHelper
//! \~english Constructs empty parser helper.
//! \~russian Создает пустой вспомогательный парсер.
PIParseHelper() {}
//! \brief Assign key \"key\" to lambda-function \"func\" without arguments
//! \~english Assigns key "key" to callback "func" without payload arguments.
//! \~russian Связывает ключ "key" с callback-функцией "func" без аргументов полезной нагрузки.
void assign(Key key, std::function<void()> func) {
auto lf = [func](PIByteArray) { func(); };
functions[key] << lf;
}
//! \brief Assign key \"key\" to lambda-function \"func\" with 1 argument
//! \~english Assigns key "key" to callback "func" with one deserialized argument.
//! \~russian Связывает ключ "key" с callback-функцией "func" с одним десериализуемым аргументом.
template<typename T>
void assign(Key key, std::function<void(const T &)> func) {
auto lf = [func](PIByteArray data) {
@@ -97,7 +81,8 @@ public:
}
//! \brief Assign key \"key\" to member function of object \"obj\" without arguments
//! \~english Assigns key "key" to zero-argument member function of object "obj".
//! \~russian Связывает ключ "key" с методом объекта "obj" без аргументов.
template<typename O>
void assign(Key key, O * obj, void (O::*member_func)()) {
auto lf = [member_func, obj](PIByteArray) { (obj->*member_func)(); };
@@ -105,7 +90,8 @@ public:
}
//! \brief Assign key \"key\" to member function of object \"obj\" with 1 argument
//! \~english Assigns key "key" to member function of object "obj" with one deserialized argument.
//! \~russian Связывает ключ "key" с методом объекта "obj" с одним десериализуемым аргументом.
template<typename T, typename O>
void assign(Key key, O * obj, void (O::*member_func)(const T &)) {
auto lf = [member_func, obj](PIByteArray data) {
@@ -119,14 +105,16 @@ public:
}
//! \brief Assign key \"key\" to functor \"func\" with 0 or 1 argument
//! \~english Assigns key "key" to functor or lambda with zero or one argument.
//! \~russian Связывает ключ "key" с функтором или lambda с нулем или одним аргументом.
template<typename L>
void assign(Key key, L func) {
return assign(key, toStdFunction(func));
}
//! \brief Deserialize data and invoke assigned to \"key\" methods
//! \~english Deserializes payload "ba" and invokes handlers assigned to "key".
//! \~russian Десериализует полезную нагрузку "ba" и вызывает обработчики, назначенные ключу "key".
void parse(Key key, PIByteArray ba) {
auto fl = functions.value(key);
for (auto f: fl)

View File

@@ -1,9 +1,8 @@
/*! \file pistreampacker.h
* \ingroup IO-Utils
* \~\brief
* \~english Simple packet wrap aroud any PIIODevice
* \~russian Простая фрагментация пакетов, использует любой PIIODevice
*/
//! \~\file pistreampacker.h
//! \~\ingroup IO-Utils
//! \~\brief
//! \~english Packet framing helper for byte-stream devices
//! \~russian Вспомогательный класс пакетирования для потоковых устройств
/*
PIP - Platform Independent Primitives
Simple packet wrap aroud any PIIODevice
@@ -33,45 +32,72 @@
class PIIODevice;
//! \~\ingroup IO-Utils
//! \~\brief
//! \~english Configuration for %PIStreamPacker packet framing.
//! \~russian Конфигурация пакетирования для %PIStreamPacker.
class PIStreamPackerConfig: public PIEthUtilBase {
friend class PIStreamPacker;
public:
//! \~english Constructs configuration with default packet framing parameters.
//! \~russian Создает конфигурацию с параметрами пакетирования по умолчанию.
PIStreamPackerConfig() {
crypt_size = false;
crypt_size = false;
aggressive_optimization = true;
max_packet_size = 1400;
packet_sign = 0xAFBE;
}
//! Set maximum size of single packet
//! \~english Sets maximum size of one emitted frame chunk.
//! \~russian Устанавливает максимальный размер одного отправляемого фрагмента.
void setMaxPacketSize(int max_size) { max_packet_size = max_size; }
//! Returns maximum size of single packet, default 1400 bytes
//! \~english Returns maximum size of one emitted frame chunk.
//! \~russian Возвращает максимальный размер одного отправляемого фрагмента.
int maxPacketSize() const { return max_packet_size; }
//! Set packet sinature
//! \~english Sets packet signature used to detect frame boundaries.
//! \~russian Устанавливает сигнатуру пакета для поиска границ кадра.
void setPacketSign(ushort sign_) { packet_sign = sign_; }
//! Returns packet sinature, default 0xAFBE
//! \~english Returns packet signature.
//! \~russian Возвращает сигнатуру пакета.
ushort packetSign() const { return packet_sign; }
//! Set receive aggressive optimization. If yes then %PIStreamPacker doesn`t
//! check every byte in incoming stream but check only begin of each read()
//! result. Default is \b true.
//! \~english Enables faster resynchronization on invalid stream data.
//! \~russian Включает более быструю ресинхронизацию при неверных данных в потоке.
//! \~\details
//! \~english
//! When enabled, %PIStreamPacker drops the whole current read chunk after a
//! signature mismatch instead of scanning byte by byte.
//! \~russian
//! Когда режим включен, %PIStreamPacker отбрасывает весь текущий прочитанный
//! блок после несовпадения сигнатуры вместо побайтного поиска.
void setaAggressiveOptimization(bool yes) { aggressive_optimization = yes; }
//! Returns aggressive optimization
//! \~english Returns whether aggressive resynchronization is enabled.
//! \~russian Возвращает, включена ли агрессивная ресинхронизация.
bool aggressiveOptimization() const { return aggressive_optimization; }
//! \~english Returns whether packet size field is encrypted too.
//! \~russian Возвращает, шифруется ли также поле размера пакета.
bool cryptSizeEnabled() const { return crypt_size; }
//! \~english Enables or disables encryption of the packet size field.
//! \~russian Включает или выключает шифрование поля размера пакета.
void setCryptSizeEnabled(bool on) { crypt_size = on; }
//! Get configuration
//! \~english Returns configuration as a const self-reference.
//! \~russian Возвращает конфигурацию как константную ссылку на себя.
const PIStreamPackerConfig & configuration() const { return *this; }
//! \~english Returns configuration as a mutable self-reference.
//! \~russian Возвращает конфигурацию как изменяемую ссылку на себя.
PIStreamPackerConfig & configuration() { return *this; }
//! Apply configuration
//! \~english Replaces current framing configuration with "config".
//! \~russian Заменяет текущую конфигурацию пакетирования на "config".
void setConfiguration(const PIStreamPackerConfig & config) { *this = config; }
private:
@@ -81,44 +107,58 @@ private:
};
//! \~\ingroup IO-Utils
//! \~\brief
//! \~english Simple packet wrapper around any PIIODevice
//! \~russian Простая фрагментация пакетов, использует любой PIIODevice
//! \details
//! \~english Provides packet framing and deframing for data transmission over any PIIODevice implementation
//! \~russian Предоставляет фрагментацию и дефрагментацию пакетов для передачи данных через любую реализацию PIIODevice
class PIP_IO_UTILS_EXPORT PIStreamPacker
: public PIObject
, public PIStreamPackerConfig {
PIOBJECT(PIStreamPacker)
public:
//! Contructs packer and try to assign \"dev\"
//! \~english Constructs packer and optionally binds it to "dev".
//! \~russian Создает упаковщик и при необходимости привязывает его к "dev".
PIStreamPacker(PIIODevice * dev = nullptr);
//! Returns progress of current packet receive in bytes
//! \~english Returns number of payload bytes collected for current packet.
//! \~russian Возвращает число байтов полезной нагрузки, собранных для текущего пакета.
int receivePacketProgress() const { return packet.size_s(); }
//! \~english Clears buffered stream state and incomplete packet data.
//! \~russian Очищает буферизованное состояние потока и данные незавершенного пакета.
void clear();
//! Prepare data for send and raise \a sendRequest() events
//! \~english Fragments data and raises \a sendRequest() for each fragment
//! \~russian Фрагментирует данные и вызывает \a sendRequest() для каждого фрагмента
void send(const PIByteArray & data);
//! Receive data part. If packet is ready, raise \a packetReceiveEvent() event
//! and \a packetReceived() virtual method
//! \~english Feeds received bytes into the unpacker.
//! \~russian Передает полученные байты в распаковщик.
//! \~\details
//! \~english Calls \a packetReceived() and emits \a packetReceiveEvent() when a packet is complete.
//! \~russian Вызывает \a packetReceived() и генерирует \a packetReceiveEvent(), когда пакет собран полностью.
void received(const PIByteArray & data);
EVENT_HANDLER2(void, received, const uchar *, readed, ssize_t, size);
//! Connect \"dev\" \a PIIODevice::threadedReadEvent() event to \a received() handler
//! and \a sendRequest() event to \"dev\" \a PIIODevice::write() handler
//! \~english Binds "dev" read and write callbacks to this packer.
//! \~russian Связывает обратные вызовы чтения и записи устройства "dev" с этим упаковщиком.
//! \~\details
//! \~english Connects \a PIIODevice::threadedReadEvent() to \a received() and \a sendRequest() to \a PIIODevice::write().
//! \~russian Подключает \a PIIODevice::threadedReadEvent() к \a received(), а \a sendRequest() к \a PIIODevice::write().
void assignDevice(PIIODevice * dev);
EVENT1(packetReceiveEvent, PIByteArray &, data);
EVENT1(startPacketReceive, int, size);
EVENT0(endPacketReceive);
EVENT1(sendRequest, PIByteArray, data);
//! \handlers
//! \{
//! \fn void received(uchar * readed, int size)
//! \brief Handler to receive data. \a PIIODevice::threadedReadEvent()
//! can be connected to this handler
//! \fn void received(const uchar * readed, ssize_t size)
//! \~english Handler overload for raw byte buffers from \a PIIODevice::threadedReadEvent().
//! \~russian Перегрузка обработчика для сырых буферов байтов из \a PIIODevice::threadedReadEvent().
EVENT_HANDLER2(void, received, const uchar *, readed, ssize_t, size);
//! \}
@@ -126,23 +166,30 @@ public:
//! \{
//! \fn void packetReceiveEvent(PIByteArray data)
//! \brief Raise on packet successfully received
//! \~english Emitted when a complete packet is received.
//! \~russian Генерируется, когда пакет полностью принят.
EVENT1(packetReceiveEvent, PIByteArray &, data);
//! \fn void startPacketReceive(int size)
//! \brief Raise on start receive packet with overall size \"size\"
//! \~english Emitted when a new packet with payload size "size" starts.
//! \~russian Генерируется при начале приема нового пакета с размером полезной нагрузки "size".
EVENT1(startPacketReceive, int, size);
//! \fn void endPacketReceive()
//! \brief Raise on finish receive packet
//! \~english Emitted after the current packet has been fully received.
//! \~russian Генерируется после полного приема текущего пакета.
EVENT0(endPacketReceive);
//! \fn void sendRequest(PIByteArray data)
//! \brief Raise from \a send() function. This data should
//! be directly sended to your device. You can
//! connect this event to \a PIIODevice::write() handler
//! \~english Emitted by \a send() for every framed chunk ready to write to the device.
//! \~russian Генерируется методом \a send() для каждого готового к записи во устройство фрагмента.
EVENT1(sendRequest, PIByteArray, data);
//! \}
protected:
//! Packet successfully received, by default does nothing
//! \~english Called after a packet payload has been reconstructed.
//! \~russian Вызывается после восстановления полезной нагрузки пакета.
virtual void packetReceived(PIByteArray data) {}
private: