Ported to weekly Go release.
diff --git a/decode.go b/decode.go index 9db4102..3a3dee9 100644 --- a/decode.go +++ b/decode.go
@@ -233,10 +233,10 @@ again = false setter, _ := (*out).Interface().(Setter) if tag != "!!null" || setter != nil { - if pv, ok := (*out).(*reflect.PtrValue); ok { + if pv := (*out); pv.Kind() == reflect.Ptr { if pv.IsNil() { - *out = reflect.MakeZero(pv.Type().(*reflect.PtrType).Elem()) - pv.PointTo(*out) + *out = reflect.Zero(pv.Type().Elem()) + pv.Set((*out).Addr()) } else { *out = pv.Elem() } @@ -246,7 +246,7 @@ } if setter != nil { var arg interface{} - *out = reflect.NewValue(&arg).(*reflect.PtrValue).Elem() + *out = reflect.NewValue(&arg).Elem() return func() { *good = setter.SetYAML(tag, arg) } @@ -307,55 +307,59 @@ defer set() } } - switch out := out.(type) { - case *reflect.StringValue: - out.Set(n.value) + switch out.Kind() { + case reflect.String: + out.SetString(n.value) good = true - case *reflect.InterfaceValue: - out.Set(reflect.NewValue(resolved)) + case reflect.Interface: + if resolved == nil { + out.Set(reflect.Zero(out.Type())) + } else { + out.Set(reflect.NewValue(resolved)) + } good = true - case *reflect.IntValue: + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: switch resolved := resolved.(type) { case int: - if !out.Overflow(int64(resolved)) { - out.Set(int64(resolved)) + if !out.OverflowInt(int64(resolved)) { + out.SetInt(int64(resolved)) good = true } case int64: - if !out.Overflow(resolved) { - out.Set(resolved) + if !out.OverflowInt(resolved) { + out.SetInt(resolved) good = true } } - case *reflect.UintValue: + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: switch resolved := resolved.(type) { case int: if resolved >= 0 { - out.Set(uint64(resolved)) + out.SetUint(uint64(resolved)) good = true } case int64: if resolved >= 0 { - out.Set(uint64(resolved)) + out.SetUint(uint64(resolved)) good = true } } - case *reflect.BoolValue: + case reflect.Bool: switch resolved := resolved.(type) { case bool: - out.Set(resolved) + out.SetBool(resolved) good = true } - case *reflect.FloatValue: + case reflect.Float32, reflect.Float64: switch resolved := resolved.(type) { case float64: - out.Set(resolved) + out.SetFloat(resolved) good = true } - case *reflect.PtrValue: + case reflect.Ptr: switch resolved := resolved.(type) { case nil: - out.PointTo(nil) + out.Set(reflect.Zero(out.Type())) good = true } default: @@ -368,24 +372,23 @@ if set := d.setter("!!seq", &out, &good); set != nil { defer set() } - if iface, ok := out.(*reflect.InterfaceValue); ok { + if out.Kind() == reflect.Interface { // No type hints. Will have to use a generic sequence. + iface := out out = reflect.NewValue(make([]interface{}, 0)) - iface.SetValue(out) + iface.Set(out) } - sv, ok := out.(*reflect.SliceValue) - if !ok { + if out.Kind() != reflect.Slice { return false } - st := sv.Type().(*reflect.SliceType) - et := st.Elem() + et := out.Type().Elem() l := len(n.children) for i := 0; i < l; i++ { - e := reflect.MakeZero(et) + e := reflect.Zero(et) if ok := d.unmarshal(n.children[i], e); ok { - sv.SetValue(reflect.Append(sv, e)) + out.Set(reflect.Append(out, e)) } } return true @@ -395,50 +398,50 @@ if set := d.setter("!!map", &out, &good); set != nil { defer set() } - if s, ok := out.(*reflect.StructValue); ok { - return d.mappingStruct(n, s) + if out.Kind() == reflect.Struct { + return d.mappingStruct(n, out) } - if iface, ok := out.(*reflect.InterfaceValue); ok { + if out.Kind() == reflect.Interface { // No type hints. Will have to use a generic map. + iface := out out = reflect.NewValue(make(map[interface{}]interface{})) - iface.SetValue(out) + iface.Set(out) } - mv, ok := out.(*reflect.MapValue) - if !ok { + if out.Kind() != reflect.Map { return false } - mt := mv.Type().(*reflect.MapType) - kt := mt.Key() - et := mt.Elem() + outt := out.Type() + kt := outt.Key() + et := outt.Elem() l := len(n.children) for i := 0; i < l; i += 2 { - k := reflect.MakeZero(kt) + k := reflect.Zero(kt) if d.unmarshal(n.children[i], k) { - e := reflect.MakeZero(et) + e := reflect.Zero(et) if d.unmarshal(n.children[i+1], e) { - mv.SetElem(k, e) + out.SetMapIndex(k, e) } } } return true } -func (d *decoder) mappingStruct(n *node, out *reflect.StructValue) (good bool) { - fields, err := getStructFields(out.Type().(*reflect.StructType)) +func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) { + fields, err := getStructFields(out.Type()) if err != nil { panic(err) } - name := reflect.NewValue("").(*reflect.StringValue) + name := reflect.NewValue("") fieldsMap := fields.Map l := len(n.children) for i := 0; i < l; i += 2 { if !d.unmarshal(n.children[i], name) { continue } - if info, ok := fieldsMap[name.Get()]; ok { + if info, ok := fieldsMap[name.String()]; ok { d.unmarshal(n.children[i+1], out.Field(info.Num)) } }
diff --git a/decode_test.go b/decode_test.go index 5fdf2b4..5c80a20 100644 --- a/decode_test.go +++ b/decode_test.go
@@ -133,19 +133,19 @@ func (s *S) TestUnmarshal(c *C) { - for _, item := range unmarshalTests { + for i, item := range unmarshalTests { t := reflect.NewValue(item.value).Type() var value interface{} - if t, ok := t.(*reflect.MapType); ok { + if t.Kind() == reflect.Map { value = reflect.MakeMap(t).Interface() } else { - pt := reflect.NewValue(item.value).Type().(*reflect.PtrType) - pv := reflect.MakeZero(pt).(*reflect.PtrValue) - pv.PointTo(reflect.MakeZero(pt.Elem())) + pt := reflect.NewValue(item.value).Type() + pv := reflect.Zero(pt) + pv.Set(reflect.Zero(pt.Elem()).Addr()) value = pv.Interface() } err := goyaml.Unmarshal([]byte(item.data), value) - c.Assert(err, IsNil) + c.Assert(err, IsNil, Bug("Item #%d", i)) c.Assert(value, Equals, item.value) } }
diff --git a/encode.go b/encode.go index 2eba6a5..242a722 100644 --- a/encode.go +++ b/encode.go
@@ -92,51 +92,51 @@ } in = reflect.NewValue(value) } - switch in := in.(type) { - case *reflect.InterfaceValue: + switch in.Kind() { + case reflect.Interface: if in.IsNil() { e.nilv() } else { e.marshal(tag, in.Elem()) } - case *reflect.MapValue: + case reflect.Map: e.mapv(tag, in) - case *reflect.PtrValue: + case reflect.Ptr: if in.IsNil() { e.nilv() } else { e.marshal(tag, in.Elem()) } - case *reflect.StructValue: + case reflect.Struct: e.structv(tag, in) - case *reflect.SliceValue: + case reflect.Slice: e.slicev(tag, in) - case *reflect.StringValue: + case reflect.String: e.stringv(tag, in) - case *reflect.IntValue: + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: e.intv(tag, in) - case *reflect.UintValue: + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: e.uintv(tag, in) - case *reflect.FloatValue: + case reflect.Float32, reflect.Float64: e.floatv(tag, in) - case *reflect.BoolValue: + case reflect.Bool: e.boolv(tag, in) default: panic("Can't marshal type yet: " + in.Type().String()) } } -func (e *encoder) mapv(tag string, in *reflect.MapValue) { +func (e *encoder) mapv(tag string, in reflect.Value) { e.mappingv(tag, func() { - for _, k := range in.Keys() { + for _, k := range in.MapKeys() { e.marshal("", k) - e.marshal("", in.Elem(k)) + e.marshal("", in.MapIndex(k)) } }) } -func (e *encoder) structv(tag string, in *reflect.StructValue) { - fields, err := getStructFields(in.Type().(*reflect.StructType)) +func (e *encoder) structv(tag string, in reflect.Value) { + fields, err := getStructFields(in.Type()) if err != nil { panic(err) } @@ -175,7 +175,7 @@ e.emit() } -func (e *encoder) slicev(tag string, in *reflect.SliceValue) { +func (e *encoder) slicev(tag string, in reflect.Value) { var ctag *C.yaml_char_t var free func() var cimplicit C.int @@ -197,15 +197,15 @@ e.emit() n := in.Len() for i := 0; i < n; i++ { - e.marshal("", in.Elem(i)) + e.marshal("", in.Index(i)) } C.yaml_sequence_end_event_initialize(&e.event) e.emit() } -func (e *encoder) stringv(tag string, in *reflect.StringValue) { +func (e *encoder) stringv(tag string, in reflect.Value) { var style C.yaml_scalar_style_t - s := in.Get() + s := in.String() if rtag, _ := resolve("", s); rtag != "!!str" { style = C.YAML_DOUBLE_QUOTED_SCALAR_STYLE } else { @@ -214,9 +214,9 @@ e.emitScalar(s, "", tag, style) } -func (e *encoder) boolv(tag string, in *reflect.BoolValue) { +func (e *encoder) boolv(tag string, in reflect.Value) { var s string - if in.Get() { + if in.Bool() { s = "true" } else { s = "false" @@ -224,19 +224,19 @@ e.emitScalar(s, "", tag, C.YAML_PLAIN_SCALAR_STYLE) } -func (e *encoder) intv(tag string, in *reflect.IntValue) { - s := strconv.Itoa64(in.Get()) +func (e *encoder) intv(tag string, in reflect.Value) { + s := strconv.Itoa64(in.Int()) e.emitScalar(s, "", tag, C.YAML_PLAIN_SCALAR_STYLE) } -func (e *encoder) uintv(tag string, in *reflect.UintValue) { - s := strconv.Uitoa64(in.Get()) +func (e *encoder) uintv(tag string, in reflect.Value) { + s := strconv.Uitoa64(in.Uint()) e.emitScalar(s, "", tag, C.YAML_PLAIN_SCALAR_STYLE) } -func (e *encoder) floatv(tag string, in *reflect.FloatValue) { +func (e *encoder) floatv(tag string, in reflect.Value) { // FIXME: Handle 64 bits here. - s := strconv.Ftoa32(float32(in.Get()), 'g', -1) + s := strconv.Ftoa32(float32(in.Float()), 'g', -1) switch s { case "+Inf": s = ".inf"
diff --git a/goyaml.go b/goyaml.go index 58a9a05..6d69268 100644 --- a/goyaml.go +++ b/goyaml.go
@@ -21,6 +21,8 @@ if r := recover(); r != nil { if _, ok := r.(runtime.Error); ok { panic(r) + } else if _, ok := r.(*reflect.ValueError); ok { + panic(r) } else if s, ok := r.(string); ok { *err = os.ErrorString("YAML error: " + s) } else if e, ok := r.(os.Error); ok { @@ -144,7 +146,7 @@ var fieldMap = make(map[string]*structFields) var fieldMapMutex sync.RWMutex -func getStructFields(st *reflect.StructType) (*structFields, os.Error) { +func getStructFields(st reflect.Type) (*structFields, os.Error) { path := st.PkgPath() name := st.Name() @@ -208,21 +210,21 @@ } func isZero(v reflect.Value) bool { - switch v := v.(type) { - case *reflect.StringValue: - return len(v.Get()) == 0 - case *reflect.InterfaceValue: + switch v.Kind() { + case reflect.String: + return len(v.String()) == 0 + case reflect.Interface: return v.IsNil() - case *reflect.SliceValue: + case reflect.Slice: return v.Len() == 0 - case *reflect.MapValue: + case reflect.Map: return v.Len() == 0 - case *reflect.IntValue: - return v.Get() == 0 - case *reflect.UintValue: - return v.Get() == 0 - case *reflect.BoolValue: - return !v.Get() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Bool: + return !v.Bool() } return false }