Commit 6ee7fe58 authored by Rob Pike's avatar Rob Pike

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
parent b682f924
......@@ -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}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment