FAQ
Reviewers: golang-dev_googlegroups.com,

Message:
Hello golang-dev@googlegroups.com,

I'd like you to review this change to
https://go.googlecode.com/hg/


Description:
bytes, strings: add (*Reader).WriteTo

Fixes issue 4031.

Please review this at http://codereview.appspot.com/6632046/

Affected files:
M src/pkg/bytes/buffer_test.go
M src/pkg/bytes/reader.go
M src/pkg/bytes/reader_test.go
M src/pkg/strings/reader.go
M src/pkg/strings/reader_test.go


Index: src/pkg/bytes/buffer_test.go
===================================================================
--- a/src/pkg/bytes/buffer_test.go
+++ b/src/pkg/bytes/buffer_test.go
@@ -246,20 +246,20 @@ func TestReadFrom(t *testing.T) {
b.ReadFrom(&buf)
empty(t, "TestReadFrom (2)", &b, s, make([]byte, len(data)))
}
}

func TestWriteTo(t *testing.T) {
var buf Buffer
for i := 3; i < 30; i += 3 {
- s := fillBytes(t, "TestReadFrom (1)", &buf, "", 5, bytes[0:len(bytes)/i])
+ s := fillBytes(t, "TestWriteTo (1)", &buf, "", 5, bytes[0:len(bytes)/i])
var b Buffer
buf.WriteTo(&b)
- empty(t, "TestReadFrom (2)", &b, s, make([]byte, len(data)))
+ empty(t, "TestWriteTo (2)", &b, s, make([]byte, len(data)))
}
}

func TestRuneIO(t *testing.T) {
const NRune = 1000
// Built a test array while we write the data
b := make([]byte, utf8.UTFMax*NRune)
var buf Buffer
Index: src/pkg/bytes/reader.go
===================================================================
--- a/src/pkg/bytes/reader.go
+++ b/src/pkg/bytes/reader.go
@@ -5,17 +5,17 @@
package bytes

import (
"errors"
"io"
"unicode/utf8"
)

-// A Reader implements the io.Reader, io.ReaderAt, io.Seeker,
+// A Reader implements the io.Reader, io.ReaderAt, io.WriterTo, io.Seeker,
// io.ByteScanner, and io.RuneScanner interfaces by reading from
// a byte slice.
// Unlike a Buffer, a Reader is read-only and supports seeking.
type Reader struct {
s []byte
i int // current reading index
prevRune int // index of previous rune; or < 0
}
@@ -116,10 +116,32 @@ func (r *Reader) Seek(offset int64, when
}
if abs >= 1<<31 {
return 0, errors.New("bytes: position out of range")
}
r.i = int(abs)
return abs, nil
}

+// WriteTo implements the io.WriterTo interface.
+func (r *Reader) WriteTo(w io.Writer) (n int64, err error) {
+ r.prevRune = -1
+ if r.i >= len(r.s) {
+ return 0, io.EOF
+ }
+ b := r.s[r.i:]
+ m, e := w.Write(b)
+ if m > len(b) {
+ panic("bytes.Reader.WriteTo: invalid Write count")
+ }
+ r.i += m
+ n = int64(m)
+ if e != nil {
+ return n, e
+ }
+ if m != len(b) {
+ return n, io.ErrShortWrite
+ }
+ return n, nil
+}
+
// NewReader returns a new Reader reading from b.
func NewReader(b []byte) *Reader { return &Reader{b, 0, -1} }
Index: src/pkg/bytes/reader_test.go
===================================================================
--- a/src/pkg/bytes/reader_test.go
+++ b/src/pkg/bytes/reader_test.go
@@ -81,8 +81,29 @@ func TestReaderAt(t *testing.T) {
if got != tt.want {
t.Errorf("%d. got %q; want %q", i, got, tt.want)
}
if fmt.Sprintf("%v", err) != fmt.Sprintf("%v", tt.wanterr) {
t.Errorf("%d. got error = %v; want %v", i, err, tt.wanterr)
}
}
}
+
+func TestReaderWriteTo(t *testing.T) {
+ for i := 3; i < 30; i += 3 {
+ s := data[:len(data)/i]
+ r := NewReader(bytes[:len(bytes)/i])
+ var b Buffer
+ n, err := r.WriteTo(&b)
+ if expect := int64(len(s)); n != expect {
+ t.Errorf("got %v; want %v", n, expect)
+ }
+ if err != nil {
+ t.Errorf("got error = %v; want nil", err)
+ }
+ if b.String() != s {
+ t.Errorf("got string %v; want %v", b.String(), s)
+ }
+ if r.Len() != 0 {
+ t.Errorf("reader contains %v bytes; want 0", r.Len())
+ }
+ }
+}
Index: src/pkg/strings/reader.go
===================================================================
--- a/src/pkg/strings/reader.go
+++ b/src/pkg/strings/reader.go
@@ -115,11 +115,33 @@ func (r *Reader) Seek(offset int64, when
}
if abs >= 1<<31 {
return 0, errors.New("strings: position out of range")
}
r.i = int(abs)
return abs, nil
}

+// WriteTo implements the io.WriterTo interface.
+func (r *Reader) WriteTo(w io.Writer) (n int64, err error) {
+ r.prevRune = -1
+ if r.i >= len(r.s) {
+ return 0, io.EOF
+ }
+ s := r.s[r.i:]
+ m, e := io.WriteString(w, s)
+ if m > len(s) {
+ panic("strings.Reader.WriteTo: invalid WriteString count")
+ }
+ r.i += m
+ n = int64(m)
+ if e != nil {
+ return n, e
+ }
+ if m != len(s) {
+ return n, io.ErrShortWrite
+ }
+ return n, nil
+}
+
// NewReader returns a new Reader reading from s.
// It is similar to bytes.NewBufferString but more efficient and read-only.
func NewReader(s string) *Reader { return &Reader{s, 0, -1} }
Index: src/pkg/strings/reader_test.go
===================================================================
--- a/src/pkg/strings/reader_test.go
+++ b/src/pkg/strings/reader_test.go
@@ -1,15 +1,16 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package strings_test

import (
+ "bytes"
"fmt"
"io"
"os"
"strings"
"testing"
)

func TestReader(t *testing.T) {
@@ -81,8 +82,30 @@ func TestReaderAt(t *testing.T) {
if got != tt.want {
t.Errorf("%d. got %q; want %q", i, got, tt.want)
}
if fmt.Sprintf("%v", err) != fmt.Sprintf("%v", tt.wanterr) {
t.Errorf("%d. got error = %v; want %v", i, err, tt.wanterr)
}
}
}
+
+func TestWriteTo(t *testing.T) {
+ const str = "0123456789"
+ for i := 0; i < len(str); i++ {
+ s := str[i:]
+ r := strings.NewReader(s)
+ var b bytes.Buffer
+ n, err := r.WriteTo(&b)
+ if expect := int64(len(s)); n != expect {
+ t.Errorf("got %v; want %v", n, expect)
+ }
+ if err != nil {
+ t.Errorf("got error = %v; want nil", err)
+ }
+ if b.String() != s {
+ t.Errorf("got string %v; want %v", b.String(), s)
+ }
+ if r.Len() != 0 {
+ t.Errorf("reader contains %v bytes; want 0", r.Len())
+ }
+ }
+}

Search Discussions

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-dev @
categoriesgo
postedOct 9, '12 at 4:31a
activeOct 12, '12 at 5:12a
posts23
users5
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase