From ee19695cfc62f965a0586dc84719121feee8859e Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Mon, 6 Apr 2009 21:42:14 -0700 Subject: [PATCH] make NewBufRead etc. idempotent R=rsc DELTA=63 (59 added, 0 deleted, 4 changed) OCL=27143 CL=27143 --- src/lib/bufio.go | 20 ++++++++++++++---- src/lib/bufio_test.go | 47 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/src/lib/bufio.go b/src/lib/bufio.go index ab70b68dd0..3bc2d3de03 100644 --- a/src/lib/bufio.go +++ b/src/lib/bufio.go @@ -54,12 +54,18 @@ type BufRead struct { } // NewBufReadSize creates a new BufRead whose buffer has the specified size, -// which must be greater than zero. +// which must be greater than zero. If the argument io.Read is already a +// BufRead with large enough size, it returns the underlying BufRead. // It returns the BufRead and any error. -func NewBufReadSize(rd io.Read, size int) (b *BufRead, err *os.Error) { +func NewBufReadSize(rd io.Read, size int) (*BufRead, *os.Error) { if size <= 0 { return nil, BadBufSize } + // Is it already a BufRead? + b, ok := rd.(*BufRead); + if ok && len(b.buf) >= size { + return b, nil + } b = new(BufRead); b.buf = make([]byte, size); b.rd = rd; @@ -381,12 +387,18 @@ type BufWrite struct { } // NewBufWriteSize creates a new BufWrite whose buffer has the specified size, -// which must be greater than zero. +// which must be greater than zero. If the argument io.Write is already a +// BufWrite with large enough size, it returns the underlying BufWrite. // It returns the BufWrite and any error. -func NewBufWriteSize(wr io.Write, size int) (b *BufWrite, err *os.Error) { +func NewBufWriteSize(wr io.Write, size int) (*BufWrite, *os.Error) { if size <= 0 { return nil, BadBufSize } + // Is it already a BufWrite? + b, ok := wr.(*BufWrite); + if ok && len(b.buf) >= size { + return b, nil + } b = new(BufWrite); b.buf = make([]byte, size); b.wr = wr; diff --git a/src/lib/bufio_test.go b/src/lib/bufio_test.go index ef97bc46ec..d8c77c153c 100644 --- a/src/lib/bufio_test.go +++ b/src/lib/bufio_test.go @@ -330,3 +330,50 @@ func TestBufWrite(t *testing.T) { } } +func TestNewBufReadSizeIdempotent(t *testing.T) { + const BufSize = 1000; + b, err := NewBufReadSize(newByteReader(io.StringBytes("hello world")), BufSize); + if err != nil { + t.Error("NewBufReadSize create fail", err); + } + // Does it recognize itself? + b1, err2 := NewBufReadSize(b, BufSize); + if err2 != nil { + t.Error("NewBufReadSize #2 create fail", err2); + } + if b1 != b { + t.Error("NewBufReadSize did not detect underlying BufRead"); + } + // Does it wrap if existing buffer is too small? + b2, err3 := NewBufReadSize(b, 2*BufSize); + if err3 != nil { + t.Error("NewBufReadSize #3 create fail", err3); + } + if b2 == b { + t.Error("NewBufReadSize did not enlarge buffer"); + } +} + +func TestNewBufWriteSizeIdempotent(t *testing.T) { + const BufSize = 1000; + b, err := NewBufWriteSize(newByteWriter(), BufSize); + if err != nil { + t.Error("NewBufWriteSize create fail", err); + } + // Does it recognize itself? + b1, err2 := NewBufWriteSize(b, BufSize); + if err2 != nil { + t.Error("NewBufWriteSize #2 create fail", err2); + } + if b1 != b { + t.Error("NewBufWriteSize did not detect underlying BufWrite"); + } + // Does it wrap if existing buffer is too small? + b2, err3 := NewBufWriteSize(b, 2*BufSize); + if err3 != nil { + t.Error("NewBufWriteSize #3 create fail", err3); + } + if b2 == b { + t.Error("NewBufWriteSize did not enlarge buffer"); + } +} -- 2.48.1