1
0
mirror of https://github.com/golang/go synced 2024-11-23 07:00:05 -07:00

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
This commit is contained in:
Rob Pike 2008-11-11 17:28:36 -08:00
parent b682f924d7
commit 6ee7fe5808

View File

@ -3,8 +3,13 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package io package io
import os "os"
import syscall "syscall" import (
"os";
"syscall";
)
export var ErrEOF = os.NewError("EOF")
export type Read interface { export type Read interface {
Read(p *[]byte) (n int, err *os.Error); 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)]); r, e := w.Write(b[0:len(s)]);
return r, e 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}
}