Commit 9b04c9b1 authored by Andrew Gerrand's avatar Andrew Gerrand

json: use panic/recover to handle errors in Marshal

R=r, gri
CC=golang-dev
https://golang.org/cl/872041
parent 735e00d4
...@@ -346,29 +346,24 @@ func (s *writeState) writeIndent() { ...@@ -346,29 +346,24 @@ func (s *writeState) writeIndent() {
} }
} }
func (s *writeState) writeArrayOrSlice(val reflect.ArrayOrSliceValue) (err os.Error) { func (s *writeState) writeArrayOrSlice(val reflect.ArrayOrSliceValue) {
s.descend('[') s.descend('[')
for i := 0; i < val.Len(); i++ { for i := 0; i < val.Len(); i++ {
s.writeIndent() s.writeIndent()
s.writeValue(val.Elem(i))
if err = s.writeValue(val.Elem(i)); err != nil {
return
}
if i < val.Len()-1 { if i < val.Len()-1 {
s.WriteByte(',') s.WriteByte(',')
} }
} }
s.ascend(']') s.ascend(']')
return
} }
func (s *writeState) writeMap(val *reflect.MapValue) (err os.Error) { func (s *writeState) writeMap(val *reflect.MapValue) {
key := val.Type().(*reflect.MapType).Key() key := val.Type().(*reflect.MapType).Key()
if _, ok := key.(*reflect.StringType); !ok { if _, ok := key.(*reflect.StringType); !ok {
return &MarshalError{val.Type()} panic(&MarshalError{val.Type()})
} }
s.descend('{') s.descend('{')
...@@ -376,45 +371,34 @@ func (s *writeState) writeMap(val *reflect.MapValue) (err os.Error) { ...@@ -376,45 +371,34 @@ func (s *writeState) writeMap(val *reflect.MapValue) (err os.Error) {
keys := val.Keys() keys := val.Keys()
for i := 0; i < len(keys); i++ { for i := 0; i < len(keys); i++ {
s.writeIndent() s.writeIndent()
fmt.Fprintf(s, "%s:", Quote(keys[i].(*reflect.StringValue).Get())) fmt.Fprintf(s, "%s:", Quote(keys[i].(*reflect.StringValue).Get()))
s.writeValue(val.Elem(keys[i]))
if err = s.writeValue(val.Elem(keys[i])); err != nil {
return
}
if i < len(keys)-1 { if i < len(keys)-1 {
s.WriteByte(',') s.WriteByte(',')
} }
} }
s.ascend('}') s.ascend('}')
return
} }
func (s *writeState) writeStruct(val *reflect.StructValue) (err os.Error) { func (s *writeState) writeStruct(val *reflect.StructValue) {
s.descend('{') s.descend('{')
typ := val.Type().(*reflect.StructType) typ := val.Type().(*reflect.StructType)
for i := 0; i < val.NumField(); i++ { for i := 0; i < val.NumField(); i++ {
s.writeIndent() s.writeIndent()
fieldValue := val.Field(i)
fmt.Fprintf(s, "%s:", Quote(typ.Field(i).Name)) fmt.Fprintf(s, "%s:", Quote(typ.Field(i).Name))
if err = s.writeValue(fieldValue); err != nil { s.writeValue(val.Field(i))
return
}
if i < val.NumField()-1 { if i < val.NumField()-1 {
s.WriteByte(',') s.WriteByte(',')
} }
} }
s.ascend('}') s.ascend('}')
return
} }
func (s *writeState) writeValue(val reflect.Value) (err os.Error) { func (s *writeState) writeValue(val reflect.Value) {
if val == nil { if val == nil {
fmt.Fprint(s, "null") fmt.Fprint(s, "null")
return return
...@@ -424,28 +408,28 @@ func (s *writeState) writeValue(val reflect.Value) (err os.Error) { ...@@ -424,28 +408,28 @@ func (s *writeState) writeValue(val reflect.Value) (err os.Error) {
case *reflect.StringValue: case *reflect.StringValue:
fmt.Fprint(s, Quote(v.Get())) fmt.Fprint(s, Quote(v.Get()))
case *reflect.ArrayValue: case *reflect.ArrayValue:
err = s.writeArrayOrSlice(v) s.writeArrayOrSlice(v)
case *reflect.SliceValue: case *reflect.SliceValue:
err = s.writeArrayOrSlice(v) s.writeArrayOrSlice(v)
case *reflect.MapValue: case *reflect.MapValue:
err = s.writeMap(v) s.writeMap(v)
case *reflect.StructValue: case *reflect.StructValue:
err = s.writeStruct(v) s.writeStruct(v)
case *reflect.ChanValue, case *reflect.ChanValue,
*reflect.UnsafePointerValue, *reflect.UnsafePointerValue,
*reflect.FuncValue: *reflect.FuncValue:
err = &MarshalError{val.Type()} panic(&MarshalError{val.Type()})
case *reflect.InterfaceValue: case *reflect.InterfaceValue:
if v.IsNil() { if v.IsNil() {
fmt.Fprint(s, "null") fmt.Fprint(s, "null")
} else { } else {
err = s.writeValue(v.Elem()) s.writeValue(v.Elem())
} }
case *reflect.PtrValue: case *reflect.PtrValue:
if v.IsNil() { if v.IsNil() {
fmt.Fprint(s, "null") fmt.Fprint(s, "null")
} else { } else {
err = s.writeValue(v.Elem()) s.writeValue(v.Elem())
} }
case *reflect.UintptrValue: case *reflect.UintptrValue:
fmt.Fprintf(s, "%d", v.Get()) fmt.Fprintf(s, "%d", v.Get())
...@@ -461,14 +445,15 @@ func (s *writeState) writeValue(val reflect.Value) (err os.Error) { ...@@ -461,14 +445,15 @@ func (s *writeState) writeValue(val reflect.Value) (err os.Error) {
value := val.(reflect.Value) value := val.(reflect.Value)
fmt.Fprintf(s, "%#v", value.Interface()) fmt.Fprintf(s, "%#v", value.Interface())
} }
return
} }
func (s *writeState) marshal(w io.Writer, val interface{}) (err os.Error) { func (s *writeState) marshal(w io.Writer, val interface{}) (err os.Error) {
err = s.writeValue(reflect.NewValue(val)) defer func() {
if err != nil { if e := recover(); e != nil {
return err = e.(*MarshalError)
} }
}()
s.writeValue(reflect.NewValue(val))
if s.newlines { if s.newlines {
s.WriteByte('\n') s.WriteByte('\n')
} }
......
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