diff options
Diffstat (limited to 'src/base/bufio/readuntil.c')
-rw-r--r-- | src/base/bufio/readuntil.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/base/bufio/readuntil.c b/src/base/bufio/readuntil.c new file mode 100644 index 0000000..8084cca --- /dev/null +++ b/src/base/bufio/readuntil.c @@ -0,0 +1,64 @@ +#include "internal.h" + +void * +bio·readuntil(io·Header *io, int delim) +{ + char *b, *e; + intptr i, j; + + i = -io->ilen; + if(i==0){ + if(io->state != io·BufRdr){ + if(io->state == io·BufEnd) + io->state = io·BufRdr; + io->line = 0; + io->g = io->e; + return nil; + } + } + + /* best case, we find it in the remaining bytes */ + b = (char*)io->e - i; + if((e = mem·findc(b, i, delim)) != nil){ + j = (e - b)+1; + io->line = j; + io->ilen += j; + return b; + } + /* ok no luck, shift over the data and get more */ + if(i < io->cap) + mem·move(io->b, b, i); + io->g = io->b; + /* write to the buffer while we search for delim */ + b = (char *)io->b + i; + while(i < io->cap){ + if(sys·read(io->fd, io->cap-i, b, &j)){ + mem·move(io->e-i, io->b, i); + io->line = +i; + io->ilen = -i; + io->g = io->e - i; + return 0; + } + io->pos += j; + i += j; + e = mem·findc(b, j, delim); + if(e!=nil){ + /* finally have a hit. reset the world */ + b = (char*)io->e - i; + if(i < io->cap){ + mem·move(b, io->b, i); + io->g = (uchar *)b; + } + j = (e - (char*)io->b) + 1; + io->line = j; + io->ilen = j - i; + return b; + } + b += j; + } + + io->line = +io->cap; + io->ilen = -io->cap; + io->g = io->b; + return 0; +} |