aboutsummaryrefslogtreecommitdiff
path: root/src/bufio/reader.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bufio/reader.c')
-rw-r--r--src/bufio/reader.c198
1 files changed, 0 insertions, 198 deletions
diff --git a/src/bufio/reader.c b/src/bufio/reader.c
deleted file mode 100644
index 915c531..0000000
--- a/src/bufio/reader.c
+++ /dev/null
@@ -1,198 +0,0 @@
-#include "impl.h"
-
-struct bufio·Reader
-{
- io·Reader r;
- Buffer buf;
-};
-
-bufio·Reader*
-bufio·newreader(io·Reader r)
-{
- bufio·Reader* br = newbuffer(offsetof(bufio·Reader, buf), 0);
- br->r = r;
- br->buf.pos = br->buf.end;
-
- return br;
-}
-
-error
-bufio·freereader(bufio·Reader* r)
-{
- free(r);
- return 0;
-}
-
-static int
-refill(bufio·Reader* r)
-{
- if (r->buf.eof) return BUF·err;
-
- int nr = r->r.read(r->r.impl, r->buf.base, r->buf.size);
- if (nr <= 0) {
- r->buf.eof = 1;
- goto end;
- }
-
- r->buf.off += nr;
- r->buf.pos = r->buf.base;
-
- if (nr < r->buf.size) {
- int d = (r->buf.size - nr);
- r->buf.eof = 1;
- memmove(r->buf.pos + d, r->buf.pos, nr);
- memmove(r->buf.pos + d - BUF·ungets, r->buf.b, BUF·ungets);
- r->buf.pos += d;
- }
-end:
- return nr;
-}
-
-// Read will attempt to read n bytes from the buffer, starting at the offet
-// offset. Returns the actual number of bytes read from the stream. Input buf
-// can not alias b
-int
-bufio·read(bufio·Reader* r, byte* buf, int count)
-{
- if (count == 0 || buf == nil || r->buf.off == BUF·eof) return BUF·err;
-
- int remain = count;
- byte* rdr = buf;
-
- int n, nr;
- while (remain) {
- int bdiff = r->buf.end - r->buf.pos;
- n = (bdiff > remain) ? remain : bdiff;
- if (!n) {
- if (r->buf.eof | (refill(r) <= 0)) break;
- }
-
- memmove(rdr, r->buf.pos, n);
- rdr += n;
- r->buf.pos += n;
- remain -= n;
- }
- return count - remain;
-}
-
-int
-bufio·readln(bufio·Reader* r, byte* buf, int count, error* err)
-{
- byte *it, *end, *cnt;
- int nb;
-Search:
- nb = 0;
- cnt = r->buf.pos + count;
- end = MIN(r->buf.end, cnt);
-
- for (it = r->buf.pos; it != end && *it != EOF; ++it, nb++) {
- if (*it == '\n') {
- *err = 0;
- goto End;
- }
- }
-
- if (it == r->buf.end) {
- memmove(buf, r->buf.pos, nb);
- r->buf.pos = r->buf.end;
- if (refill(r) <= 0) {
- *err = 1;
- return nb;
- }
- Assert(nb < count);
- count -= nb;
- buf += nb;
- goto Search;
- }
-
- if (it == cnt) {
- Assert(nb == count);
- *err = 2;
- }
-
- Assert(*it == EOF || *err == 2);
-
-End:
- memmove(buf, r->buf.pos, nb);
- r->buf.pos = it;
- return nb;
-}
-
-// advanceBuffer moves the buffer ahead by n without reading.
-void
-bufio·discard(bufio·Reader* r, int count)
-{
- if (count > BUF·max)
- panicf("can't discard %d bytes", count);
- byte stack[BUF·max];
-
- bufio·read(r, stack, count);
-}
-
-// ReadByte reads a single byte from the buffered stream.
-byte
-bufio·get(bufio·Reader* r)
-{
-getbyte:
- if (r->buf.pos < r->buf.end) { return *r->buf.pos++; }
-
- memmove(r->buf.b, r->buf.end - BUF·ungets, BUF·ungets);
- if (refill(r) <= 0) { return EOF; }
- goto getbyte;
-}
-
-error
-bufio·unget(bufio·Reader* r)
-{
- if (r->buf.pos == r->buf.b) { return BUF·err; }
-
- r->buf.pos--;
- return 0;
-}
-
-byte
-bufio·peek(bufio·Reader* r)
-{
- if (r->buf.pos != r->buf.end) return *r->buf.pos;
-
- byte* old = r->buf.pos;
- byte c = bufio·get(r);
- if (r->buf.pos != old && (bufio·unget(r) == BUF·err)) {
- panicf("buffer failure, can't move backwards");
- }
-
- return c;
-}
-
-// peekBytes has the same behavior as read, but doesn't advance the buffer.
-int
-bufio·peekfor(bufio·Reader* r, byte* buf, int count)
-{
- if (count == 0 || buf == nil) return 0;
-
- int delta = r->buf.end - r->buf.pos;
- if (delta > count) {
- memcpy(buf, r->buf.pos, count);
- return count;
- }
-
- byte c, *it;
- for (it = buf; it != buf + count; ++it) {
- c = bufio·get(r);
- *it = c;
- if (c == EOF) break;
- }
-
- int diff = it - buf;
- for (int n = 0; n < diff; n++) {
- bufio·unget(r);
- }
-
- return diff;
-}
-
-void
-bufio·clear(bufio·Reader* r)
-{
- memset(r->buf.b, 0, r->buf.size);
-}