]> Cypherpunks repositories - gostls13.git/commitdiff
json: use new reflect interface (CL 31107)
authorRuss Cox <rsc@golang.org>
Tue, 7 Jul 2009 18:04:18 +0000 (11:04 -0700)
committerRuss Cox <rsc@golang.org>
Tue, 7 Jul 2009 18:04:18 +0000 (11:04 -0700)
R=r
DELTA=192  (52 added, 43 deleted, 97 changed)
OCL=31116
CL=31286

src/pkg/json/struct.go
src/pkg/json/struct_test.go

index 400bf8b6c974b2de654e517f5eef98a36b14992b..81887b1c80c899d7302759004395f09a4c90be65 100644 (file)
@@ -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) }
                        }
                }
        }
index 193bfe139e1a044e5de293cedb73188a3afd1081..4fbfd424c1b8f9a029a8c047732407ff42b641fc 100644 (file)
@@ -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);
        }
 }