Exemplo n.º 1
0
/**
 *	针对字段进行设值
 *
 *	@param fieldValue		字段反射对象
 *	@param fieldName		字段名,以便递归寻找下个设值字段
 *	@param fieldSplitName	字段名分割集合,以"."进行分割,主要是为了递归子字段进行拼接传递
 *	@param value			设置值
 */
func parampackSetFieldValue(fieldValue reflect.Value, fieldName string, fieldSplitName []string, value interface{}) {

	if fieldValue.IsValid() {

		//	为递归下一个参数做准备,保留后面的参数名(tag.TagName)
		isRec := false
		joinLaterFieldName := ""
		if 1 < len(fieldSplitName) {
			joinLaterFieldName = strings.Join(fieldSplitName[1:], ".")
			isRec = true
			//	进入这里表明还需要进行一次字段查询,所以需要进行递归操作,直到截取到最后一位的参数名标识(TagName)
		}

		switch fieldValue.Kind() {
		case reflect.Ptr:

			if fieldValue.IsNil() {
				fieldValue.Set(reflect.New(fieldValue.Type().Elem()))
			}

			//	指针与非指针区分开,主要是在进行参数设值的时候对应与设置值相同的类型,减免指针的过多操作。
			switch fieldValue.Elem().Kind() {
			case reflect.Struct:
				if isRec && !parampackFilterParamPackStructType(fieldValue.Type().Elem()) {
					parampackSetStructFieldValue(fieldValue, joinLaterFieldName, value)
				} else {
					parampackSetParamValue(fieldValue, fieldName, value)
				}

			case reflect.Slice:
				//	如果属于切片类型,传递fieldName主要是在操作一遍集合元素的赋值,因为不是结构类型无需再向下查找
				parampackSetStructFieldValue(fieldValue, fieldName, value)
			default:
				parampackSetParamValue(fieldValue, fieldName, value)
			}

		case reflect.Struct:

			if isRec && !parampackFilterParamPackStructType(fieldValue.Type()) {
				parampackSetStructFieldValue(fieldValue, joinLaterFieldName, value)
			} else {
				//	如果检测的是系统或则非用户定义的struct就可以直接赋值了,赋值那里已经做了匹配类型才进行赋值的处理
				parampackSetParamValue(fieldValue, fieldName, value)
			}
		case reflect.Slice:
			parampackSetStructFieldValue(fieldValue, fieldName, value)
		default:
			parampackSetParamValue(fieldValue, fieldName, value)
		}

	}
}
Exemplo n.º 2
0
/**
 *  private marshal
 */
func marshal(v reflect.Value, nullTag, boolTag string, buf *bytes.Buffer) error {
	var err error

	switch v.Kind() {
	case reflect.Bool:
		boolTrue := "true"
		boolFalse := "false"
		if "" != boolTag {
			bs := strings.Split(boolTag, "|")
			if 2 == len(bs) {
				boolTrue = bs[0]
				boolFalse = bs[1]
			}
		}
		bv := v.Bool()
		if bv {
			buf.WriteString(boolTrue)
		} else {
			buf.WriteString(boolFalse)
		}
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		b := strconv.AppendInt(scratch[:0], v.Int(), 10)
		buf.Write(b)
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		b := strconv.AppendUint(scratch[:0], v.Uint(), 10)
		buf.Write(b)
	case reflect.Float32, reflect.Float64:
		f := v.Float()
		if math.IsInf(f, 0) || math.IsNaN(f) {
			err = errors.New(strconv.FormatFloat(f, 'g', -1, v.Type().Bits()))
		}
		b := strconv.AppendFloat(scratch[:0], f, 'g', -1, v.Type().Bits())
		buf.Write(b)
	case reflect.String:
		if 0 == v.Len() {
			buf.WriteString("\"\"")
		} else {
			buf.WriteByte('"')
			_, err = escapeString(buf, v.String())
			buf.WriteByte('"')
		}

	case reflect.Struct:
		vt := v.Type()
		numTField := vt.NumField()

		if 0 == numTField {
			if "" != nullTag && 0 < buf.Len() {
				buf.WriteString(nullTag)
			}
			break
		}

		if vt.Implements(textMarshalerType) {
			imt := v.Interface().(encoding.TextMarshaler)
			mt, e := imt.MarshalText()
			if nil != e {
				err = e
			} else {
				buf.WriteByte('"')
				buf.Write(mt)
				buf.WriteByte('"')
			}
			break
		}

		buf.WriteByte('{')
		first := true

		for i := 0; i < numTField; i++ {
			childFieldT := vt.Field(i)
			childFieldV := v.Field(i)

			if "" == nullTag && SFReflectUtil.IsNullValue(childFieldV) {
				continue
			}

			keyName := childFieldT.Tag.Get("json")
			if 0 == len(keyName) {
				keyName = childFieldT.Name
			} else if "-" == keyName {
				continue
			}

			if first {
				first = false
			} else {
				buf.WriteByte(',')
			}

			buf.WriteString("\"" + keyName + "\"")
			buf.WriteByte(':')
			marshal(childFieldV, nullTag, boolTag, buf)
		}

		buf.WriteByte('}')
	case reflect.Map:
		if v.Type().Key().Kind() != reflect.String {
			err = errors.New("json: unsupported type: " + v.Type().String())
			break
		}
		if 0 == v.Len() {
			if "" != nullTag && 0 < buf.Len() {
				buf.WriteString(nullTag)
			}
			break
		}

		buf.WriteByte('{')
		first := true
		for _, k := range v.MapKeys() {
			kv := v.MapIndex(k)

			if "" == nullTag && SFReflectUtil.IsNullValue(kv) {
				continue
			}

			if first {
				first = false
			} else {
				buf.WriteByte(',')
			}
			buf.WriteString("\"" + k.String() + "\"")
			buf.WriteByte(':')
			marshal(kv, nullTag, boolTag, buf)
		}
		buf.WriteByte('}')

	case reflect.Array, reflect.Slice:
		if 0 == v.Len() {
			if "" != nullTag && 0 < buf.Len() {
				buf.WriteString(nullTag)
			}
			break
		}
		if v.Type().Elem().Kind() == reflect.Uint8 {

			s := v.Bytes()
			buf.WriteByte('"')
			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)
				buf.Write(dst)
			} else {
				// for large buffers, avoid unnecessary extra temporary
				// buffer space.
				enc := base64.NewEncoder(base64.StdEncoding, buf)
				enc.Write(s)
				enc.Close()
			}
			buf.WriteByte('"')

		} else {
			buf.WriteByte('[')
			first := true
			count := v.Len()
			for i := 0; i < count; i++ {
				v2 := v.Index(i)
				if "" == nullTag && SFReflectUtil.IsNullValue(v2) {
					continue
				}
				if first {
					first = false
				} else {
					buf.WriteByte(',')
				}
				marshal(v2, nullTag, boolTag, buf)
			}
			buf.WriteByte(']')
		}
	case reflect.Interface, reflect.Ptr:
		if v.IsNil() {
			if "" != nullTag {
				buf.WriteString(nullTag)
			}
			break
		}
		marshal(v.Elem(), nullTag, boolTag, buf)
	default:
	}

	return err
}