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