]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/stream.cpp
fix va_arg(.,short int) problem
[wxWidgets.git] / src / common / stream.cpp
index c6ffc3895be16d426d10abaa53cacef505c54a85..a1d8cb04ccc4f6a2680bd3bb417e1c7f7a7bfb29 100644 (file)
@@ -39,6 +39,7 @@
 #include "wx/stream.h"
 #include "wx/datstrm.h"
 #include "wx/textfile.h"
+#include "wx/log.h"
 
 // ----------------------------------------------------------------------------
 // constants
@@ -612,9 +613,21 @@ off_t wxStreamBuffer::Seek(off_t pos, wxSeekMode mode)
 
 off_t wxStreamBuffer::Tell() const
 {
-    off_t pos = m_stream->OnSysTell();
-    if ( pos == wxInvalidOffset )
-        return wxInvalidOffset;
+    off_t pos;
+
+    // only ask the stream for position if we have a real stream and not a
+    // dummy one which we created ourselves, otherwise we'd call
+    // wxStream::OnSysTell() which would always return wxInvalidOffset
+    if ( !m_destroystream )
+    {
+        pos = m_stream->OnSysTell();
+        if ( pos == wxInvalidOffset )
+            return wxInvalidOffset;
+    }
+    else // no associated stream
+    {
+        pos = 0;
+    }
 
     pos += GetIntPosition();
 
@@ -702,14 +715,14 @@ char *wxInputStream::AllocSpaceWBack(size_t needed_size)
     if (!temp_b)
         return NULL;
 
-    /* copy previous data (and free old buffer) if needed */
+    // 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 */
+    // done
     m_wback = temp_b;
     m_wbackcur = 0;
     m_wbacksize = needed_size + toget;
@@ -750,22 +763,27 @@ size_t wxInputStream::GetWBack(void *buf, size_t bsize)
 
 size_t wxInputStream::Ungetch(const void *buf, size_t bufsize)
 {
+    if ( m_lasterror != wxSTREAM_NO_ERROR && m_lasterror != wxSTREAM_EOF )
+    {
+        // can't operate on this stream until the error is cleared
+        return 0;
+    }
+
     char *ptrback = AllocSpaceWBack(bufsize);
     if (!ptrback)
         return 0;
 
+    // Eof() shouldn't return TRUE any longer
+    if ( m_lasterror == wxSTREAM_EOF )
+        m_lasterror = wxSTREAM_NO_ERROR;
+
     memcpy(ptrback, buf, bufsize);
     return bufsize;
 }
 
 bool wxInputStream::Ungetch(char c)
 {
-    void *ptrback = AllocSpaceWBack(1);
-    if (!ptrback)
-        return FALSE;
-
-    *(char *)ptrback = c;
-    return TRUE;
+    return Ungetch(&c, sizeof(char)) != 0;
 }
 
 char wxInputStream::GetC()
@@ -777,17 +795,30 @@ char wxInputStream::GetC()
 
 wxInputStream& wxInputStream::Read(void *buf, size_t size)
 {
-    size_t retsize = GetWBack(buf, size);
-    if (retsize == size)
+    char *p = (char *)buf;
+    m_lastcount = 0;
+
+    size_t read = GetWBack(buf, size);
+    for ( ;; )
     {
-        m_lastcount = size;
-        m_lasterror = wxStream_NOERROR;
-        return *this;
+        size -= read;
+        m_lastcount += read;
+        p += read;
+
+        if ( !size )
+        {
+            // we read the requested amount of data
+            break;
+        }
+
+        read = OnSysRead(buf, size);
+        if ( !read )
+        {
+            // no more data available
+            break;
+        }
     }
-    size -= retsize;
-    buf = (char *)buf + retsize;
 
-    m_lastcount = OnSysRead(buf, size) + retsize;
     return *this;
 }
 
@@ -819,23 +850,29 @@ 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 ? */
+    // RR: This code is duplicated in wxBufferedInputStream. This is
+    // not really a good design, but buffered stream are different
+    // from all other in that they handle two stream-related objects,
+    // the stream buffer and parent stream.
+
+    // 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 SeekI() to one
+    /* RR: A call to SeekI() will automatically invalidate any previous
+       call to Ungetch(), otherwise it would be possible to SeekI() to
        one position, unread some bytes there, SeekI() to another position
        and the data would be corrupted.
 
        GRG: Could add code here to try to navigate within the wback
        buffer if possible, but is it really needed? It would only work
        when seeking in wxFromCurrent mode, else it would invalidate
-       anyway...
-     */
+       anyway... */
+       
     if (m_wback)
     {
+        wxLogDebug( wxT("Seeking in stream which has data written back to it.") );
+        
         free(m_wback);
         m_wback = NULL;
         m_wbacksize = 0;
@@ -847,7 +884,6 @@ off_t wxInputStream::SeekI(off_t pos, wxSeekMode mode)
 
 off_t wxInputStream::TellI() const
 {
-    /* GRG: Changed to make it compatible with the wback buffer */
     off_t pos = OnSysTell();
 
     if (pos != wxInvalidOffset)
@@ -1061,12 +1097,32 @@ wxInputStream& wxBufferedInputStream::Read(void *buf, size_t size)
 
 off_t wxBufferedInputStream::SeekI(off_t pos, wxSeekMode mode)
 {
+    // RR: Look at wxInputStream for comments.
+
+    if (m_lasterror==wxSTREAM_EOF)
+        m_lasterror=wxSTREAM_NOERROR;
+
+    if (m_wback)
+    {
+        wxLogDebug( wxT("Seeking in stream which has data written back to it.") );
+        
+        free(m_wback);
+        m_wback = NULL;
+        m_wbacksize = 0;
+        m_wbackcur = 0;
+    }
+    
     return m_i_streambuf->Seek(pos, mode);
 }
 
 off_t wxBufferedInputStream::TellI() const
 {
-    return m_i_streambuf->Tell();
+    off_t pos = m_i_streambuf->Tell();
+
+    if (pos != wxInvalidOffset)
+        pos -= (m_wbacksize - m_wbackcur);
+        
+    return pos;
 }
 
 size_t wxBufferedInputStream::OnSysRead(void *buffer, size_t bufsize)