aboutsummaryrefslogtreecommitdiffstats
path: root/camel/camel-stream-buffer.c
diff options
context:
space:
mode:
author5 <NotZed@Ximian.com>2001-09-26 03:48:11 +0800
committerMichael Zucci <zucchi@src.gnome.org>2001-09-26 03:48:11 +0800
commit9c2f01c606823e1f6a0d77bbd0590ef8079f05d5 (patch)
treee9b74531565ddf8651ceb65c293059a13046b858 /camel/camel-stream-buffer.c
parent33e37fae702232c6ba91ede05dae7af999925547 (diff)
downloadgsoc2013-evolution-9c2f01c606823e1f6a0d77bbd0590ef8079f05d5.tar
gsoc2013-evolution-9c2f01c606823e1f6a0d77bbd0590ef8079f05d5.tar.gz
gsoc2013-evolution-9c2f01c606823e1f6a0d77bbd0590ef8079f05d5.tar.bz2
gsoc2013-evolution-9c2f01c606823e1f6a0d77bbd0590ef8079f05d5.tar.lz
gsoc2013-evolution-9c2f01c606823e1f6a0d77bbd0590ef8079f05d5.tar.xz
gsoc2013-evolution-9c2f01c606823e1f6a0d77bbd0590ef8079f05d5.tar.zst
gsoc2013-evolution-9c2f01c606823e1f6a0d77bbd0590ef8079f05d5.zip
A "safe write" function that always writes out all data asked of it, till
2001-09-25 <NotZed@Ximian.com> * camel-stream-buffer.c (stream_write_all): A "safe write" function that always writes out all data asked of it, till finished. (stream_write): Rewritten. What was i on when i wrote that originally, how did it ever work with tcp streams ... svn path=/trunk/; revision=13115
Diffstat (limited to 'camel/camel-stream-buffer.c')
-rw-r--r--camel/camel-stream-buffer.c73
1 files changed, 42 insertions, 31 deletions
diff --git a/camel/camel-stream-buffer.c b/camel/camel-stream-buffer.c
index 4d9a4de600..6f1aef96ab 100644
--- a/camel/camel-stream-buffer.c
+++ b/camel/camel-stream-buffer.c
@@ -270,49 +270,60 @@ stream_read (CamelStream *stream, char *buffer, size_t n)
return (ssize_t)(bptr - buffer);
}
+/* only returns the number passed in, or -1 on an error */
+static ssize_t
+stream_write_all(CamelStream *stream, const char *buffer, size_t n)
+{
+ size_t left = n, w;
+
+ while (left > 0) {
+ w = camel_stream_write(stream, buffer, left);
+ if (w == -1)
+ return -1;
+ left -= w;
+ buffer += w;
+ }
+
+ return n;
+}
+
static ssize_t
stream_write (CamelStream *stream, const char *buffer, size_t n)
{
CamelStreamBuffer *sbf = CAMEL_STREAM_BUFFER (stream);
- const char *bptr = buffer;
- ssize_t bytes_written = 1;
- ssize_t bytes_left;
ssize_t total = n;
+ ssize_t left, todo;
g_return_val_if_fail( (sbf->mode & CAMEL_STREAM_BUFFER_MODE) == CAMEL_STREAM_BUFFER_WRITE, 0);
- while (n && bytes_written > 0) {
- bytes_left = sbf->size - (sbf->ptr-sbf->buf);
- if (bytes_left<n) {
- memcpy(sbf->ptr, bptr, bytes_left);
- n -= bytes_left;
- bptr += bytes_left;
- bytes_written = camel_stream_write(sbf->stream, sbf->buf, sbf->size);
- sbf->ptr = sbf->buf;
- /* if we are writing a lot, write directly to the stream */
- if (n >= sbf->size/3) {
- bytes_written = camel_stream_write(sbf->stream, bptr, n);
- if (bytes_written >0) {
- bytes_written = n;
- n -= bytes_written;
- bptr += bytes_written;
- }
- } else {
- memcpy(sbf->ptr, bptr, n);
- sbf->ptr += n;
- bptr += n;
- n = 0;
- }
+ /* first, copy as much as we can */
+ left = sbf->size - (sbf->ptr-sbf->buf);
+ todo = MIN(left, n);
+
+ memcpy(sbf->ptr, buffer, todo);
+ n -= todo;
+ buffer += todo;
+ sbf->ptr += todo;
+
+ /* if we've filled the buffer, write it out, reset buffer */
+ if (left == todo) {
+ if (stream_write_all(sbf->stream, sbf->buf, sbf->size) == -1)
+ return -1;
+
+ sbf->ptr = sbf->buf;
+ }
+
+ /* if we still have more, write directly, or copy to buffer */
+ if (n > 0) {
+ if (n >= sbf->size/3) {
+ if (stream_write_all(sbf->stream, buffer, n) == -1)
+ return -1;
} else {
- memcpy(sbf->ptr, bptr, n);
+ memcpy(sbf->ptr, buffer, n);
sbf->ptr += n;
- bptr += n;
- n = 0;
}
}
- if (bytes_written == -1)
- return -1;
-
+
return total;
}