/*! \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; class PIStreamPackerConfig: public PIEthUtilBase { friend class PIStreamPacker; public: PIStreamPackerConfig() { crypt_size = false; aggressive_optimization = true; max_packet_size = 1400; packet_sign = 0xAFBE; } //! Set maximum size of single packet void setMaxPacketSize(int max_size) { max_packet_size = max_size; } //! Returns maximum size of single packet, default 1400 bytes int maxPacketSize() const { return max_packet_size; } //! Set packet sinature void setPacketSign(ushort sign_) { packet_sign = sign_; } //! Returns packet sinature, default 0xAFBE 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. void setaAggressiveOptimization(bool yes) { aggressive_optimization = yes; } //! Returns aggressive optimization bool aggressiveOptimization() const { return aggressive_optimization; } bool cryptSizeEnabled() const { return crypt_size; } void setCryptSizeEnabled(bool on) { crypt_size = on; } //! Get configuration const PIStreamPackerConfig & configuration() const { return *this; } PIStreamPackerConfig & configuration() { return *this; } //! Apply configuration void setConfiguration(const PIStreamPackerConfig & config) { *this = config; } private: bool crypt_size, aggressive_optimization; ushort packet_sign; int max_packet_size; }; class PIP_IO_UTILS_EXPORT PIStreamPacker : public PIObject , public PIStreamPackerConfig { PIOBJECT(PIStreamPacker) public: //! Contructs packer and try to assign \"dev\" PIStreamPacker(PIIODevice * dev = nullptr); //! Returns progress of current packet receive in bytes int receivePacketProgress() const { return packet.size_s(); } void clear(); //! Prepare data for send and raise \a sendRequest() events void send(const PIByteArray & data); //! Receive data part. If packet is ready, raise \a packetReceiveEvent() event //! and \a packetReceived() virtual method 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 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