diff options
author | Nicholas <nbnoll@eml.cc> | 2021-11-20 20:12:21 -0800 |
---|---|---|
committer | Nicholas <nbnoll@eml.cc> | 2021-11-20 20:12:21 -0800 |
commit | 138fb272fae79587de3469493b55e4d18eadc722 (patch) | |
tree | 447d2af80b8c2ea080253e76d33e128c9b27d3f6 /src/base/bufio/read.c | |
parent | c9a32c1a43d2bdded07eaa45732c3a6e195a5442 (diff) |
Feat: added buffered io from plan9
As we no longer have the FILE type, we need to buffer our reading and
writing so that we don't have to make so many syscalls. The API is nice
so that we can buffer other readers. We will update it so that it eats
io·Readers/io·Writers.
Diffstat (limited to 'src/base/bufio/read.c')
-rw-r--r-- | src/base/bufio/read.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/base/bufio/read.c b/src/base/bufio/read.c new file mode 100644 index 0000000..ad0275c --- /dev/null +++ b/src/base/bufio/read.c @@ -0,0 +1,54 @@ +#include "internal.h" + +intptr +bio·read(io·Header *io, intptr len, void *buf) +{ + uchar *b; + intptr c0, c, nr, n, ic; + + b = buf; + c = len; + ic = io->ilen; // how many bytes we've read and not flushed + + while(c > 0){ + n = -ic; + if(n > c) + n = c; + if(n == 0){ + /* only continue if we are a file reader */ + if(io->state != io·BufRdr) + break; + + /* get more bytes */ + if(sys·read(io->fd, io->cap, io->b, &nr)){ + io->state = io·BufNil; + break; + } + + if(nr == 0){ + io->state = io·BufEnd; + break; + } + + /* shift bytes within buffer so they end at terminal */ + io->g = io->b; + io->pos += nr; + if(nr < io->cap){ + io->g = io->e-nr; + mem·move(io->g, io->b, nr); + } + ic -= nr; + continue; + } + /* move our read bytes into the caller's buffer */ + mem·move(b, io->e+ic, n); + c -= n; + ic += n; + b += n; + } + io->ilen = ic; + if(c == len && io->state == io·BufNil) + return -1; + + return len-c; +} |