#ifndef __JNET__JLIGIEROBJECTITERATOR__ #define __JNET__JLIGIEROBJECTITERATOR__ #include #include #include "JLang/JAbstractObjectIterator.hh" #include "JNet/JPrefix.hh" #include "JNet/JServerSocket.hh" #include "JNet/JSocketChannel.hh" #include "JNet/JSelectReader.hh" /** * \author mdejong */ namespace JNET {} namespace JPP { using namespace JNET; } namespace JNET { using JLANG::JAbstractObjectIterator; typedef JSocketInputChannel JSocketInputChannel_t; /** * Get total size of internet packet. * * \param prefix prefix * \return number of bytes */ inline int getSizeOfPacket(const JPrefix& prefix) { return prefix.getSize() + sizeof(JPrefix); } /** * Object iteration through ControlHost server. * This class implements the JLANG::JObjectIterator interface. */ template class JLigierObjectIterator : public JServerSocket, public JAbstractObjectIterator, public std::vector { public: /** * Constructor. * * \param port server port * \param backlog server backlog * \param buffer_size socket buffer size * \param timeout_us timeout [us] */ JLigierObjectIterator(const int port, const int backlog, const int buffer_size = 262144, const int timeout_us = 10) : JServerSocket(port,backlog), buffer_size (buffer_size), timeout_us (timeout_us) {} /** * Set object. * * \param object reference to object to be set * \return true if set; else false */ virtual bool setObject(T& object) override { using namespace std; for ( ; ; ) { select.reset(); select.setReaderMask(this->getFileDescriptor()); for (const_iterator channel = this->begin(); channel != this->end(); ++channel) { if (!channel->isReady()) { select.setReaderMask(channel->getFileDescriptor()); } } if (select(timeout_us) > 0) { for (iterator channel = this->begin(); channel != this->end(); ) { if (select.hasReaderMask(*channel)) { try { channel->read(); if (channel->isReady()) { if (channel->prefix.getTag() == getTag()) { channel->seekg(sizeof(JPrefix)); *channel >> object; // read object channel->reset(); return true; } else { channel->reset(); // skip data } } } catch(const exception& error) { channel->shutdown(); channel = this->erase(channel); continue; } } ++channel; } if (select.hasReaderMask(*this)) { JTCPSocket socket(this->getFileDescriptor()); //socket.setSendBufferSize (buffer_size); socket.setReceiveBufferSize(buffer_size); socket.setKeepAlive (true); socket.setNonBlocking(true); this->push_back(JSocketInputChannel_t(socket)); } } } return false; } private: JSelectReader select; int buffer_size; int timeout_us; }; } #endif