mirror of
https://github.com/golang/go
synced 2024-10-03 06:21:21 -06:00
json: use new reflect interface (CL 31107)
R=r DELTA=192 (52 added, 43 deleted, 97 changed) OCL=31116 CL=31286
This commit is contained in:
parent
65dbe76532
commit
1b35969871
@ -10,6 +10,7 @@ package json
|
||||
import (
|
||||
"json";
|
||||
"reflect";
|
||||
"strings";
|
||||
)
|
||||
|
||||
type _StructBuilder struct {
|
||||
@ -18,39 +19,51 @@ type _StructBuilder struct {
|
||||
|
||||
var nobuilder *_StructBuilder
|
||||
|
||||
func isfloat(v reflect.Value) bool {
|
||||
switch v := v.(type) {
|
||||
case *reflect.FloatValue:
|
||||
return true;
|
||||
case *reflect.Float32Value:
|
||||
return true;
|
||||
case *reflect.Float64Value:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
func setfloat(v reflect.Value, f float64) {
|
||||
switch v.Kind() {
|
||||
case reflect.FloatKind:
|
||||
v.(reflect.FloatValue).Set(float(f));
|
||||
case reflect.Float32Kind:
|
||||
v.(reflect.Float32Value).Set(float32(f));
|
||||
case reflect.Float64Kind:
|
||||
v.(reflect.Float64Value).Set(float64(f));
|
||||
switch v := v.(type) {
|
||||
case *reflect.FloatValue:
|
||||
v.Set(float(f));
|
||||
case *reflect.Float32Value:
|
||||
v.Set(float32(f));
|
||||
case *reflect.Float64Value:
|
||||
v.Set(float64(f));
|
||||
}
|
||||
}
|
||||
|
||||
func setint(v reflect.Value, i int64) {
|
||||
switch v.Kind() {
|
||||
case reflect.IntKind:
|
||||
v.(reflect.IntValue).Set(int(i));
|
||||
case reflect.Int8Kind:
|
||||
v.(reflect.Int8Value).Set(int8(i));
|
||||
case reflect.Int16Kind:
|
||||
v.(reflect.Int16Value).Set(int16(i));
|
||||
case reflect.Int32Kind:
|
||||
v.(reflect.Int32Value).Set(int32(i));
|
||||
case reflect.Int64Kind:
|
||||
v.(reflect.Int64Value).Set(int64(i));
|
||||
case reflect.UintKind:
|
||||
v.(reflect.UintValue).Set(uint(i));
|
||||
case reflect.Uint8Kind:
|
||||
v.(reflect.Uint8Value).Set(uint8(i));
|
||||
case reflect.Uint16Kind:
|
||||
v.(reflect.Uint16Value).Set(uint16(i));
|
||||
case reflect.Uint32Kind:
|
||||
v.(reflect.Uint32Value).Set(uint32(i));
|
||||
case reflect.Uint64Kind:
|
||||
v.(reflect.Uint64Value).Set(uint64(i));
|
||||
switch v := v.(type) {
|
||||
case *reflect.IntValue:
|
||||
v.Set(int(i));
|
||||
case *reflect.Int8Value:
|
||||
v.Set(int8(i));
|
||||
case *reflect.Int16Value:
|
||||
v.Set(int16(i));
|
||||
case *reflect.Int32Value:
|
||||
v.Set(int32(i));
|
||||
case *reflect.Int64Value:
|
||||
v.Set(int64(i));
|
||||
case *reflect.UintValue:
|
||||
v.Set(uint(i));
|
||||
case *reflect.Uint8Value:
|
||||
v.Set(uint8(i));
|
||||
case *reflect.Uint16Value:
|
||||
v.Set(uint16(i));
|
||||
case *reflect.Uint32Value:
|
||||
v.Set(uint32(i));
|
||||
case *reflect.Uint64Value:
|
||||
v.Set(uint64(i));
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,10 +72,9 @@ func (b *_StructBuilder) Int64(i int64) {
|
||||
return
|
||||
}
|
||||
v := b.val;
|
||||
switch v.Kind() {
|
||||
case reflect.FloatKind, reflect.Float32Kind, reflect.Float64Kind:
|
||||
if isfloat(v) {
|
||||
setfloat(v, float64(i));
|
||||
default:
|
||||
} else {
|
||||
setint(v, i);
|
||||
}
|
||||
}
|
||||
@ -72,10 +84,9 @@ func (b *_StructBuilder) Uint64(i uint64) {
|
||||
return
|
||||
}
|
||||
v := b.val;
|
||||
switch v.Kind() {
|
||||
case reflect.FloatKind, reflect.Float32Kind, reflect.Float64Kind:
|
||||
if isfloat(v) {
|
||||
setfloat(v, float64(i));
|
||||
default:
|
||||
} else {
|
||||
setint(v, int64(i));
|
||||
}
|
||||
}
|
||||
@ -85,10 +96,9 @@ func (b *_StructBuilder) Float64(f float64) {
|
||||
return
|
||||
}
|
||||
v := b.val;
|
||||
switch v.Kind() {
|
||||
case reflect.FloatKind, reflect.Float32Kind, reflect.Float64Kind:
|
||||
if isfloat(v) {
|
||||
setfloat(v, f);
|
||||
default:
|
||||
} else {
|
||||
setint(v, int64(f));
|
||||
}
|
||||
}
|
||||
@ -100,8 +110,8 @@ func (b *_StructBuilder) String(s string) {
|
||||
if b == nil {
|
||||
return
|
||||
}
|
||||
if v := b.val; v.Kind() == reflect.StringKind {
|
||||
v.(reflect.StringValue).Set(s);
|
||||
if v, ok := b.val.(*reflect.StringValue); ok {
|
||||
v.Set(s);
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,8 +119,8 @@ func (b *_StructBuilder) Bool(tf bool) {
|
||||
if b == nil {
|
||||
return
|
||||
}
|
||||
if v := b.val; v.Kind() == reflect.BoolKind {
|
||||
v.(reflect.BoolValue).Set(tf);
|
||||
if v, ok := b.val.(*reflect.BoolValue); ok {
|
||||
v.Set(tf);
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,10 +128,9 @@ func (b *_StructBuilder) Array() {
|
||||
if b == nil {
|
||||
return
|
||||
}
|
||||
if v := b.val; v.Kind() == reflect.ArrayKind {
|
||||
av := v.(reflect.ArrayValue);
|
||||
if av.IsSlice() && av.IsNil() {
|
||||
av.Set(reflect.NewSliceValue(av.Type().(reflect.ArrayType), 0, 8));
|
||||
if v, ok := b.val.(*reflect.SliceValue); ok {
|
||||
if v.IsNil() {
|
||||
v.Set(reflect.MakeSlice(v.Type().(*reflect.SliceType), 0, 8));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -130,41 +139,41 @@ func (b *_StructBuilder) Elem(i int) Builder {
|
||||
if b == nil || i < 0 {
|
||||
return nobuilder
|
||||
}
|
||||
v := b.val;
|
||||
if v.Kind() != reflect.ArrayKind {
|
||||
return nobuilder
|
||||
}
|
||||
av := v.(reflect.ArrayValue);
|
||||
if av.IsSlice() && i > av.Cap() {
|
||||
n := av.Cap();
|
||||
if n < 8 {
|
||||
n = 8
|
||||
switch v := b.val.(type) {
|
||||
case *reflect.ArrayValue:
|
||||
if i < v.Len() {
|
||||
return &_StructBuilder{ v.Elem(i) }
|
||||
}
|
||||
for n <= i {
|
||||
n *= 2
|
||||
case *reflect.SliceValue:
|
||||
if i > v.Cap() {
|
||||
n := v.Cap();
|
||||
if n < 8 {
|
||||
n = 8
|
||||
}
|
||||
for n <= i {
|
||||
n *= 2
|
||||
}
|
||||
nv := reflect.MakeSlice(v.Type().(*reflect.SliceType), v.Len(), n);
|
||||
reflect.ArrayCopy(nv, v);
|
||||
v.Set(nv);
|
||||
}
|
||||
if v.Len() <= i && i < v.Cap() {
|
||||
v.SetLen(i+1);
|
||||
}
|
||||
if i < v.Len() {
|
||||
return &_StructBuilder{ v.Elem(i) }
|
||||
}
|
||||
av1 := reflect.NewSliceValue(av.Type().(reflect.ArrayType), av.Len(), n);
|
||||
av1.CopyFrom(av, av.Len());
|
||||
av.Set(av1);
|
||||
}
|
||||
// Array was grown above, or is fixed size.
|
||||
if av.Len() <= i && i < av.Cap() {
|
||||
av.SetLen(i+1);
|
||||
}
|
||||
if i < av.Len() {
|
||||
return &_StructBuilder{ av.Elem(i) }
|
||||
}
|
||||
return nobuilder
|
||||
return nobuilder;
|
||||
}
|
||||
|
||||
func (b *_StructBuilder) Map() {
|
||||
if b == nil {
|
||||
return
|
||||
}
|
||||
if v := b.val; v.Kind() == reflect.PtrKind {
|
||||
pv := v.(reflect.PtrValue);
|
||||
if pv.Get() == nil {
|
||||
pv.SetSub(reflect.NewZeroValue(pv.Type().(reflect.PtrType).Sub()))
|
||||
if v, ok := b.val.(*reflect.PtrValue); ok {
|
||||
if v.IsNil() {
|
||||
v.PointTo(reflect.MakeZero(v.Type().(*reflect.PtrType).Elem()))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -173,17 +182,17 @@ func (b *_StructBuilder) Key(k string) Builder {
|
||||
if b == nil {
|
||||
return nobuilder
|
||||
}
|
||||
v := b.val;
|
||||
if v.Kind() == reflect.PtrKind {
|
||||
v = v.(reflect.PtrValue).Sub();
|
||||
}
|
||||
if v.Kind() == reflect.StructKind {
|
||||
sv := v.(reflect.StructValue);
|
||||
t := v.Type().(reflect.StructType);
|
||||
for i := 0; i < t.Len(); i++ {
|
||||
name, typ, tag, off := t.Field(i);
|
||||
if k == name {
|
||||
return &_StructBuilder{ sv.Field(i) }
|
||||
if v, ok := reflect.Indirect(b.val).(*reflect.StructValue); ok {
|
||||
t := v.Type().(*reflect.StructType);
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
if t.Field(i).Name == k {
|
||||
return &_StructBuilder{ v.Field(i) }
|
||||
}
|
||||
}
|
||||
// Again, case-insensitive.
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
if strings.LowerASCII(t.Field(i).Name) == k {
|
||||
return &_StructBuilder{ v.Field(i) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,24 +10,24 @@ import (
|
||||
)
|
||||
|
||||
type _MyStruct struct {
|
||||
t bool;
|
||||
f bool;
|
||||
s string;
|
||||
i8 int8;
|
||||
i16 int16;
|
||||
i32 int32;
|
||||
i64 int64;
|
||||
u8 uint8;
|
||||
u16 uint16;
|
||||
u32 uint32;
|
||||
u64 uint64;
|
||||
i int;
|
||||
u uint;
|
||||
fl float;
|
||||
fl32 float32;
|
||||
fl64 float64;
|
||||
a []string;
|
||||
my *_MyStruct;
|
||||
T bool;
|
||||
F bool;
|
||||
S string;
|
||||
I8 int8;
|
||||
I16 int16;
|
||||
I32 int32;
|
||||
I64 int64;
|
||||
U8 uint8;
|
||||
U16 uint16;
|
||||
U32 uint32;
|
||||
U64 uint64;
|
||||
I int;
|
||||
U uint;
|
||||
Fl float;
|
||||
Fl32 float32;
|
||||
Fl64 float64;
|
||||
A []string;
|
||||
My *_MyStruct;
|
||||
};
|
||||
|
||||
const _Encoded =
|
||||
@ -48,35 +48,35 @@ func _Check(t *testing.T, ok bool, name string, v interface{}) {
|
||||
|
||||
func TestUnmarshal(t *testing.T) {
|
||||
var m _MyStruct;
|
||||
m.f = true;
|
||||
m.F = true;
|
||||
ok, errtok := Unmarshal(_Encoded, &m);
|
||||
if !ok {
|
||||
t.Fatalf("Unmarshal failed near %s", errtok);
|
||||
}
|
||||
_Check(t, m.t==true, "t", m.t);
|
||||
_Check(t, m.f==false, "f", m.f);
|
||||
_Check(t, m.s=="abc", "s", m.s);
|
||||
_Check(t, m.i8==1, "i8", m.i8);
|
||||
_Check(t, m.i16==2, "i16", m.i16);
|
||||
_Check(t, m.i32==3, "i32", m.i32);
|
||||
_Check(t, m.i64==4, "i64", m.i64);
|
||||
_Check(t, m.u8==5, "u8", m.u8);
|
||||
_Check(t, m.u16==6, "u16", m.u16);
|
||||
_Check(t, m.u32==7, "u32", m.u32);
|
||||
_Check(t, m.u64==8, "u64", m.u64);
|
||||
_Check(t, m.i==-9, "i", m.i);
|
||||
_Check(t, m.u==10, "u", m.u);
|
||||
_Check(t, m.fl==11.5, "fl", m.fl);
|
||||
_Check(t, m.fl32==12.25, "fl32", m.fl32);
|
||||
_Check(t, m.fl64==13.75, "fl64", m.fl64);
|
||||
_Check(t, m.a!=nil, "a", m.a);
|
||||
if m.a != nil {
|
||||
_Check(t, m.a[0]=="x", "a[0]", m.a[0]);
|
||||
_Check(t, m.a[1]=="y", "a[1]", m.a[1]);
|
||||
_Check(t, m.a[2]=="z", "a[2]", m.a[2]);
|
||||
_Check(t, m.T==true, "t", m.T);
|
||||
_Check(t, m.F==false, "f", m.F);
|
||||
_Check(t, m.S=="abc", "s", m.S);
|
||||
_Check(t, m.I8==1, "i8", m.I8);
|
||||
_Check(t, m.I16==2, "i16", m.I16);
|
||||
_Check(t, m.I32==3, "i32", m.I32);
|
||||
_Check(t, m.I64==4, "i64", m.I64);
|
||||
_Check(t, m.U8==5, "u8", m.U8);
|
||||
_Check(t, m.U16==6, "u16", m.U16);
|
||||
_Check(t, m.U32==7, "u32", m.U32);
|
||||
_Check(t, m.U64==8, "u64", m.U64);
|
||||
_Check(t, m.I==-9, "i", m.I);
|
||||
_Check(t, m.U==10, "u", m.U);
|
||||
_Check(t, m.Fl==11.5, "fl", m.Fl);
|
||||
_Check(t, m.Fl32==12.25, "fl32", m.Fl32);
|
||||
_Check(t, m.Fl64==13.75, "fl64", m.Fl64);
|
||||
_Check(t, m.A!=nil, "a", m.A);
|
||||
if m.A != nil {
|
||||
_Check(t, m.A[0]=="x", "a[0]", m.A[0]);
|
||||
_Check(t, m.A[1]=="y", "a[1]", m.A[1]);
|
||||
_Check(t, m.A[2]=="z", "a[2]", m.A[2]);
|
||||
}
|
||||
_Check(t, m.my!=nil, "my", m.my);
|
||||
if m.my != nil {
|
||||
_Check(t, m.my.s=="subguy", "my.s", m.my.s);
|
||||
_Check(t, m.My!=nil, "my", m.My);
|
||||
if m.My != nil {
|
||||
_Check(t, m.My.S=="subguy", "my.s", m.My.S);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user