In my C ++ library code, I use an abstract base class as an interface to all the various types of objects that are capable of input / output. Currently, it looks like this:
class IDataIO
{
public:
virtual ssize_t Read(void * buffer, size_t size) = 0;
virtual ssize_t Write(const void * buffer, size_t size) = 0;
virtual result_t Seek(ssize_t offset, int whence) = 0;
virtual ssize_t GetCurrentSeekPosition() const = 0;
virtual ssize_t GetStreamLength() const = 0;
virtual const IPAddressAndPort & GetSourceOfLastReadPacket() const = 0;
virtual result_t SetPacketSendDestination(const IPAddressAndPort & iap) = 0;
};
This works very well - I have various specific subclasses for TCP, UDP, files, memory buffers, SSL, RS232, stdin / stdout, etc., and I can write agnostic I / O procedures that can be used in combination with any of them.
decorator, IDataIO , . , / IDataIO. ():
class XorDataIO : public IDataIO
{
public:
XorDataIO(IDataIO * child) : _child(child) {}
virtual ~XorDataIO() {delete _child;}
virtual ssize_t Read(void * buffer, size_t size)
{
ssize_t ret = _child->Read(buffer, size);
if (ret > 0) XorData(buffer, ret);
return ret;
}
virtual ssize_t Write(const void * buffer, size_t size)
{
XorData(buffer, size);
return _child->Write(buffer, size);
}
virtual result_t Seek(ssize_t offset, int whence) {return _child->Seek(offset, whence);}
virtual ssize_t GetCurrentSeekPosition() const {return _child->GetCurrentSeekPosition();}
virtual ssize_t GetStreamLength() const {return _child->GetStreamLength();}
virtual const IPAddressAndPort & GetSourceOfLastReadPacket() const {return _child->GetSourceOfLastReadPacket();}
virtual result_t SetPacketSendDestination(const IPAddressAndPort & iap) {return _child->SetPacketSendDestination(iap);}
private:
IDataIO * _child;
};
, , IDataIO - , UDPSocketDataIO Seek(), GetCurrentSeekPosition() GetStreamLength(), FileDataIO GetSourceOfLastReadPacket() SetPacketSendDestination(). , , , .
, IDataIO , :
class IDataIO
{
public:
virtual ssize_t Read(void * buffer, size_t size) = 0;
virtual ssize_t Write(const void * buffer, size_t size) = 0;
};
class ISeekableDataIO : public IDataIO
{
public:
virtual result_t Seek(ssize_t offset, int whence) = 0;
virtual ssize_t GetCurrentSeekPosition() const = 0;
virtual ssize_t GetStreamLength() const = 0;
};
class IPacketDataIO : public IDataIO
{
public:
virtual const IPAddressAndPort & GetSourceOfLastReadPacket() const = 0;
virtual result_t SetPacketSendDestination(const IPAddressAndPort & iap) = 0;
};
.... UDPSocketDataIO - IPacketDataIO FileDataIO ISeekableDataIO, TCPSocketDataIO - IDataIO, . , - , , no-op/stub , , .
, , , - XorDataIO ? , XorDataIO, a XorSeekableDataIO a XorPacketDataIO, , - / , , , .
- / , ?