]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/json: add Decoder.Buffered accessor to get overread data
authorBrad Fitzpatrick <bradfitz@golang.org>
Tue, 29 Jan 2013 00:31:46 +0000 (16:31 -0800)
committerBrad Fitzpatrick <bradfitz@golang.org>
Tue, 29 Jan 2013 00:31:46 +0000 (16:31 -0800)
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

src/pkg/encoding/json/stream.go
src/pkg/encoding/json/stream_test.go

index 9592467d25baaefa853bdc2f1c87751b8fe4564f..00f4726cf7f6dce09cbda73c271eeea1babad756 100644 (file)
@@ -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) {
index 4d66f556767215d8abd4e88d6b161d8caf85efac..07c9e1d390c68db75a19a88a120d60e981594387 100644 (file)
@@ -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 ""