From 1b359698712a625b8967a2e596fd065c35c99bc1 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 7 Jul 2009 11:04:18 -0700 Subject: [PATCH] json: use new reflect interface (CL 31107) R=r DELTA=192 (52 added, 43 deleted, 97 changed) OCL=31116 CL=31286 --- src/pkg/json/struct.go | 173 +++++++++++++++++++----------------- src/pkg/json/struct_test.go | 86 +++++++++--------- 2 files changed, 134 insertions(+), 125 deletions(-) diff --git a/src/pkg/json/struct.go b/src/pkg/json/struct.go index 400bf8b6c9..81887b1c80 100644 --- a/src/pkg/json/struct.go +++ b/src/pkg/json/struct.go @@ -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) } } } } diff --git a/src/pkg/json/struct_test.go b/src/pkg/json/struct_test.go index 193bfe139e..4fbfd424c1 100644 --- a/src/pkg/json/struct_test.go +++ b/src/pkg/json/struct_test.go @@ -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); } } -- 2.48.1