github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/gnovm/tests/files/issue_558b.gno (about) 1 package main 2 3 import ( 4 "fmt" 5 "io" 6 "io" 7 "log" 8 "strings" 9 ) 10 11 type readAutoCloser struct { 12 r io.ReadCloser 13 } 14 15 func (a readAutoCloser) Read(b []byte) (n int, err error) { 16 if a.r == nil { 17 return 0, io.EOF 18 } 19 n, err = a.r.Read(b) 20 if err == io.EOF { 21 a.Close() 22 } 23 return n, err 24 } 25 26 func (a readAutoCloser) Close() error { 27 if a.r == nil { 28 return nil 29 } 30 return a.r.(io.Closer).Close() 31 } 32 33 type pipe struct { 34 Reader readAutoCloser 35 } 36 37 func newReadAutoCloser(r io.Reader) readAutoCloser { 38 if _, ok := r.(io.Closer); !ok { 39 return readAutoCloser{io.NopCloser(r)} 40 } 41 return readAutoCloser{r.(io.ReadCloser)} 42 } 43 44 type Reader interface { 45 Read(b []byte) (n int, err error) 46 } 47 48 func ReadAll(r Reader) ([]byte, error) { 49 b := make([]byte, 0, 512) 50 for { 51 if len(b) == cap(b) { 52 // Add more capacity (let append pick how much). 53 b = append(b, 0)[:len(b)] 54 } 55 n, err := r.Read(b[len(b):cap(b)]) 56 b = b[:len(b)+n] 57 if err != nil { 58 if err == io.EOF { 59 err = nil 60 } 61 return b, err 62 } 63 } 64 } 65 66 func main() { 67 p := &pipe{} 68 p.Reader = newReadAutoCloser(strings.NewReader("test")) 69 b, err := ReadAll(p.Reader) 70 if err != nil { 71 log.Fatal(err) 72 } 73 fmt.Println(string(b)) 74 } 75 76 // Output: 77 // test