diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/libbio |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/libbio')
-rwxr-xr-x | sys/src/libbio/bbuffered.c | 21 | ||||
-rwxr-xr-x | sys/src/libbio/bfildes.c | 10 | ||||
-rwxr-xr-x | sys/src/libbio/bflush.c | 34 | ||||
-rwxr-xr-x | sys/src/libbio/bgetc.c | 54 | ||||
-rwxr-xr-x | sys/src/libbio/bgetd.c | 37 | ||||
-rwxr-xr-x | sys/src/libbio/bgetrune.c | 47 | ||||
-rwxr-xr-x | sys/src/libbio/binit.c | 136 | ||||
-rwxr-xr-x | sys/src/libbio/boffset.c | 26 | ||||
-rwxr-xr-x | sys/src/libbio/bprint.c | 15 | ||||
-rwxr-xr-x | sys/src/libbio/bputc.c | 21 | ||||
-rwxr-xr-x | sys/src/libbio/bputrune.c | 23 | ||||
-rwxr-xr-x | sys/src/libbio/brdline.c | 95 | ||||
-rwxr-xr-x | sys/src/libbio/brdstr.c | 112 | ||||
-rwxr-xr-x | sys/src/libbio/bread.c | 48 | ||||
-rwxr-xr-x | sys/src/libbio/bseek.c | 58 | ||||
-rwxr-xr-x | sys/src/libbio/btestprint.c | 20 | ||||
-rwxr-xr-x | sys/src/libbio/bvprint.c | 37 | ||||
-rwxr-xr-x | sys/src/libbio/bwrite.c | 43 | ||||
-rwxr-xr-x | sys/src/libbio/mkfile | 32 |
19 files changed, 869 insertions, 0 deletions
diff --git a/sys/src/libbio/bbuffered.c b/sys/src/libbio/bbuffered.c new file mode 100755 index 000000000..1b2bdbe09 --- /dev/null +++ b/sys/src/libbio/bbuffered.c @@ -0,0 +1,21 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +int +Bbuffered(Biobufhdr *bp) +{ + switch(bp->state) { + case Bracteof: + case Bractive: + return -bp->icount; + + case Bwactive: + return bp->bsize + bp->ocount; + + case Binactive: + return 0; + } + fprint(2, "Bbuffered: unknown state %d\n", bp->state); + return 0; +} diff --git a/sys/src/libbio/bfildes.c b/sys/src/libbio/bfildes.c new file mode 100755 index 000000000..6b3fd289d --- /dev/null +++ b/sys/src/libbio/bfildes.c @@ -0,0 +1,10 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +int +Bfildes(Biobufhdr *bp) +{ + + return bp->fid; +} diff --git a/sys/src/libbio/bflush.c b/sys/src/libbio/bflush.c new file mode 100755 index 000000000..d4339eea7 --- /dev/null +++ b/sys/src/libbio/bflush.c @@ -0,0 +1,34 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +int +Bflush(Biobufhdr *bp) +{ + int n, c; + + switch(bp->state) { + case Bwactive: + n = bp->bsize+bp->ocount; + if(n == 0) + return 0; + c = write(bp->fid, bp->bbuf, n); + if(n == c) { + bp->offset += n; + bp->ocount = -bp->bsize; + return 0; + } + bp->state = Binactive; + bp->ocount = 0; + break; + + case Bracteof: + bp->state = Bractive; + + case Bractive: + bp->icount = 0; + bp->gbuf = bp->ebuf; + return 0; + } + return Beof; +} diff --git a/sys/src/libbio/bgetc.c b/sys/src/libbio/bgetc.c new file mode 100755 index 000000000..1119c4517 --- /dev/null +++ b/sys/src/libbio/bgetc.c @@ -0,0 +1,54 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +int +Bgetc(Biobufhdr *bp) +{ + int i; + +loop: + i = bp->icount; + if(i != 0) { + bp->icount = i+1; + return bp->ebuf[i]; + } + if(bp->state != Bractive) { + if(bp->state == Bracteof) + bp->state = Bractive; + return Beof; + } + /* + * get next buffer, try to keep Bungetsize + * characters pre-catenated from the previous + * buffer to allow that many ungets. + */ + memmove(bp->bbuf-Bungetsize, bp->ebuf-Bungetsize, Bungetsize); + i = read(bp->fid, bp->bbuf, bp->bsize); + bp->gbuf = bp->bbuf; + if(i <= 0) { + bp->state = Bracteof; + if(i < 0) + bp->state = Binactive; + return Beof; + } + if(i < bp->bsize) { + memmove(bp->ebuf-i-Bungetsize, bp->bbuf-Bungetsize, i+Bungetsize); + bp->gbuf = bp->ebuf-i; + } + bp->icount = -i; + bp->offset += i; + goto loop; +} + +int +Bungetc(Biobufhdr *bp) +{ + + if(bp->state == Bracteof) + bp->state = Bractive; + if(bp->state != Bractive) + return Beof; + bp->icount--; + return 1; +} diff --git a/sys/src/libbio/bgetd.c b/sys/src/libbio/bgetd.c new file mode 100755 index 000000000..abede2647 --- /dev/null +++ b/sys/src/libbio/bgetd.c @@ -0,0 +1,37 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +struct bgetd +{ + Biobufhdr* b; + int eof; +}; + +static int +Bgetdf(void *vp) +{ + int c; + struct bgetd *bg = vp; + + c = Bgetc(bg->b); + if(c == Beof) + bg->eof = 1; + return c; +} + +int +Bgetd(Biobufhdr *bp, double *dp) +{ + double d; + struct bgetd b; + + b.b = bp; + b.eof = 0; + d = charstod(Bgetdf, &b); + if(b.eof) + return -1; + Bungetc(bp); + *dp = d; + return 1; +} diff --git a/sys/src/libbio/bgetrune.c b/sys/src/libbio/bgetrune.c new file mode 100755 index 000000000..3ba90384e --- /dev/null +++ b/sys/src/libbio/bgetrune.c @@ -0,0 +1,47 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +long +Bgetrune(Biobufhdr *bp) +{ + int c, i; + Rune rune; + char str[4]; + + c = Bgetc(bp); + if(c < Runeself) { /* one char */ + bp->runesize = 1; + return c; + } + str[0] = c; + + for(i=1;;) { + c = Bgetc(bp); + if(c < 0) + return c; + str[i++] = c; + + if(fullrune(str, i)) { + bp->runesize = chartorune(&rune, str); + while(i > bp->runesize) { + Bungetc(bp); + i--; + } + return rune; + } + } +} + +int +Bungetrune(Biobufhdr *bp) +{ + + if(bp->state == Bracteof) + bp->state = Bractive; + if(bp->state != Bractive) + return Beof; + bp->icount -= bp->runesize; + bp->runesize = 0; + return 1; +} diff --git a/sys/src/libbio/binit.c b/sys/src/libbio/binit.c new file mode 100755 index 000000000..75cee333b --- /dev/null +++ b/sys/src/libbio/binit.c @@ -0,0 +1,136 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +static Biobufhdr* wbufs[20]; +static int atexitflag; + +static +void +batexit(void) +{ + Biobufhdr *bp; + int i; + + for(i=0; i<nelem(wbufs); i++) { + bp = wbufs[i]; + if(bp != 0) { + wbufs[i] = 0; + Bflush(bp); + } + } +} + +static +void +deinstall(Biobufhdr *bp) +{ + int i; + + for(i=0; i<nelem(wbufs); i++) + if(wbufs[i] == bp) + wbufs[i] = 0; +} + +static +void +install(Biobufhdr *bp) +{ + int i; + + deinstall(bp); + for(i=0; i<nelem(wbufs); i++) + if(wbufs[i] == 0) { + wbufs[i] = bp; + break; + } + if(atexitflag == 0) { + atexitflag = 1; + atexit(batexit); + } +} + +int +Binits(Biobufhdr *bp, int f, int mode, uchar *p, int size) +{ + + p += Bungetsize; /* make room for Bungets */ + size -= Bungetsize; + + switch(mode&~(OCEXEC|ORCLOSE|OTRUNC)) { + default: + fprint(2, "Binits: unknown mode %d\n", mode); + return Beof; + + case OREAD: + bp->state = Bractive; + bp->ocount = 0; + break; + + case OWRITE: + install(bp); + bp->state = Bwactive; + bp->ocount = -size; + break; + } + bp->bbuf = p; + bp->ebuf = p+size; + bp->bsize = size; + bp->icount = 0; + bp->gbuf = bp->ebuf; + bp->fid = f; + bp->flag = 0; + bp->rdline = 0; + bp->offset = 0; + bp->runesize = 0; + return 0; +} + + +int +Binit(Biobuf *bp, int f, int mode) +{ + return Binits(bp, f, mode, bp->b, sizeof(bp->b)); +} + +Biobuf* +Bopen(char *name, int mode) +{ + Biobuf *bp; + int f; + + switch(mode&~(OCEXEC|ORCLOSE|OTRUNC)) { + default: + fprint(2, "Bopen: unknown mode %#x\n", mode); + return 0; + case OREAD: + f = open(name, mode); + break; + case OWRITE: + f = create(name, mode, 0666); + break; + } + if(f < 0) + return 0; + bp = malloc(sizeof(Biobuf)); + Binits(bp, f, mode, bp->b, sizeof(bp->b)); + bp->flag = Bmagic; /* mark bp open & malloced */ + return bp; +} + +int +Bterm(Biobufhdr *bp) +{ + int r; + + deinstall(bp); + r = Bflush(bp); + if(bp->flag == Bmagic) { + bp->flag = 0; + close(bp->fid); + bp->fid = -1; /* prevent accidents */ + free(bp); + } + /* otherwise opened with Binit(s) */ + return r; +} diff --git a/sys/src/libbio/boffset.c b/sys/src/libbio/boffset.c new file mode 100755 index 000000000..23d74816d --- /dev/null +++ b/sys/src/libbio/boffset.c @@ -0,0 +1,26 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +vlong +Boffset(Biobufhdr *bp) +{ + vlong n; + + switch(bp->state) { + default: + fprint(2, "Boffset: unknown state %d\n", bp->state); + n = Beof; + break; + + case Bracteof: + case Bractive: + n = bp->offset + bp->icount; + break; + + case Bwactive: + n = bp->offset + (bp->bsize + bp->ocount); + break; + } + return n; +} diff --git a/sys/src/libbio/bprint.c b/sys/src/libbio/bprint.c new file mode 100755 index 000000000..fc016c2be --- /dev/null +++ b/sys/src/libbio/bprint.c @@ -0,0 +1,15 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +int +Bprint(Biobufhdr *bp, char *fmt, ...) +{ + va_list arg; + int n; + + va_start(arg, fmt); + n = Bvprint(bp, fmt, arg); + va_end(arg); + return n; +} diff --git a/sys/src/libbio/bputc.c b/sys/src/libbio/bputc.c new file mode 100755 index 000000000..7332c29fd --- /dev/null +++ b/sys/src/libbio/bputc.c @@ -0,0 +1,21 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +int +Bputc(Biobufhdr *bp, int c) +{ + int i; + + for(;;) { + i = bp->ocount; + if(i) { + bp->ebuf[i++] = c; + bp->ocount = i; + return 0; + } + if(Bflush(bp) == Beof) + break; + } + return Beof; +} diff --git a/sys/src/libbio/bputrune.c b/sys/src/libbio/bputrune.c new file mode 100755 index 000000000..2a625bd9a --- /dev/null +++ b/sys/src/libbio/bputrune.c @@ -0,0 +1,23 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +int +Bputrune(Biobufhdr *bp, long c) +{ + Rune rune; + char str[4]; + int n; + + rune = c; + if(rune < Runeself) { + Bputc(bp, rune); + return 1; + } + n = runetochar(str, &rune); + if(n == 0) + return Bbad; + if(Bwrite(bp, str, n) != n) + return Beof; + return n; +} diff --git a/sys/src/libbio/brdline.c b/sys/src/libbio/brdline.c new file mode 100755 index 000000000..c116e3859 --- /dev/null +++ b/sys/src/libbio/brdline.c @@ -0,0 +1,95 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +void* +Brdline(Biobufhdr *bp, int delim) +{ + char *ip, *ep; + int i, j; + + i = -bp->icount; + if(i == 0) { + /* + * eof or other error + */ + if(bp->state != Bractive) { + if(bp->state == Bracteof) + bp->state = Bractive; + bp->rdline = 0; + bp->gbuf = bp->ebuf; + return 0; + } + } + + /* + * first try in remainder of buffer (gbuf doesn't change) + */ + ip = (char*)bp->ebuf - i; + ep = memchr(ip, delim, i); + if(ep) { + j = (ep - ip) + 1; + bp->rdline = j; + bp->icount += j; + return ip; + } + + /* + * copy data to beginning of buffer + */ + if(i < bp->bsize) + memmove(bp->bbuf, ip, i); + bp->gbuf = bp->bbuf; + + /* + * append to buffer looking for the delim + */ + ip = (char*)bp->bbuf + i; + while(i < bp->bsize) { + j = read(bp->fid, ip, bp->bsize-i); + if(j <= 0) { + /* + * end of file with no delim + */ + memmove(bp->ebuf-i, bp->bbuf, i); + bp->rdline = i; + bp->icount = -i; + bp->gbuf = bp->ebuf-i; + return 0; + } + bp->offset += j; + i += j; + ep = memchr(ip, delim, j); + if(ep) { + /* + * found in new piece + * copy back up and reset everything + */ + ip = (char*)bp->ebuf - i; + if(i < bp->bsize){ + memmove(ip, bp->bbuf, i); + bp->gbuf = (uchar*)ip; + } + j = (ep - (char*)bp->bbuf) + 1; + bp->rdline = j; + bp->icount = j - i; + return ip; + } + ip += j; + } + + /* + * full buffer without finding + */ + bp->rdline = bp->bsize; + bp->icount = -bp->bsize; + bp->gbuf = bp->bbuf; + return 0; +} + +int +Blinelen(Biobufhdr *bp) +{ + + return bp->rdline; +} diff --git a/sys/src/libbio/brdstr.c b/sys/src/libbio/brdstr.c new file mode 100755 index 000000000..b5727ad2a --- /dev/null +++ b/sys/src/libbio/brdstr.c @@ -0,0 +1,112 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +static char* +badd(char *p, int *np, char *data, int ndata, int delim, int nulldelim) +{ + int n; + + n = *np; + p = realloc(p, n+ndata+1); + if(p){ + memmove(p+n, data, ndata); + n += ndata; + if(n>0 && nulldelim && p[n-1]==delim) + p[--n] = '\0'; + else + p[n] = '\0'; + *np = n; + } + return p; +} + +char* +Brdstr(Biobufhdr *bp, int delim, int nulldelim) +{ + char *ip, *ep, *p; + int i, j; + + i = -bp->icount; + bp->rdline = 0; + if(i == 0) { + /* + * eof or other error + */ + if(bp->state != Bractive) { + if(bp->state == Bracteof) + bp->state = Bractive; + bp->gbuf = bp->ebuf; + return nil; + } + } + + /* + * first try in remainder of buffer (gbuf doesn't change) + */ + ip = (char*)bp->ebuf - i; + ep = memchr(ip, delim, i); + if(ep) { + j = (ep - ip) + 1; + bp->icount += j; + return badd(nil, &bp->rdline, ip, j, delim, nulldelim); + } + + /* + * copy data to beginning of buffer + */ + if(i < bp->bsize) + memmove(bp->bbuf, ip, i); + bp->gbuf = bp->bbuf; + + /* + * append to buffer looking for the delim + */ + p = nil; + for(;;){ + ip = (char*)bp->bbuf + i; + while(i < bp->bsize) { + j = read(bp->fid, ip, bp->bsize-i); + if(j <= 0 && i == 0) + return p; + if(j <= 0 && i > 0){ + /* + * end of file but no delim. pretend we got a delim + * by making the delim \0 and smashing it with nulldelim. + */ + j = 1; + ep = ip; + delim = '\0'; + nulldelim = 1; + *ep = delim; /* there will be room for this */ + }else{ + bp->offset += j; + ep = memchr(ip, delim, j); + } + i += j; + if(ep) { + /* + * found in new piece + * copy back up and reset everything + */ + ip = (char*)bp->ebuf - i; + if(i < bp->bsize){ + memmove(ip, bp->bbuf, i); + bp->gbuf = (uchar*)ip; + } + j = (ep - (char*)bp->bbuf) + 1; + bp->icount = j - i; + return badd(p, &bp->rdline, ip, j, delim, nulldelim); + } + ip += j; + } + + /* + * full buffer without finding; add to user string and continue + */ + p = badd(p, &bp->rdline, (char*)bp->bbuf, bp->bsize, 0, 0); + i = 0; + bp->icount = 0; + bp->gbuf = bp->ebuf; + } +} diff --git a/sys/src/libbio/bread.c b/sys/src/libbio/bread.c new file mode 100755 index 000000000..9780ffac1 --- /dev/null +++ b/sys/src/libbio/bread.c @@ -0,0 +1,48 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +long +Bread(Biobufhdr *bp, void *ap, long count) +{ + long c; + uchar *p; + int i, n, ic; + + p = ap; + c = count; + ic = bp->icount; + + while(c > 0) { + n = -ic; + if(n > c) + n = c; + if(n == 0) { + if(bp->state != Bractive) + break; + i = read(bp->fid, bp->bbuf, bp->bsize); + if(i <= 0) { + bp->state = Bracteof; + if(i < 0) + bp->state = Binactive; + break; + } + bp->gbuf = bp->bbuf; + bp->offset += i; + if(i < bp->bsize) { + memmove(bp->ebuf-i, bp->bbuf, i); + bp->gbuf = bp->ebuf-i; + } + ic = -i; + continue; + } + memmove(p, bp->ebuf+ic, n); + c -= n; + ic += n; + p += n; + } + bp->icount = ic; + if(count == c && bp->state == Binactive) + return -1; + return count-c; +} diff --git a/sys/src/libbio/bseek.c b/sys/src/libbio/bseek.c new file mode 100755 index 000000000..809b09323 --- /dev/null +++ b/sys/src/libbio/bseek.c @@ -0,0 +1,58 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +vlong +Bseek(Biobufhdr *bp, vlong offset, int base) +{ + vlong n, d; + + switch(bp->state) { + default: + fprint(2, "Bseek: unknown state %d\n", bp->state); + return Beof; + + case Bracteof: + bp->state = Bractive; + bp->icount = 0; + bp->gbuf = bp->ebuf; + + case Bractive: + n = offset; + if(base == 1) { + n += Boffset(bp); + base = 0; + } + + /* + * try to seek within buffer + */ + if(base == 0) { + /* + * if d is too large for an int, icount may wrap, + * so we need to ensure that icount hasn't wrapped + * and points within the buffer's valid data. + */ + d = n - Boffset(bp); + bp->icount += d; + if(d <= bp->bsize && bp->icount <= 0 && + bp->ebuf - bp->gbuf >= -bp->icount) + return n; + } + + /* + * reset the buffer + */ + n = seek(bp->fid, n, base); + bp->icount = 0; + bp->gbuf = bp->ebuf; + break; + + case Bwactive: + Bflush(bp); + n = seek(bp->fid, offset, base); + break; + } + bp->offset = n; + return n; +} diff --git a/sys/src/libbio/btestprint.c b/sys/src/libbio/btestprint.c new file mode 100755 index 000000000..69b9c5242 --- /dev/null +++ b/sys/src/libbio/btestprint.c @@ -0,0 +1,20 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +void +main(int argc, char **argv) +{ + Biobuf b; + char *s; + int n; + + + n = atoi(argv[1]); + s = malloc(n+1); + memset(s, 'a', n); + s[n] = '\0'; + Binit(&b, 1, OWRITE); + Bprint(&b, "%s\n", s); + Bflush(&b); +} diff --git a/sys/src/libbio/bvprint.c b/sys/src/libbio/bvprint.c new file mode 100755 index 000000000..4881bee9d --- /dev/null +++ b/sys/src/libbio/bvprint.c @@ -0,0 +1,37 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +static int +fmtBflush(Fmt *f) +{ + Biobufhdr *bp; + + bp = f->farg; + bp->ocount = (char*)f->to - (char*)f->stop; + if(Bflush(bp) < 0) + return 0; + f->stop = bp->ebuf; + f->to = (char*)f->stop + bp->ocount; + f->start = f->to; + return 1; +} + +int +Bvprint(Biobufhdr *bp, char *fmt, va_list arg) +{ + int n; + Fmt f; + + f.runes = 0; + f.stop = bp->ebuf; + f.start = (char*)f.stop + bp->ocount; + f.to = f.start; + f.flush = fmtBflush; + f.farg = bp; + f.nfmt = 0; + f.args = arg; + n = dofmt(&f, fmt); + bp->ocount = (char*)f.to - (char*)f.stop; + return n; +} diff --git a/sys/src/libbio/bwrite.c b/sys/src/libbio/bwrite.c new file mode 100755 index 000000000..ae7a7d97c --- /dev/null +++ b/sys/src/libbio/bwrite.c @@ -0,0 +1,43 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +long +Bwrite(Biobufhdr *bp, void *ap, long count) +{ + long c; + uchar *p; + int i, n, oc; + char errbuf[ERRMAX]; + + p = ap; + c = count; + oc = bp->ocount; + + while(c > 0) { + n = -oc; + if(n > c) + n = c; + if(n == 0) { + if(bp->state != Bwactive) + return Beof; + i = write(bp->fid, bp->bbuf, bp->bsize); + if(i != bp->bsize) { + errstr(errbuf, sizeof errbuf); + if(strstr(errbuf, "interrupt") == nil) + bp->state = Binactive; + errstr(errbuf, sizeof errbuf); + return Beof; + } + bp->offset += i; + oc = -bp->bsize; + continue; + } + memmove(bp->ebuf+oc, p, n); + oc += n; + c -= n; + p += n; + } + bp->ocount = oc; + return count-c; +} diff --git a/sys/src/libbio/mkfile b/sys/src/libbio/mkfile new file mode 100755 index 000000000..a8c21dbaa --- /dev/null +++ b/sys/src/libbio/mkfile @@ -0,0 +1,32 @@ +</$objtype/mkfile + +LIB=/$objtype/lib/libbio.a +OFILES=\ + bbuffered.$O\ + bfildes.$O\ + bflush.$O\ + bgetrune.$O\ + bgetc.$O\ + bgetd.$O\ + binit.$O\ + boffset.$O\ + bprint.$O\ + bputrune.$O\ + bputc.$O\ + brdline.$O\ + brdstr.$O\ + bread.$O\ + bseek.$O\ + bwrite.$O\ + bvprint.$O\ + +HFILES=/sys/include/bio.h + +UPDATE=\ + mkfile\ + $HFILES\ + ${OFILES:%.$O=%.c}\ + ${LIB:/$objtype/%=/386/%}\ + +</sys/src/cmd/mksyslib + |