CXStream
From cxwiki
The CXStream class hierarchy provides support for readable and writeable streams, ranging from file streams and network sockets to adaptors such as data codecs. The underlying functionality is virtual, but non-virtual caching operations are provided transparently to avoid exessive virtual call overhead. As much as is possible, CXStream-derived classes provide completely generic behaviour, and CXStream-utilising functions accept a base CXStream* rather than specifying a more specialised derived type. This allows an application to create a CXStream of any type (potentially even creating something new) and pass it to an existing function or system.
This page documents the usage of CXStream (and its derived classes). For guidance on creating new CXStream-derived classes, see CXStream Development.
Any given CXStream-derived object may be used on any thread, or passed between threads, but is NOT reentrant, except where specifically noted.
It is expected that CXStream implementations will closely follow the expected behaviour detailed in this document. In scenarios where customised behaviour may be preferrable, that behaviour should either be exposed through additional APIs which do not affect the behaviour of the standard APIs, or via additional capabilities flags which should be explicitly enabled.
Read / Write
// Read from the current read cursor position in this stream. If the
// size is greater than zero, the output buffer must be non-null. The
// return value is the number of bytes successfully read.
// This function will normally block until the requested number of
// bytes have been read or until an error condition has resulted
// (eg. end-of-file, i/o error, disconnected, etc.) A non-blocking
// stream (which is not the default behaviour) will instead return
// after any non-zero number of bytes has been read, without
// raising an error status.
StreamSize Read(void* __nullable o_buffer, StreamSize size);
// Writes to the current write cursor position in this stream. If
// the size is gerater than zero, the input buffer must be non-null.
// The return value is the number of bytes succesfully written.
// This function will normally block until the requested number of
// bytes have been written, or until an error condition has resulted
// (eg. end-of-file, i/o error, disconnected, etc.) A non-blocking
// stream (which is not the default behaviour) will instead return
// after any non-zero number of bytes has been written, without
// raising an error status.
StreamSize Write(const void* __nullable buffer, StreamSize size);
//
CXStream::StreamSize ReadDiscard(CXStream::StreamSize a_size);
//
CXStream::StreamSize WriteDiscard(const void* __nonnull a_buffer, StreamSize a_size);
//void Flush(FlushFlags flags = FLUSH_FLAGS_BLOCK);
Cursor
//
StreamPos Seek(StreamPos a_pos, uint a_mode = STREAM_SEEK_START);
//
StreamPos Tell(void) const;
//
StreamSize GetSize(void) const;
//
void SetSize(StreamSize size);
//
void Truncate(void)
//
StreamSize GetRemain(void) const;
//
bool GetRemain(StreamSize& o_remain) const;
// End-of-File detection
bool IsEOF(void) const;
Capabilities Flags
enum
{
CAPS_READ = 1, // stream is readable
CAPS_WRITE = 2, // stream is writable
CAPS_SIZE = 4, // stream provider supports GetSize() and STREAM_SEEK_END
CAPS_SEEK = 8, // stream provider supports Seek() -- usually you actually want CAPS_TELL
CAPS_TELL = 16, // stream provider supports Tell()
CAPS_UNIFIED_CURSOR = 32, // stream has unified read / write cursor -- ie. Tell() is affected by both Read() and Write()
CAPS_NO_REWIND = 64, // stream cannot seek backwards, and GetSize() returns the number of bytes after the current position
CAPS_SEEK_IN_WRITE_CACHE = 128, // since the original implementation did not support this, we have to flag if we support the technique.
// "flag" caps
CAPS_OPEN = 256, // stream is open
CAPS_EOF = 512, // stream is known to be at the EOF position
//
CAPS_NON_BLOCKING = 1024, // stream is in non-blocking mode
};
// get the capabilities flags for this stream
Flags32 GetCaps(void) const;
// request a change of capabilities for this stream
void SetCaps(const Flags32& caps, const Flags32& mask);
//
void SetCaps(const Flags32& caps);
//
void ClearCaps(const Flags32& caps);
// Provider-specific hints
void SetHint(uint32 hintEnum, uint32 hintValue);
Status
// Determine the last error that has occurred.
CXResultCode GetStreamResult(void) const;
// clear the error result
void ClearStreamResult(void);
//
void SetStreamResult(CXResultCode a_result) const;
//
void ConcatenateResult(CXResultCode a_result) const;
// shut down this stream, ready for another Open()
void Close(void);
//
bool IsOpen(void) const;
//
bool IsClosed(void) const;
Events
CXGenericEventRef GetStreamEvent(EventType eventType) const;