#ifndef __ARC_PAYLOADSTREAM_H__ #define __ARC_PAYLOADSTREAM_H__ #include #include "Message.h" namespace Arc { /// Stream-like Payload for Message object. /** This class is a virtual interface for managing stream-like source and destination. It's supposed to be passed through MCC chain as payload of Message. It must be treated by MCCs and Services as dynamic payload. */ class PayloadStreamInterface: virtual public MessagePayload { public: // Avoid defining size of int - just use biggest possible typedef signed long long int Size_t; PayloadStreamInterface(void) { }; virtual ~PayloadStreamInterface(void) { }; /** Extracts information from stream up to 'size' bytes. 'size' contains number of read bytes on exit. Returns true in case of success. */ virtual bool Get(char* buf,int& size) = 0; /** Read as many as possible (sane amount) of bytes into buf. Implemented through call to Get(char*,int). */ virtual bool Get(std::string& buf); /** Read and return as many as possible (sane amount) of bytes. Implemented through call to Get(std::string&). */ virtual std::string Get(void); /** Read up to 'size' bytes and pass them to 'dest'. 'size' contains number of read bytes on exit. If on input 'size' contains -1 then as much as possible is transfered. This method is both for convenience and for making it possible to have optimized implementations. */ virtual bool Get(PayloadStreamInterface& dest,int& size); /** Push 'size' bytes from 'buf' into stream. Returns true on success. */ virtual bool Put(const char* buf,Size_t size) = 0; /** Push information from 'buf' into stream. Returns true on success. Implemented though call to Put(const char*,Size_t). */ virtual bool Put(const std::string& buf); /** Push null terminated information from 'buf' into stream. Returns true on success. Implemented though call to Put(const char*,Size_t). */ virtual bool Put(const char* buf); /** Push 'size' bytes from 'source' into stream. If on 'size' contains -1 then as much as possible is transfered. This method is both for convenience and for making it possible to have optimized implementations. */ virtual bool Put(PayloadStreamInterface& source,Size_t size); /** Returns true if stream is valid. */ virtual operator bool(void) = 0; /** Returns true if stream is invalid. */ virtual bool operator!(void) = 0; /** Query current timeout for Get() and Put() operations. */ virtual int Timeout(void) const = 0; /** Set current timeout for Get() and Put() operations. */ virtual void Timeout(int to) = 0; /** Returns current position in stream if supported. */ virtual Size_t Pos(void) const = 0; /** Returns size of underlying object if supported. */ virtual Size_t Size(void) const = 0; /** Returns position at which stream reading will stop if supported. That may be not same as Size() if instance is meant to provide access to only part of underlying obejct. */ virtual Size_t Limit(void) const = 0; }; /// POSIX handle as Payload /** This is an implemetation of PayloadStreamInterface for generic POSIX handle. */ class PayloadStream: virtual public PayloadStreamInterface { protected: int timeout_; /** Timeout for read/write operations */ int handle_; /** Handle for operations */ bool seekable_; /** true if lseek operation is applicable to open handle */ public: /** Constructor. Attaches to already open handle. Handle is not managed by this class and must be closed by external code. */ PayloadStream(int h = -1); /** Destructor. */ virtual ~PayloadStream(void) { }; virtual bool Get(char* buf,int& size); virtual bool Put(const char* buf,Size_t size); virtual operator bool(void) { return (handle_ != -1); }; virtual bool operator!(void) { return (handle_ == -1); }; virtual int Timeout(void) const { return timeout_; }; virtual void Timeout(int to) { timeout_=to; }; virtual Size_t Pos(void) const { return 0; }; virtual Size_t Size(void) const { return 0; }; virtual Size_t Limit(void) const { return 0; }; }; } #endif /* __ARC_PAYLOADSTREAM_H__ */