]> Cypherpunks repositories - gostls13.git/commitdiff
Implement a "full reader" wrapper for io.Read, guaranteeing that
authorRob Pike <r@golang.org>
Wed, 12 Nov 2008 01:28:36 +0000 (17:28 -0800)
committerRob Pike <r@golang.org>
Wed, 12 Nov 2008 01:28:36 +0000 (17:28 -0800)
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

src/lib/io.go

index 20b7b90292262d15add8a7d5d3c0a2cf838b4958..44d072caa9b73f7b19b0905f8dee5298fbea681e 100644 (file)
@@ -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}
+}