#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; }