]> Cypherpunks repositories - gostls13.git/commitdiff
slices
authorRob Pike <r@golang.org>
Fri, 3 Jul 2009 01:02:42 +0000 (18:02 -0700)
committerRob Pike <r@golang.org>
Fri, 3 Jul 2009 01:02:42 +0000 (18:02 -0700)
R=rsc
DELTA=59  (44 added, 13 deleted, 2 changed)
OCL=31105
CL=31105

src/pkg/gob/codec_test.go
src/pkg/gob/decode.go

index 8dd252b4ce49639002cae338f9ec74411800e4a1..e25a719fad80657a596ecd6178413ee38e0b432c 100644 (file)
@@ -525,7 +525,7 @@ func TestScalarDecInstructions(t *testing.T) {
 }
 
 
-func TestEncode(t *testing.T) {
+func TestEndToEnd(t *testing.T) {
        type T2 struct {
                t string
        }
@@ -535,6 +535,7 @@ func TestEncode(t *testing.T) {
                a, b,c int;
                n *[3]float;
                strs *[2]string;
+               int64s *[]int64;
                s string;
                y []byte;
                t *T2;
@@ -545,6 +546,7 @@ func TestEncode(t *testing.T) {
                c: -5,
                n: &[3]float{1.5, 2.5, 3.5},
                strs: &[2]string{s1, s2},
+               int64s: &[]int64{77, 89, 123412342134},
                s: "Now is the time",
                y: strings.Bytes("hello, sailor"),
                t: &T2{"this is T2"},
index 8a7440b0b4dfb0765f2bf0f502571c9d40bcf380..80d772fd0d53fbc52cbee4191033c7a1c90faf7d 100644 (file)
@@ -313,30 +313,54 @@ func decodeStruct(engine *decEngine, rtyp reflect.StructType, r io.Reader, p uin
        return state.err
 }
 
-func decodeArray(atyp reflect.ArrayType, state *DecState, p uintptr, elemOp decOp, elemWid int, length int, indir, elemIndir int) os.Error {
+func decodeArrayHelper(state *DecState, p uintptr, elemOp decOp, elemWid, length, elemIndir int) os.Error {
+       instr := &decInstr{elemOp, 0, elemIndir, 0};
+       for i := 0; i < length && state.err == nil; i++ {
+               up := unsafe.Pointer(p);
+               if elemIndir > 1 {
+                       up = decIndirect(up, elemIndir);
+               }
+               elemOp(instr, state, up);
+               p += uintptr(elemWid);
+       }
+       return state.err
+}
+
+func decodeArray(atyp reflect.ArrayType, state *DecState, p uintptr, elemOp decOp, elemWid, length, indir, elemIndir int) os.Error {
        if indir > 0 {
                up := unsafe.Pointer(p);
                if *(*unsafe.Pointer)(up) == nil {
-                       // Allocate the structure by making a slice of bytes and recording the
-                       // address of the beginning of the array. TODO(rsc).
+                       // Allocate the array by making a slice of bytes of the correct size
+                       // and taking the address of the beginning of the array. TODO(rsc).
                        b := make([]byte, atyp.Size());
-                       *(*unsafe.Pointer)(up) = unsafe.Pointer(&b[0]);
+                       *(**byte)(up) = &b[0];
                }
                p = *(*uintptr)(up);
        }
-       instr := &decInstr{elemOp, 0, elemIndir, 0};
        if DecodeUint(state) != uint64(length) {
-               state.err = os.ErrorString("length mismatch in decodeArray");
+               return os.ErrorString("length mismatch in decodeArray");
        }
-       for i := 0; i < length && state.err == nil; i++ {
+       return decodeArrayHelper(state, p, elemOp, elemWid, length, elemIndir);
+}
+
+func decodeSlice(atyp reflect.ArrayType, state *DecState, p uintptr, elemOp decOp, elemWid, indir, elemIndir int) os.Error {
+       length := int(DecodeUint(state));
+       if indir > 0 {
                up := unsafe.Pointer(p);
-               if elemIndir > 1 {
-                       up = decIndirect(up, elemIndir);
+               if *(*unsafe.Pointer)(up) == nil {
+                       // Allocate the slice header.
+                       *(*unsafe.Pointer)(up) = unsafe.Pointer(new(reflect.SliceHeader));
                }
-               elemOp(instr, state, up);
-               p += uintptr(elemWid);
+               p = *(*uintptr)(up);
        }
-       return state.err
+       // Allocate storage for the slice elements, that is, the underlying array.
+       data := make([]byte, length*atyp.Elem().Size());
+       // Always write a header at p.
+       hdrp := (*reflect.SliceHeader)(unsafe.Pointer(p));
+       hdrp.Data = uintptr(unsafe.Pointer(&data[0]));
+       hdrp.Len = uint32(length);
+       hdrp.Cap = uint32(length);
+       return decodeArrayHelper(state, hdrp.Data, elemOp, elemWid, length, elemIndir);
 }
 
 var decEngineMap = make(map[reflect.Type] *decEngine)
@@ -370,6 +394,11 @@ func decOpFor(typ reflect.Type) decOp {
                        case atyp.Elem().Kind() == reflect.Uint8Kind:
                                op = decUint8Array
                        case atyp.IsSlice():
+                               elemOp := decOpFor(atyp.Elem());
+                               _, elemIndir := indirect(atyp.Elem());
+                               op = func(i *decInstr, state *DecState, p unsafe.Pointer) {
+                                       state.err = decodeSlice(atyp, state, uintptr(p), elemOp, atyp.Elem().Size(), i.indir, elemIndir);
+                               };
                        case !atyp.IsSlice():
                                elemOp := decOpFor(atyp.Elem());
                                _, elemIndir := indirect(atyp.Elem());