diff options
author | Rob Pike <r@golang.org> | 2008-11-11 17:28:36 -0800 |
---|---|---|
committer | Rob Pike <r@golang.org> | 2008-11-11 17:28:36 -0800 |
commit | 212f618ae91f83be99602e1483eadbf63f69d8e3 (patch) | |
tree | da7e2f69ce406cbf95781c7a1f356950339fca7b | |
parent | ca38a24d87d119b70ad2d531ddfc12add31c39b7 (diff) | |
download | golang-212f618ae91f83be99602e1483eadbf63f69d8e3.tar.gz |
Implement a "full reader" wrapper for io.Read, guaranteeing that
either the buffer is full, zero bytes were read, or an error is returned.
R=rsc
DELTA=44 (42 added, 0 deleted, 2 changed)
OCL=19027
CL=19047
-rw-r--r-- | src/lib/io.go | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/src/lib/io.go b/src/lib/io.go index 20b7b9029..44d072caa 100644 --- a/src/lib/io.go +++ b/src/lib/io.go @@ -3,8 +3,13 @@ // license that can be found in the LICENSE file. package io -import os "os" -import syscall "syscall" + +import ( + "os"; + "syscall"; +) + +export var ErrEOF = os.NewError("EOF") export type Read interface { Read(p *[]byte) (n int, err *os.Error); @@ -34,3 +39,40 @@ export func WriteString(w Write, s string) (n int, err *os.Error) { r, e := w.Write(b[0:len(s)]); return r, e } + +// Read until buffer is full, EOF, or error +export func Readn(fd Read, buf *[]byte) (n int, err *os.Error) { + n = 0; + for n < len(buf) { + nn, e := fd.Read(buf[n:len(buf)]); + if nn > 0 { + n += nn + } + if e != nil { + return n, e + } + if nn <= 0 { + return n, ErrEOF // no error but insufficient data + } + } + return n, nil +} + +// Convert something that implements Read into something +// whose Reads are always Readn +type FullRead struct { + fd Read; +} + +func (fd *FullRead) Read(p *[]byte) (n int, err *os.Error) { + n, err = Readn(fd, p); + return n, err +} + +export func MakeFullReader(fd Read) Read { + if fr, ok := fd.(*FullRead); ok { + // already a FullRead + return fd + } + return &FullRead{fd} +} |