summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2009-12-29 14:03:12 +1100
committerRob Pike <r@golang.org>2009-12-29 14:03:12 +1100
commit83c923a6c591440bc5b47e6c88b91e175ac80286 (patch)
tree78ccef046180514fd066313dcd1aa7862f9c05af
parent66b13bd9dcf2105bb58b8246ccdfc0a16310b588 (diff)
downloadgo-83c923a6c591440bc5b47e6c88b91e175ac80286.tar.gz
remove all references to gobType() from the decoder.
Fixes issue 470. R=rsc CC=golang-dev http://codereview.appspot.com/183074
-rw-r--r--src/pkg/gob/decode.go34
1 files changed, 20 insertions, 14 deletions
diff --git a/src/pkg/gob/decode.go b/src/pkg/gob/decode.go
index c7f314369..41951d357 100644
--- a/src/pkg/gob/decode.go
+++ b/src/pkg/gob/decode.go
@@ -540,7 +540,7 @@ func (dec *Decoder) decOpFor(wireId typeId, rt reflect.Type, name string) (decOp
case *reflect.ArrayType:
name = "element of " + name
- elemId := wireId.gobType().(*arrayType).Elem
+ elemId := dec.wireType[wireId].array.Elem
elemOp, elemIndir, err := dec.decOpFor(elemId, t.Elem(), name)
if err != nil {
return nil, 0, err
@@ -573,28 +573,29 @@ func (dec *Decoder) decIgnoreOpFor(wireId typeId) (decOp, os.Error) {
op, ok := decIgnoreOpMap[wireId]
if !ok {
// Special cases
- switch t := wireId.gobType().(type) {
- case *sliceType:
- elemId := wireId.gobType().(*sliceType).Elem
+ wire := dec.wireType[wireId]
+ switch {
+ case wire.array != nil:
+ elemId := wire.array.Elem
elemOp, err := dec.decIgnoreOpFor(elemId)
if err != nil {
return nil, err
}
op = func(i *decInstr, state *decodeState, p unsafe.Pointer) {
- state.err = ignoreSlice(state, elemOp)
+ state.err = ignoreArray(state, elemOp, wire.array.Len)
}
- case *arrayType:
- elemId := wireId.gobType().(*arrayType).Elem
+ case wire.slice != nil:
+ elemId := wire.slice.Elem
elemOp, err := dec.decIgnoreOpFor(elemId)
if err != nil {
return nil, err
}
op = func(i *decInstr, state *decodeState, p unsafe.Pointer) {
- state.err = ignoreArray(state, elemOp, t.Len)
+ state.err = ignoreSlice(state, elemOp)
}
- case *structType:
+ case wire.strct != nil:
// Generate a closure that calls out to the engine for the nested type.
enginePtr, err := dec.getIgnoreEnginePtr(wireId)
if err != nil {
@@ -660,8 +661,12 @@ func (dec *Decoder) compatibleType(fr reflect.Type, fw typeId) bool {
case *reflect.StringType:
return fw == tString
case *reflect.ArrayType:
- aw, ok := fw.gobType().(*arrayType)
- return ok && t.Len() == aw.Len && dec.compatibleType(t.Elem(), aw.Elem)
+ wire, ok := dec.wireType[fw]
+ if !ok || wire.array == nil {
+ return false
+ }
+ array := wire.array
+ return ok && t.Len() == array.Len && dec.compatibleType(t.Elem(), array.Elem)
case *reflect.SliceType:
// Is it an array of bytes?
et := t.Elem()
@@ -714,8 +719,9 @@ func (dec *Decoder) compileDec(remoteId typeId, rt reflect.Type) (engine *decEng
continue
}
if !dec.compatibleType(localField.Type, wireField.id) {
- details := " (" + wireField.id.string() + " incompatible with " + localField.Type.String() + ") in type " + remoteId.Name()
- return nil, os.ErrorString("gob: wrong type for field " + wireField.name + details)
+ return nil, os.ErrorString("gob: wrong type (" +
+ localField.Type.String() + ") for received field " +
+ wireStruct.name + "." + wireField.name)
}
op, indir, err := dec.decOpFor(wireField.id, localField.Type, localField.Name)
if err != nil {
@@ -776,7 +782,7 @@ func (dec *Decoder) decode(wireId typeId, e interface{}) os.Error {
return err
}
engine := *enginePtr
- if engine.numInstr == 0 && st.NumField() > 0 && len(wireId.gobType().(*structType).field) > 0 {
+ if engine.numInstr == 0 && st.NumField() > 0 && len(dec.wireType[wireId].strct.field) > 0 {
name := rt.Name()
return os.ErrorString("gob: type mismatch: no fields matched compiling decoder for " + name)
}