X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e2acb9ae1c69c1e37cbe0e46933929f5b1b021ba..1aaaa7120e9a7a5c0c11fa1c532fef414f071594:/src/common/stream.cpp diff --git a/src/common/stream.cpp b/src/common/stream.cpp index fdfc912333..2c10591517 100644 --- a/src/common/stream.cpp +++ b/src/common/stream.cpp @@ -27,9 +27,9 @@ #if wxUSE_STREAMS #include -#include -#include -#include +#include "wx/stream.h" +#include "wx/datstrm.h" +#include "wx/objstrm.h" #define BUF_TEMP_SIZE 10000 @@ -98,9 +98,9 @@ void wxStreamBuffer::SetBufferIO(size_t bufsize) wxDELETEA(m_buffer_start); if (!bufsize) { - m_buffer_start = NULL; - m_buffer_end = NULL; - m_buffer_pos = NULL; + m_buffer_start = (char*)NULL; + m_buffer_end = (char*)NULL; + m_buffer_pos = (char*)NULL; m_buffer_size = 0; return; } @@ -114,7 +114,7 @@ void wxStreamBuffer::ResetBuffer() { m_stream->m_lasterror = wxStream_NOERROR; m_stream->m_lastcount = 0; - if (m_mode == read) + if (m_mode == read && m_flushable) m_buffer_pos = m_buffer_end; else m_buffer_pos = m_buffer_start; @@ -165,10 +165,17 @@ void wxStreamBuffer::PutToBuffer(const void *buffer, size_t size) size_t s_toput = m_buffer_end-m_buffer_pos; if (s_toput < size && !m_fixed) { - m_buffer_start = (char *)realloc(m_buffer_start, m_buffer_size+size); - // I round a bit - m_buffer_size += size; - m_buffer_end = m_buffer_start+m_buffer_size; + if (!m_buffer_start) + SetBufferIO(size); + else { + size_t delta = m_buffer_pos-m_buffer_start; + + m_buffer_start = (char *)realloc(m_buffer_start, m_buffer_size+size); + m_buffer_pos = m_buffer_start + delta; + // I round a bit + m_buffer_size += size; + m_buffer_end = m_buffer_start+m_buffer_size; + } s_toput = size; } if (s_toput > size) @@ -195,6 +202,23 @@ void wxStreamBuffer::PutChar(char c) m_stream->m_lastcount = 1; } +char wxStreamBuffer::Peek() +{ + char c; + + wxASSERT(m_stream != NULL && m_buffer_size != 0); + + if (!GetDataLeft()) { + CHECK_ERROR(wxStream_READ_ERR); + return 0; + } + + GetFromBuffer(&c, 1); + m_buffer_pos--; + + return c; +} + char wxStreamBuffer::GetChar() { char c; @@ -248,7 +272,7 @@ size_t wxStreamBuffer::Read(void *buffer, size_t size) buffer = (char *)buffer + buf_left; // ANSI C++ violation. if (!FillBuffer()) { - CHECK_ERROR(wxStream_READ_ERR); + CHECK_ERROR(wxStream_EOF); return (m_stream->m_lastcount = orig_size-size); } } else { @@ -289,7 +313,7 @@ size_t wxStreamBuffer::Write(const void *buffer, size_t size) // ------------------ m_stream->m_lasterror = wxStream_NOERROR; - if (!m_buffer_size) + if (!m_buffer_size && m_fixed) return (m_stream->m_lastcount = m_stream->OnSysWrite(buffer, size)); // ------------------ @@ -303,7 +327,9 @@ size_t wxStreamBuffer::Write(const void *buffer, size_t size) // First case: the buffer to write is larger than the stream buffer, // we split it - if (size > buf_left) { + // NB: If stream buffer isn't fixed (as for wxMemoryOutputStream), + // we always go to the second case. + if (size > buf_left && m_fixed) { PutToBuffer(buffer, buf_left); size -= buf_left; buffer = (char *)buffer + buf_left; // ANSI C++ violation. @@ -353,7 +379,12 @@ off_t wxStreamBuffer::Seek(off_t pos, wxSeekMode mode) last_access = GetLastAccess(); if (!m_flushable) { - diff = pos + GetIntPosition(); + switch (mode) { + case wxFromStart: diff = pos; break; + case wxFromCurrent: diff = pos + GetIntPosition(); break; + case wxFromEnd: diff = pos + last_access; break; + default: return wxInvalidOffset; + } if (diff < 0 || diff > last_access) return wxInvalidOffset; SetIntPosition(diff); @@ -463,19 +494,30 @@ wxInputStream::~wxInputStream() char *wxInputStream::AllocSpaceWBack(size_t needed_size) { char *temp_b; + size_t toget; - m_wbacksize += needed_size; + /* get number of bytes left from previous wback buffer */ + toget = m_wbacksize - m_wbackcur; - if (!m_wback) - temp_b = (char *)malloc(m_wbacksize); - else - temp_b = (char *)realloc(m_wback, m_wbacksize); + /* allocate a buffer large enough to hold prev + new data */ + temp_b = (char *) malloc(needed_size + toget); if (!temp_b) return NULL; + + /* copy previous data (and free old buffer) if needed */ + if (m_wback) + { + memmove(temp_b + needed_size, m_wback + m_wbackcur, toget); + free(m_wback); + } + + /* done */ m_wback = temp_b; - - return (char *)(m_wback+(m_wbacksize-needed_size)); + m_wbackcur = 0; + m_wbacksize = needed_size + toget; + + return (char *) m_wback; } size_t wxInputStream::GetWBack(char *buf, size_t bsize) @@ -543,10 +585,10 @@ wxInputStream& wxInputStream::Read(void *buffer, size_t size) m_lasterror = wxStream_NOERROR; return *this; } - size -= retsize; - buf += retsize; + size -= retsize; + buf += retsize; - m_lastcount = OnSysRead(buf, size); + m_lastcount = OnSysRead(buf, size) + retsize; return *this; } @@ -576,6 +618,22 @@ wxInputStream& wxInputStream::Read(wxOutputStream& stream_out) off_t wxInputStream::SeekI(off_t pos, wxSeekMode mode) { + // Should be check and improve, just to remove a slight bug ! + // I don't know whether it should be put as well in wxFileInputStream::OnSysSeek ? + if (m_lasterror==wxSTREAM_EOF) + m_lasterror=wxSTREAM_NOERROR; + + // A call to SeekI() will automatically invalidate any previous call + // to Ungetch(), otherwise it would be possible to SeeI() to one + // one position, unread some bytes there, SeekI() to another position + // and the data would be corrupted. + if (m_wback) { + free(m_wback); + m_wback = (char*) NULL; + m_wbacksize = 0; + m_wbackcur = 0; + } + return OnSysSeek(pos, mode); } @@ -610,6 +668,11 @@ wxOutputStream::~wxOutputStream() { } +void wxOutputStream::PutC(char c) +{ + Write((void *) &c, 1); +} + wxOutputStream& wxOutputStream::Write(const void *buffer, size_t size) { m_lastcount = OnSysWrite(buffer, size); @@ -660,7 +723,7 @@ size_t wxCountingOutputStream::GetSize() const return m_lastcount; } -size_t wxCountingOutputStream::OnSysWrite(const void *buffer, size_t size) +size_t wxCountingOutputStream::OnSysWrite(const void *WXUNUSED(buffer), size_t size) { m_currentPos += size; if (m_currentPos > m_lastcount) m_lastcount = m_currentPos; @@ -740,9 +803,17 @@ wxBufferedInputStream::wxBufferedInputStream(wxInputStream& s) wxBufferedInputStream::~wxBufferedInputStream() { + off_t unused_bytes=m_i_streambuf->GetBufferPos()-m_i_streambuf->GetBufferEnd(); + m_parent_i_stream->SeekI(unused_bytes,wxFromCurrent); + delete m_i_streambuf; } +char wxBufferedInputStream::Peek() +{ + return m_i_streambuf->Peek(); +} + wxInputStream& wxBufferedInputStream::Read(void *buffer, size_t size) { size_t retsize; @@ -800,6 +871,7 @@ wxBufferedOutputStream::wxBufferedOutputStream(wxOutputStream& s) wxBufferedOutputStream::~wxBufferedOutputStream() { + Sync(); delete m_o_streambuf; } @@ -812,6 +884,7 @@ wxOutputStream& wxBufferedOutputStream::Write(const void *buffer, size_t size) off_t wxBufferedOutputStream::SeekO(off_t pos, wxSeekMode mode) { + Sync(); return m_o_streambuf->Seek(pos, mode); }