func (r *ReflectRouter) CallFunc(context *HttpContext, funcName string, option *RouterOption) (returnValue interface{}, statusCode HttpStatus, err error) {

	if index, ok := r.checkFuncName[funcName]; ok {
		statusCode = Status200

		var controller reflect.Value

		if reflect.Invalid != option.RouterDataRefVal.Kind() {
			controller = option.RouterDataRefVal
		} else {
			controller = r.ctlRefVal
		}

		refMet := controller.Method(index)

		//	get params
		args := r.getFuncArgs(refMet.Type(), context)

		//	call method
		reVals := refMet.Call(args)

		if 0 != len(reVals) {
			returnValue = reVals[0].Interface()
		}

	} else {
		statusCode = Status404
		err = NewLeafveinError("(" + r.typestr + ") not found func name: " + funcName)
	}

	return
}
// Evaluate interfaces and pointers looking for a value that can look up the name, via a
// struct field, method, or map key, and return the result of the lookup.
func (t *Template) lookup(st *state, v reflect.Value, name string) reflect.Value {
	for v != nil {
		typ := v.Type()
		if n := v.Type().NumMethod(); n > 0 {
			for i := 0; i < n; i++ {
				m := typ.Method(i)
				mtyp := m.Type
				if m.Name == name && mtyp.NumIn() == 1 && mtyp.NumOut() == 1 {
					if !isExported(name) {
						t.execError(st, t.linenum, "name not exported: %s in type %s", name, st.data.Type())
					}
					return v.Method(i).Call(nil)[0]
				}
			}
		}
		switch av := v.(type) {
		case *reflect.PtrValue:
			v = av.Elem()
		case *reflect.InterfaceValue:
			v = av.Elem()
		case *reflect.StructValue:
			if !isExported(name) {
				t.execError(st, t.linenum, "name not exported: %s in type %s", name, st.data.Type())
			}
			return av.FieldByName(name)
		case *reflect.MapValue:
			return av.Elem(reflect.NewValue(name))
		default:
			return nil
		}
	}
	return v
}
Beispiel #3
0
func (s *Scrubber) collectMethods(v reflect.Value, path Path, callbackMap map[string]Path) {
	for i := 0; i < v.NumMethod(); i++ {
		if v.Type().Method(i).PkgPath == "" { // exported
			name := v.Type().Method(i).Name
			name = strings.ToLower(name[0:1]) + name[1:]
			s.registerCallback(v.Method(i), append(path, name), callbackMap)
		}
	}
}
Beispiel #4
0
// TODO: delete when reflect's own MethodByName is released.
func methodByName(receiver reflect.Value, name string) (reflect.Value, bool) {
	typ := receiver.Type()
	for i := 0; i < typ.NumMethod(); i++ {
		if typ.Method(i).Name == name {
			return receiver.Method(i), true // This value includes the receiver.
		}
	}
	return zero, false
}
Beispiel #5
0
func (pgv *pgValue) getValue(v reflect.Value) reflect.Value {
	switch pgv.Source.(type) {
	case reflect.StructField:
		return v.FieldByIndex(pgv.Index)
	case reflect.Method:
		return v.Method(pgv.Index[0]).Call(nil)[0]
	default:
		panic("not reached")
	}
}
Beispiel #6
0
func init() {
	var opcode Opcode
	var opcodeType reflect.Type = reflect.TypeOf(opcode)
	var opcodeValue reflect.Value = reflect.ValueOf(opcode)

	numMethods := opcodeType.NumMethod()
	for i := 0; i < numMethods; i++ {
		funcName := opcodeType.Method(i).Name
		funcValue := opcodeValue.Method(i)
		funcTable[funcName] = funcValue
	}
}
Beispiel #7
0
func (ctx *Context) pushStructMethods(obj int, t reflect.Type, v reflect.Value) {
	mCount := t.NumMethod()
	for i := 0; i < mCount; i++ {
		methodName := t.Method(i).Name
		if !isExported(methodName) {
			continue
		}

		ctx.PushGoFunction(v.Method(i).Interface())
		ctx.PutPropString(obj, nameToJavaScript(methodName))

	}
}
Beispiel #8
0
// methods walks over a structure and scrubs its exported methods.
func (s *Scrubber) methods(rv reflect.Value, path Path, callbacks map[string]Path) {
	for i := 0; i < rv.NumMethod(); i++ {
		if rv.Type().Method(i).PkgPath == "" { // exported
			cb, ok := rv.Method(i).Interface().(func(*Partial))
			if !ok {
				continue
			}

			name := rv.Type().Method(i).Name
			name = strings.ToLower(name[0:1]) + name[1:]
			s.register(cb, append(path, name), callbacks)
		}
	}
}
// Return the result of calling the Iter method on v, or nil.
func iter(v reflect.Value) *reflect.ChanValue {
	for j := 0; j < v.Type().NumMethod(); j++ {
		mth := v.Type().Method(j)
		fv := v.Method(j)
		ft := fv.Type().(*reflect.FuncType)
		// TODO(rsc): NumIn() should return 0 here, because ft is from a curried FuncValue.
		if mth.Name != "Iter" || ft.NumIn() != 1 || ft.NumOut() != 1 {
			continue
		}
		ct, ok := ft.Out(0).(*reflect.ChanType)
		if !ok || ct.Dir()&reflect.RecvDir == 0 {
			continue
		}
		return fv.Call(nil)[0].(*reflect.ChanValue)
	}
	return nil
}
Beispiel #10
0
// Return the result of calling the Iter method on v, or nil.
func iter(v reflect.Value) reflect.Value {
	for j := 0; j < v.Type().NumMethod(); j++ {
		mth := v.Type().Method(j)
		fv := v.Method(j)
		ft := fv.Type()
		// TODO(rsc): NumIn() should return 0 here, because ft is from a curried FuncValue.
		if mth.Name != "Iter" || ft.NumIn() != 1 || ft.NumOut() != 1 {
			continue
		}
		ct := ft.Out(0)
		if ct.Kind() != reflect.Chan ||
			ct.ChanDir()&reflect.RecvDir == 0 {
			continue
		}
		return fv.Call(nil)[0]
	}
	return reflect.Value{}
}
Beispiel #11
0
func findHttpMethod(rcti reflect.Type, rcvi reflect.Value) map[string][]filterMethod {
	rcvhm := make(map[string][]filterMethod)

	for i := 0; i < rcti.NumMethod(); i++ {
		mName := rcti.Method(i).Name
		if hpos := strings.Index(mName, "Http_"); hpos != -1 {
			hpMname := mName[hpos+len("Http_"):]
			if mpos := strings.Index(hpMname, "_"); mpos != -1 {
				httpMethod := hpMname[:mpos]
				//len("_") == 1
				objMethod := hpMname[mpos+1:]

				rcvhm[objMethod] = append(rcvhm[objMethod], filterMethod{
					method: httpMethod,
					rcvm:   rcvi.Method(i),
				})
			}
		}
	}

	return rcvhm
}
Beispiel #12
0
// Evaluate interfaces and pointers looking for a value that can look up the name, via a
// struct field, method, or map key, and return the result of the lookup.
func (t *Template) lookup(st *state, v reflect.Value, name string) reflect.Value {
	for v.IsValid() {
		typ := v.Type()
		if n := v.Type().NumMethod(); n > 0 {
			for i := 0; i < n; i++ {
				m := typ.Method(i)
				mtyp := m.Type
				if m.Name == name && mtyp.NumIn() == 1 && mtyp.NumOut() == 1 {
					if !isExported(name) {
						t.execError(st, t.linenum, "name not exported: %s in type %s", name, st.data.Type())
					}
					return v.Method(i).Call(nil)[0]
				}
			}
		}
		switch av := v; av.Kind() {
		case reflect.Ptr:
			v = av.Elem()
		case reflect.Interface:
			v = av.Elem()
		case reflect.Struct:
			if !isExported(name) {
				t.execError(st, t.linenum, "name not exported: %s in type %s", name, st.data.Type())
			}
			return av.FieldByName(name)
		case reflect.Map:
			if v := av.MapIndex(reflect.ValueOf(name)); v.IsValid() {
				return v
			}
			return reflect.Zero(typ.Elem())
		default:
			return reflect.Value{}
		}
	}
	return v
}
Beispiel #13
0
func newMethod(receiver reflect.Value, i int) *methodType {
	return &methodType{receiver.Method(i), receiver.Type().Method(i)}
}
Beispiel #14
0
// Funkcja zwraca wartosc zmiennej o podanej nazwie lub indeksie. Jesli zmienna
// jest funkcja, wczesniej wywoluje ja z podanymi argumentami. Funkcja
// przeprowadza niezbedne dereferencje tak aby zwrocic zmienna, ktora nie jest
// ani wskaznikiem, ani interfejsem lub zwrocic wskaznik lub interface do takiej
// zmiennej. Uwaga! Funkcja moze modyfikowac wartosci args!
func getVarFun(ctx, name reflect.Value, args []reflect.Value, fun bool) (
	ret reflect.Value, stat int) {

	if !ctx.IsValid() {
		stat = RUN_NIL_CTX
		return
	}

	// Dereferencja nazwy
	dereference(&name)

	// Dereferencja jesli kontekst jest interfejsem
	if ctx.Kind() == reflect.Interface {
		ctx = ctx.Elem()
	}

	// Jesli nazwa jest stringiem probujemy znalezc metode o tej nazwie
	if name.Kind() == reflect.String {
		tt := ctx.Type()
		//nm := tt.NumMethod()
		for ii := 0; ii < tt.NumMethod(); ii++ {
			method := tt.Method(ii)
			// Sprawdzamy zgodnosc nazwy metody oraz typu receiver'a
			if method.Name == name.String() && tt == method.Type.In(0) {
				stat = argsMatch(method.Type, args, 1)
				if stat != RUN_OK {
					return
				}
				// Zwracamy pierwsza wartosc zwrocona przez metode
				ctx = ctx.Method(ii).Call(args)[0]
				// Nie pozwalamy na dalsza analize nazwy
				name = reflect.Value{}
				// Nie pozwalamy na traktowanie zwroconej zmiennej jak funkcji
				args = nil
				fun = false
				break
			}
		}
	}

	// Jesli name zawiera wartosc operujemy na nazwanej zmiennej z kontekstu,
	// w przeciwnym razie operujemy na samym kontekscie jako zmiennej.
	if name.IsValid() {
		// Pelna dereferencja kontekstu
		dereference(&ctx)
		// Pobieramy wartosc
		switch ctx.Kind() {
		case reflect.Struct:
			switch name.Kind() {
			case reflect.String:
				// Zwracamy pole struktury o podanej nazwie
				ft, ok := ctx.Type().FieldByName(name.String())
				if !ok {
					stat = RUN_NOT_FOUND
					return
				}
				if ft.PkgPath != "" {
					stat = RUN_UNEXPORTED
					return
				}
				ctx = ctx.FieldByIndex(ft.Index)
			case reflect.Int:
				// Zwracamy pole sruktury o podanym indeksie
				fi := int(name.Int())
				if fi < 0 || fi >= ctx.NumField() {
					stat = RUN_INDEX_OOR
					return
				}
				if ctx.Type().Field(fi).PkgPath != "" {
					stat = RUN_UNEXPORTED
					return
				}
				ctx = ctx.Field(fi)
			default:
				stat = RUN_NOT_FOUND
				return
			}

		case reflect.Map:
			kt := ctx.Type().Key()
			if !name.Type().AssignableTo(kt) {
				stat = RUN_NOT_FOUND
			}
			ctx = ctx.MapIndex(name)
			if !ctx.IsValid() {
				stat = RUN_NOT_FOUND
				return
			}

		case reflect.Array, reflect.Slice:
			switch name.Kind() {
			case reflect.Int:
				// Zwracamy element tablicy o podanym indeksie
				ei := int(name.Int())
				if ei < 0 || ei >= ctx.Len() {
					stat = RUN_INDEX_OOR
					return
				}
				ctx = ctx.Index(ei)
			default:
				stat = RUN_NOT_FOUND
				return
			}

		case reflect.Invalid:
			stat = RUN_NIL_CTX
			return

		default:
			stat = RUN_UNK_TYPE
			return
		}
	}

	// Jesli mamy wywolanie funkcji to robimy pelna dereferencje.
	if fun {
		dereference(&ctx)
	}

	// Sprawdzenie czy ctx odnosi sie do funkcji.
	if ctx.Kind() == reflect.Func {
		ft := ctx.Type()
		if fun || ft.NumIn() == 0 {
			// Sprawdzamy zgodnosc liczby argumentow
			stat = argsMatch(ft, args, 0)
			if stat != RUN_OK {
				return
			}
			// Zwracamy pierwsza wrtosc zwrocaona przez funkcje.
			ctx = ctx.Call(args)[0]
		}
	} else if fun {
		stat = RUN_NOT_FUNC
		return
	}

	//fmt.Println("DEB getvar.ret:", reflect.Typeof(ctx.Interface()))
	return ctx, RUN_OK
}
Beispiel #15
0
func (m *method) AppendValue(dst []byte, v reflect.Value, quote bool) []byte {
	mv := v.Method(m.Index).Call(nil)[0]
	return m.appender(dst, mv, quote)
}
Beispiel #16
0
// Funkcja zwraca wartosc zmiennej o podanej nazwie lub indeksie. Jesli zmienna
// jest funkcja, wczesniej wywoluje ja z podanymi argumentami. Funkcja
// przeprowadza niezbedne dereferencje tak aby zwrocic zmienna, ktora nie jest
// ani wskaznikiem, ani interfejsem lub zwrocic wskaznik lub interface do takiej
// zmiennej. Uwaga! Funkcja moze modyfikowac wartosci args!
func getVarFun(ctx, name reflect.Value, args []reflect.Value, fun bool) (
	reflect.Value, int) {

	if ctx == nil {
		return nil, RUN_NIL_CTX
	}

	// Dereferencja nazwy
	dereference(&name)

	// Dereferencja jesli kontekst jest interfejsem
	if vi, ok := ctx.(*reflect.InterfaceValue); ok {
		ctx = vi.Elem()
	}

	// Jesli nazwa jest stringiem probujemy znalezc metode o tej nazwie
	if id, ok := name.(*reflect.StringValue); ok {
		tt := ctx.Type()
		for ii := 0; ii < tt.NumMethod(); ii++ {
			method := tt.Method(ii)
			// Sprawdzamy zgodnosc nazwy metody i typu receiver'a
			if method.Name == id.Get() && tt == method.Type.In(0) {
				stat := argsMatch(method.Type, &args, 1)
				if stat != RUN_OK {
					return nil, stat
				}
				// Zwracamy pierwsza wartosc zwrocona przez metode
				ctx = ctx.Method(ii).Call(args)[0]
				name = nil
				args = nil
				fun = false
				break
			}
		}
	}

	// Jesli name != nil operujemy na nazwanej zmiennej z kontekstu,
	// w przeciwnym razie operujemy na samym kontekscie jako zmiennej.
	if name != nil {
		// Pelna dereferencja kontekstu
		dereference(&ctx)
		// Pobieramy wartosc
		switch vt := ctx.(type) {
		case *reflect.StructValue:
			switch id := name.(type) {
			case *reflect.StringValue:
				// Zwracamy pole struktury o podanej nazwie
				ctx = vt.FieldByName(id.Get())
				if ctx == nil {
					return nil, RUN_NOT_FOUND
				}
			case *reflect.IntValue:
				// Zwracamy pole sruktury o podanym indeksie
				fi := int(id.Get())
				if fi >= vt.NumField() {
					return nil, RUN_INDEX_OOR
				}
				if fi < 0 {
					fi += vt.NumField()
					if fi < 0 {
						return nil, RUN_INDEX_OOR
					}
				}
				ctx = vt.Field(fi)
			default:
				return nil, RUN_NOT_FOUND
			}

		case reflect.ArrayOrSliceValue:
			switch id := name.(type) {
			case *reflect.IntValue:
				// Zwracamy element tablicy o podanym indeksie
				ei := int(id.Get())
				if ei >= vt.Len() {
					return nil, RUN_INDEX_OOR
				}
				if ei < 0 {
					ei += vt.Len()
					if ei < 0 {
						return nil, RUN_INDEX_OOR
					}
				}
				ctx = vt.Elem(ei)
			default:
				return nil, RUN_NOT_FOUND
			}

		case *reflect.MapValue:
			kt := vt.Type().(*reflect.MapType).Key()
			if name.Type() != kt {
				if it, ok := kt.(*reflect.InterfaceType); ok && it.NumMethod() == 0 {
					// Jesli mapa posiada klucz typu interface{} to
					// przeksztalcamy indeks na typ interface{}
					vi := name.Interface()
					name = reflect.NewValue(&vi).(*reflect.PtrValue).Elem()
				} else {
					return nil, RUN_NOT_FOUND
				}
			}
			ctx = vt.Elem(name)
			if ctx == nil {
				return nil, RUN_NOT_FOUND
			}

		case nil:
			return nil, RUN_NIL_CTX

		default:
			return nil, RUN_UNK_TYPE
		}
	}

	// Jesli mamy wywolanie funkcji to robimy pelna dereferencje.
	if fun {
		dereference(&ctx)
	}

	// Sprawdzenie czy ctx odnosi sie do funkcji.
	if vt, ok := ctx.(*reflect.FuncValue); ok {
		ft := vt.Type().(*reflect.FuncType)
		// Sprawdzamy zgodnosc liczby argumentow
		stat := argsMatch(ft, &args, 0)
		if stat != RUN_OK {
			return nil, stat
		}
		// Zwracamy pierwsza wrtosc zwrocaona przez funkcje.
		ctx = vt.Call(args)[0]
	} else if fun {
		return nil, RUN_NOT_FUNC
	}

	//fmt.Println("DEB getvar.ret:", reflect.Typeof(ctx.Interface()))
	return ctx, RUN_OK
}
func formatQuery(dst, src []byte, params []interface{}) ([]byte, error) {
	if len(params) == 0 {
		return append(dst, src...), nil
	}

	var structptr, structv reflect.Value
	var fields map[string][]int
	var methods map[string]int
	var paramInd int

	p := &parser{b: src}

	for p.Valid() {
		if ch := p.Next(); ch != '?' {
			dst = append(dst, ch)
			continue
		}

		var value interface{}

		name := p.ReadName()
		if name != "" {
			// Lazily initialize named params.
			if fields == nil {
				if len(params) == 0 {
					return nil, errorf("pg: expected at least one parameter, got nothing")
				}
				structptr = reflect.ValueOf(params[len(params)-1])
				params = params[:len(params)-1]
				if structptr.Kind() == reflect.Ptr {
					structv = structptr.Elem()
				} else {
					structv = structptr
				}
				if structv.Kind() != reflect.Struct {
					return nil, errorf("pg: expected struct, got %s", structv.Kind())
				}
				fields = structs.Fields(structv.Type())
				methods = structs.Methods(structptr.Type())
			}

			if indx, ok := fields[name]; ok {
				value = structv.FieldByIndex(indx).Interface()
			} else if indx, ok := methods[name]; ok {
				value = structptr.Method(indx).Call(nil)[0].Interface()
			} else {
				return nil, errorf("pg: cannot map %q", name)
			}
		} else {
			if paramInd >= len(params) {
				return nil, errorf(
					"pg: expected at least %d parameters, got %d",
					paramInd+1, len(params),
				)
			}

			value = params[paramInd]
			paramInd++
		}

		dst = appendIface(dst, value)
	}

	if paramInd < len(params) {
		return nil, errorf("pg: expected %d parameters, got %d", paramInd, len(params))
	}

	return dst, nil
}