summaryrefslogtreecommitdiff
path: root/libbio
diff options
context:
space:
mode:
Diffstat (limited to 'libbio')
-rw-r--r--libbio/NOTICE29
-rw-r--r--libbio/bbuffered.c20
-rw-r--r--libbio/bfildes.c9
-rw-r--r--libbio/bflush.c33
-rw-r--r--libbio/bgetc.c52
-rw-r--r--libbio/bgetd.c36
-rw-r--r--libbio/bgetrune.c46
-rw-r--r--libbio/binit.c142
-rw-r--r--libbio/boffset.c25
-rw-r--r--libbio/bprint.c28
-rw-r--r--libbio/bputc.c29
-rw-r--r--libbio/bputrune.c22
-rw-r--r--libbio/brdline.c94
-rw-r--r--libbio/bread.c47
-rw-r--r--libbio/bseek.c56
-rw-r--r--libbio/bwrite.c38
-rw-r--r--libbio/mkfile23
17 files changed, 729 insertions, 0 deletions
diff --git a/libbio/NOTICE b/libbio/NOTICE
new file mode 100644
index 00000000..d2099067
--- /dev/null
+++ b/libbio/NOTICE
@@ -0,0 +1,29 @@
+This copyright NOTICE applies to all files in this directory and
+subdirectories, unless another copyright notice appears in a given
+file or subdirectory. If you take substantial code from this software to use in
+other programs, you must somehow include with it an appropriate
+copyright notice that includes the copyright notice and the other
+notices below. It is fine (and often tidier) to do that in a separate
+file such as NOTICE, LICENCE or COPYING.
+
+ Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
+ Revisions Copyright © 2000-2006 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
diff --git a/libbio/bbuffered.c b/libbio/bbuffered.c
new file mode 100644
index 00000000..dfc0cf53
--- /dev/null
+++ b/libbio/bbuffered.c
@@ -0,0 +1,20 @@
+#include "lib9.h"
+#include <bio.h>
+
+int
+Bbuffered(Biobuf *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/libbio/bfildes.c b/libbio/bfildes.c
new file mode 100644
index 00000000..5188180f
--- /dev/null
+++ b/libbio/bfildes.c
@@ -0,0 +1,9 @@
+#include "lib9.h"
+#include <bio.h>
+
+int
+Bfildes(Biobuf *bp)
+{
+
+ return bp->fid;
+}
diff --git a/libbio/bflush.c b/libbio/bflush.c
new file mode 100644
index 00000000..0ab81267
--- /dev/null
+++ b/libbio/bflush.c
@@ -0,0 +1,33 @@
+#include "lib9.h"
+#include <bio.h>
+
+int
+Bflush(Biobuf *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/libbio/bgetc.c b/libbio/bgetc.c
new file mode 100644
index 00000000..4c8ae90c
--- /dev/null
+++ b/libbio/bgetc.c
@@ -0,0 +1,52 @@
+#include "lib9.h"
+#include <bio.h>
+
+int
+Bgetc(Biobuf *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) {
+ 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(Biobuf *bp)
+{
+
+ if(bp->state == Bracteof)
+ bp->state = Bractive;
+ if(bp->state != Bractive)
+ return Beof;
+ bp->icount--;
+ return 1;
+}
diff --git a/libbio/bgetd.c b/libbio/bgetd.c
new file mode 100644
index 00000000..e0bd76a7
--- /dev/null
+++ b/libbio/bgetd.c
@@ -0,0 +1,36 @@
+#include "lib9.h"
+#include <bio.h>
+
+struct bgetd
+{
+ Biobuf* 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(Biobuf *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/libbio/bgetrune.c b/libbio/bgetrune.c
new file mode 100644
index 00000000..ed216379
--- /dev/null
+++ b/libbio/bgetrune.c
@@ -0,0 +1,46 @@
+#include "lib9.h"
+#include <bio.h>
+
+long
+Bgetrune(Biobuf *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(Biobuf *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/libbio/binit.c b/libbio/binit.c
new file mode 100644
index 00000000..ecbad119
--- /dev/null
+++ b/libbio/binit.c
@@ -0,0 +1,142 @@
+#include "lib9.h"
+#include <bio.h>
+
+enum
+{
+ MAXBUFS = 20
+};
+
+static Biobuf* wbufs[MAXBUFS];
+static int atexitflag;
+
+static
+void
+batexit(void)
+{
+ Biobuf *bp;
+ int i;
+
+ for(i=0; i<nelem(wbufs); i++) {
+ bp = wbufs[i];
+ if(bp != 0) {
+ wbufs[i] = 0;
+ Bflush(bp);
+ }
+ }
+}
+
+static
+void
+deinstall(Biobuf *bp)
+{
+ int i;
+
+ for(i=0; i<nelem(wbufs); i++)
+ if(wbufs[i] == bp)
+ wbufs[i] = 0;
+}
+
+static
+void
+install(Biobuf *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(Biobuf *bp, int f, int mode, uchar *p, int size)
+{
+
+ p += Bungetsize; /* make room for Bungets */
+ size -= Bungetsize;
+
+ switch(mode) {
+ default:
+ fprint(2, "Bopen: 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) {
+ default:
+ fprint(2, "Bopen: unknown mode %d\n", mode);
+ return 0;
+
+ case OREAD:
+ f = open(name, OREAD);
+ if(f < 0)
+ return 0;
+ break;
+
+ case OWRITE:
+ f = create(name, OWRITE, 0666);
+ if(f < 0)
+ return 0;
+ }
+ bp = malloc(sizeof(Biobuf));
+ if(bp == nil)
+ return 0;
+ Binits(bp, f, mode, bp->b, sizeof(bp->b));
+ bp->flag = Bmagic;
+ return bp;
+}
+
+int
+Bterm(Biobuf *bp)
+{
+
+ deinstall(bp);
+ Bflush(bp);
+ if(bp->flag == Bmagic) {
+ bp->flag = 0;
+ close(bp->fid);
+ free(bp);
+ }
+ return 0;
+}
diff --git a/libbio/boffset.c b/libbio/boffset.c
new file mode 100644
index 00000000..72ce34cf
--- /dev/null
+++ b/libbio/boffset.c
@@ -0,0 +1,25 @@
+#include "lib9.h"
+#include <bio.h>
+
+long
+Boffset(Biobuf *bp)
+{
+ long 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/libbio/bprint.c b/libbio/bprint.c
new file mode 100644
index 00000000..6e21e444
--- /dev/null
+++ b/libbio/bprint.c
@@ -0,0 +1,28 @@
+#include "lib9.h"
+#include <bio.h>
+
+int
+Bprint(Biobuf *bp, char *fmt, ...)
+{
+ va_list ap;
+ char *ip, *ep, *out;
+ int n;
+
+ ep = (char*)bp->ebuf;
+ ip = ep + bp->ocount;
+ va_start(ap, fmt);
+ out = vseprint(ip, ep, fmt, ap);
+ va_end(ap);
+ if(out == nil || out >= ep-5) {
+ Bflush(bp);
+ ip = ep + bp->ocount;
+ va_start(ap, fmt);
+ out = vseprint(ip, ep, fmt, ap);
+ va_end(ap);
+ if(out >= ep-5)
+ return Beof;
+ }
+ n = out-ip;
+ bp->ocount += n;
+ return n;
+}
diff --git a/libbio/bputc.c b/libbio/bputc.c
new file mode 100644
index 00000000..5f0fba59
--- /dev/null
+++ b/libbio/bputc.c
@@ -0,0 +1,29 @@
+#include "lib9.h"
+#include <bio.h>
+
+int
+Bputc(Biobuf *bp, int c)
+{
+ int i, j;
+
+loop:
+ i = bp->ocount;
+ j = i+1;
+ if(i != 0) {
+ bp->ocount = j;
+ bp->ebuf[i] = c;
+ return 0;
+ }
+ if(bp->state != Bwactive)
+ return Beof;
+ j = write(bp->fid, bp->bbuf, bp->bsize);
+ if(j == bp->bsize) {
+ bp->ocount = -bp->bsize;
+ bp->offset += j;
+ goto loop;
+ }
+ fprint(2, "Bputc: write error\n");
+ bp->state = Binactive;
+ bp->ocount = 0;
+ return Beof;
+}
diff --git a/libbio/bputrune.c b/libbio/bputrune.c
new file mode 100644
index 00000000..a864541d
--- /dev/null
+++ b/libbio/bputrune.c
@@ -0,0 +1,22 @@
+#include "lib9.h"
+#include <bio.h>
+
+int
+Bputrune(Biobuf *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/libbio/brdline.c b/libbio/brdline.c
new file mode 100644
index 00000000..e25c0314
--- /dev/null
+++ b/libbio/brdline.c
@@ -0,0 +1,94 @@
+#include "lib9.h"
+#include <bio.h>
+
+void*
+Brdline(Biobuf *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(Biobuf *bp)
+{
+
+ return bp->rdline;
+}
diff --git a/libbio/bread.c b/libbio/bread.c
new file mode 100644
index 00000000..c92482ca
--- /dev/null
+++ b/libbio/bread.c
@@ -0,0 +1,47 @@
+#include "lib9.h"
+#include <bio.h>
+
+long
+Bread(Biobuf *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/libbio/bseek.c b/libbio/bseek.c
new file mode 100644
index 00000000..9e68f5ea
--- /dev/null
+++ b/libbio/bseek.c
@@ -0,0 +1,56 @@
+#include "lib9.h"
+#include <bio.h>
+
+long
+Bseek(Biobuf *bp, long offset, int base)
+{
+ long 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) {
+ d = n - Boffset(bp);
+ bp->icount += d;
+ if(d >= 0) {
+ if(bp->icount <= 0)
+ return n;
+ } else {
+ if(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/libbio/bwrite.c b/libbio/bwrite.c
new file mode 100644
index 00000000..87256fd0
--- /dev/null
+++ b/libbio/bwrite.c
@@ -0,0 +1,38 @@
+#include "lib9.h"
+#include <bio.h>
+
+long
+Bwrite(Biobuf *bp, void *ap, long count)
+{
+ long c;
+ uchar *p;
+ int i, n, oc;
+
+ 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) {
+ bp->state = Binactive;
+ 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/libbio/mkfile b/libbio/mkfile
new file mode 100644
index 00000000..e9afe025
--- /dev/null
+++ b/libbio/mkfile
@@ -0,0 +1,23 @@
+<../mkconfig
+
+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\
+ bread.$O\
+ bseek.$O\
+ bwrite.$O\
+
+HFILES= $ROOT/include/bio.h
+
+<$ROOT/mkfiles/mksyslib-$SHELLTYPE