/*! \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 . */ #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