summaryrefslogtreecommitdiff
path: root/src/pkg/gob/decode.go
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2009-10-11 17:37:22 -0700
committerRob Pike <r@golang.org>2009-10-11 17:37:22 -0700
commit92b93dd042130a68d3784c690b74b6db75d7c770 (patch)
treedc94d68df7ac8250b1af92afb8b1330771a78b89 /src/pkg/gob/decode.go
parent81355af7a117fb5e2ea9293fc571a5e5ec1f46fe (diff)
downloadgolang-92b93dd042130a68d3784c690b74b6db75d7c770.tar.gz
fix bugs in gob.
1) didn't handle attempts to encode non-structs properly. 2) if there were multiple indirections involving allocation, didn't allocate the intermediate cells. tests added. R=rsc DELTA=82 (65 added, 5 deleted, 12 changed) OCL=35582 CL=35582
Diffstat (limited to 'src/pkg/gob/decode.go')
-rw-r--r--src/pkg/gob/decode.go26
1 files changed, 13 insertions, 13 deletions
diff --git a/src/pkg/gob/decode.go b/src/pkg/gob/decode.go
index dddc1ec05..415b4b677 100644
--- a/src/pkg/gob/decode.go
+++ b/src/pkg/gob/decode.go
@@ -355,13 +355,18 @@ type decEngine struct {
}
func decodeStruct(engine *decEngine, rtyp *reflect.StructType, b *bytes.Buffer, p uintptr, indir int) os.Error {
- if indir > 0 {
+ for ; indir > 0; indir-- {
up := unsafe.Pointer(p);
if *(*unsafe.Pointer)(up) == nil {
- // Allocate the structure by making a slice of bytes and recording the
+ // Allocate object by making a slice of bytes and recording the
// address of the beginning of the array. TODO(rsc).
- b := make([]byte, rtyp.Size());
- *(*unsafe.Pointer)(up) = unsafe.Pointer(&b[0]);
+ if indir > 1 { // allocate a pointer
+ b := make([]byte, unsafe.Sizeof((*int)(nil)));
+ *(*unsafe.Pointer)(up) = unsafe.Pointer(&b[0]);
+ } else { // allocate a struct
+ b := make([]byte, rtyp.Size());
+ *(*unsafe.Pointer)(up) = unsafe.Pointer(&b[0]);
+ }
}
p = *(*uintptr)(up);
}
@@ -753,15 +758,10 @@ func getIgnoreEnginePtr(wireId typeId) (enginePtr **decEngine, err os.Error) {
}
func decode(b *bytes.Buffer, wireId typeId, e interface{}) os.Error {
- // Dereference down to the underlying object.
+ // Dereference down to the underlying struct type.
rt, indir := indirect(reflect.Typeof(e));
- v := reflect.NewValue(e);
- for i := 0; i < indir; i++ {
- v = reflect.Indirect(v);
- }
- var st *reflect.StructValue;
- var ok bool;
- if st, ok = v.(*reflect.StructValue); !ok {
+ st, ok := rt.(*reflect.StructType);
+ if !ok {
return os.ErrorString("gob: decode can't handle " + rt.String());
}
typeLock.Lock();
@@ -779,7 +779,7 @@ func decode(b *bytes.Buffer, wireId typeId, e interface{}) os.Error {
name := rt.Name();
return os.ErrorString("gob: type mismatch: no fields matched compiling decoder for " + name);
}
- return decodeStruct(engine, rt.(*reflect.StructType), b, uintptr(v.Addr()), 0);
+ return decodeStruct(engine, st, b, uintptr(reflect.NewValue(e).Addr()), indir);
}
func init() {