You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdelibs/kdecore/network/ksocketdevice.h

434 lines
13 KiB

/* -*- C++ -*-
* Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net>
*
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef KSOCKETDEVICE_H
#define KSOCKETDEVICE_H
#include <tqsocketnotifier.h>
#include "ksocketbase.h"
namespace KNetwork {
class KSocketDevice;
class KSocketDeviceFactoryBase;
class KSocketDevicePrivate;
/** @class KSocketDevice ksocketdevice.h ksocketdevice.h
* @brief Low-level socket functionality.
*
* This class provides low-level socket functionality.
*
* Most users will prefer "cooked" interfaces like those of @ref KStreamSocket or
* @ref KServerSocket.
*
* Descended classes from this one provide some other kinds of socket functionality,
* like proxying or specific socket types.
*
* @author Thiago Macieira <thiago.macieira@kdemail.net>
*/
class KDECORE_EXPORT KSocketDevice: public KActiveSocketBase, public KPassiveSocketBase
{
public:
/**
* Capabilities for the socket implementation.
*
* KSocketDevice-derived classes can implement certain capabilities that are not
* available in the default class. These capabilities are described by these flags.
* The default KSocketDevice class has none of these capabilities.
*
* For the negative capabilities (inabilities, the CanNot* forms), when a capability
* is not present, the implementation will default to the original behaviour.
*/
enum Capabilities
{
/** Can connect to hostnames.
* If this flag is present, the string form of @ref connect can be used. */
CanConnectString = 0x01,
/** Can bind to hostnames.
* If this flag is present, the string form of @ref bind can be used */
CanBindString = 0x02,
/** Can not bind.
* If this flag is present, this implementation cannot bind */
CanNotBind = 0x04,
/** Can not listen.
* If this flag is present, this implementation cannot listen */
CanNotListen = 0x08,
/**
* Can send multicast as well as join/leave multicast groups.
*/
CanMulticast = 0x10,
/**
* Can not use datagrams.
* Note that this implies multicast capability not being available either.
*/
CanNotUseDatagrams = 0x20
};
protected:
/// The socket file descriptor. It is used throughout the implementation
/// and subclasses.
int m_sockfd;
public:
/**
* Default constructor.
*
* The parameter is used to specify which socket this object is used as
* a device for.
*/
explicit KSocketDevice(const KSocketBase* = 0L);
/**
* Constructs a new object around an already-open socket.
*
* Note: you should write programs that create sockets through
* the classes whenever possible.
*/
explicit KSocketDevice(int fd);
/**
* Destructor. This closes the socket if it's open.
*/
virtual ~KSocketDevice();
/**
* Returns the file descriptor for this socket.
*/
inline int socket() const
{ return m_sockfd; }
/**
* Returns the set of capabilities this socket class implements.
* The set of capabilities is defined as an OR-ed tqmask of
* @ref Capabilities bits.
*
* The default implementation is guaranteed to always return 0. That
* is, derived implementations always return bits where they differ
* from the system standard sockets.
*/
virtual int capabilities() const
{ return 0; }
/**
* This implementation sets the options on the socket.
*/
virtual bool setSocketOptions(int opts);
/**
* Reimplementation from TQIODevice. You should not call this function in sockets.
*/
virtual bool open(int mode);
/**
* Closes the socket. Reimplemented from TQIODevice.
*
* Use this function to close the socket this object is holding open.
*/
virtual void close();
/**
* This call is not supported on sockets. Reimplemented from TQIODevice.
*/
virtual void flush()
{ }
/**
* Creates a socket but don't connect or bind anywhere.
* This function is the equivalent of the system call socket(2).
*/
virtual bool create(int family, int type, int protocol);
/**
* @overload
* Creates a socket but don't connect or bind anywhere.
*/
bool create(const KResolverEntry& address);
/**
* Binds this socket to the given address.
*/
virtual bool bind(const KResolverEntry& address);
/**
* Puts this socket into listening mode.
*/
virtual bool listen(int backlog = 5); // 5 is arbitrary
/**
* Connect to a remote host.
*/
virtual bool connect(const KResolverEntry& address);
/**
* Accepts a new incoming connection.
* Note: this function returns a socket of type KSocketDevice.
*/
virtual KSocketDevice* accept();
/**
* Disconnects this socket.
*/
virtual bool disconnect();
/**
* Returns the number of bytes available for reading without blocking.
*/
#ifdef USE_QT3
virtual TQ_LONG bytesAvailable() const;
#endif
#ifdef USE_QT4
virtual qint64 bytesAvailable() const;
#endif
/**
* Waits up to @p msecs for more data to be available on this socket.
*
* This function is a wrapper against @ref poll. This function will wait
* for any read events.
*/
virtual TQ_LONG waitForMore(int msecs, bool *timeout = 0L);
/**
* Reads data from this socket.
*/
virtual TQ_LONG readBlock(char *data, TQ_ULONG maxlen);
/**
* Reads data and the source address from this socket.
*/
virtual TQ_LONG readBlock(char *data, TQ_ULONG maxlen, KSocketAddress& from);
/**
* Peeks data in the socket.
*/
virtual TQ_LONG peekBlock(char *data, TQ_ULONG maxlen);
/**
* Peeks the data in the socket and the source address.
*/
virtual TQ_LONG peekBlock(char *data, TQ_ULONG maxlen, KSocketAddress& from);
/**
* Writes data to the socket.
*/
virtual TQ_LONG writeBlock(const char *data, TQ_ULONG len);
/**
* Writes the given data to the given destination address.
*/
virtual TQ_LONG writeBlock(const char *data, TQ_ULONG len, const KSocketAddress& to);
/**
* Returns this socket's local address.
*/
virtual KSocketAddress localAddress() const;
/**
* Returns this socket's peer address. If this implementation does proxying
* of some sort, this is the real external address, not the proxy's address.
*/
virtual KSocketAddress peerAddress() const;
/**
* Returns this socket's externally visible local address.
*
* If this socket has a local address visible externally different
* from the normal local address (as returned by @ref localAddress), then
* return it.
*
* Certain implementations will use proxies and thus have externally visible
* addresses different from the local socket values. The default implementation
* returns the same value as @ref localAddress.
*
* @note This function may return an empty KSocketAddress. In that case, the
* externally visible address could/can not be determined.
*/
virtual KSocketAddress externalAddress() const;
/**
* Returns a socket notifier for input on this socket.
* The notifier is created only when requested. Whether
* it is enabled or not depends on the implementation.
*
* This function might return NULL.
*/
TQSocketNotifier* readNotifier() const;
/**
* Returns a socket notifier for output on this socket.
* The is created only when requested.
*
* This function might return NULL.
*/
TQSocketNotifier* writeNotifier() const;
/**
* Returns a socket notifier for exceptional events on this socket.
* The is created only when requested.
*
* This function might return NULL.
*/
TQSocketNotifier* exceptionNotifier() const;
/**
* Executes a poll in the socket, via select(2) or poll(2).
* The events polled are returned in the parameters pointers.
* Set any of them to NULL to disable polling of that event.
*
* On exit, @p input, @p output and @p exception will contain
* true if an event of that kind is waiting on the socket or false
* if not. If a timeout occurred, set @p timedout to true (all other
* parameters are necessarily set to false).
*
* @param input if set, turns on polling for input events
* @param output if set, turns on polling for output events
* @param exception if set, turns on polling for exceptional events
* @param timeout the time in milliseconds to wait for an event;
* 0 for no wait and any negative value to wait forever
* @param timedout on exit, will contain true if the polling timed out
* @return true if the poll call succeeded and false if an error occurred
*/
virtual bool poll(bool* input, bool* output, bool* exception = 0L,
int timeout = -1, bool* timedout = 0L);
/**
* Shorter version to poll for any events in a socket. This call
* polls for input, output and exceptional events in a socket but
* does not return their states. This is useful if you need to wait for
* any event, but don't need to know which; or for timeouts.
*
* @param timeout the time in milliseconds to wait for an event;
* 0 for no wait and any negative value to wait forever
* @param timedout on exit, will contain true if the polling timed out
* @return true if the poll call succeeded and false if an error occurred
*/
bool poll(int timeout = -1, bool* timedout = 0L);
protected:
/**
* Special constructor. This constructor will cause the internal
* socket device NOT to be set. Use this if your socket device class
* takes another underlying socket device.
*
* @param parent the parent, if any
*/
KSocketDevice(bool, const KSocketBase* parent = 0L);
/**
* Creates a socket notifier of the given type.
*
* This function is called by @ref readNotifier, @ref writeNotifier and
* @ref exceptionNotifier when they need to create a socket notifier
* (i.e., the first call to those functions after the socket is open).
* After that call, those functions cache the socket notifier and will
* not need to call this function again.
*
* Reimplement this function in your derived class if your socket type
* requires a different kind of TQSocketNotifier. The return value should
* be deleteable with delete. (@ref close deletes them).
*
* @param type the socket notifier type
*/
virtual TQSocketNotifier* createNotifier(TQSocketNotifier::Type type) const;
public:
/**
* Creates a new default KSocketDevice object given
* the parent object.
*
* The capabilities flag indicates the desired capabilities the object being
* created should possess. Those capabilities are not guaranteed: if no factory
* can provide such an object, a default object will be created.
*
* @param parent the KSocketBase parent
*/
static KSocketDevice* createDefault(KSocketBase* parent);
/**
* @overload
*
* This will create an object only if the requested capabilities match.
*
* @param parent the parent
* @param capabilities the requested capabilities
*/
static KSocketDevice* createDefault(KSocketBase* parent, int capabilities);
/**
* Sets the default KSocketDevice implementation to use and
* return the old factory.
*
* @param factory the factory object for the implementation
*/
static KSocketDeviceFactoryBase* setDefaultImpl(KSocketDeviceFactoryBase* factory);
/**
* Adds a factory of KSocketDevice objects to the list, along with its
* capabilities flag.
*/
static void addNewImpl(KSocketDeviceFactoryBase* factory, int capabilities);
private:
KSocketDevice(const KSocketDevice&);
KSocketDevice& operator=(const KSocketDevice&);
KSocketDevicePrivate *d;
};
/** @internal
* This class provides functionality for creating and registering
* socket implementations.
*/
class KSocketDeviceFactoryBase
{
public:
KSocketDeviceFactoryBase() {}
virtual ~KSocketDeviceFactoryBase() {}
virtual KSocketDevice* create(KSocketBase*) const = 0;
};
/**
* This class provides functionality for creating and registering
* socket implementations.
*/
template<class Impl>
class KSocketDeviceFactory: public KSocketDeviceFactoryBase
{
public:
KSocketDeviceFactory() {}
virtual ~KSocketDeviceFactory() {}
virtual KSocketDevice* create(KSocketBase* parent) const
{ return new Impl(parent); }
};
} // namespaces
#endif