func TestUintCodec(t *testing.T) {
defer testError(t)
b := new(bytes.Buffer)
- encState := newEncoderState(nil, b)
+ encState := newEncoderState(b)
for _, tt := range encodeT {
b.Reset()
encState.encodeUint(tt.x)
t.Errorf("encodeUint: %#x encode: expected % x got % x", tt.x, tt.b, b.Bytes())
}
}
- decState := newDecodeState(nil, b)
+ decState := newDecodeState(b)
for u := uint64(0); ; u = (u + 1) * 7 {
b.Reset()
encState.encodeUint(u)
func verifyInt(i int64, t *testing.T) {
defer testError(t)
var b = new(bytes.Buffer)
- encState := newEncoderState(nil, b)
+ encState := newEncoderState(b)
encState.encodeInt(i)
- decState := newDecodeState(nil, b)
+ decState := newDecodeState(b)
decState.buf = make([]byte, 8)
j := decState.decodeInt()
if i != j {
// The result of encoding "hello" with field number 7
var bytesResult = []byte{0x07, 0x05, 'h', 'e', 'l', 'l', 'o'}
-func newencoderState(b *bytes.Buffer) *encoderState {
+func newDecodeState(buf *bytes.Buffer) *decoderState {
+ d := new(decoderState)
+ d.b = buf
+ d.buf = make([]byte, uint64Size)
+ return d
+}
+
+func newEncoderState(b *bytes.Buffer) *encoderState {
b.Reset()
- state := newEncoderState(nil, b)
+ state := &encoderState{enc: nil, b: b}
state.fieldnum = -1
return state
}
{
data := struct{ a bool }{true}
instr := &encInstr{encBool, 6, 0, 0}
- state := newencoderState(b)
+ state := newEncoderState(b)
instr.op(instr, state, unsafe.Pointer(&data))
if !bytes.Equal(boolResult, b.Bytes()) {
t.Errorf("bool enc instructions: expected % x got % x", boolResult, b.Bytes())
b.Reset()
data := struct{ a int }{17}
instr := &encInstr{encInt, 6, 0, 0}
- state := newencoderState(b)
+ state := newEncoderState(b)
instr.op(instr, state, unsafe.Pointer(&data))
if !bytes.Equal(signedResult, b.Bytes()) {
t.Errorf("int enc instructions: expected % x got % x", signedResult, b.Bytes())
b.Reset()
data := struct{ a uint }{17}
instr := &encInstr{encUint, 6, 0, 0}
- state := newencoderState(b)
+ state := newEncoderState(b)
instr.op(instr, state, unsafe.Pointer(&data))
if !bytes.Equal(unsignedResult, b.Bytes()) {
t.Errorf("uint enc instructions: expected % x got % x", unsignedResult, b.Bytes())
b.Reset()
data := struct{ a int8 }{17}
instr := &encInstr{encInt8, 6, 0, 0}
- state := newencoderState(b)
+ state := newEncoderState(b)
instr.op(instr, state, unsafe.Pointer(&data))
if !bytes.Equal(signedResult, b.Bytes()) {
t.Errorf("int8 enc instructions: expected % x got % x", signedResult, b.Bytes())
b.Reset()
data := struct{ a uint8 }{17}
instr := &encInstr{encUint8, 6, 0, 0}
- state := newencoderState(b)
+ state := newEncoderState(b)
instr.op(instr, state, unsafe.Pointer(&data))
if !bytes.Equal(unsignedResult, b.Bytes()) {
t.Errorf("uint8 enc instructions: expected % x got % x", unsignedResult, b.Bytes())
b.Reset()
data := struct{ a int16 }{17}
instr := &encInstr{encInt16, 6, 0, 0}
- state := newencoderState(b)
+ state := newEncoderState(b)
instr.op(instr, state, unsafe.Pointer(&data))
if !bytes.Equal(signedResult, b.Bytes()) {
t.Errorf("int16 enc instructions: expected % x got % x", signedResult, b.Bytes())
b.Reset()
data := struct{ a uint16 }{17}
instr := &encInstr{encUint16, 6, 0, 0}
- state := newencoderState(b)
+ state := newEncoderState(b)
instr.op(instr, state, unsafe.Pointer(&data))
if !bytes.Equal(unsignedResult, b.Bytes()) {
t.Errorf("uint16 enc instructions: expected % x got % x", unsignedResult, b.Bytes())
b.Reset()
data := struct{ a int32 }{17}
instr := &encInstr{encInt32, 6, 0, 0}
- state := newencoderState(b)
+ state := newEncoderState(b)
instr.op(instr, state, unsafe.Pointer(&data))
if !bytes.Equal(signedResult, b.Bytes()) {
t.Errorf("int32 enc instructions: expected % x got % x", signedResult, b.Bytes())
b.Reset()
data := struct{ a uint32 }{17}
instr := &encInstr{encUint32, 6, 0, 0}
- state := newencoderState(b)
+ state := newEncoderState(b)
instr.op(instr, state, unsafe.Pointer(&data))
if !bytes.Equal(unsignedResult, b.Bytes()) {
t.Errorf("uint32 enc instructions: expected % x got % x", unsignedResult, b.Bytes())
b.Reset()
data := struct{ a int64 }{17}
instr := &encInstr{encInt64, 6, 0, 0}
- state := newencoderState(b)
+ state := newEncoderState(b)
instr.op(instr, state, unsafe.Pointer(&data))
if !bytes.Equal(signedResult, b.Bytes()) {
t.Errorf("int64 enc instructions: expected % x got % x", signedResult, b.Bytes())
b.Reset()
data := struct{ a uint64 }{17}
instr := &encInstr{encUint64, 6, 0, 0}
- state := newencoderState(b)
+ state := newEncoderState(b)
instr.op(instr, state, unsafe.Pointer(&data))
if !bytes.Equal(unsignedResult, b.Bytes()) {
t.Errorf("uint64 enc instructions: expected % x got % x", unsignedResult, b.Bytes())
b.Reset()
data := struct{ a float32 }{17}
instr := &encInstr{encFloat32, 6, 0, 0}
- state := newencoderState(b)
+ state := newEncoderState(b)
instr.op(instr, state, unsafe.Pointer(&data))
if !bytes.Equal(floatResult, b.Bytes()) {
t.Errorf("float32 enc instructions: expected % x got % x", floatResult, b.Bytes())
b.Reset()
data := struct{ a float64 }{17}
instr := &encInstr{encFloat64, 6, 0, 0}
- state := newencoderState(b)
+ state := newEncoderState(b)
instr.op(instr, state, unsafe.Pointer(&data))
if !bytes.Equal(floatResult, b.Bytes()) {
t.Errorf("float64 enc instructions: expected % x got % x", floatResult, b.Bytes())
b.Reset()
data := struct{ a []byte }{[]byte("hello")}
instr := &encInstr{encUint8Array, 6, 0, 0}
- state := newencoderState(b)
+ state := newEncoderState(b)
instr.op(instr, state, unsafe.Pointer(&data))
if !bytes.Equal(bytesResult, b.Bytes()) {
t.Errorf("bytes enc instructions: expected % x got % x", bytesResult, b.Bytes())
b.Reset()
data := struct{ a string }{"hello"}
instr := &encInstr{encString, 6, 0, 0}
- state := newencoderState(b)
+ state := newEncoderState(b)
instr.op(instr, state, unsafe.Pointer(&data))
if !bytes.Equal(bytesResult, b.Bytes()) {
t.Errorf("string enc instructions: expected % x got % x", bytesResult, b.Bytes())
func newDecodeStateFromData(data []byte) *decoderState {
b := bytes.NewBuffer(data)
- state := newDecodeState(nil, b)
+ state := newDecodeState(b)
state.fieldnum = -1
return state
}
b *bytes.Buffer
fieldnum int // the last field number read.
buf []byte
+ next *decoderState // for free list
}
// We pass the bytes.Buffer separately for easier testing of the infrastructure
// without requiring a full Decoder.
-func newDecodeState(dec *Decoder, buf *bytes.Buffer) *decoderState {
- d := new(decoderState)
- d.dec = dec
+func (dec *Decoder) newDecoderState(buf *bytes.Buffer) *decoderState {
+ d := dec.freeList
+ if d == nil {
+ d = new(decoderState)
+ d.dec = dec
+ } else {
+ dec.freeList = d.next
+ }
d.b = buf
d.buf = make([]byte, uint64Size)
return d
}
+func (dec *Decoder) freeDecoderState(d *decoderState) {
+ d.next = dec.freeList
+ dec.freeList = d
+}
+
func overflow(name string) os.ErrorString {
return os.ErrorString(`value for "` + name + `" out of range`)
}
indir = int(ut.decIndir)
}
p = allocate(ut.base, p, indir)
- state := newDecodeState(dec, &dec.buf)
+ state := dec.newDecoderState(&dec.buf)
state.fieldnum = singletonField
basep := p
delta := int(state.decodeUint())
ptr = decIndirect(ptr, instr.indir)
}
instr.op(instr, state, ptr)
+ dec.freeDecoderState(state)
return nil
}
// from the user's value, not from the innards of an engine.
func (dec *Decoder) decodeStruct(engine *decEngine, ut *userTypeInfo, p uintptr, indir int) (err os.Error) {
p = allocate(ut.base.(*reflect.StructType), p, indir)
- state := newDecodeState(dec, &dec.buf)
+ state := dec.newDecoderState(&dec.buf)
state.fieldnum = -1
basep := p
for state.b.Len() > 0 {
instr.op(instr, state, p)
state.fieldnum = fieldnum
}
+ dec.freeDecoderState(state)
return nil
}
// ignoreStruct discards the data for a struct with no destination.
func (dec *Decoder) ignoreStruct(engine *decEngine) (err os.Error) {
- state := newDecodeState(dec, &dec.buf)
+ state := dec.newDecoderState(&dec.buf)
state.fieldnum = -1
for state.b.Len() > 0 {
delta := int(state.decodeUint())
instr.op(instr, state, unsafe.Pointer(nil))
state.fieldnum = fieldnum
}
+ dec.freeDecoderState(state)
return nil
}
// ignoreSingle discards the data for a top-level non-struct value with no
// destination. It's used when calling Decode with a nil value.
func (dec *Decoder) ignoreSingle(engine *decEngine) (err os.Error) {
- state := newDecodeState(dec, &dec.buf)
+ state := dec.newDecoderState(&dec.buf)
state.fieldnum = singletonField
delta := int(state.decodeUint())
if delta != 0 {
}
instr := &engine.instr[singletonField]
instr.op(instr, state, unsafe.Pointer(nil))
+ dec.freeDecoderState(state)
return nil
}
sendZero bool // encoding an array element or map key/value pair; send zero values
fieldnum int // the last field number written.
buf [1 + uint64Size]byte // buffer used by the encoder; here to avoid allocation.
+ next *encoderState // for free list
}
-func newEncoderState(enc *Encoder, b *bytes.Buffer) *encoderState {
- return &encoderState{enc: enc, b: b}
+func (enc *Encoder) newEncoderState(b *bytes.Buffer) *encoderState {
+ e := enc.freeList
+ if e == nil {
+ e = new(encoderState)
+ e.enc = enc
+ } else {
+ enc.freeList = e.next
+ }
+ e.sendZero = false
+ e.fieldnum = 0
+ e.b = b
+ return e
+}
+
+func (enc *Encoder) freeEncoderState(e *encoderState) {
+ e.next = enc.freeList
+ enc.freeList = e
}
// Unsigned integers have a two-state encoding. If the number is less
// encodeSingle encodes a single top-level non-struct value.
func (enc *Encoder) encodeSingle(b *bytes.Buffer, engine *encEngine, basep uintptr) {
- state := newEncoderState(enc, b)
+ state := enc.newEncoderState(b)
state.fieldnum = singletonField
// There is no surrounding struct to frame the transmission, so we must
// generate data even if the item is zero. To do this, set sendZero.
}
}
instr.op(instr, state, p)
+ enc.freeEncoderState(state)
}
// encodeStruct encodes a single struct value.
func (enc *Encoder) encodeStruct(b *bytes.Buffer, engine *encEngine, basep uintptr) {
- state := newEncoderState(enc, b)
+ state := enc.newEncoderState(b)
state.fieldnum = -1
for i := 0; i < len(engine.instr); i++ {
instr := &engine.instr[i]
}
instr.op(instr, state, p)
}
+ enc.freeEncoderState(state)
}
// encodeArray encodes the array whose 0th element is at p.
func (enc *Encoder) encodeArray(b *bytes.Buffer, p uintptr, op encOp, elemWid uintptr, elemIndir int, length int) {
- state := newEncoderState(enc, b)
+ state := enc.newEncoderState(b)
state.fieldnum = -1
state.sendZero = true
state.encodeUint(uint64(length))
op(nil, state, unsafe.Pointer(elemp))
p += uintptr(elemWid)
}
+ enc.freeEncoderState(state)
}
// encodeReflectValue is a helper for maps. It encodes the value v.
// Because map internals are not exposed, we must use reflection rather than
// addresses.
func (enc *Encoder) encodeMap(b *bytes.Buffer, mv *reflect.MapValue, keyOp, elemOp encOp, keyIndir, elemIndir int) {
- state := newEncoderState(enc, b)
+ state := enc.newEncoderState(b)
state.fieldnum = -1
state.sendZero = true
keys := mv.Keys()
encodeReflectValue(state, key, keyOp, keyIndir)
encodeReflectValue(state, mv.Elem(key), elemOp, elemIndir)
}
+ enc.freeEncoderState(state)
}
// encodeInterface encodes the interface value iv.
// by the concrete value. A nil value gets sent as the empty string for the name,
// followed by no value.
func (enc *Encoder) encodeInterface(b *bytes.Buffer, iv *reflect.InterfaceValue) {
- state := newEncoderState(enc, b)
+ state := enc.newEncoderState(b)
state.fieldnum = -1
state.sendZero = true
if iv.IsNil() {
if enc.err != nil {
error(err)
}
+ enc.freeEncoderState(state)
}
// encGobEncoder encodes a value that implements the GobEncoder interface.
if err != nil {
error(err)
}
- state := newEncoderState(enc, b)
+ state := enc.newEncoderState(b)
state.fieldnum = -1
state.encodeUint(uint64(len(data)))
state.b.Write(data)
+ enc.freeEncoderState(state)
}
var encOpTable = [...]encOp{