Remove set_{reader,writer}_limit in test/c code
diff --git a/test/c/std/deflate.c b/test/c/std/deflate.c
index ae6d8e6..b30a53b 100644
--- a/test/c/std/deflate.c
+++ b/test/c/std/deflate.c
@@ -148,18 +148,19 @@
   }
 
   while (true) {
-    wuffs_base__io_writer dst_writer = wuffs_base__io_buffer__writer(dst);
-    if (wlimit < UINT64_MAX) {
-      set_writer_limit(&dst_writer, wlimit);
-    }
-    wuffs_base__io_reader src_reader = wuffs_base__io_buffer__reader(src);
-    if (rlimit < UINT64_MAX) {
-      set_reader_limit(&src_reader, rlimit);
-    }
+    wuffs_base__io_buffer limited_dst = make_limited_writer(*dst, wlimit);
+    wuffs_base__io_writer dst_writer =
+        wuffs_base__io_buffer__writer(&limited_dst);
+    wuffs_base__io_buffer limited_src = make_limited_reader(*src, rlimit);
+    wuffs_base__io_reader src_reader =
+        wuffs_base__io_buffer__reader(&limited_src);
 
     status = wuffs_deflate__decoder__decode_io_writer(
         &dec, dst_writer, src_reader, global_work_slice);
 
+    dst->meta.wi += limited_dst.meta.wi;
+    src->meta.ri += limited_src.meta.ri;
+
     if (((wlimit < UINT64_MAX) &&
          (status == wuffs_base__suspension__short_write)) ||
         ((rlimit < UINT64_MAX) &&
@@ -330,15 +331,16 @@
   got->meta.ri = 0;
   got->meta.wi = 0;
 
-  wuffs_base__io_writer dst_writer = wuffs_base__io_buffer__writer(got);
+  wuffs_base__io_buffer limited_got = make_limited_writer(*got, wlimit);
+  wuffs_base__io_writer dst_writer =
+      wuffs_base__io_buffer__writer(&limited_got);
   wuffs_base__io_reader src_reader = wuffs_base__io_buffer__reader(src);
 
   dec->private_impl.f_history_index = starting_history_index;
 
-  set_writer_limit(&dst_writer, wlimit);
-
   const char* got_z = wuffs_deflate__decoder__decode_io_writer(
       dec, dst_writer, src_reader, global_work_slice);
+  got->meta.wi += limited_got.meta.wi;
   if (got_z != want_z) {
     RETURN_FAIL("i=%d: starting_history_index=0x%04" PRIX32
                 ": decode status: got \"%s\", want \"%s\"",
diff --git a/test/c/std/gif.c b/test/c/std/gif.c
index ab379a1..c8a2374 100644
--- a/test/c/std/gif.c
+++ b/test/c/std/gif.c
@@ -324,13 +324,13 @@
   int num_iters = 0;
   while (true) {
     num_iters++;
-    wuffs_base__io_reader src_reader = wuffs_base__io_buffer__reader(&src);
-    if (rlimit < UINT64_MAX) {
-      set_reader_limit(&src_reader, rlimit);
-    }
+    wuffs_base__io_buffer limited_src = make_limited_reader(src, rlimit);
+    wuffs_base__io_reader src_reader =
+        wuffs_base__io_buffer__reader(&limited_src);
     size_t old_ri = src.meta.ri;
 
     status = wuffs_gif__decoder__decode_frame_config(&dec, &fc, src_reader);
+    src.meta.ri += limited_src.meta.ri;
 
     if (!status) {
       break;
@@ -350,14 +350,14 @@
 
   while (true) {
     num_iters++;
-    wuffs_base__io_reader src_reader = wuffs_base__io_buffer__reader(&src);
-    if (rlimit < UINT64_MAX) {
-      set_reader_limit(&src_reader, rlimit);
-    }
+    wuffs_base__io_buffer limited_src = make_limited_reader(src, rlimit);
+    wuffs_base__io_reader src_reader =
+        wuffs_base__io_buffer__reader(&limited_src);
     size_t old_ri = src.meta.ri;
 
     const char* status = wuffs_gif__decoder__decode_frame(
         &dec, &pb, src_reader, global_work_slice, NULL);
+    src.meta.ri += limited_src.meta.ri;
 
     if (!status) {
       break;
@@ -568,10 +568,12 @@
   }
 
   {
-    wuffs_base__io_reader src_reader = wuffs_base__io_buffer__reader(&src);
-    set_reader_limit(&src_reader, 700);
+    wuffs_base__io_buffer limited_src = make_limited_reader(src, 700);
+    wuffs_base__io_reader src_reader =
+        wuffs_base__io_buffer__reader(&limited_src);
 
     status = wuffs_gif__decoder__decode_frame_config(&dec, NULL, src_reader);
+    src.meta.ri += limited_src.meta.ri;
     if (status != wuffs_base__suspension__short_read) {
       RETURN_FAIL("decode_frame_config: got \"%s\", want \"%s\"", status,
                   wuffs_base__suspension__short_read);
@@ -1674,10 +1676,13 @@
   int i = 0;
 
   while (true) {
-    wuffs_base__io_reader src_reader = wuffs_base__io_buffer__reader(&src);
-    set_reader_limit(&src_reader, 1);
+    wuffs_base__io_buffer limited_src = make_limited_reader(src, 1);
+    wuffs_base__io_reader src_reader =
+        wuffs_base__io_buffer__reader(&limited_src);
+
     status = wuffs_gif__decoder__decode_frame(&dec, &pb, src_reader,
                                               global_work_slice, NULL);
+    src.meta.ri += limited_src.meta.ri;
 
     wuffs_base__rect_ie_u32 r = wuffs_gif__decoder__frame_dirty_rect(&dec);
     if ((i < WUFFS_TESTLIB_ARRAY_SIZE(wants)) && (wants[i] == r.max_excl_y)) {
diff --git a/test/c/std/gzip.c b/test/c/std/gzip.c
index 251c8db..9b53bb1 100644
--- a/test/c/std/gzip.c
+++ b/test/c/std/gzip.c
@@ -96,18 +96,19 @@
   }
 
   while (true) {
-    wuffs_base__io_writer dst_writer = wuffs_base__io_buffer__writer(dst);
-    if (wlimit < UINT64_MAX) {
-      set_writer_limit(&dst_writer, wlimit);
-    }
-    wuffs_base__io_reader src_reader = wuffs_base__io_buffer__reader(src);
-    if (rlimit < UINT64_MAX) {
-      set_reader_limit(&src_reader, rlimit);
-    }
+    wuffs_base__io_buffer limited_dst = make_limited_writer(*dst, wlimit);
+    wuffs_base__io_writer dst_writer =
+        wuffs_base__io_buffer__writer(&limited_dst);
+    wuffs_base__io_buffer limited_src = make_limited_reader(*src, rlimit);
+    wuffs_base__io_reader src_reader =
+        wuffs_base__io_buffer__reader(&limited_src);
 
     status = wuffs_gzip__decoder__decode_io_writer(&dec, dst_writer, src_reader,
                                                    global_work_slice);
 
+    dst->meta.wi += limited_dst.meta.wi;
+    src->meta.ri += limited_src.meta.ri;
+
     if (((wlimit < UINT64_MAX) &&
          (status == wuffs_base__suspension__short_write)) ||
         ((rlimit < UINT64_MAX) &&
@@ -158,7 +159,7 @@
     // or isn't zero.
     int i;
     for (i = 0; i < 2; i++) {
-      wuffs_base__io_reader src_reader = wuffs_base__io_buffer__reader(&src);
+      uint64_t rlimit = UINT64_MAX;
       const char* want_z = NULL;
       if (i == 0) {
         if (end_limit == 0) {
@@ -167,7 +168,7 @@
         if (src.meta.wi < end_limit) {
           RETURN_FAIL("end_limit=%d: not enough source data", end_limit);
         }
-        set_reader_limit(&src_reader, src.meta.wi - (uint64_t)(end_limit));
+        rlimit = src.meta.wi - (uint64_t)(end_limit);
         want_z = wuffs_base__suspension__short_read;
       } else {
         want_z = (bad_checksum && !ignore_checksum)
@@ -175,8 +176,13 @@
                      : NULL;
       }
 
+      wuffs_base__io_buffer limited_src = make_limited_reader(src, rlimit);
+      wuffs_base__io_reader src_reader =
+          wuffs_base__io_buffer__reader(&limited_src);
+
       const char* got_z = wuffs_gzip__decoder__decode_io_writer(
           &dec, got_writer, src_reader, global_work_slice);
+      src.meta.ri += limited_src.meta.ri;
       if (got_z != want_z) {
         RETURN_FAIL("end_limit=%d: got \"%s\", want \"%s\"", end_limit, got_z,
                     want_z);
diff --git a/test/c/std/lzw.c b/test/c/std/lzw.c
index 9101b1b..1b6a9be 100644
--- a/test/c/std/lzw.c
+++ b/test/c/std/lzw.c
@@ -118,19 +118,19 @@
   int num_iters = 0;
   while (true) {
     num_iters++;
-    wuffs_base__io_writer got_writer = wuffs_base__io_buffer__writer(&got);
-    if (wlimit < UINT64_MAX) {
-      set_writer_limit(&got_writer, wlimit);
-    }
-    wuffs_base__io_reader src_reader = wuffs_base__io_buffer__reader(&src);
-    if (rlimit < UINT64_MAX) {
-      set_reader_limit(&src_reader, rlimit);
-    }
+    wuffs_base__io_buffer limited_got = make_limited_writer(got, wlimit);
+    wuffs_base__io_writer got_writer =
+        wuffs_base__io_buffer__writer(&limited_got);
+    wuffs_base__io_buffer limited_src = make_limited_reader(src, rlimit);
+    wuffs_base__io_reader src_reader =
+        wuffs_base__io_buffer__reader(&limited_src);
     size_t old_wi = got.meta.wi;
     size_t old_ri = src.meta.ri;
 
     status = wuffs_lzw__decoder__decode_io_writer(&dec, got_writer, src_reader,
                                                   global_work_slice);
+    got.meta.wi += limited_got.meta.wi;
+    src.meta.ri += limited_src.meta.ri;
     if (!status) {
       if (src.meta.ri != src.meta.wi) {
         RETURN_FAIL("decode returned \"ok\" but src was not exhausted");
diff --git a/test/c/std/zlib.c b/test/c/std/zlib.c
index d89e95e..e49d171 100644
--- a/test/c/std/zlib.c
+++ b/test/c/std/zlib.c
@@ -96,18 +96,19 @@
   }
 
   while (true) {
-    wuffs_base__io_writer dst_writer = wuffs_base__io_buffer__writer(dst);
-    if (wlimit < UINT64_MAX) {
-      set_writer_limit(&dst_writer, wlimit);
-    }
-    wuffs_base__io_reader src_reader = wuffs_base__io_buffer__reader(src);
-    if (rlimit < UINT64_MAX) {
-      set_reader_limit(&src_reader, rlimit);
-    }
+    wuffs_base__io_buffer limited_dst = make_limited_writer(*dst, wlimit);
+    wuffs_base__io_writer dst_writer =
+        wuffs_base__io_buffer__writer(&limited_dst);
+    wuffs_base__io_buffer limited_src = make_limited_reader(*src, rlimit);
+    wuffs_base__io_reader src_reader =
+        wuffs_base__io_buffer__reader(&limited_src);
 
     status = wuffs_zlib__decoder__decode_io_writer(&dec, dst_writer, src_reader,
                                                    global_work_slice);
 
+    dst->meta.wi += limited_dst.meta.wi;
+    src->meta.ri += limited_src.meta.ri;
+
     if (((wlimit < UINT64_MAX) &&
          (status == wuffs_base__suspension__short_write)) ||
         ((rlimit < UINT64_MAX) &&
@@ -157,7 +158,7 @@
     // or isn't zero.
     int i;
     for (i = 0; i < 2; i++) {
-      wuffs_base__io_reader src_reader = wuffs_base__io_buffer__reader(&src);
+      uint64_t rlimit = UINT64_MAX;
       const char* want_z = NULL;
       if (i == 0) {
         if (end_limit == 0) {
@@ -166,7 +167,7 @@
         if (src.meta.wi < end_limit) {
           RETURN_FAIL("end_limit=%d: not enough source data", end_limit);
         }
-        set_reader_limit(&src_reader, src.meta.wi - (uint64_t)(end_limit));
+        rlimit = src.meta.wi - (uint64_t)(end_limit);
         want_z = wuffs_base__suspension__short_read;
       } else {
         want_z = (bad_checksum && !ignore_checksum)
@@ -174,8 +175,13 @@
                      : NULL;
       }
 
+      wuffs_base__io_buffer limited_src = make_limited_reader(src, rlimit);
+      wuffs_base__io_reader src_reader =
+          wuffs_base__io_buffer__reader(&limited_src);
+
       const char* got_z = wuffs_zlib__decoder__decode_io_writer(
           &dec, got_writer, src_reader, global_work_slice);
+      src.meta.ri += limited_src.meta.ri;
       if (got_z != want_z) {
         RETURN_FAIL("end_limit=%d: got \"%s\", want \"%s\"", end_limit, got_z,
                     want_z);
diff --git a/test/c/testlib/testlib.c b/test/c/testlib/testlib.c
index a6b17d3..30a8389 100644
--- a/test/c/testlib/testlib.c
+++ b/test/c/testlib/testlib.c
@@ -366,32 +366,40 @@
   return ret;
 }
 
-void set_reader_limit(wuffs_base__io_reader* o, uint64_t limit) {
-  if (o && o->private_impl.buf) {
-    uint8_t* p = o->private_impl.buf->data.ptr + o->private_impl.buf->meta.ri;
-    uint8_t* q = o->private_impl.buf->data.ptr + o->private_impl.buf->meta.wi;
-    if (!o->private_impl.mark) {
-      o->private_impl.mark = p;
-      o->private_impl.limit = q;
-    }
-    if ((o->private_impl.limit - p) > limit) {
-      o->private_impl.limit = p + limit;
-    }
+wuffs_base__io_buffer make_limited_reader(wuffs_base__io_buffer b,
+                                          uint64_t limit) {
+  uint64_t n = b.meta.wi - b.meta.ri;
+  bool closed = b.meta.closed;
+  if (n > limit) {
+    n = limit;
+    closed = false;
   }
+
+  wuffs_base__io_buffer ret;
+  ret.data.ptr = b.data.ptr + b.meta.ri;
+  ret.data.len = n;
+  ret.meta.wi = n;
+  ret.meta.ri = 0;
+  ret.meta.pos = wuffs_base__u64__sat_add(b.meta.pos, b.meta.ri);
+  ret.meta.closed = closed;
+  return ret;
 }
 
-void set_writer_limit(wuffs_base__io_writer* o, uint64_t limit) {
-  if (o && o->private_impl.buf) {
-    uint8_t* p = o->private_impl.buf->data.ptr + o->private_impl.buf->meta.wi;
-    uint8_t* q = o->private_impl.buf->data.ptr + o->private_impl.buf->data.len;
-    if (!o->private_impl.mark) {
-      o->private_impl.mark = p;
-      o->private_impl.limit = q;
-    }
-    if ((o->private_impl.limit - p) > limit) {
-      o->private_impl.limit = p + limit;
-    }
+wuffs_base__io_buffer make_limited_writer(wuffs_base__io_buffer b,
+                                          uint64_t limit) {
+  uint64_t n = b.data.len - b.meta.wi;
+  if (n > limit) {
+    n = limit;
   }
+
+  wuffs_base__io_buffer ret;
+  ret.data.ptr = b.data.ptr + b.meta.wi;
+  ret.data.len = n;
+  ret.meta.wi = 0;
+  ret.meta.ri = 0;
+  ret.meta.pos = wuffs_base__u64__sat_add(b.meta.pos, b.meta.wi);
+  ret.meta.closed = b.meta.closed;
+  return ret;
 }
 
 // TODO: we shouldn't need to pass the rect. Instead, pass a subset pixbuf.