Skip to content

Commit

Permalink
io: add an Err field to LimitedReader
Browse files Browse the repository at this point in the history
Fixes golang#51115

Change-Id: I3c5296e4adc71c1c1b1808a45abd4801ae43465a
GitHub-Last-Rev: 4c197ac
GitHub-Pull-Request: golang#51990
Reviewed-on: https://go-review.googlesource.com/c/go/+/396215
Reviewed-by: Dmitri Shuralyov <[email protected]>
TryBot-Result: Gopher Robot <[email protected]>
Run-TryBot: Ian Lance Taylor <[email protected]>
Run-TryBot: Ian Lance Taylor <[email protected]>
Auto-Submit: Ian Lance Taylor <[email protected]>
Reviewed-by: Ian Lance Taylor <[email protected]>
  • Loading branch information
earthboundkid authored and gopherbot committed May 4, 2022
1 parent 037b209 commit fd6ef06
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 5 deletions.
1 change: 1 addition & 0 deletions api/next/51115.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pkg io, type LimitedReader struct, Err error #51115
14 changes: 14 additions & 0 deletions src/io/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package io_test

import (
"bytes"
"errors"
"fmt"
"io"
"log"
Expand Down Expand Up @@ -283,3 +284,16 @@ func ExampleReadAll() {
// Output:
// Go is a general-purpose language designed with systems programming in mind.
}

func ExampleLimitedReader() {
r := strings.NewReader("some io.Reader stream to be read\n")
sentinel := errors.New("reached read limit")
lr := &io.LimitedReader{R: r, N: 4, Err: sentinel}

if _, err := io.Copy(os.Stdout, lr); err != sentinel {
log.Fatal(err)
}

// Output:
// some
}
16 changes: 11 additions & 5 deletions src/io/io.go
Original file line number Diff line number Diff line change
Expand Up @@ -455,20 +455,26 @@ func copyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) {
// LimitReader returns a Reader that reads from r
// but stops with EOF after n bytes.
// The underlying implementation is a *LimitedReader.
func LimitReader(r Reader, n int64) Reader { return &LimitedReader{r, n} }
func LimitReader(r Reader, n int64) Reader { return &LimitedReader{r, n, nil} }

// A LimitedReader reads from R but limits the amount of
// data returned to just N bytes. Each call to Read
// updates N to reflect the new amount remaining.
// Read returns EOF when N <= 0 or when the underlying R returns EOF.
// Read returns Err when N <= 0.
// If Err is nil, it returns EOF instead.
type LimitedReader struct {
R Reader // underlying reader
N int64 // max bytes remaining
R Reader // underlying reader
N int64 // max bytes remaining
Err error // error to return on reaching the limit
}

func (l *LimitedReader) Read(p []byte) (n int, err error) {
if l.N <= 0 {
return 0, EOF
err := l.Err
if err == nil {
err = EOF
}
return 0, err
}
if int64(len(p)) > l.N {
p = p[0:l.N]
Expand Down

0 comments on commit fd6ef06

Please sign in to comment.