Files
pip/libs/main/io_utils/pistreampacker.h

186 lines
7.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*! \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