Added wxWrapperInputStream class.

This stream allows to wrap another stream. This is a useful base class for
adapter classes providing stream interface on top of something else, like the
upcoming wxFSInputStream.

See #14185.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@71205 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2012-04-16 13:53:45 +00:00
parent 11527fc9f0
commit f5ef4d69b7
3 changed files with 190 additions and 0 deletions

View File

@@ -640,6 +640,54 @@ protected:
inline wxStreamBuffer *wxBufferedOutputStream::OutputStreamBuffer() const { return m_o_streambuf; }
#endif // WXWIN_COMPATIBILITY_2_6
// ---------------------------------------------------------------------------
// wxWrapperInputStream: forwards all IO to another stream.
// ---------------------------------------------------------------------------
class WXDLLIMPEXP_BASE wxWrapperInputStream : public wxFilterInputStream
{
public:
// Constructor fully initializing the stream. The overload taking pointer
// takes ownership of the parent stream, the one taking reference does not.
//
// Notice that this class also has a default ctor but it's protected as the
// derived class is supposed to take care of calling InitParentStream() if
// it's used.
wxWrapperInputStream(wxInputStream& stream);
wxWrapperInputStream(wxInputStream* stream);
// Override the base class methods to forward to the wrapped stream.
virtual wxFileOffset GetLength() const;
virtual bool IsSeekable() const;
protected:
virtual size_t OnSysRead(void *buffer, size_t size);
virtual wxFileOffset OnSysSeek(wxFileOffset pos, wxSeekMode mode);
virtual wxFileOffset OnSysTell() const;
// Ensure that our own last error is the same as that of the real stream.
//
// This method is const because the error must be updated even from const
// methods (in other words, it really should have been mutable in the first
// place).
void SynchronizeLastError() const
{
const_cast<wxWrapperInputStream*>(this)->
Reset(m_parent_i_stream->GetLastError());
}
// Default constructor, use InitParentStream() later.
wxWrapperInputStream();
// Set up the wrapped stream for an object initialized using the default
// constructor. The ownership logic is the same as above.
void InitParentStream(wxInputStream& stream);
void InitParentStream(wxInputStream* stream);
wxDECLARE_NO_COPY_CLASS(wxWrapperInputStream);
};
#endif // wxUSE_STREAMS
#endif // _WX_WXSTREAM_H__

View File

@@ -1066,3 +1066,57 @@ public:
};
/**
@class wxWrapperInputStream
A wrapper input stream is a kind of filter stream which forwards all the
operations to its base stream. This is useful to build utility classes such
as wxFSInputStream.
@note
The interface of this class is the same as that of wxInputStream.
Only a constructor differs and it is documented below.
@library{wxbase}
@category{streams}
@see wxFSInputStream, wxFilterInputStream
@since 2.9.4
*/
class wxWrapperInputStream : public wxFilterInputStream
{
public:
//@{
/**
Initializes a wrapper stream.
If the parent stream is passed as a pointer then the new wrapper stream
takes ownership of it. If it is passed by reference then it does not.
*/
wxWrapperInputStream(wxInputStream& stream);
wxWrapperInputStream(wxInputStream* stream);
//@}
protected:
/**
Default constructor, use InitParentStream() to finish initialization.
This constructor can be used by the derived classes from their own
constructors when the parent stream can't be specified immediately.
The derived class must call InitParentStream() later to do it.
*/
wxWrapperInputStream();
//@{
/**
Set up the wrapped stream for an object initialized using the default
constructor.
The ownership logic is the same as for the non-default constructor,
i.e. this object takes ownership of the stream if it's passed by
pointer but not if it's passed by reference.
*/
void InitParentStream(wxInputStream& stream);
void InitParentStream(wxInputStream* stream);
//@}
};

View File

@@ -36,6 +36,7 @@
#include <ctype.h>
#include "wx/datstrm.h"
#include "wx/textfile.h"
#include "wx/scopeguard.h"
// ----------------------------------------------------------------------------
// constants
@@ -1446,6 +1447,93 @@ void wxBufferedOutputStream::SetOutputStreamBuffer(wxStreamBuffer *buffer)
m_o_streambuf = buffer;
}
// ---------------------------------------------------------------------------
// wxWrapperInputStream implementation
// ---------------------------------------------------------------------------
wxWrapperInputStream::wxWrapperInputStream()
{
m_lasterror = wxSTREAM_READ_ERROR;
}
wxWrapperInputStream::wxWrapperInputStream(wxInputStream& stream)
: wxFilterInputStream(stream)
{
SynchronizeLastError();
}
wxWrapperInputStream::wxWrapperInputStream(wxInputStream *stream)
: wxFilterInputStream(stream)
{
if ( m_parent_i_stream )
SynchronizeLastError();
else
m_lasterror = wxSTREAM_READ_ERROR;
}
void wxWrapperInputStream::InitParentStream(wxInputStream& stream)
{
wxCHECK_RET( !m_parent_i_stream, "Can't init parent stream twice" );
m_parent_i_stream = &stream;
SynchronizeLastError();
}
void wxWrapperInputStream::InitParentStream(wxInputStream* stream)
{
wxCHECK_RET( !m_parent_i_stream, "Can't init parent stream twice" );
m_parent_i_stream = stream;
if ( m_parent_i_stream )
{
m_owns = true;
SynchronizeLastError();
}
}
wxFileOffset wxWrapperInputStream::GetLength() const
{
wxCHECK_MSG(m_parent_i_stream, wxInvalidOffset, "Stream not valid");
wxON_BLOCK_EXIT_THIS0(wxWrapperInputStream::SynchronizeLastError);
return m_parent_i_stream->GetLength();
}
bool wxWrapperInputStream::IsSeekable() const
{
wxCHECK_MSG(m_parent_i_stream, false, "Stream not valid");
return m_parent_i_stream->IsSeekable();
}
size_t wxWrapperInputStream::OnSysRead(void *buffer, size_t size)
{
wxCHECK_MSG(m_parent_i_stream, false, "Stream not valid");
wxON_BLOCK_EXIT_THIS0(wxWrapperInputStream::SynchronizeLastError);
m_parent_i_stream->Read(buffer, size);
return m_parent_i_stream->LastRead();
}
wxFileOffset wxWrapperInputStream::OnSysSeek(wxFileOffset pos, wxSeekMode mode)
{
wxCHECK_MSG(IsSeekable(), false, "Stream not seekable");
wxON_BLOCK_EXIT_THIS0(wxWrapperInputStream::SynchronizeLastError);
return m_parent_i_stream->SeekI (pos, mode);
}
wxFileOffset wxWrapperInputStream::OnSysTell() const
{
wxCHECK_MSG(m_parent_i_stream, false, "Stream not valid");
wxON_BLOCK_EXIT_THIS0(wxWrapperInputStream::SynchronizeLastError);
return m_parent_i_stream->TellI();
}
// ----------------------------------------------------------------------------
// Some IOManip function
// ----------------------------------------------------------------------------