func getDecEngine(rt reflect.Type) *decEngine
-func decOpFor(typ reflect.Type) decOp {
+// Return the decoding op for the base type under rt and
+// the indirection count to reach it.
+func decOpFor(rt reflect.Type) (decOp, int) {
+ typ, indir := indirect(rt);
op, ok := decOpMap[reflect.Typeof(typ)];
if !ok {
// Special cases
op = decUint8Array;
break;
}
- elemOp := decOpFor(t.Elem());
- _, elemIndir := indirect(t.Elem());
+ elemOp, elemIndir := decOpFor(t.Elem());
op = func(i *decInstr, state *DecState, p unsafe.Pointer) {
state.err = decodeSlice(t, state, uintptr(p), elemOp, t.Elem().Size(), i.indir, elemIndir);
};
case *reflect.ArrayType:
- elemOp := decOpFor(t.Elem());
- _, elemIndir := indirect(t.Elem());
+ elemOp, elemIndir := decOpFor(t.Elem());
op = func(i *decInstr, state *DecState, p unsafe.Pointer) {
state.err = decodeArray(t, state, uintptr(p), elemOp, t.Elem().Size(), t.Len(), i.indir, elemIndir);
};
}
}
if op == nil {
- panicln("decode can't handle type", typ.String());
+ panicln("decode can't handle type", rt.String());
}
- return op
+ return op, indir
}
func compileDec(rt reflect.Type, typ Type) *decEngine {
// TODO(r): verify compatibility with corresponding field of data.
// For now, assume perfect correspondence between struct and gob.
f := srt.Field(fieldnum);
- ftyp, indir := indirect(f.Type);
- op := decOpFor(ftyp);
+ op, indir := decOpFor(f.Type);
engine.instr[fieldnum] = decInstr{op, fieldnum, indir, uintptr(f.Offset)};
}
return engine;
p := unsafe.Pointer(basep+instr.offset);
if instr.indir > 0 {
if p = encIndirect(p, instr.indir); p == nil {
- state.fieldnum = i;
continue
}
}
func getEncEngine(rt reflect.Type) *encEngine
-func encOpFor(typ reflect.Type) encOp {
+// Return the encoding op for the base type under rt and
+// the indirection count to reach it.
+func encOpFor(rt reflect.Type) (encOp, int) {
+ typ, indir := indirect(rt);
op, ok := encOpMap[reflect.Typeof(typ)];
if !ok {
+ typ, _ := indirect(rt);
// Special cases
switch t := typ.(type) {
case *reflect.SliceType:
break;
}
// Slices have a header; we decode it to find the underlying array.
- elemOp := encOpFor(t.Elem());
- _, indir := indirect(t.Elem());
+ elemOp, indir := encOpFor(t.Elem());
op = func(i *encInstr, state *EncState, p unsafe.Pointer) {
slice := (*reflect.SliceHeader)(p);
if slice.Len == 0 {
};
case *reflect.ArrayType:
// True arrays have size in the type.
- elemOp := encOpFor(t.Elem());
- _, indir := indirect(t.Elem());
+ elemOp, indir := encOpFor(t.Elem());
op = func(i *encInstr, state *EncState, p unsafe.Pointer) {
state.update(i);
state.err = encodeArray(state.w, uintptr(p), elemOp, t.Elem().Size(), t.Len(), indir);
}
}
if op == nil {
- panicln("encode can't handle type", typ.String());
+ panicln("encode can't handle type", rt.String());
}
- return op
+ return op, indir
}
// The local Type was compiled from the actual value, so we know
engine.instr = make([]encInstr, srt.NumField()+1); // +1 for terminator
for fieldnum := 0; fieldnum < srt.NumField(); fieldnum++ {
f := srt.Field(fieldnum);
- ftyp, indir := indirect(f.Type);
- op := encOpFor(ftyp);
+ op, indir := encOpFor(f.Type);
engine.instr[fieldnum] = encInstr{op, fieldnum, indir, uintptr(f.Offset)};
}
engine.instr[srt.NumField()] = encInstr{encStructTerminator, 0, 0, 0};