X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2d67974d248156678a45aded725f5b92c69f502a..888dde65f43d5f57e8fb2028b27191cca1741403:/src/common/stream.cpp diff --git a/src/common/stream.cpp b/src/common/stream.cpp index e797ad3f67..32e6fe8d15 100644 --- a/src/common/stream.cpp +++ b/src/common/stream.cpp @@ -18,28 +18,24 @@ // headers // ---------------------------------------------------------------------------- -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) - #pragma implementation "stream.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ - #pragma hdrstop + #pragma hdrstop #endif +#if wxUSE_STREAMS + +#include "wx/stream.h" + #ifndef WX_PRECOMP - #include "wx/defs.h" + #include "wx/log.h" #endif -#if wxUSE_STREAMS - #include -#include "wx/stream.h" #include "wx/datstrm.h" #include "wx/textfile.h" -#include "wx/log.h" // ---------------------------------------------------------------------------- // constants @@ -121,7 +117,10 @@ wxStreamBuffer::wxStreamBuffer(const wxStreamBuffer& buffer) void wxStreamBuffer::FreeBuffer() { if ( m_destroybuf ) + { free(m_buffer_start); + m_buffer_start = NULL; + } } wxStreamBuffer::~wxStreamBuffer() @@ -167,15 +166,15 @@ void wxStreamBuffer::SetBufferIO(void *start, void wxStreamBuffer::SetBufferIO(size_t bufsize) { - // start by freeing the old buffer - FreeBuffer(); - if ( bufsize ) { + // this will free the old buffer and allocate the new one SetBufferIO(malloc(bufsize), bufsize, true /* take ownership */); } else // no buffer size => no buffer { + // still free the old one + FreeBuffer(); InitBuffer(); } } @@ -193,6 +192,28 @@ void wxStreamBuffer::ResetBuffer() : m_buffer_start; } +void wxStreamBuffer::Truncate() +{ + size_t new_size = m_buffer_pos - m_buffer_start; + if ( new_size == m_buffer_size ) + return; + + if ( !new_size ) + { + FreeBuffer(); + InitBuffer(); + return; + } + + char *new_start = (char *)realloc(m_buffer_start, new_size); + wxCHECK_RET( new_size, _T("shrinking buffer shouldn't fail") ); + + m_buffer_start = new_start; + m_buffer_size = new_size; + m_buffer_end = m_buffer_start + m_buffer_size; + m_buffer_pos = m_buffer_end; +} + // fill the buffer with as much data as possible (only for read buffers) bool wxStreamBuffer::FillBuffer() { @@ -372,18 +393,23 @@ char wxStreamBuffer::GetChar() size_t wxStreamBuffer::Read(void *buffer, size_t size) { + wxASSERT_MSG( buffer, _T("Warning: Null pointer is about to be used") ); + + /* Clear buffer first */ + memset(buffer, 0x00, size); + // lasterror is reset before all new IO calls if ( m_stream ) m_stream->Reset(); - size_t read; + size_t readBytes; if ( !HasBuffer() ) { wxInputStream *inStream = GetInputStream(); wxCHECK_MSG( inStream, 0, _T("should have a stream in wxStreamBuffer") ); - read = inStream->OnSysRead(buffer, size); + readBytes = inStream->OnSysRead(buffer, size); } else // we have a buffer, use it { @@ -414,13 +440,13 @@ size_t wxStreamBuffer::Read(void *buffer, size_t size) } } - read = orig_size - size; + readBytes = orig_size - size; } if ( m_stream ) - m_stream->m_lastcount = read; + m_stream->m_lastcount = readBytes; - return read; + return readBytes; } // this should really be called "Copy()" @@ -434,7 +460,7 @@ size_t wxStreamBuffer::Read(wxStreamBuffer *dbuf) do { - nRead = Read(dbuf, WXSIZEOF(buf)); + nRead = Read(buf, WXSIZEOF(buf)); if ( nRead ) { nRead = dbuf->Write(buf, nRead); @@ -448,6 +474,8 @@ size_t wxStreamBuffer::Read(wxStreamBuffer *dbuf) size_t wxStreamBuffer::Write(const void *buffer, size_t size) { + wxASSERT_MSG( buffer, _T("Warning: Null pointer is about to be send") ); + if (m_stream) { // lasterror is reset before all new IO calls @@ -580,7 +608,9 @@ wxFileOffset wxStreamBuffer::Seek(wxFileOffset pos, wxSeekMode mode) } if (diff < 0 || diff > last_access) return wxInvalidOffset; - SetIntPosition(diff); + size_t int_diff = wx_truncate_cast(size_t, diff); + wxCHECK_MSG( (wxFileOffset)int_diff == diff, wxInvalidOffset, wxT("huge file not supported") ); + SetIntPosition(int_diff); return diff; } @@ -605,7 +635,9 @@ wxFileOffset wxStreamBuffer::Seek(wxFileOffset pos, wxSeekMode mode) } else { - SetIntPosition(diff); + size_t int_diff = wx_truncate_cast(size_t, diff); + wxCHECK_MSG( (wxFileOffset)int_diff == diff, wxInvalidOffset, wxT("huge file not supported") ); + SetIntPosition(int_diff); return pos; } @@ -647,6 +679,8 @@ wxFileOffset wxStreamBuffer::Tell() const // wxStreamBase // ---------------------------------------------------------------------------- +IMPLEMENT_ABSTRACT_CLASS(wxStreamBase, wxObject) + wxStreamBase::wxStreamBase() { m_lasterror = wxSTREAM_NO_ERROR; @@ -660,7 +694,13 @@ wxStreamBase::~wxStreamBase() size_t wxStreamBase::GetSize() const { wxFileOffset length = GetLength(); - return length == wxInvalidOffset ? 0 : (size_t)length; + if ( length == (wxFileOffset)wxInvalidOffset ) + return 0; + + const size_t len = wx_truncate_cast(size_t, length); + wxASSERT_MSG( len == length + size_t(0), _T("large files not supported") ); + + return len; } wxFileOffset wxStreamBase::OnSysSeek(wxFileOffset WXUNUSED(seek), wxSeekMode WXUNUSED(mode)) @@ -673,24 +713,12 @@ wxFileOffset wxStreamBase::OnSysTell() const return wxInvalidOffset; } -#if WXWIN_COMPATIBILITY_2_2 - -wxStreamError wxStreamBase::LastError() const -{ - return m_lasterror; -} - -size_t wxStreamBase::StreamSize() const -{ - return GetSize(); -} - -#endif // WXWIN_COMPATIBILITY_2_2 - // ---------------------------------------------------------------------------- // wxInputStream // ---------------------------------------------------------------------------- +IMPLEMENT_ABSTRACT_CLASS(wxInputStream, wxStreamBase) + wxInputStream::wxInputStream() { m_wback = NULL; @@ -746,6 +774,11 @@ char *wxInputStream::AllocSpaceWBack(size_t needed_size) size_t wxInputStream::GetWBack(void *buf, size_t size) { + wxASSERT_MSG( buf, _T("Warning: Null pointer is about to be used") ); + + /* Clear buffer first */ + memset(buf, 0x00, size); + if (!m_wback) return 0; @@ -777,6 +810,8 @@ size_t wxInputStream::GetWBack(void *buf, size_t size) size_t wxInputStream::Ungetch(const void *buf, size_t bufsize) { + wxASSERT_MSG( buf, _T("Warning: Null pointer is about to be used in Ungetch()") ); + if ( m_lasterror != wxSTREAM_NO_ERROR && m_lasterror != wxSTREAM_EOF ) { // can't operate on this stream until the error is cleared @@ -800,15 +835,17 @@ bool wxInputStream::Ungetch(char c) return Ungetch(&c, sizeof(c)) != 0; } -char wxInputStream::GetC() +int wxInputStream::GetC() { - char c; + unsigned char c; Read(&c, sizeof(c)); - return c; + return LastRead() ? c : wxEOF; } wxInputStream& wxInputStream::Read(void *buf, size_t size) { + wxASSERT_MSG( buf, _T("Warning: Null pointer is about to be read") ); + char *p = (char *)buf; m_lastcount = 0; @@ -858,6 +895,7 @@ char wxInputStream::Peek() wxInputStream& wxInputStream::Read(wxOutputStream& stream_out) { + size_t lastcount = 0; char buf[BUF_TEMP_SIZE]; for ( ;; ) @@ -868,8 +906,12 @@ wxInputStream& wxInputStream::Read(wxOutputStream& stream_out) if ( stream_out.Write(buf, bytes_read).LastWrite() != bytes_read ) break; + + lastcount += bytes_read; } + m_lastcount = lastcount; + return *this; } @@ -922,6 +964,8 @@ wxFileOffset wxInputStream::TellI() const // wxOutputStream // ---------------------------------------------------------------------------- +IMPLEMENT_ABSTRACT_CLASS(wxOutputStream, wxStreamBase) + wxOutputStream::wxOutputStream() { } @@ -972,6 +1016,8 @@ void wxOutputStream::Sync() // wxCountingOutputStream // ---------------------------------------------------------------------------- +IMPLEMENT_DYNAMIC_CLASS(wxCountingOutputStream, wxOutputStream) + wxCountingOutputStream::wxCountingOutputStream () { m_currentPos = 0; @@ -994,18 +1040,22 @@ size_t wxCountingOutputStream::OnSysWrite(const void *WXUNUSED(buffer), wxFileOffset wxCountingOutputStream::OnSysSeek(wxFileOffset pos, wxSeekMode mode) { + ssize_t new_pos = wx_truncate_cast(ssize_t, pos); + switch ( mode ) { case wxFromStart: - m_currentPos = pos; + wxCHECK_MSG( (wxFileOffset)new_pos == pos, wxInvalidOffset, wxT("huge position not supported") ); break; case wxFromEnd: - m_currentPos = m_lastcount + pos; + new_pos = m_lastcount + new_pos; + wxCHECK_MSG( (wxFileOffset)new_pos == (wxFileOffset)(m_lastcount + pos), wxInvalidOffset, wxT("huge position not supported") ); break; case wxFromCurrent: - m_currentPos += pos; + new_pos = m_currentPos + new_pos; + wxCHECK_MSG( (wxFileOffset)new_pos == (wxFileOffset)(m_currentPos + pos), wxInvalidOffset, wxT("huge position not supported") ); break; default: @@ -1013,6 +1063,8 @@ wxFileOffset wxCountingOutputStream::OnSysSeek(wxFileOffset pos, wxSeekMode mode return wxInvalidOffset; } + m_currentPos = new_pos; + if (m_currentPos > m_lastcount) m_lastcount = m_currentPos; @@ -1028,36 +1080,127 @@ wxFileOffset wxCountingOutputStream::OnSysTell() const // wxFilterInputStream // ---------------------------------------------------------------------------- +IMPLEMENT_ABSTRACT_CLASS(wxFilterInputStream, wxInputStream) + wxFilterInputStream::wxFilterInputStream() + : m_parent_i_stream(NULL), + m_owns(false) { - m_parent_i_stream = NULL; } wxFilterInputStream::wxFilterInputStream(wxInputStream& stream) + : m_parent_i_stream(&stream), + m_owns(false) +{ +} + +wxFilterInputStream::wxFilterInputStream(wxInputStream *stream) + : m_parent_i_stream(stream), + m_owns(true) { - m_parent_i_stream = &stream; } wxFilterInputStream::~wxFilterInputStream() { + if (m_owns) + delete m_parent_i_stream; } // ---------------------------------------------------------------------------- // wxFilterOutputStream // ---------------------------------------------------------------------------- +IMPLEMENT_ABSTRACT_CLASS(wxFilterOutputStream, wxOutputStream) + wxFilterOutputStream::wxFilterOutputStream() + : m_parent_o_stream(NULL), + m_owns(false) { - m_parent_o_stream = NULL; } wxFilterOutputStream::wxFilterOutputStream(wxOutputStream& stream) + : m_parent_o_stream(&stream), + m_owns(false) +{ +} + +wxFilterOutputStream::wxFilterOutputStream(wxOutputStream *stream) + : m_parent_o_stream(stream), + m_owns(true) +{ +} + +bool wxFilterOutputStream::Close() { - m_parent_o_stream = &stream; + if (m_parent_o_stream && m_owns) + return m_parent_o_stream->Close(); + else + return true; } wxFilterOutputStream::~wxFilterOutputStream() { + if (m_owns) + delete m_parent_o_stream; +} + +// ---------------------------------------------------------------------------- +// wxFilterClassFactoryBase +// ---------------------------------------------------------------------------- + +IMPLEMENT_ABSTRACT_CLASS(wxFilterClassFactoryBase, wxObject) + +wxString wxFilterClassFactoryBase::PopExtension(const wxString& location) const +{ + return location.substr(0, FindExtension(location)); +} + +wxString::size_type wxFilterClassFactoryBase::FindExtension( + const wxString& location) const +{ + for (const wxChar *const *p = GetProtocols(wxSTREAM_FILEEXT); *p; p++) + { + if ( location.EndsWith(*p) ) + return location.length() - wxStrlen(*p); + } + + return wxString::npos; +} + +bool wxFilterClassFactoryBase::CanHandle(const wxString& protocol, + wxStreamProtocolType type) const +{ + if (type == wxSTREAM_FILEEXT) + return FindExtension(protocol) != wxString::npos; + else + for (const wxChar *const *p = GetProtocols(type); *p; p++) + if (protocol == *p) + return true; + + return false; +} + +// ---------------------------------------------------------------------------- +// wxFilterClassFactory +// ---------------------------------------------------------------------------- + +IMPLEMENT_ABSTRACT_CLASS(wxFilterClassFactory, wxFilterClassFactoryBase) + +wxFilterClassFactory *wxFilterClassFactory::sm_first = NULL; + +void wxFilterClassFactory::Remove() +{ + if (m_next != this) + { + wxFilterClassFactory **pp = &sm_first; + + while (*pp != this) + pp = &(*pp)->m_next; + + *pp = m_next; + + m_next = this; + } } // ---------------------------------------------------------------------------- @@ -1269,5 +1412,4 @@ wxOutputStream& wxEndL(wxOutputStream& stream) return stream.Write(eol, wxStrlen(eol)); } -#endif - // wxUSE_STREAMS +#endif // wxUSE_STREAMS