mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
slices
R=rsc DELTA=59 (44 added, 13 deleted, 2 changed) OCL=31105 CL=31105
This commit is contained in:
parent
c1fc4c8f37
commit
265674fa57
2 changed files with 46 additions and 15 deletions
|
|
@ -525,7 +525,7 @@ func TestScalarDecInstructions(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func TestEncode(t *testing.T) {
|
func TestEndToEnd(t *testing.T) {
|
||||||
type T2 struct {
|
type T2 struct {
|
||||||
t string
|
t string
|
||||||
}
|
}
|
||||||
|
|
@ -535,6 +535,7 @@ func TestEncode(t *testing.T) {
|
||||||
a, b,c int;
|
a, b,c int;
|
||||||
n *[3]float;
|
n *[3]float;
|
||||||
strs *[2]string;
|
strs *[2]string;
|
||||||
|
int64s *[]int64;
|
||||||
s string;
|
s string;
|
||||||
y []byte;
|
y []byte;
|
||||||
t *T2;
|
t *T2;
|
||||||
|
|
@ -545,6 +546,7 @@ func TestEncode(t *testing.T) {
|
||||||
c: -5,
|
c: -5,
|
||||||
n: &[3]float{1.5, 2.5, 3.5},
|
n: &[3]float{1.5, 2.5, 3.5},
|
||||||
strs: &[2]string{s1, s2},
|
strs: &[2]string{s1, s2},
|
||||||
|
int64s: &[]int64{77, 89, 123412342134},
|
||||||
s: "Now is the time",
|
s: "Now is the time",
|
||||||
y: strings.Bytes("hello, sailor"),
|
y: strings.Bytes("hello, sailor"),
|
||||||
t: &T2{"this is T2"},
|
t: &T2{"this is T2"},
|
||||||
|
|
|
||||||
|
|
@ -313,21 +313,8 @@ func decodeStruct(engine *decEngine, rtyp reflect.StructType, r io.Reader, p uin
|
||||||
return state.err
|
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 {
|
||||||
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).
|
|
||||||
b := make([]byte, atyp.Size());
|
|
||||||
*(*unsafe.Pointer)(up) = unsafe.Pointer(&b[0]);
|
|
||||||
}
|
|
||||||
p = *(*uintptr)(up);
|
|
||||||
}
|
|
||||||
instr := &decInstr{elemOp, 0, elemIndir, 0};
|
instr := &decInstr{elemOp, 0, elemIndir, 0};
|
||||||
if DecodeUint(state) != uint64(length) {
|
|
||||||
state.err = os.ErrorString("length mismatch in decodeArray");
|
|
||||||
}
|
|
||||||
for i := 0; i < length && state.err == nil; i++ {
|
for i := 0; i < length && state.err == nil; i++ {
|
||||||
up := unsafe.Pointer(p);
|
up := unsafe.Pointer(p);
|
||||||
if elemIndir > 1 {
|
if elemIndir > 1 {
|
||||||
|
|
@ -339,6 +326,43 @@ func decodeArray(atyp reflect.ArrayType, state *DecState, p uintptr, elemOp decO
|
||||||
return state.err
|
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 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());
|
||||||
|
*(**byte)(up) = &b[0];
|
||||||
|
}
|
||||||
|
p = *(*uintptr)(up);
|
||||||
|
}
|
||||||
|
if DecodeUint(state) != uint64(length) {
|
||||||
|
return os.ErrorString("length mismatch in decodeArray");
|
||||||
|
}
|
||||||
|
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 *(*unsafe.Pointer)(up) == nil {
|
||||||
|
// Allocate the slice header.
|
||||||
|
*(*unsafe.Pointer)(up) = unsafe.Pointer(new(reflect.SliceHeader));
|
||||||
|
}
|
||||||
|
p = *(*uintptr)(up);
|
||||||
|
}
|
||||||
|
// 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)
|
var decEngineMap = make(map[reflect.Type] *decEngine)
|
||||||
var decOpMap = map[int] decOp {
|
var decOpMap = map[int] decOp {
|
||||||
reflect.BoolKind: decBool,
|
reflect.BoolKind: decBool,
|
||||||
|
|
@ -370,6 +394,11 @@ func decOpFor(typ reflect.Type) decOp {
|
||||||
case atyp.Elem().Kind() == reflect.Uint8Kind:
|
case atyp.Elem().Kind() == reflect.Uint8Kind:
|
||||||
op = decUint8Array
|
op = decUint8Array
|
||||||
case atyp.IsSlice():
|
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():
|
case !atyp.IsSlice():
|
||||||
elemOp := decOpFor(atyp.Elem());
|
elemOp := decOpFor(atyp.Elem());
|
||||||
_, elemIndir := indirect(atyp.Elem());
|
_, elemIndir := indirect(atyp.Elem());
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue