コード例 #1
0
ファイル: utils.go プロジェクト: jango2015/wk
// convertResult convert reflect.Value to http result
func convertResult(ctx *HttpContext, v reflect.Value) HttpResult {
	i := v.Interface()

	if r, ok := i.(HttpResult); ok {
		return r
	}

	if Formatters != nil {
		for _, f := range Formatters {
			if formatted, ok := f(ctx, v.Interface()); ok {
				return formatted
			}
		}
	}

	kind := reflect.Indirect(v).Kind()

	switch {
	case gotype.IsSimple(kind):
		return &DataResult{Data: i}
	case gotype.IsStruct(kind) || gotype.IsCollect(kind):
		accept := ctx.Accept()
		switch {
		case strings.Index(accept, "xml") > -1:
			return &XmlResult{Data: v.Interface()}
		case strings.Index(accept, "jsonp") > -1:
			return &JsonpResult{Data: v.Interface()}
		default:
			return &JsonResult{Data: v.Interface()}
		}
	}
	return &ContentResult{Data: i}
}
コード例 #2
0
ファイル: kson.go プロジェクト: samuelyao314/mygo
func (n *Node) setMap(v reflect.Value) {

	// fmt.Println("setmap", nameOfNodeType(n.Type), v.Type(), v.Kind())
	// fmt.Println(n.Dump())

	kind := v.Kind()
	if n.Type != NodeHash || kind != reflect.Map {
		return
	}

	typ := v.Type()
	if n.Hash == nil {
		if v.CanSet() {
			v.Set(reflect.Zero(typ))
		}
		return
	}

	if typ.Key() != gotype.TypeString { // only support string key
		return
	}

	if v.IsNil() {
		if v.CanSet() {
			v.Set(reflect.MakeMap(typ))
		} else {
			return
		}
	}

	elemType := typ.Elem()
	elemKind := elemType.Kind()
	simple := gotype.IsSimple(elemKind)

	for name, x := range n.Hash {
		if simple && x.Type == NodeLiteral {
			mapElem, err := gotype.Atok(x.Literal, elemKind)
			if err == nil {
				v.SetMapIndex(reflect.ValueOf(name), mapElem)
			}
		} else {
			var mapElem reflect.Value
			if elemType.Kind() == reflect.Ptr {
				mapElem = reflect.New(elemType.Elem())
			} else {
				mapElem = reflect.New(elemType)
			}
			x.set(mapElem)
			v.SetMapIndex(reflect.ValueOf(name), mapElem)
		}
	}
}
コード例 #3
0
ファイル: route.go プロジェクト: jango2015/wk
// Bind
func (binder *structBinder) Bind(ctx *HttpContext) ([]reflect.Value, error) {
	numIn := binder.method.NumIn
	args := make([]reflect.Value, numIn, numIn)

	for i := 0; i < numIn; i++ {
		in := binder.method.In[i]
		args[i] = reflect.Zero(in)

		if in.Kind() == reflect.Struct {
			args[i] = reflect.New(in).Elem()
		} else if in.Kind() == reflect.Ptr && in.Elem().Kind() == reflect.Struct {
			args[i] = reflect.New(in.Elem())
		} else {
			continue
		}

		uType := gotype.UnderlyingType(in)
		uValue := gotype.Underlying(args[i])
		filedNum := uType.NumField()

		for f := 0; f < filedNum; f++ {
			field := uType.Field(f)
			fieldValue := uValue.Field(f)
			fieldType := field.Type

			if !fieldValue.CanSet() {
				continue
			}

			fieldKind := fieldType.Kind()
			name := strings.ToLower(field.Name)

			str, ok := ctx.RouteData[name]
			if !ok {
				str = ctx.Request.FormValue(name)
			}
			if str == "" {
				continue
			}

			if gotype.IsSimple(fieldKind) {
				gotype.Value(fieldValue).Parse(str)
			} else {
				//TODO
			}
		}
	}

	return args, nil
}
コード例 #4
0
ファイル: kson.go プロジェクト: samuelyao314/mygo
func (n *Node) setArray(v reflect.Value) {

	kind := v.Kind()
	if n.Type != NodeList || (kind != reflect.Slice && kind != reflect.Array) {
		return
	}

	typ := v.Type()
	if n.List == nil {
		if v.CanSet() {
			v.Set(reflect.Zero(typ))
		}
		return
	}

	l := len(n.List)
	if kind == reflect.Slice {
		if v.CanSet() {
			v.Set(reflect.MakeSlice(v.Type(), l, l))
		} else {
			return
		}
	}

	vl := v.Len()
	elemType := typ.Elem()
	elemKind := elemType.Kind()
	simple := gotype.IsSimple(elemKind)

	for i, x := range n.List {
		if i < vl { // capacity of array maybe less of i
			if simple && x.Type == NodeLiteral {
				gotype.Value(v.Index(i)).Parse(x.Literal)
			} else {
				x.set(v.Index(i))
			}
		}
	}

	if kind == reflect.Array && l < vl {
		for i := l; i < vl; i++ {
			z := reflect.Zero(v.Type().Elem()) //reset
			v.Index(i).Set(z)
		}
	}
}
コード例 #5
0
ファイル: kson.go プロジェクト: samuelyao314/mygo
func (n *Node) setObject(v reflect.Value) {

	kind := v.Kind()
	if n.Type != NodeHash || kind != reflect.Struct {
		return
	}

	typ := v.Type()
	if n.Hash == nil {
		if v.CanSet() {
			v.Set(reflect.Zero(typ))
			return
		}
	}

	numFiled := typ.NumField()
	for i := 0; i < numFiled; i++ {
		field := typ.Field(i)
		if field.PkgPath != "" {
			continue
		}

		name := field.Name
		filedNode, ok := n.Child(name)
		if !ok {
			filedNode, ok = n.ChildFold(name)
		}
		if !ok {
			continue
		}

		fv := v.Field(i)
		if !fv.CanSet() {
			continue
		}

		kind := field.Type.Kind()
		if filedNode.Type == NodeLiteral && gotype.IsSimple(kind) {
			gotype.Value(fv).Parse(filedNode.Literal)
		} else {
			filedNode.set(fv)
		}
	}

}
コード例 #6
0
ファイル: kson.go プロジェクト: samuelyao314/mygo
func (n *Node) set(v reflect.Value) {

	// if !v.CanSet() || !v.IsValid() {
	// 	return
	// }

	// fmt.Println("set==", nameOfNodeType(n.Type), v.Type(), v.Kind())
	// fmt.Println(n.Dump())

	kind := v.Kind()
	switch {
	case gotype.IsSimple(kind):
		if n.Literal != "" {
			gotype.Value(v).Parse(n.Literal)
		}
	case kind == reflect.Invalid || kind == reflect.Uintptr || kind == reflect.UnsafePointer || kind == reflect.Func || kind == reflect.Chan || kind == reflect.Complex64 || kind == reflect.Complex128:
		//TODO: unsupport
	case kind == reflect.Array:
		n.setArray(v)
	case kind == reflect.Slice:
		n.setArray(v)
	case kind == reflect.Map:
		n.setMap(v)
	case kind == reflect.Struct:
		n.setObject(v)
	case kind == reflect.Interface:
		if n.Type == NodeLiteral {
			gotype.Value(v).Parse(n.Literal)
		}
	case kind == reflect.Ptr:
		if v.IsNil() && v.CanSet() {
			v.Set(reflect.New(v.Type().Elem()))
		}
		n.set(v.Elem())
	default:
		//TODO:
	}
}
コード例 #7
0
ファイル: encoder.go プロジェクト: samuelyao314/mygo
// TODO: adjust indent algorithm
func (e *encoder) visitReflectValue(v reflect.Value) {

	if !v.IsValid() {
		e.WriteString("")
	}

	//v = gotype.Underlying(v)
	kind := v.Kind()
	switch kind {
	case reflect.Bool,
		reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
		reflect.Float32, reflect.Float64:
		e.WriteString(gotype.Value(v).Format())
	case reflect.String:
		s := v.String()
		if b, quote := stringNeedQuote(s); b {
			e.WriteString(quote)
			e.WriteString(s)
			e.WriteString(quote)
			//e.WriteString("\n")
		} else {
			e.WriteString(s)
		}
	case reflect.Struct:
		//fmt.Fprintln(e, "{")
		e.WriteByte('{')
		e.WriteByte('\n')
		e.indentInner()

		typ := v.Type()
		count := typ.NumField()
		for i := 0; i < count; i++ {
			f := typ.Field(i)

			if f.PkgPath != "" {
				continue
			}

			e.indent()
			//fmt.Fprint(e, f.Name)
			e.WriteString(f.Name)
			//fmt.Fprint(e, ":")
			e.WriteByte(':')
			e.visitReflectValue(v.Field(i))
			//fmt.Fprintln(e, "")
			e.WriteByte('\n')
		}

		e.indentOuter()
		e.indent()
		//fmt.Fprintln(e, "}")
		e.WriteByte('}')
		e.WriteByte('\n')
	case reflect.Map:
		if !gotype.IsSimple(v.Type().Key().Kind()) {
			return
		}

		if v.IsNil() {
			//fmt.Fprint(e, "") //fmt.Fprint(e, "null")
			e.WriteByte(' ')
			break
		}

		//fmt.Fprintln(e, "{")
		e.WriteByte('{')
		e.WriteByte('\n')
		e.indentInner()

		keys := v.MapKeys()
		for _, k := range keys {
			e.indent()
			//fmt.Fprint(e, k)
			e.WriteString(k.String())
			//fmt.Fprint(e, ":")
			e.WriteByte(':')
			e.visitReflectValue(v.MapIndex(k))
			//fmt.Fprintln(e, "")
			e.WriteByte('\n')
		}
		e.indentOuter()
		e.indent()
		//fmt.Fprintln(e, "}")
		e.WriteByte('}')
		e.WriteByte('\n')
	case reflect.Slice:

		if v.IsNil() {
			//fmt.Fprint(e, "") //fmt.Fprint(e, "null")
			e.WriteByte(' ')
			break
		}
		e.visitArray(v)
	case reflect.Array:
		e.visitArray(v)
	case reflect.Interface, reflect.Ptr:
		if v.IsNil() || !v.IsValid() {
			//fmt.Fprint(e, "") //fmt.Fprint(e, "null")
			e.WriteByte(' ')
			return
		}
		e.visitReflectValue(v.Elem())
	default:
		fmt.Fprint(e, v.Interface())
		//return errors.New("Unsupported type " + v.Type().String())
	}
	return
}