AMQP-CPP/src/linux_tcp/tcpstate.h

184 lines
5.1 KiB
C++

/**
* TcpState.h
*
* Base class / interface of the various states of the TCP connection
*
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
* @copyright 2015 - 2018 Copernica BV
*/
/**
* Include guard
*/
#pragma once
/**
* Set up namespace
*/
namespace AMQP {
/**
* Class definition
*/
class TcpState
{
protected:
/**
* Parent TcpConnection object as is seen by the user
* @var TcpConnection
*/
TcpConnection *_connection;
/**
* User-supplied handler
* @var TcpHandler
*/
TcpHandler *_handler;
protected:
/**
* Protected constructor
* @param connection Original TCP connection object
* @param handler User-supplied handler class
*/
TcpState(TcpConnection *connection, TcpHandler *handler) :
_connection(connection), _handler(handler) {}
/**
* Protected "copy" constructor
* @param state Original TcpState object
*/
TcpState(const TcpState *state) :
_connection(state->_connection), _handler(state->_handler) {}
public:
/**
* Virtual destructor
*/
virtual ~TcpState() = default;
/**
* The filedescriptor of this connection
* @return int
*/
virtual int fileno() const { return -1; }
/**
* The number of outgoing bytes queued on this connection.
* @return size_t
*/
virtual std::size_t queued() const { return 0; }
/**
* Process the filedescriptor in the object
*
* This method should return the handler object that will be responsible for
* all future readable/writable events for the file descriptor, or nullptr
* if the underlying connection object has already been destructed by the
* user and it would be pointless to set up a new handler.
*
* @param monitor Monitor that can be used to check if the tcp connection is still alive
* @param fd The filedescriptor that is active
* @param flags AMQP::readable and/or AMQP::writable
* @return New implementation object
*/
virtual TcpState *process(const Monitor &monitor, int fd, int flags)
{
// default implementation does nothing and preserves same implementation
return this;
}
/**
* Send data over the connection
* @param buffer Buffer to send
* @param size Size of the buffer
*/
virtual void send(const char *buffer, size_t size)
{
// default does nothing
}
/**
* Flush the connection, all outgoing operations should be completed.
*
* If the state changes during the operation, the new state object should
* be returned instead, or nullptr if the user has closed the connection
* in the meantime. If the connection object got destructed by a user space
* call, this method should return nullptr. A monitor object is pass in to
* allow the flush() method to check if the connection still exists.
*
* If this object returns a new state object (instead of "this"), the
* connection object will immediately proceed with calling flush() on that
* new state object too.
*
* @param monitor Monitor that can be used to check if the tcp connection is still alive
* @return TcpState New implementation object
*/
virtual TcpState *flush(const Monitor &monitor) { return this; }
/**
* Report to the handler that heartbeat negotiation is going on
* @param heartbeat suggested heartbeat
* @return uint16_t accepted heartbeat
*/
virtual uint16_t reportNegotiate(uint16_t heartbeat)
{
// pass to handler
return _handler->onNegotiate(_connection, heartbeat);
}
/**
* Report to the handler that the object is in an error state.
*
* This is the last method to be called on the handler object, from now on
* the handler will no longer be called to report things to user space.
* The state object itself stays active, and further calls to process()
* may be possible.
*
* @param error
*/
virtual void reportError(const char *error)
{
// pass to handler
_handler->onError(_connection, error);
}
/**
* Report that a heartbeat frame was received
*/
virtual void reportHeartbeat()
{
// pass to handler
_handler->onHeartbeat(_connection);
}
/**
* Report to the handler that the connection is ready for use
*/
virtual void reportConnected()
{
// pass to handler
_handler->onConnected(_connection);
}
/**
* Report to the handler that the connection was correctly closed, after
* the user has called the Connection::close() method. The underlying TCP
* connection still has to be closed.
*
* This is the last method that is called on the object, from now on no
* other methods may be called on the _handler variable.
*/
virtual void reportClosed()
{
// pass to handler
_handler->onClosed(_connection);
}
};
/**
* End of namespace
*/
}