Beispiel #1
0
// 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
}
Beispiel #2
0
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
}
Beispiel #3
0
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)))
		}
	}
}
Beispiel #4
0
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
}
Beispiel #5
0
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")
}
Beispiel #6
0
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()))
	}
}
Beispiel #7
0
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")
}