// Is there no data to look at? func empty(v reflect.Value) bool { v = reflect.Indirect(v) if v == nil { return true } switch v := v.(type) { case *reflect.BoolValue: return v.Get() == false case *reflect.StringValue: return v.Get() == "" case *reflect.StructValue: return false case *reflect.ArrayValue: return v.Len() == 0 case *reflect.SliceValue: return v.Len() == 0 } return true }
func (e *encodeState) reflectValue(v reflect.Value) { if v == nil { e.WriteString("null") return } if j, ok := v.Interface().(Marshaler); ok { b, err := j.MarshalXML() if err == nil { // copy XML into buffer, checking validity. err = Compact(&e.Buffer, b) } if err != nil { e.error(&MarshalerError{v.Type(), err}) } return } switch v := v.(type) { case *reflect.BoolValue: x := v.Get() if x { e.WriteString("true") } else { e.WriteString("false") } case *reflect.IntValue: e.WriteString(strconv.Itoa64(v.Get())) case *reflect.UintValue: e.WriteString(strconv.Uitoa64(v.Get())) case *reflect.FloatValue: e.WriteString(strconv.FtoaN(v.Get(), 'g', -1, v.Type().Bits())) case *reflect.StringValue: e.WriteString(v.Get()) case *reflect.StructValue: t := v.Type().(*reflect.StructType) e.openTag(t.Name()) n := v.NumField() for i := 0; i < n; i++ { f := t.Field(i) if f.Tag != "" { e.openTag(f.Tag) e.reflectValue(v.Field(i)) e.closeTag(f.Tag) } else { e.openTag(f.Name) e.reflectValue(v.Field(i)) e.closeTag(f.Name) } } e.closeTag(t.Name()) case *reflect.MapValue: if _, ok := v.Type().(*reflect.MapType).Key().(*reflect.StringType); !ok { e.error(&UnsupportedTypeError{v.Type()}) } if v.IsNil() { e.WriteString("null") break } e.WriteByte('{') var sv stringValues = v.Keys() sort.Sort(sv) for i, k := range sv { if i > 0 { e.WriteByte(',') } e.string(k.(*reflect.StringValue).Get()) e.WriteByte(':') e.reflectValue(v.Elem(k)) } e.WriteByte('}') case reflect.ArrayOrSliceValue: e.WriteByte('[') n := v.Len() for i := 0; i < n; i++ { if i > 0 { e.WriteByte(',') } e.reflectValue(v.Elem(i)) } e.WriteByte(']') case interfaceOrPtrValue: if v.IsNil() { e.WriteString("null") return } e.reflectValue(v.Elem()) default: e.error(&UnsupportedTypeError{v.Type()}) } return }
func (e *encoder) value(v reflect.Value) { switch v := v.(type) { case *reflect.ArrayValue: l := v.Len() for i := 0; i < l; i++ { e.value(v.Elem(i)) } case *reflect.StructValue: l := v.NumField() for i := 0; i < l; i++ { e.value(v.Field(i)) } case *reflect.SliceValue: l := v.Len() for i := 0; i < l; i++ { e.value(v.Elem(i)) } case *reflect.IntValue: switch v.Type().Kind() { case reflect.Int8: e.int8(int8(v.Get())) case reflect.Int16: e.int16(int16(v.Get())) case reflect.Int32: e.int32(int32(v.Get())) case reflect.Int64: e.int64(v.Get()) } case *reflect.UintValue: switch v.Type().Kind() { case reflect.Uint8: e.uint8(uint8(v.Get())) case reflect.Uint16: e.uint16(uint16(v.Get())) case reflect.Uint32: e.uint32(uint32(v.Get())) case reflect.Uint64: e.uint64(v.Get()) } case *reflect.FloatValue: switch v.Type().Kind() { case reflect.Float32: e.uint32(math.Float32bits(float32(v.Get()))) case reflect.Float64: e.uint64(math.Float64bits(v.Get())) } case *reflect.ComplexValue: switch v.Type().Kind() { case reflect.Complex64: x := v.Get() e.uint32(math.Float32bits(float32(real(x)))) e.uint32(math.Float32bits(float32(imag(x)))) case reflect.Complex128: x := v.Get() e.uint64(math.Float64bits(real(x))) e.uint64(math.Float64bits(imag(x))) } } }
func (e *encodeState) reflectValue(v reflect.Value) { if v == nil { e.WriteString("null") return } if j, ok := v.Interface().(Marshaler); ok { b, err := j.MarshalJSON() if err == nil { // copy JSON into buffer, checking validity. err = Compact(&e.Buffer, b) } if err != nil { e.error(&MarshalerError{v.Type(), err}) } return } switch v := v.(type) { case *reflect.BoolValue: x := v.Get() if x { e.WriteString("true") } else { e.WriteString("false") } case *reflect.IntValue: e.WriteString(strconv.Itoa64(v.Get())) case *reflect.UintValue: e.WriteString(strconv.Uitoa64(v.Get())) case *reflect.FloatValue: e.WriteString(strconv.FtoaN(v.Get(), 'g', -1, v.Type().Bits())) case *reflect.StringValue: e.string(v.Get()) case *reflect.StructValue: e.WriteByte('{') t := v.Type().(*reflect.StructType) n := v.NumField() first := true for i := 0; i < n; i++ { f := t.Field(i) if f.PkgPath != "" { continue } if first { first = false } else { e.WriteByte(',') } if isValidTag(f.Tag) { e.string(f.Tag) } else { e.string(f.Name) } e.WriteByte(':') e.reflectValue(v.Field(i)) } e.WriteByte('}') case *reflect.MapValue: if _, ok := v.Type().(*reflect.MapType).Key().(*reflect.StringType); !ok { e.error(&UnsupportedTypeError{v.Type()}) } if v.IsNil() { e.WriteString("null") break } e.WriteByte('{') var sv stringValues = v.Keys() sort.Sort(sv) for i, k := range sv { if i > 0 { e.WriteByte(',') } e.string(k.(*reflect.StringValue).Get()) e.WriteByte(':') e.reflectValue(v.Elem(k)) } e.WriteByte('}') case reflect.ArrayOrSliceValue: if v.Type() == byteSliceType { e.WriteByte('"') s := v.Interface().([]byte) if len(s) < 1024 { // for small buffers, using Encode directly is much faster. dst := make([]byte, base64.StdEncoding.EncodedLen(len(s))) base64.StdEncoding.Encode(dst, s) e.Write(dst) } else { // for large buffers, avoid unnecessary extra temporary // buffer space. enc := base64.NewEncoder(base64.StdEncoding, e) enc.Write(s) enc.Close() } e.WriteByte('"') break } e.WriteByte('[') n := v.Len() for i := 0; i < n; i++ { if i > 0 { e.WriteByte(',') } e.reflectValue(v.Elem(i)) } e.WriteByte(']') case interfaceOrPtrValue: if v.IsNil() { e.WriteString("null") return } e.reflectValue(v.Elem()) default: e.error(&UnsupportedTypeError{v.Type()}) } return }
func valueToString(v reflect.Value) (string, os.Error) { if v == nil { return "null", nil } switch v := v.(type) { case *reflect.PtrValue: return valueToString(reflect.Indirect(v)) case *reflect.InterfaceValue: return valueToString(v.Elem()) case *reflect.BoolValue: x := v.Get() if x { return "true", nil } else { return "false", nil } case *reflect.IntValue: return strconv.Itoa(v.Get()), nil case *reflect.Int8Value: return strconv.Itoa(int(v.Get())), nil case *reflect.Int16Value: return strconv.Itoa(int(v.Get())), nil case *reflect.Int32Value: return strconv.Itoa(int(v.Get())), nil case *reflect.Int64Value: return strconv.Itoa64(v.Get()), nil case *reflect.UintValue: return strconv.Uitoa(v.Get()), nil case *reflect.Uint8Value: return strconv.Uitoa(uint(v.Get())), nil case *reflect.Uint16Value: return strconv.Uitoa(uint(v.Get())), nil case *reflect.Uint32Value: return strconv.Uitoa(uint(v.Get())), nil case *reflect.Uint64Value: return strconv.Uitoa64(v.Get()), nil case *reflect.UintptrValue: return strconv.Uitoa64(uint64(v.Get())), nil case *reflect.FloatValue: return strconv.Ftoa(v.Get(), 'g', -1), nil case *reflect.Float32Value: return strconv.Ftoa32(v.Get(), 'g', -1), nil case *reflect.Float64Value: return strconv.Ftoa64(v.Get(), 'g', -1), nil case *reflect.StringValue: return v.Get(), nil case *reflect.SliceValue: typ := v.Type().(*reflect.SliceType) if _, ok := typ.Elem().(*reflect.Uint8Type); ok { return string(v.Interface().([]byte)), nil } } return "", os.NewError("Unsupported type") }
func (e *encoder) value(v reflect.Value) { switch v := v.(type) { case *reflect.ArrayValue: l := v.Len() for i := 0; i < l; i++ { e.value(v.Elem(i)) } case *reflect.StructValue: l := v.NumField() for i := 0; i < l; i++ { e.value(v.Field(i)) } case *reflect.SliceValue: l := v.Len() for i := 0; i < l; i++ { e.value(v.Elem(i)) } case *reflect.Uint8Value: e.uint8(v.Get()) case *reflect.Uint16Value: e.uint16(v.Get()) case *reflect.Uint32Value: e.uint32(v.Get()) case *reflect.Uint64Value: e.uint64(v.Get()) case *reflect.Int8Value: e.int8(v.Get()) case *reflect.Int16Value: e.int16(v.Get()) case *reflect.Int32Value: e.int32(v.Get()) case *reflect.Int64Value: e.int64(v.Get()) case *reflect.Float32Value: e.uint32(math.Float32bits(v.Get())) case *reflect.Float64Value: e.uint64(math.Float64bits(v.Get())) } }
func valueToString(v reflect.Value) (string, os.Error) { if v == nil { return "null", nil } switch v := v.(type) { case *reflect.PtrValue: return valueToString(reflect.Indirect(v)) case *reflect.InterfaceValue: return valueToString(v.Elem()) case *reflect.BoolValue: x := v.Get() if x { return "true", nil } else { return "false", nil } case *reflect.IntValue: return strconv.Itoa64(v.Get()), nil case *reflect.UintValue: return strconv.Uitoa64(v.Get()), nil case *reflect.UnsafePointerValue: return strconv.Uitoa64(uint64(v.Get())), nil case *reflect.FloatValue: return strconv.Ftoa64(v.Get(), 'g', -1), nil case *reflect.StringValue: return v.Get(), nil //This is kind of a rough hack to replace the old []byte //detection with reflect.Uint8Type, it doesn't catch //zero-length byte slices case *reflect.SliceValue: typ := v.Type().(*reflect.SliceType) if _, ok := typ.Elem().(*reflect.UintType); ok { if v.Len() > 0 { if v.Elem(1).(*reflect.UintValue).Overflow(257) { return string(v.Interface().([]byte)), nil } } } } return "", os.NewError("Unsupported type") }