stream: add read/write_all() methods to stream
authorMartin Willi <martin@revosec.ch>
Mon, 1 Jul 2013 08:36:52 +0000 (10:36 +0200)
committerMartin Willi <martin@revosec.ch>
Thu, 18 Jul 2013 14:00:28 +0000 (16:00 +0200)
src/libstrongswan/networking/streams/stream.c
src/libstrongswan/networking/streams/stream.h

index 9a4a3d3..20379fb 100644 (file)
@@ -54,8 +54,6 @@ struct private_stream_t {
         * Data for write-ready callback
         */
        void *write_data;
-
-
 };
 
 METHOD(stream_t, read_, ssize_t,
@@ -86,6 +84,29 @@ METHOD(stream_t, read_, ssize_t,
        }
 }
 
+METHOD(stream_t, read_all, bool,
+       private_stream_t *this, void *buf, size_t len)
+{
+       ssize_t ret;
+
+       while (len)
+       {
+               ret = read_(this, buf, len, TRUE);
+               if (ret < 0)
+               {
+                       return FALSE;
+               }
+               if (ret == 0)
+               {
+                       errno = ECONNRESET;
+                       return FALSE;
+               }
+               len -= ret;
+               buf += ret;
+       }
+       return TRUE;
+}
+
 METHOD(stream_t, write_, ssize_t,
        private_stream_t *this, void *buf, size_t len, bool block)
 {
@@ -114,6 +135,29 @@ METHOD(stream_t, write_, ssize_t,
        }
 }
 
+METHOD(stream_t, write_all, bool,
+       private_stream_t *this, void *buf, size_t len)
+{
+       ssize_t ret;
+
+       while (len)
+       {
+               ret = write_(this, buf, len, TRUE);
+               if (ret < 0)
+               {
+                       return FALSE;
+               }
+               if (ret == 0)
+               {
+                       errno = ECONNRESET;
+                       return FALSE;
+               }
+               len -= ret;
+               buf += ret;
+       }
+       return TRUE;
+}
+
 /**
  * Remove a registered watcher
  */
@@ -236,8 +280,10 @@ stream_t *stream_create_from_fd(int fd)
        INIT(this,
                .public = {
                        .read = _read_,
+                       .read_all = _read_all,
                        .on_read = _on_read,
                        .write = _write_,
+                       .write_all = _write_all,
                        .on_write = _on_write,
                        .get_file = _get_file,
                        .destroy = _destroy,
index 17e5a94..8cd8419 100644 (file)
@@ -72,6 +72,19 @@ struct stream_t {
        ssize_t (*read)(stream_t *this, void *buf, size_t len, bool block);
 
        /**
+        * Read data from the stream, avoiding short reads.
+        *
+        * This call is always blocking, and reads until len has been read
+        * completely. If the connection is closed before enough bytes could be
+        * returned, errno is set to ECONNRESET.
+        *
+        * @param buf           data buffer to read into
+        * @param len           number of bytes to read
+        * @return                      TRUE if len bytes read, FALSE on error
+        */
+       bool (*read_all)(stream_t *this, void *buf, size_t len);
+
+       /**
         * Register a callback to invoke when stream has data to read.
         *
         * @param cb            callback function, NULL to unregister
@@ -93,6 +106,18 @@ struct stream_t {
        ssize_t (*write)(stream_t *this, void *buf, size_t len, bool block);
 
        /**
+        * Write data to the stream, avoiding short writes.
+        *
+        * This call is always blocking, and writes until len bytes has been
+        * written.
+        *
+        * @param buf           data buffer to write
+        * @param len           number of bytes to write
+        * @return                      TRUE if len bytes written, FALSE on error
+        */
+       bool (*write_all)(stream_t *this, void *buf, size_t len);
+
+       /**
         * Register a callback to invoke when a write would not block.
         *
         * @param cb            callback function, NULL to unregister