Commit 1b359698 authored by Russ Cox's avatar Russ Cox

json: use new reflect interface (CL 31107)

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