]> git.saurik.com Git - wxWidgets.git/commitdiff
Add wxInputStream::ReadAll() and wxOutputStream::WriteAll().
authorVadim Zeitlin <vadim@wxwidgets.org>
Mon, 20 May 2013 13:15:16 +0000 (13:15 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Mon, 20 May 2013 13:15:16 +0000 (13:15 +0000)
Unlike Read() and Write(), these functions always transfer exactly the
specified number of bytes or fail.

See #12056.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74034 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
include/wx/stream.h
interface/wx/stream.h
src/common/stream.cpp

index 20015c11a3fb04315f627e740cc0d4bd4b2f4c51..28c14151426abb1daddff23a234135a03920ac1d 100644 (file)
@@ -576,6 +576,7 @@ All:
 - Add wxDIR_NO_FOLLOW flag for wxDir traversal (David Hart).
 - Allow testing for symlink/FIFO/socket existence in wxFileName (David Hart).
 - Many important bug fixes in wxFileSystemWatcher (David Hart).
+- Add wxInputStream::ReadAll() and wxOutputStream::WriteAll() (Catalin Raceanu).
 - Add new wxFSW_EVENT_ATTRIB and wxFSW_EVENT_UNMOUNT flags (David Hart).
 - Add separate read/written bytes counters and per-direction NOWAIT and WAITALL
   flags to wxSocket (Rob Bresalier).
index 80c81bcbdc0a8f32bd6aeb1de583dee4cb36fd29..7f57e1f39c22e7e3e9a25f55afa9ec2d61fe394d 100644 (file)
@@ -128,6 +128,11 @@ public:
     // it means that EOF has been reached.
     virtual wxInputStream& Read(void *buffer, size_t size);
 
+    // Read exactly the given number of bytes, unlike Read(), which may read
+    // less than the requested amount of data without returning an error, this
+    // method either reads all the data or returns false.
+    bool ReadAll(void *buffer, size_t size);
+
     // copy the entire contents of this stream into streamOut, stopping only
     // when EOF is reached or an error occurs
     wxInputStream& Read(wxOutputStream& streamOut);
@@ -233,6 +238,12 @@ public:
 
     void PutC(char c);
     virtual wxOutputStream& Write(const void *buffer, size_t size);
+
+    // This is ReadAll() equivalent for Write(): it either writes exactly the
+    // given number of bytes or returns false, unlike Write() which can write
+    // less data than requested but still return without error.
+    bool WriteAll(const void *buffer, size_t size);
+
     wxOutputStream& Write(wxInputStream& stream_in);
 
     virtual wxFileOffset SeekO(wxFileOffset pos, wxSeekMode mode = wxFromStart);
index 6fd27a412607116e8657c04d7c8e1de30eff55aa..7bed3174ca369459bf2bd3627a56c2a5f38d595f 100644 (file)
@@ -537,6 +537,20 @@ public:
     */
     wxOutputStream& Write(wxInputStream& stream_in);
 
+    /**
+        Writes exactly the specified number of bytes from the buffer.
+
+        Returns @true if exactly @a size bytes were written. Otherwise, returns
+        @false and LastWrite() should be used to retrieve the exact amount of
+        the data written if necessary.
+
+        This method uses repeated calls to Write() (which may return writing
+        only part of the data) if necessary.
+
+        @since 2.9.5
+    */
+    bool WriteAll(const void* buffer, size_t size);
+
 protected:
     /**
         Internal function. It is called when the stream wants to write data of the
@@ -629,6 +643,23 @@ public:
     */
     wxInputStream& Read(wxOutputStream& stream_out);
 
+    /**
+        Reads exactly the specified number of bytes into the buffer.
+
+        Returns @true only if the entire amount of data was read, otherwise
+        @false is returned and the number of bytes really read can be retrieved
+        using LastRead(), as with Read().
+
+        This method uses repeated calls to Read() (which may return after
+        reading less than the requested number of bytes) if necessary.
+
+        @warning
+        The buffer absolutely needs to have at least the specified size.
+
+        @since 2.9.5
+    */
+    bool ReadAll(void* buffer, size_t size);
+
     /**
         Changes the stream current position.
 
index f7cd2ea2c58db63aa52248adc2857100f501c1e5..94a1244b2b2058bbbd51cd41e0dbdd2962b6f046 100644 (file)
@@ -913,6 +913,42 @@ wxInputStream& wxInputStream::Read(wxOutputStream& stream_out)
     return *this;
 }
 
+bool wxInputStream::ReadAll(void *buffer_, size_t size)
+{
+    char* buffer = static_cast<char*>(buffer_);
+
+    m_lastcount = 0;
+
+    for ( ;; )
+    {
+        const size_t lastCount = Read(buffer, size).LastRead();
+
+        // There is no point in continuing looping if we can't read anything at
+        // all.
+        if ( !lastCount )
+            break;
+
+        m_lastcount += lastCount;
+
+        // ... Or if an error occurred on the stream.
+        if ( !IsOk() )
+            break;
+
+        // Return successfully if we read exactly the requested number of
+        // bytes (normally the ">" case should never occur and so we could use
+        // "==" test, but be safe and avoid overflowing size even in case of
+        // bugs in LastRead()).
+        if ( lastCount >= size )
+            return true;
+
+        // Advance the buffer before trying to read the rest of data.
+        size -= lastCount;
+        buffer += lastCount;
+    }
+
+    return false;
+}
+
 wxFileOffset wxInputStream::SeekI(wxFileOffset pos, wxSeekMode mode)
 {
     // RR: This code is duplicated in wxBufferedInputStream. This is
@@ -1030,6 +1066,34 @@ wxOutputStream& wxOutputStream::Write(wxInputStream& stream_in)
     return *this;
 }
 
+bool wxOutputStream::WriteAll(const void *buffer_, size_t size)
+{
+    // This exactly mirrors ReadAll(), see there for more comments.
+    const char* buffer = static_cast<const char*>(buffer_);
+
+    m_lastcount = 0;
+
+    for ( ;; )
+    {
+        const size_t lastCount = Write(buffer, size).LastWrite();
+        if ( !lastCount )
+            break;
+
+        m_lastcount += lastCount;
+
+        if ( !IsOk() )
+            break;
+
+        if ( lastCount >= size )
+            return true;
+
+        size -= lastCount;
+        buffer += lastCount;
+    }
+
+    return false;
+}
+
 wxFileOffset wxOutputStream::TellO() const
 {
     return OnSysTell();