add io.ByteReader.
add testing/iotest package.
make bufio return error on short write.

R=r
DELTA=423  (208 added, 154 deleted, 61 changed)
OCL=28997
CL=28999
diff --git a/src/lib/io/bytebuffer.go b/src/lib/io/bytebuffer.go
index c862818..921ddb1 100644
--- a/src/lib/io/bytebuffer.go
+++ b/src/lib/io/bytebuffer.go
@@ -42,13 +42,17 @@
 // Truncate discards all but the first n unread bytes from the buffer.
 // It is an error to call b.Truncate(n) with n > b.Len().
 func (b *ByteBuffer) Truncate(n int) {
+	if n == 0 {
+		// Reuse buffer space.
+		b.off = 0;
+	}
 	b.buf = b.buf[0 : b.off + n];
 }
 
 // Reset resets the buffer so it has no content.
 // b.Reset() is the same as b.Truncate(0).
 func (b *ByteBuffer) Reset() {
-	b.buf = b.buf[0 : b.off];
+	b.Truncate(0);
 }
 
 // Write appends the contents of p to the buffer.  The return
diff --git a/src/lib/io/io.go b/src/lib/io/io.go
index 70c82d5..91b6ffd 100644
--- a/src/lib/io/io.go
+++ b/src/lib/io/io.go
@@ -185,3 +185,29 @@
 	}
 	return written, err
 }
+
+// A ByteReader satisfies Reads by consuming data from a slice of bytes.
+// Clients can call NewByteReader to create one or wrap pointers
+// to their own slices: r := ByteReader{&data}.
+type ByteReader struct {
+	Data *[]byte
+}
+
+func (r ByteReader) Read(p []byte) (int, os.Error) {
+	n := len(p);
+	b := r.Data;
+	if n > len(b) {
+		n = len(b);
+	}
+	for i := 0; i < n; i++ {
+		p[i] = b[i];
+	}
+	*b = b[n:len(b)];
+	return n, nil;
+}
+
+// NewByteReader returns a new ByteReader reading from data.
+func NewByteReader(data []byte) ByteReader {
+	return ByteReader{ &data };
+}
+