Commit bb7b1a11 authored by Rob Pike's avatar Rob Pike

bufio: drop error return for NewReaderSize and NewWriterSize

It complicates the interface unnecessarily.
Document this in go1.html.
Also update the go/doc Makefile.

Fixes #2836.

R=golang-dev, gri, bradfitz
CC=golang-dev
https://golang.org/cl/5642054
parent 518ee115
...@@ -2,12 +2,6 @@ ...@@ -2,12 +2,6 @@
# Use of this source code is governed by a BSD-style # Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file. # license that can be found in the LICENSE file.
include ../src/Make.inc
TARG=tmpltohtml
GOFILES=\
tmpltohtml.go\
HTML=\ HTML=\
articles/defer_panic_recover.html\ articles/defer_panic_recover.html\
articles/error_handling.html\ articles/error_handling.html\
...@@ -18,7 +12,8 @@ HTML=\ ...@@ -18,7 +12,8 @@ HTML=\
all: tmpltohtml $(HTML) all: tmpltohtml $(HTML)
tmpltohtml: tmpltohtml.go
go build tmpltohtml.go
%.html: %.tmpl tmpltohtml %.html: %.tmpl tmpltohtml
./makehtml $*.tmpl ./makehtml $*.tmpl
include ../src/Make.cmd
...@@ -863,6 +863,22 @@ few programs beyond the need to run <code>go fix</code>. ...@@ -863,6 +863,22 @@ few programs beyond the need to run <code>go fix</code>.
This category includes packages that are new in Go 1. This category includes packages that are new in Go 1.
</p> </p>
<h3 id="bufio">The bufio package</h3>
<p>
In Go 1, <a href="/pkg/bufio/#NewReaderSize"><code>bufio.NewReaderSize</code></a>
and
<a href="/pkg/bufio/#NewWriterSize"><code>bufio.NewWriterSize</code></a>
functions no longer return an error for invalid sizes.
If the argument size is too small or invalid, it is adjusted.
</p>
<p>
<em>Updating</em>:
These functions are rarely used, and code must be updated by hand.
All that is required is to drop the second return value.
</p>
<h3 id="crypto_elliptic">The crypto/elliptic package</h3> <h3 id="crypto_elliptic">The crypto/elliptic package</h3>
<p> <p>
......
...@@ -767,6 +767,22 @@ few programs beyond the need to run <code>go fix</code>. ...@@ -767,6 +767,22 @@ few programs beyond the need to run <code>go fix</code>.
This category includes packages that are new in Go 1. This category includes packages that are new in Go 1.
</p> </p>
<h3 id="bufio">The bufio package</h3>
<p>
In Go 1, <a href="/pkg/bufio/#NewReaderSize"><code>bufio.NewReaderSize</code></a>
and
<a href="/pkg/bufio/#NewWriterSize"><code>bufio.NewWriterSize</code></a>
functions no longer return an error for invalid sizes.
If the argument size is too small or invalid, it is adjusted.
</p>
<p>
<em>Updating</em>:
These functions are rarely used, and code must be updated by hand.
All that is required is to drop the second return value.
</p>
<h3 id="crypto_elliptic">The crypto/elliptic package</h3> <h3 id="crypto_elliptic">The crypto/elliptic package</h3>
<p> <p>
......
...@@ -11,7 +11,6 @@ import ( ...@@ -11,7 +11,6 @@ import (
"bytes" "bytes"
"errors" "errors"
"io" "io"
"strconv"
"unicode/utf8" "unicode/utf8"
) )
...@@ -27,13 +26,6 @@ var ( ...@@ -27,13 +26,6 @@ var (
errInternal = errors.New("bufio: internal error") errInternal = errors.New("bufio: internal error")
) )
// BufSizeError is the error representing an invalid buffer size.
type BufSizeError int
func (b BufSizeError) Error() string {
return "bufio: bad buffer size " + strconv.Itoa(int(b))
}
// Buffered input. // Buffered input.
// Reader implements buffering for an io.Reader object. // Reader implements buffering for an io.Reader object.
...@@ -48,35 +40,29 @@ type Reader struct { ...@@ -48,35 +40,29 @@ type Reader struct {
const minReadBufferSize = 16 const minReadBufferSize = 16
// NewReaderSize creates a new Reader whose buffer has the specified size, // NewReaderSize returns a new Reader whose buffer has at least the specified
// which must be at least 16 bytes. If the argument io.Reader is already a // size. If the argument io.Reader is already a Reader with large enough
// Reader with large enough size, it returns the underlying Reader. // size, it returns the underlying Reader.
// It returns the Reader and any error. func NewReaderSize(rd io.Reader, size int) *Reader {
func NewReaderSize(rd io.Reader, size int) (*Reader, error) {
if size < minReadBufferSize {
return nil, BufSizeError(size)
}
// Is it already a Reader? // Is it already a Reader?
b, ok := rd.(*Reader) b, ok := rd.(*Reader)
if ok && len(b.buf) >= size { if ok && len(b.buf) >= size {
return b, nil return b
}
if size < minReadBufferSize {
size = minReadBufferSize
}
return &Reader{
buf: make([]byte, size),
rd: rd,
lastByte: -1,
lastRuneSize: -1,
} }
b = new(Reader)
b.buf = make([]byte, size)
b.rd = rd
b.lastByte = -1
b.lastRuneSize = -1
return b, nil
} }
// NewReader returns a new Reader whose buffer has the default size. // NewReader returns a new Reader whose buffer has the default size.
func NewReader(rd io.Reader) *Reader { func NewReader(rd io.Reader) *Reader {
b, err := NewReaderSize(rd, defaultBufSize) return NewReaderSize(rd, defaultBufSize)
if err != nil {
// cannot happen - defaultBufSize is a valid size
panic(err)
}
return b
} }
// fill reads a new chunk into the buffer. // fill reads a new chunk into the buffer.
...@@ -396,33 +382,27 @@ type Writer struct { ...@@ -396,33 +382,27 @@ type Writer struct {
wr io.Writer wr io.Writer
} }
// NewWriterSize creates a new Writer whose buffer has the specified size, // NewWriterSize returns a new Writer whose buffer has at least the specified
// which must be greater than zero. If the argument io.Writer is already a // size. If the argument io.Writer is already a Writer with large enough
// Writer with large enough size, it returns the underlying Writer. // size, it returns the underlying Writer.
// It returns the Writer and any error. func NewWriterSize(wr io.Writer, size int) *Writer {
func NewWriterSize(wr io.Writer, size int) (*Writer, error) {
if size <= 0 {
return nil, BufSizeError(size)
}
// Is it already a Writer? // Is it already a Writer?
b, ok := wr.(*Writer) b, ok := wr.(*Writer)
if ok && len(b.buf) >= size { if ok && len(b.buf) >= size {
return b, nil return b
}
if size <= 0 {
size = defaultBufSize
} }
b = new(Writer) b = new(Writer)
b.buf = make([]byte, size) b.buf = make([]byte, size)
b.wr = wr b.wr = wr
return b, nil return b
} }
// NewWriter returns a new Writer whose buffer has the default size. // NewWriter returns a new Writer whose buffer has the default size.
func NewWriter(wr io.Writer) *Writer { func NewWriter(wr io.Writer) *Writer {
b, err := NewWriterSize(wr, defaultBufSize) return NewWriterSize(wr, defaultBufSize)
if err != nil {
// cannot happen - defaultBufSize is valid size
panic(err)
}
return b
} }
// Flush writes any buffered data to the underlying io.Writer. // Flush writes any buffered data to the underlying io.Writer.
......
...@@ -161,7 +161,7 @@ func TestReader(t *testing.T) { ...@@ -161,7 +161,7 @@ func TestReader(t *testing.T) {
bufreader := bufreaders[j] bufreader := bufreaders[j]
bufsize := bufsizes[k] bufsize := bufsizes[k]
read := readmaker.fn(bytes.NewBufferString(text)) read := readmaker.fn(bytes.NewBufferString(text))
buf, _ := NewReaderSize(read, bufsize) buf := NewReaderSize(read, bufsize)
s := bufreader.fn(buf) s := bufreader.fn(buf)
if s != text { if s != text {
t.Errorf("reader=%s fn=%s bufsize=%d want=%q got=%q", t.Errorf("reader=%s fn=%s bufsize=%d want=%q got=%q",
...@@ -379,18 +379,14 @@ func TestWriter(t *testing.T) { ...@@ -379,18 +379,14 @@ func TestWriter(t *testing.T) {
// and that the data is correct. // and that the data is correct.
w.Reset() w.Reset()
buf, e := NewWriterSize(w, bs) buf := NewWriterSize(w, bs)
context := fmt.Sprintf("nwrite=%d bufsize=%d", nwrite, bs) context := fmt.Sprintf("nwrite=%d bufsize=%d", nwrite, bs)
if e != nil {
t.Errorf("%s: NewWriterSize %d: %v", context, bs, e)
continue
}
n, e1 := buf.Write(data[0:nwrite]) n, e1 := buf.Write(data[0:nwrite])
if e1 != nil || n != nwrite { if e1 != nil || n != nwrite {
t.Errorf("%s: buf.Write %d = %d, %v", context, nwrite, n, e1) t.Errorf("%s: buf.Write %d = %d, %v", context, nwrite, n, e1)
continue continue
} }
if e = buf.Flush(); e != nil { if e := buf.Flush(); e != nil {
t.Errorf("%s: buf.Flush = %v", context, e) t.Errorf("%s: buf.Flush = %v", context, e)
} }
...@@ -447,23 +443,14 @@ func TestWriteErrors(t *testing.T) { ...@@ -447,23 +443,14 @@ func TestWriteErrors(t *testing.T) {
func TestNewReaderSizeIdempotent(t *testing.T) { func TestNewReaderSizeIdempotent(t *testing.T) {
const BufSize = 1000 const BufSize = 1000
b, err := NewReaderSize(bytes.NewBufferString("hello world"), BufSize) b := NewReaderSize(bytes.NewBufferString("hello world"), BufSize)
if err != nil {
t.Error("NewReaderSize create fail", err)
}
// Does it recognize itself? // Does it recognize itself?
b1, err2 := NewReaderSize(b, BufSize) b1 := NewReaderSize(b, BufSize)
if err2 != nil {
t.Error("NewReaderSize #2 create fail", err2)
}
if b1 != b { if b1 != b {
t.Error("NewReaderSize did not detect underlying Reader") t.Error("NewReaderSize did not detect underlying Reader")
} }
// Does it wrap if existing buffer is too small? // Does it wrap if existing buffer is too small?
b2, err3 := NewReaderSize(b, 2*BufSize) b2 := NewReaderSize(b, 2*BufSize)
if err3 != nil {
t.Error("NewReaderSize #3 create fail", err3)
}
if b2 == b { if b2 == b {
t.Error("NewReaderSize did not enlarge buffer") t.Error("NewReaderSize did not enlarge buffer")
} }
...@@ -471,23 +458,14 @@ func TestNewReaderSizeIdempotent(t *testing.T) { ...@@ -471,23 +458,14 @@ func TestNewReaderSizeIdempotent(t *testing.T) {
func TestNewWriterSizeIdempotent(t *testing.T) { func TestNewWriterSizeIdempotent(t *testing.T) {
const BufSize = 1000 const BufSize = 1000
b, err := NewWriterSize(new(bytes.Buffer), BufSize) b := NewWriterSize(new(bytes.Buffer), BufSize)
if err != nil {
t.Error("NewWriterSize create fail", err)
}
// Does it recognize itself? // Does it recognize itself?
b1, err2 := NewWriterSize(b, BufSize) b1 := NewWriterSize(b, BufSize)
if err2 != nil {
t.Error("NewWriterSize #2 create fail", err2)
}
if b1 != b { if b1 != b {
t.Error("NewWriterSize did not detect underlying Writer") t.Error("NewWriterSize did not detect underlying Writer")
} }
// Does it wrap if existing buffer is too small? // Does it wrap if existing buffer is too small?
b2, err3 := NewWriterSize(b, 2*BufSize) b2 := NewWriterSize(b, 2*BufSize)
if err3 != nil {
t.Error("NewWriterSize #3 create fail", err3)
}
if b2 == b { if b2 == b {
t.Error("NewWriterSize did not enlarge buffer") t.Error("NewWriterSize did not enlarge buffer")
} }
...@@ -496,10 +474,7 @@ func TestNewWriterSizeIdempotent(t *testing.T) { ...@@ -496,10 +474,7 @@ func TestNewWriterSizeIdempotent(t *testing.T) {
func TestWriteString(t *testing.T) { func TestWriteString(t *testing.T) {
const BufSize = 8 const BufSize = 8
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
b, err := NewWriterSize(buf, BufSize) b := NewWriterSize(buf, BufSize)
if err != nil {
t.Error("NewWriterSize create fail", err)
}
b.WriteString("0") // easy b.WriteString("0") // easy
b.WriteString("123456") // still easy b.WriteString("123456") // still easy
b.WriteString("7890") // easy after flush b.WriteString("7890") // easy after flush
...@@ -516,10 +491,7 @@ func TestWriteString(t *testing.T) { ...@@ -516,10 +491,7 @@ func TestWriteString(t *testing.T) {
func TestBufferFull(t *testing.T) { func TestBufferFull(t *testing.T) {
const longString = "And now, hello, world! It is the time for all good men to come to the aid of their party" const longString = "And now, hello, world! It is the time for all good men to come to the aid of their party"
buf, err := NewReaderSize(strings.NewReader(longString), minReadBufferSize) buf := NewReaderSize(strings.NewReader(longString), minReadBufferSize)
if err != nil {
t.Fatal("NewReaderSize:", err)
}
line, err := buf.ReadSlice('!') line, err := buf.ReadSlice('!')
if string(line) != "And now, hello, " || err != ErrBufferFull { if string(line) != "And now, hello, " || err != ErrBufferFull {
t.Errorf("first ReadSlice(,) = %q, %v", line, err) t.Errorf("first ReadSlice(,) = %q, %v", line, err)
...@@ -533,7 +505,7 @@ func TestBufferFull(t *testing.T) { ...@@ -533,7 +505,7 @@ func TestBufferFull(t *testing.T) {
func TestPeek(t *testing.T) { func TestPeek(t *testing.T) {
p := make([]byte, 10) p := make([]byte, 10)
// string is 16 (minReadBufferSize) long. // string is 16 (minReadBufferSize) long.
buf, _ := NewReaderSize(strings.NewReader("abcdefghijklmnop"), minReadBufferSize) buf := NewReaderSize(strings.NewReader("abcdefghijklmnop"), minReadBufferSize)
if s, err := buf.Peek(1); string(s) != "a" || err != nil { if s, err := buf.Peek(1); string(s) != "a" || err != nil {
t.Fatalf("want %q got %q, err=%v", "a", string(s), err) t.Fatalf("want %q got %q, err=%v", "a", string(s), err)
} }
...@@ -609,7 +581,7 @@ func testReadLine(t *testing.T, input []byte) { ...@@ -609,7 +581,7 @@ func testReadLine(t *testing.T, input []byte) {
for stride := 1; stride < 2; stride++ { for stride := 1; stride < 2; stride++ {
done := 0 done := 0
reader := testReader{input, stride} reader := testReader{input, stride}
l, _ := NewReaderSize(&reader, len(input)+1) l := NewReaderSize(&reader, len(input)+1)
for { for {
line, isPrefix, err := l.ReadLine() line, isPrefix, err := l.ReadLine()
if len(line) > 0 && err != nil { if len(line) > 0 && err != nil {
...@@ -646,7 +618,7 @@ func TestLineTooLong(t *testing.T) { ...@@ -646,7 +618,7 @@ func TestLineTooLong(t *testing.T) {
data = append(data, '0'+byte(i%10)) data = append(data, '0'+byte(i%10))
} }
buf := bytes.NewBuffer(data) buf := bytes.NewBuffer(data)
l, _ := NewReaderSize(buf, minReadBufferSize) l := NewReaderSize(buf, minReadBufferSize)
line, isPrefix, err := l.ReadLine() line, isPrefix, err := l.ReadLine()
if !isPrefix || !bytes.Equal(line, data[:minReadBufferSize]) || err != nil { if !isPrefix || !bytes.Equal(line, data[:minReadBufferSize]) || err != nil {
t.Errorf("bad result for first line: got %q want %q %v", line, data[:minReadBufferSize], err) t.Errorf("bad result for first line: got %q want %q %v", line, data[:minReadBufferSize], err)
...@@ -673,7 +645,7 @@ func TestReadAfterLines(t *testing.T) { ...@@ -673,7 +645,7 @@ func TestReadAfterLines(t *testing.T) {
inbuf := bytes.NewBuffer([]byte(line1 + "\n" + restData)) inbuf := bytes.NewBuffer([]byte(line1 + "\n" + restData))
outbuf := new(bytes.Buffer) outbuf := new(bytes.Buffer)
maxLineLength := len(line1) + len(restData)/2 maxLineLength := len(line1) + len(restData)/2
l, _ := NewReaderSize(inbuf, maxLineLength) l := NewReaderSize(inbuf, maxLineLength)
line, isPrefix, err := l.ReadLine() line, isPrefix, err := l.ReadLine()
if isPrefix || err != nil || string(line) != line1 { if isPrefix || err != nil || string(line) != line1 {
t.Errorf("bad result for first line: isPrefix=%v err=%v line=%q", isPrefix, err, string(line)) t.Errorf("bad result for first line: isPrefix=%v err=%v line=%q", isPrefix, err, string(line))
...@@ -688,7 +660,7 @@ func TestReadAfterLines(t *testing.T) { ...@@ -688,7 +660,7 @@ func TestReadAfterLines(t *testing.T) {
} }
func TestReadEmptyBuffer(t *testing.T) { func TestReadEmptyBuffer(t *testing.T) {
l, _ := NewReaderSize(new(bytes.Buffer), minReadBufferSize) l := NewReaderSize(new(bytes.Buffer), minReadBufferSize)
line, isPrefix, err := l.ReadLine() line, isPrefix, err := l.ReadLine()
if err != io.EOF { if err != io.EOF {
t.Errorf("expected EOF from ReadLine, got '%s' %t %s", line, isPrefix, err) t.Errorf("expected EOF from ReadLine, got '%s' %t %s", line, isPrefix, err)
...@@ -696,7 +668,7 @@ func TestReadEmptyBuffer(t *testing.T) { ...@@ -696,7 +668,7 @@ func TestReadEmptyBuffer(t *testing.T) {
} }
func TestLinesAfterRead(t *testing.T) { func TestLinesAfterRead(t *testing.T) {
l, _ := NewReaderSize(bytes.NewBuffer([]byte("foo")), minReadBufferSize) l := NewReaderSize(bytes.NewBuffer([]byte("foo")), minReadBufferSize)
_, err := ioutil.ReadAll(l) _, err := ioutil.ReadAll(l)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
...@@ -752,10 +724,7 @@ func TestReadLineNewlines(t *testing.T) { ...@@ -752,10 +724,7 @@ func TestReadLineNewlines(t *testing.T) {
} }
func testReadLineNewlines(t *testing.T, input string, expect []readLineResult) { func testReadLineNewlines(t *testing.T, input string, expect []readLineResult) {
b, err := NewReaderSize(strings.NewReader(input), minReadBufferSize) b := NewReaderSize(strings.NewReader(input), minReadBufferSize)
if err != nil {
t.Fatal(err)
}
for i, e := range expect { for i, e := range expect {
line, isPrefix, err := b.ReadLine() line, isPrefix, err := b.ReadLine()
if bytes.Compare(line, e.line) != 0 { if bytes.Compare(line, e.line) != 0 {
......
...@@ -408,10 +408,7 @@ func (e *encoder) writeIDATs() { ...@@ -408,10 +408,7 @@ func (e *encoder) writeIDATs() {
return return
} }
var bw *bufio.Writer var bw *bufio.Writer
bw, e.err = bufio.NewWriterSize(e, 1<<15) bw = bufio.NewWriterSize(e, 1<<15)
if e.err != nil {
return
}
e.err = writeImage(bw, e.m, e.cb) e.err = writeImage(bw, e.m, e.cb)
if e.err != nil { if e.err != nil {
return return
......
...@@ -217,7 +217,7 @@ func (h *Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { ...@@ -217,7 +217,7 @@ func (h *Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
defer cmd.Wait() defer cmd.Wait()
defer stdoutRead.Close() defer stdoutRead.Close()
linebody, _ := bufio.NewReaderSize(stdoutRead, 1024) linebody := bufio.NewReaderSize(stdoutRead, 1024)
headers := make(http.Header) headers := make(http.Header)
statusCode := 0 statusCode := 0
for { for {
......
...@@ -240,7 +240,7 @@ func (w *bufWriter) Close() error { ...@@ -240,7 +240,7 @@ func (w *bufWriter) Close() error {
func newWriter(c *conn, recType recType, reqId uint16) *bufWriter { func newWriter(c *conn, recType recType, reqId uint16) *bufWriter {
s := &streamWriter{c: c, recType: recType, reqId: reqId} s := &streamWriter{c: c, recType: recType, reqId: reqId}
w, _ := bufio.NewWriterSize(s, maxWrite) w := bufio.NewWriterSize(s, maxWrite)
return &bufWriter{s, w} return &bufWriter{s, w}
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment