From: Brad Fitzpatrick Date: Tue, 29 Jan 2013 00:31:46 +0000 (-0800) Subject: encoding/json: add Decoder.Buffered accessor to get overread data X-Git-Tag: go1.1rc2~1268 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=91e99c13457109e3571767cae3fc56c472bdd7dc;p=gostls13.git encoding/json: add Decoder.Buffered accessor to get overread data Otherwise it's impossible to know how much data from the json.Decoder's underlying Reader was actually consumed. The old fix from golang.org/issue/1955 just added docs. This provides an actual mechanism. Update #1955 R=golang-dev, adg, rsc CC=golang-dev https://golang.org/cl/7181053 --- diff --git a/src/pkg/encoding/json/stream.go b/src/pkg/encoding/json/stream.go index 9592467d25..00f4726cf7 100644 --- a/src/pkg/encoding/json/stream.go +++ b/src/pkg/encoding/json/stream.go @@ -5,6 +5,7 @@ package json import ( + "bytes" "errors" "io" ) @@ -58,6 +59,12 @@ func (dec *Decoder) Decode(v interface{}) error { return err } +// Buffered returns a reader of the data remaining in the Decoder's +// buffer. The reader is valid until the next call to Decode. +func (dec *Decoder) Buffered() io.Reader { + return bytes.NewReader(dec.buf) +} + // readValue reads a JSON value into dec.buf. // It returns the length of the encoding. func (dec *Decoder) readValue() (int, error) { diff --git a/src/pkg/encoding/json/stream_test.go b/src/pkg/encoding/json/stream_test.go index 4d66f55676..07c9e1d390 100644 --- a/src/pkg/encoding/json/stream_test.go +++ b/src/pkg/encoding/json/stream_test.go @@ -6,8 +6,10 @@ package json import ( "bytes" + "io/ioutil" "net" "reflect" + "strings" "testing" ) @@ -83,6 +85,28 @@ func TestDecoder(t *testing.T) { } } +func TestDecoderBuffered(t *testing.T) { + r := strings.NewReader(`{"Name": "Gopher"} extra `) + var m struct { + Name string + } + d := NewDecoder(r) + err := d.Decode(&m) + if err != nil { + t.Fatal(err) + } + if m.Name != "Gopher" { + t.Errorf("Name = %q; want Gopher", m.Name) + } + rest, err := ioutil.ReadAll(d.Buffered()) + if err != nil { + t.Fatal(err) + } + if g, w := string(rest), " extra "; g != w { + t.Errorf("Remaining = %q; want %q", g, w) + } +} + func nlines(s string, n int) string { if n <= 0 { return ""