Factor out 3 copies of identical code into wxInputStreamPeeker
Resolve the long standing "NOTE" comments about having the same code in wxAnimationDecoder::CanRead(), wxImage::CanRead() and GetImageCount() by extracting the common logic into a helper wxInputStreamPeeker class and using it from all places. This loses the possibility to log a debug message if rewinding the stream fails, but this is probably not very valuable and the actual error should be already logged by SeekI() itself when it fails on a seekable stream. No real changes.
This commit is contained in:
@@ -96,24 +96,8 @@ public:
|
||||
|
||||
bool CanRead( wxInputStream& stream ) const
|
||||
{
|
||||
// NOTE: this code is the same of wxImageHandler::CallDoCanRead
|
||||
|
||||
if ( !stream.IsSeekable() )
|
||||
return false; // can't test unseekable stream
|
||||
|
||||
wxFileOffset posOld = stream.TellI();
|
||||
bool ok = DoCanRead(stream);
|
||||
|
||||
// restore the old position to be able to test other formats and so on
|
||||
if ( stream.SeekI(posOld) == wxInvalidOffset )
|
||||
{
|
||||
wxLogDebug(wxT("Failed to rewind the stream in wxAnimationDecoder!"));
|
||||
|
||||
// reading would fail anyhow as we're not at the right position
|
||||
return false;
|
||||
}
|
||||
|
||||
return ok;
|
||||
return wxInputStreamPeeker(stream).
|
||||
CallIfCanSeek(&wxAnimationDecoder::DoCanRead, this);
|
||||
}
|
||||
|
||||
virtual wxAnimationDecoder *Clone() const = 0;
|
||||
|
||||
@@ -682,6 +682,53 @@ protected:
|
||||
wxDECLARE_NO_COPY_CLASS(wxWrapperInputStream);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxPeekInputStream(): read some data from a stream and then rewind it back
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// This semi-private class is used in wx code to read some data, using the
|
||||
// provided method of the class T, from a stream if it's seekable and then
|
||||
// rewind it back.
|
||||
class wxInputStreamPeeker
|
||||
{
|
||||
public:
|
||||
explicit wxInputStreamPeeker(wxInputStream& stream)
|
||||
: m_stream(stream),
|
||||
m_ofsOrig(stream.IsSeekable() ? stream.TellI() : wxInvalidOffset)
|
||||
{
|
||||
}
|
||||
|
||||
// Call the given function if the stream is seekable, otherwise return 0.
|
||||
template <typename R, typename T>
|
||||
R CallIfCanSeek(R (T::*func)(wxInputStream&), T* obj)
|
||||
{
|
||||
return RewindAndReturn(CanSeek() ? (obj->*func)(m_stream) : R(0));
|
||||
}
|
||||
|
||||
// Overload for const methods.
|
||||
template <typename R, typename T>
|
||||
R CallIfCanSeek(R (T::*func)(wxInputStream&) const, const T* obj)
|
||||
{
|
||||
return RewindAndReturn(CanSeek() ? (obj->*func)(m_stream) : R(0));
|
||||
}
|
||||
|
||||
private:
|
||||
bool CanSeek() const { return m_ofsOrig != wxInvalidOffset; }
|
||||
|
||||
template <typename R>
|
||||
R RewindAndReturn(R retval)
|
||||
{
|
||||
if ( CanSeek() && m_stream.SeekI(m_ofsOrig) == wxInvalidOffset )
|
||||
return R(0);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
wxInputStream& m_stream;
|
||||
const wxFileOffset m_ofsOrig;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(wxInputStreamPeeker);
|
||||
};
|
||||
|
||||
#endif // wxUSE_STREAMS
|
||||
|
||||
|
||||
@@ -3445,25 +3445,8 @@ wxIMPLEMENT_ABSTRACT_CLASS(wxImageHandler, wxObject);
|
||||
#if wxUSE_STREAMS
|
||||
int wxImageHandler::GetImageCount( wxInputStream& stream )
|
||||
{
|
||||
// NOTE: this code is the same of wxAnimationDecoder::CanRead and
|
||||
// wxImageHandler::CallDoCanRead
|
||||
|
||||
if ( !stream.IsSeekable() )
|
||||
return false; // can't test unseekable stream
|
||||
|
||||
wxFileOffset posOld = stream.TellI();
|
||||
int n = DoGetImageCount(stream);
|
||||
|
||||
// restore the old position to be able to test other formats and so on
|
||||
if ( stream.SeekI(posOld) == wxInvalidOffset )
|
||||
{
|
||||
wxLogDebug(wxT("Failed to rewind the stream in wxImageHandler!"));
|
||||
|
||||
// reading would fail anyhow as we're not at the right position
|
||||
return false;
|
||||
}
|
||||
|
||||
return n;
|
||||
return wxInputStreamPeeker(stream).
|
||||
CallIfCanSeek(&wxImageHandler::DoGetImageCount, this);
|
||||
}
|
||||
|
||||
bool wxImageHandler::CanRead( const wxString& name )
|
||||
@@ -3481,25 +3464,8 @@ bool wxImageHandler::CanRead( const wxString& name )
|
||||
|
||||
bool wxImageHandler::CallDoCanRead(wxInputStream& stream)
|
||||
{
|
||||
// NOTE: this code is the same of wxAnimationDecoder::CanRead and
|
||||
// wxImageHandler::GetImageCount
|
||||
|
||||
if ( !stream.IsSeekable() )
|
||||
return false; // can't test unseekable stream
|
||||
|
||||
wxFileOffset posOld = stream.TellI();
|
||||
bool ok = DoCanRead(stream);
|
||||
|
||||
// restore the old position to be able to test other formats and so on
|
||||
if ( stream.SeekI(posOld) == wxInvalidOffset )
|
||||
{
|
||||
wxLogDebug(wxT("Failed to rewind the stream in wxImageHandler!"));
|
||||
|
||||
// reading would fail anyhow as we're not at the right position
|
||||
return false;
|
||||
}
|
||||
|
||||
return ok;
|
||||
return wxInputStreamPeeker(stream)
|
||||
.CallIfCanSeek(&wxImageHandler::DoCanRead, this);
|
||||
}
|
||||
|
||||
#endif // wxUSE_STREAMS
|
||||
|
||||
Reference in New Issue
Block a user