186 lines
7.3 KiB
C++
186 lines
7.3 KiB
C++
/*! \file pistreampacker.h
|
||
* \ingroup IO-Utils
|
||
* \~\brief
|
||
* \~english Simple packet wrap aroud any PIIODevice
|
||
* \~russian Простая фрагментация пакетов, использует любой PIIODevice
|
||
*/
|
||
/*
|
||
PIP - Platform Independent Primitives
|
||
Simple packet wrap aroud any PIIODevice
|
||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||
|
||
This program is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
This program is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#ifndef PISTREAMPACKER_H
|
||
#define PISTREAMPACKER_H
|
||
|
||
#include "piethutilbase.h"
|
||
#include "piobject.h"
|
||
#include "pip_io_utils_export.h"
|
||
|
||
|
||
class PIIODevice;
|
||
|
||
//! \~english Stream packer configuration
|
||
//! \~russian Конфигурация упаковщика потока
|
||
class PIStreamPackerConfig: public PIEthUtilBase {
|
||
friend class PIStreamPacker;
|
||
|
||
public:
|
||
//! \~english Constructs default configuration
|
||
//! \~russian Создает конфигурацию по умолчанию
|
||
PIStreamPackerConfig() {
|
||
crypt_size = false;
|
||
aggressive_optimization = true;
|
||
max_packet_size = 1400;
|
||
packet_sign = 0xAFBE;
|
||
}
|
||
|
||
//! \~english Set maximum size of single packet
|
||
//! \~russian Установить максимальный размер одного пакета
|
||
void setMaxPacketSize(int max_size) { max_packet_size = max_size; }
|
||
|
||
//! \~english Returns maximum size of single packet, default 1400 bytes
|
||
//! \~russian Возвращает максимальный размер одного пакета, по умолчанию 1400 байт
|
||
int maxPacketSize() const { return max_packet_size; }
|
||
|
||
//! \~english Set packet signature
|
||
//! \~russian Установить подпись пакета
|
||
void setPacketSign(ushort sign_) { packet_sign = sign_; }
|
||
|
||
//! \~english Returns packet signature, default 0xAFBE
|
||
//! \~russian Возвращает подпись пакета, по умолчанию 0xAFBE
|
||
ushort packetSign() const { return packet_sign; }
|
||
|
||
//! \~english 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.
|
||
//! \~russian Установить агрессивную оптимизацию приема. Если да, то %PIStreamPacker не проверяет каждый байт во входящем потоке, а
|
||
//! только начало каждого результата read(). По умолчанию \b true.
|
||
void setaAggressiveOptimization(bool yes) { aggressive_optimization = yes; }
|
||
|
||
//! \~english Returns aggressive optimization
|
||
//! \~russian Возвращает агрессивную оптимизацию
|
||
bool aggressiveOptimization() const { return aggressive_optimization; }
|
||
|
||
//! \~english Check if crypt size enabled
|
||
//! \~russian Проверить, включен ли размер шифрования
|
||
bool cryptSizeEnabled() const { return crypt_size; }
|
||
|
||
//! \~english Set crypt size enabled
|
||
//! \~russian Установить включенный размер шифрования
|
||
void setCryptSizeEnabled(bool on) { crypt_size = on; }
|
||
|
||
//! \~english Get configuration
|
||
//! \~russian Получить конфигурацию
|
||
const PIStreamPackerConfig & configuration() const { return *this; }
|
||
|
||
//! \~english Get configuration
|
||
//! \~russian Получить конфигурацию
|
||
PIStreamPackerConfig & configuration() { return *this; }
|
||
|
||
//! \~english Apply configuration
|
||
//! \~russian Применить конфигурацию
|
||
void setConfiguration(const PIStreamPackerConfig & config) { *this = config; }
|
||
|
||
private:
|
||
bool crypt_size, aggressive_optimization;
|
||
ushort packet_sign;
|
||
int max_packet_size;
|
||
};
|
||
|
||
|
||
//! \~english Simple packet wrap around any PIIODevice
|
||
//! \~russian Простая фрагментация пакетов, использует любой PIIODevice
|
||
class PIP_IO_UTILS_EXPORT PIStreamPacker
|
||
: public PIObject
|
||
, public PIStreamPackerConfig {
|
||
PIOBJECT(PIStreamPacker)
|
||
|
||
public:
|
||
//! \~english Constructs packer and try to assign "dev"
|
||
//! \~russian Создает упаковщик и пытается присвоить "dev"
|
||
PIStreamPacker(PIIODevice * dev = nullptr);
|
||
|
||
//! \~english Returns progress of current packet receive in bytes
|
||
//! \~russian Возвращает прогресс приема текущего пакета в байтах
|
||
int receivePacketProgress() const { return packet.size_s(); }
|
||
|
||
//! \~english Clear all buffers
|
||
//! \~russian Очистить все буферы
|
||
void clear();
|
||
|
||
//! \~english Prepare data for send and raise \a sendRequest() events
|
||
//! \~russian Подготовить данные для отправки и вызвать события \a sendRequest()
|
||
void send(const PIByteArray & data);
|
||
|
||
//! \~english Receive data part. If packet is ready, raise \a packetReceiveEvent() event and \a packetReceived() virtual method
|
||
//! \~russian Принять часть данных. Если пакет готов, вызвать событие \a packetReceiveEvent() и виртуальный метод \a packetReceived()
|
||
void received(const PIByteArray & data);
|
||
|
||
EVENT_HANDLER2(void, received, const uchar *, readed, ssize_t, size);
|
||
|
||
//! \~english Connect "dev" \a PIIODevice::threadedReadEvent() event to \a received() handler and \a sendRequest() event to "dev" \a
|
||
//! PIIODevice::write() handler
|
||
//! \~russian Подключить событие \a PIIODevice::threadedReadEvent() устройства "dev" к обработчику \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
|
||
|
||
//! \}
|
||
|
||
//! \events
|
||
//! \{
|
||
|
||
//! \fn void packetReceiveEvent(PIByteArray data)
|
||
//! \brief Raise on packet successfully received
|
||
|
||
//! \fn void startPacketReceive(int size)
|
||
//! \brief Raise on start receive packet with overall size \"size\"
|
||
|
||
//! \fn void endPacketReceive()
|
||
//! \brief Raise on finish receive packet
|
||
|
||
//! \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
|
||
|
||
//! \}
|
||
|
||
protected:
|
||
//! Packet successfully received, by default does nothing
|
||
virtual void packetReceived(PIByteArray data) {}
|
||
|
||
private:
|
||
uint sizeCryptedSize();
|
||
|
||
PIByteArray stream, packet;
|
||
int packet_size;
|
||
mutable PIMutex prog_s_mutex, prog_r_mutex;
|
||
};
|
||
|
||
#endif // PISTREAMPACKER_H
|