mirror of
https://github.com/golang/go
synced 2024-11-25 12:17:56 -07:00
gob: when possible, allow sequential decoders on the same input stream.
This can work only if there is no type info required to initialize the decoder, but it's easy and gains a few percent in the basic benchmarks by avoiding bufio when it's a bytes.Buffer - a testing-only scenario, I admit. Add a comment about what Decode expects from the input. R=rsc CC=golang-dev https://golang.org/cl/5165048
This commit is contained in:
parent
305f167b01
commit
457dfd7546
@ -29,9 +29,15 @@ type Decoder struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewDecoder returns a new decoder that reads from the io.Reader.
|
// NewDecoder returns a new decoder that reads from the io.Reader.
|
||||||
|
// If r does not also implement io.ByteReader, it will be wrapped in a
|
||||||
|
// bufio.Reader.
|
||||||
func NewDecoder(r io.Reader) *Decoder {
|
func NewDecoder(r io.Reader) *Decoder {
|
||||||
dec := new(Decoder)
|
dec := new(Decoder)
|
||||||
dec.r = bufio.NewReader(r)
|
// We use the ability to read bytes as a plausible surrogate for buffering.
|
||||||
|
if _, ok := r.(io.ByteReader); !ok {
|
||||||
|
r = bufio.NewReader(r)
|
||||||
|
}
|
||||||
|
dec.r = r
|
||||||
dec.wireType = make(map[typeId]*wireType)
|
dec.wireType = make(map[typeId]*wireType)
|
||||||
dec.decoderCache = make(map[reflect.Type]map[typeId]**decEngine)
|
dec.decoderCache = make(map[reflect.Type]map[typeId]**decEngine)
|
||||||
dec.ignorerCache = make(map[typeId]**decEngine)
|
dec.ignorerCache = make(map[typeId]**decEngine)
|
||||||
|
@ -638,3 +638,28 @@ func TestBadCount(t *testing.T) {
|
|||||||
t.Error("expected bad count error; got", err)
|
t.Error("expected bad count error; got", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify that sequential Decoders built on a single input will
|
||||||
|
// succeed if the input implements ReadByte and there is no
|
||||||
|
// type information in the stream.
|
||||||
|
func TestSequentialDecoder(t *testing.T) {
|
||||||
|
b := new(bytes.Buffer)
|
||||||
|
enc := NewEncoder(b)
|
||||||
|
const count = 10
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
s := fmt.Sprintf("%d", i)
|
||||||
|
if err := enc.Encode(s); err != nil {
|
||||||
|
t.Error("encoder fail:", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
dec := NewDecoder(b)
|
||||||
|
var s string
|
||||||
|
if err := dec.Decode(&s); err != nil {
|
||||||
|
t.Fatal("decoder fail:", err)
|
||||||
|
}
|
||||||
|
if s != fmt.Sprintf("%d", i) {
|
||||||
|
t.Fatalf("decode expected %d got %s", i, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user