Changeset: d26ed9dcd412 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=d26ed9dcd412
Modified Files:
        clients/examples/C/streamcat.c
        common/stream/text_stream.c
Branch: makelibstreamgreatagain
Log Message:

Do not read short when skipping boms


diffs (78 lines):

diff --git a/clients/examples/C/streamcat.c b/clients/examples/C/streamcat.c
--- a/clients/examples/C/streamcat.c
+++ b/clients/examples/C/streamcat.c
@@ -279,10 +279,13 @@ static void copy_stream_to_file(stream *
        ssize_t nread;
        size_t nwritten;
        unsigned long total = 0;
+       long iterations = -1;
+       ssize_t short_read = 0;
 
        buffer = malloc(bufsize);
 
        while (1) {
+               iterations += 1;
                nread = mnstr_read(in, buffer, 1, bufsize);
                if (nread < 0)
                        croak(2, "Error reading from stream after %lu bytes: 
%s", total, mnstr_error(in));
@@ -290,6 +293,12 @@ static void copy_stream_to_file(stream *
                        // eof
                        break;
                }
+
+               if (short_read != 0)
+                       // A short read MUST be followed by either error or eof.
+                       croak(2, "Short read (%zd/%zu) after %ld iterations not 
followed by EOF or error", short_read, bufsize, iterations - 1);
+               short_read = (size_t)nread < bufsize ? nread : 0;
+
                errno = 0;
                nwritten = fwrite(buffer, 1, nread, out);
                if (nwritten != (size_t)nread)
diff --git a/common/stream/text_stream.c b/common/stream/text_stream.c
--- a/common/stream/text_stream.c
+++ b/common/stream/text_stream.c
@@ -45,22 +45,34 @@ text_read(stream *restrict s, void *rest
 }
 
 static ssize_t
-text_read_putback(stream *restrict s, void *restrict buf, size_t elmsize, 
size_t cnt)
+text_read_putback(stream *restrict s, void *restrict buf_, size_t elmsize, 
size_t cnt)
 {
        state *st = (state*) s->stream_data.p;
+       char *buf = buf_; // more convenient type
        char *p = buf;
-       size_t size = elmsize * cnt;
-       size_t i;
+       char *end = buf + elmsize * cnt;
 
-       for (i = 0; i < size; i++) {
-               if (st->putback_start == st->putback_end) {
-                       s->read = text_read;
-                       break;
-               }
-               *p++ = st->putback_buf[st->putback_start++];
+       while (st->putback_start < st->putback_end) {
+               if (p < end)
+                       *p++ = st->putback_buf[st->putback_start++];
+               else
+                       return p - buf;
        }
 
-       return i;
+       // If we get here, the putback buffer is empty but we may still have
+       // some output buffer left.
+       // First, arrange for subsequent read calls to go straight to text_read
+       // instead of text_read_putback.
+       s->read = text_read;
+
+       if (p == end)
+               return p - buf;
+
+       ssize_t nread = text_read(s, p, 1, end - p);
+       if (nread < 0)
+               return nread;
+       p += nread;
+       return p - buf;
 }
 
 
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to