mirror of
https://github.com/golang/go
synced 2024-11-22 23:50:03 -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:
parent
b682f924d7
commit
6ee7fe5808
@ -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}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user