Пример #1
0
func groupByChan(dataChan interface{}, f interface{}) (result interface{}) {
	fType := reflect.TypeOf(f)
	fInType := fType.In(0)
	fRetType := fType.Out(0)

	sliceOfFInTypes := reflect.SliceOf(fInType)
	resultValue := reflect.MakeMap(reflect.MapOf(fRetType, sliceOfFInTypes))

	fVal := reflect.ValueOf(f)
	chanValue := reflect.ValueOf(dataChan)
	value, ok := chanValue.Recv()
	for ok {
		idx := fVal.Call([]reflect.Value{value})[0]
		existingValue := resultValue.MapIndex(idx)
		if !existingValue.IsValid() {
			existingValue = reflect.MakeSlice(sliceOfFInTypes, 0, defaultCapacity)
		}
		existingValue = reflect.Append(existingValue, value)
		resultValue.SetMapIndex(idx, existingValue)
		value, ok = chanValue.Recv()
	}

	result = resultValue.Interface()
	return
}
Пример #2
0
func (p Pages) GroupBy(key string, order ...string) (PagesGroup, error) {
	if len(p) < 1 {
		return nil, nil
	}

	direction := "asc"

	if len(order) > 0 && (strings.ToLower(order[0]) == "desc" || strings.ToLower(order[0]) == "rev" || strings.ToLower(order[0]) == "reverse") {
		direction = "desc"
	}

	ppt := reflect.TypeOf(&Page{})
	ft, ok := ppt.Elem().FieldByName(key)
	if !ok {
		return nil, errors.New("No such field in Page struct")
	}
	tmp := reflect.MakeMap(reflect.MapOf(ft.Type, reflect.SliceOf(ppt)))

	for _, e := range p {
		ppv := reflect.ValueOf(e)
		fv := ppv.Elem().FieldByName(key)
		if !tmp.MapIndex(fv).IsValid() {
			tmp.SetMapIndex(fv, reflect.MakeSlice(reflect.SliceOf(ppt), 0, 0))
		}
		tmp.SetMapIndex(fv, reflect.Append(tmp.MapIndex(fv), ppv))
	}

	var r []PageGroup
	for _, k := range sortKeys(tmp.MapKeys(), direction) {
		r = append(r, PageGroup{Key: k.Interface(), Pages: tmp.MapIndex(k).Interface().([]*Page)})
	}

	return r, nil
}
Пример #3
0
// toReflectType converts the DataType to reflect.Type.
func toReflectType(dtype DataType) reflect.Type {
	switch dtype.Kind() {
	case BooleanKind:
		return reflect.TypeOf(true)
	case IntegerKind:
		return reflect.TypeOf(int(0))
	case NumberKind:
		return reflect.TypeOf(float64(0))
	case StringKind:
		return reflect.TypeOf("")
	case DateTimeKind:
		return reflect.TypeOf(time.Time{})
	case ObjectKind, UserTypeKind, MediaTypeKind:
		return reflect.TypeOf(map[string]interface{}{})
	case ArrayKind:
		return reflect.SliceOf(toReflectType(dtype.ToArray().ElemType.Type))
	case HashKind:
		hash := dtype.ToHash()
		// avoid complication: not allow object as the hash key
		var ktype reflect.Type
		if !hash.KeyType.Type.IsObject() {
			ktype = toReflectType(hash.KeyType.Type)
		} else {
			ktype = reflect.TypeOf([]interface{}{}).Elem()
		}
		return reflect.MapOf(ktype, toReflectType(hash.ElemType.Type))
	default:
		return reflect.TypeOf([]interface{}{}).Elem()
	}
}
Пример #4
0
func (d *mapAsMapDecoder) decode(dv, sv reflect.Value) {
	dt := dv.Type()
	dv.Set(reflect.MakeMap(reflect.MapOf(dt.Key(), dt.Elem())))

	var mapKey reflect.Value
	var mapElem reflect.Value

	keyType := dv.Type().Key()
	elemType := dv.Type().Elem()

	for _, sElemKey := range sv.MapKeys() {
		var dElemKey reflect.Value
		var dElemVal reflect.Value

		if !mapKey.IsValid() {
			mapKey = reflect.New(keyType).Elem()
		} else {
			mapKey.Set(reflect.Zero(keyType))
		}
		dElemKey = mapKey

		if !mapElem.IsValid() {
			mapElem = reflect.New(elemType).Elem()
		} else {
			mapElem.Set(reflect.Zero(elemType))
		}
		dElemVal = mapElem

		d.keyDec(dElemKey, sElemKey)
		d.elemDec(dElemVal, sv.MapIndex(sElemKey))

		dv.SetMapIndex(dElemKey, dElemVal)
	}
}
func (w *walker) Map(m reflect.Value) error {
	t := m.Type()
	newMap := reflect.MakeMap(reflect.MapOf(t.Key(), t.Elem()))
	w.cs = append(w.cs, newMap)
	w.valPush(newMap)
	return nil
}
Пример #6
0
func byOutputMap(iterable interface{}, field string, fn string, slices bool) (itr reflect.Value, f reflect.StructField, out reflect.Value, err error) {
	itr = reflect.ValueOf(iterable)
	if itr.Kind() != reflect.Slice && itr.Kind() != reflect.Array {
		err = fmt.Errorf("first argument to %s must be slice or array, not %T", fn, iterable)
		return
	}
	elem := itr.Type().Elem()
	s := elem
	for s.Kind() == reflect.Ptr {
		s = s.Elem()
	}
	if s.Kind() != reflect.Struct {
		err = fmt.Errorf("first argument to %s must contain structs or pointers to structs, not %v", fn, elem)
		return
	}
	var ok bool
	f, ok = s.FieldByName(field)
	if !ok {
		err = fmt.Errorf("type %v does not have a field named %q", elem, field)
		return
	}
	if slices {
		elem = reflect.SliceOf(elem)
	}
	mapType := reflect.MapOf(f.Type, elem)
	out = reflect.MakeMap(mapType)
	return
}
Пример #7
0
// tysubst attempts to substitute all type variables within a single return
// type with their corresponding Go type from the type environment.
//
// tysubst will panic if a type variable is unbound, or if it encounters a
// type that cannot be dynamically created. Such types include arrays,
// functions and structs. (A limitation of the `reflect` package.)
func (rt returnType) tysubst(typ reflect.Type) reflect.Type {
	if tyname := tyvarName(typ); len(tyname) > 0 {
		if thetype, ok := rt.tyenv[tyname]; !ok {
			rt.panic("Unbound type variable %s.", tyname)
		} else {
			return thetype
		}
	}

	switch typ.Kind() {
	case reflect.Array:
		rt.panic("Cannot dynamically create Array types.")
	case reflect.Chan:
		return reflect.ChanOf(typ.ChanDir(), rt.tysubst(typ.Elem()))
	case reflect.Func:
		rt.panic("Cannot dynamically create Function types.")
	case reflect.Interface:
		rt.panic("TODO")
	case reflect.Map:
		return reflect.MapOf(rt.tysubst(typ.Key()), rt.tysubst(typ.Elem()))
	case reflect.Ptr:
		return reflect.PtrTo(rt.tysubst(typ.Elem()))
	case reflect.Slice:
		return reflect.SliceOf(rt.tysubst(typ.Elem()))
	case reflect.Struct:
		rt.panic("Cannot dynamically create Struct types.")
	case reflect.UnsafePointer:
		rt.panic("Cannot dynamically create unsafe.Pointer types.")
	}

	// We've covered all the composite types, so we're only left with
	// base types.
	return typ
}
Пример #8
0
// If op is Operator of "[]T", type of f must be "func(T) T2".
// And GroupBy(f) returns value of "map[T2] []T"
func (op *Op) GroupBy(f interface{}) interface{} {
	vs := reflect.ValueOf(op.Slice)
	vf := reflect.ValueOf(f)

	tf := vf.Type()
	if tf.NumIn() != 1 {
		panic("Number of Argument must be 1")
	}
	if tf.NumOut() != 1 {
		panic("Number of return value must be 1")
	}

	tif := tf.In(0)
	tof := tf.Out(0)
	if tif != vs.Type().Elem() {
		panic("Mismatch function type")
	}

	len := vs.Len()
	vom := reflect.MakeMap(reflect.MapOf(tof, vs.Type()))
	for i := 0; i < len; i++ {
		v := vs.Index(i)
		vk := vf.Call([]reflect.Value{v})[0]
		vi := vom.MapIndex(vk)
		if vi.IsValid() {
			vom.SetMapIndex(vk, reflect.Append(vi, v))
		} else {
			vom.SetMapIndex(vk, reflect.Append(reflect.MakeSlice(vs.Type(), 0, len), v))
		}
	}

	return vom.Interface()
}
Пример #9
0
func goType(t *TypeInfo) reflect.Type {
	switch t.Type {
	case TypeVarchar, TypeAscii, TypeInet:
		return reflect.TypeOf(*new(string))
	case TypeBigInt, TypeCounter:
		return reflect.TypeOf(*new(int64))
	case TypeTimestamp:
		return reflect.TypeOf(*new(time.Time))
	case TypeBlob:
		return reflect.TypeOf(*new([]byte))
	case TypeBoolean:
		return reflect.TypeOf(*new(bool))
	case TypeFloat:
		return reflect.TypeOf(*new(float32))
	case TypeDouble:
		return reflect.TypeOf(*new(float64))
	case TypeInt:
		return reflect.TypeOf(*new(int))
	case TypeDecimal:
		return reflect.TypeOf(*new(*inf.Dec))
	case TypeUUID, TypeTimeUUID:
		return reflect.TypeOf(*new(UUID))
	case TypeList, TypeSet:
		return reflect.SliceOf(goType(t.Elem))
	case TypeMap:
		return reflect.MapOf(goType(t.Key), goType(t.Elem))
	case TypeVarint:
		return reflect.TypeOf(*new(*big.Int))
	default:
		return nil
	}
}
Пример #10
0
func (p Pages) GroupBy(key, order string) ([]PageGroup, error) {
	if len(p) < 1 {
		return nil, nil
	}

	if order != "asc" && order != "desc" {
		return nil, errors.New("order argument must be 'asc' or 'desc'")
	}

	ppt := reflect.TypeOf(&Page{})
	ft, ok := ppt.Elem().FieldByName(key)
	if !ok {
		return nil, errors.New("No such field in Page struct")
	}
	tmp := reflect.MakeMap(reflect.MapOf(ft.Type, reflect.SliceOf(ppt)))

	for _, e := range p {
		ppv := reflect.ValueOf(e)
		fv := ppv.Elem().FieldByName(key)
		if !tmp.MapIndex(fv).IsValid() {
			tmp.SetMapIndex(fv, reflect.MakeSlice(reflect.SliceOf(ppt), 0, 0))
		}
		tmp.SetMapIndex(fv, reflect.Append(tmp.MapIndex(fv), ppv))
	}

	var r []PageGroup
	for _, k := range sortKeys(tmp.MapKeys(), order) {
		r = append(r, PageGroup{Key: k.Interface(), Data: tmp.MapIndex(k).Interface().([]*Page)})
	}

	return r, nil
}
Пример #11
0
func Uniq(source, selector interface{}) interface{} {
	if selector == nil {
		selector = func(value, _ interface{}) Facade {
			return Facade{reflect.ValueOf(value)}
		}
	}

	var mapRV reflect.Value
	var arrRV reflect.Value
	each(source, selector, func(resRV, valueRv, _ reflect.Value) bool {
		if !mapRV.IsValid() {
			mapRT := reflect.MapOf(resRV.Type(), reflect.TypeOf(false))
			mapRV = reflect.MakeMap(mapRT)

			arrRT := reflect.SliceOf(valueRv.Type())
			arrRV = reflect.MakeSlice(arrRT, 0, 0)
		}

		mapValueRV := mapRV.MapIndex(resRV)
		if !mapValueRV.IsValid() {
			mapRV.SetMapIndex(resRV, reflect.ValueOf(true))
			arrRV = reflect.Append(arrRV, valueRv)
		}
		return false
	})
	if mapRV.IsValid() {
		return arrRV.Interface()
	}

	return nil
}
Пример #12
0
Файл: types.go Проект: DavyC/goa
// MakeMap examines the key type from a Hash and create a map with builtin type if possible.
// The idea is to avoid generating map[interface{}]interface{}, which cannot be handled by json.Marshal.
func (h *Hash) MakeMap(pair map[interface{}]interface{}) interface{} {
	if !h.KeyType.Type.IsPrimitive() {
		// well, a type can't be handled by json.Marshal... not much we can do
		return pair
	}
	if len(pair) == 0 {
		// figure out the map type manually
		switch h.KeyType.Type.Kind() {
		case BooleanKind:
			return map[bool]interface{}{}
		case IntegerKind:
			return map[int]interface{}{}
		case NumberKind:
			return map[float64]interface{}{}
		case StringKind:
			return map[string]interface{}{}
		case DateTimeKind:
			return map[time.Time]interface{}{}
		default:
			return pair
		}
	}
	var newMap reflect.Value
	for key, value := range pair {
		rkey, rvalue := reflect.ValueOf(key), reflect.ValueOf(value)
		if !newMap.IsValid() {
			newMap = reflect.MakeMap(reflect.MapOf(rkey.Type(), rvalue.Type()))
		}
		newMap.SetMapIndex(rkey, rvalue)
	}
	return newMap.Interface()
}
Пример #13
0
Файл: rule.go Проект: kego/ke
func (r *RuleWrapper) GetReflectType() (reflect.Type, error) {

	if r.Struct != nil && r.Struct.Interface {
		typ, ok := r.Parent.GetReflectInterface(r.Ctx)
		if !ok {
			return nil, kerr.New("QGUVEUTXAN", "Type interface for %s not found", r.Parent.Id.Value())
		}
		return typ, nil
	}

	if c, ok := r.Interface.(CollectionRule); ok {
		itemsRule := c.GetItemsRule()
		if itemsRule != nil {
			items := WrapRule(r.Ctx, itemsRule)
			itemsType, err := items.GetReflectType()
			if err != nil {
				return nil, kerr.Wrap("LMKEHHWHKL", err)
			}
			if r.Parent.NativeJsonType(r.Ctx) == J_MAP {
				return reflect.MapOf(reflect.TypeOf(""), itemsType), nil
			}
			return reflect.SliceOf(itemsType), nil
		}
	}

	typ, ok := r.Parent.GetReflectType(r.Ctx)
	if !ok {
		return nil, kerr.New("DLAJJPJDPL", "Type %s not found", r.Parent.Id.Value())
	}

	return typ, nil

}
Пример #14
0
func (s *Common) ExtendMap(i interface{}, with interface{}) {
	name := fmt.Sprintf("%v", i)
	m, ok := s.data[name]
	if !ok {
		m = reflect.MakeMap(reflect.MapOf(reflect.TypeOf(""), reflect.TypeOf(with)))
	}
	m.SetMapIndex(reflect.ValueOf(name), reflect.ValueOf(with))
	s.data[name] = m
}
Пример #15
0
func (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) error {
	valType := val.Type()
	valKeyType := valType.Key()
	valElemType := valType.Elem()

	// Make a new map to hold our result
	mapType := reflect.MapOf(valKeyType, valElemType)
	valMap := reflect.MakeMap(mapType)

	// Check input type
	dataVal := reflect.Indirect(reflect.ValueOf(data))
	if dataVal.Kind() != reflect.Map {
		// Accept empty array/slice instead of an empty map in weakly typed mode
		if d.config.WeaklyTypedInput &&
			(dataVal.Kind() == reflect.Slice || dataVal.Kind() == reflect.Array) &&
			dataVal.Len() == 0 {
			val.Set(valMap)
			return nil
		} else {
			return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind())
		}
	}

	// Accumulate errors
	errors := make([]string, 0)

	for _, k := range dataVal.MapKeys() {
		fieldName := fmt.Sprintf("%s[%s]", name, k)

		// First decode the key into the proper type
		currentKey := reflect.Indirect(reflect.New(valKeyType))
		if err := d.decode(fieldName, k.Interface(), currentKey); err != nil {
			errors = appendErrors(errors, err)
			continue
		}

		// Next decode the data into the proper type
		v := dataVal.MapIndex(k).Interface()
		currentVal := reflect.Indirect(reflect.New(valElemType))
		if err := d.decode(fieldName, v, currentVal); err != nil {
			errors = appendErrors(errors, err)
			continue
		}

		valMap.SetMapIndex(currentKey, currentVal)
	}

	// Set the built up map to the value
	val.Set(valMap)

	// If we had errors, return those
	if len(errors) > 0 {
		return &Error{errors}
	}

	return nil
}
Пример #16
0
// AsMap converts given map into other map
func AsMap(v interface{}, key reflect.Type, val reflect.Type, add func(to reflect.Value, key reflect.Value, val reflect.Value)) reflect.Value {
	res := reflect.MakeMap(reflect.MapOf(key, val))
	r := reflect.ValueOf(v)
	switch r.Kind() {
	case reflect.Map:
		for _, k := range r.MapKeys() {
			add(res, k, r.MapIndex(k))
		}
	}
	return res
}
Пример #17
0
// MapTypeParser 定义了序列类型解析逻辑
func MapTypeParser(st p.State) (interface{}, error) {
	key, err := p.Between(p.Str("map["), p.Chr(']'), TypeParser)(st)
	if err != nil {
		return nil, err
	}
	value, err := TypeParser(st)
	if err != nil {
		return nil, err
	}
	return reflect.MapOf(key.(Type).Type, value.(Type).Type), nil
}
Пример #18
0
func (d *decoder) decodeInterface(name string, v *MrbValue, result reflect.Value) error {
	var set reflect.Value
	redecode := true

	switch t := v.Type(); t {
	case TypeHash:
		var temp map[string]interface{}
		tempVal := reflect.ValueOf(temp)
		result := reflect.MakeMap(
			reflect.MapOf(
				reflect.TypeOf(""),
				tempVal.Type().Elem()))

		set = result
	case TypeArray:
		var temp []interface{}
		tempVal := reflect.ValueOf(temp)
		result := reflect.MakeSlice(
			reflect.SliceOf(tempVal.Type().Elem()), 0, 0)
		set = result
	case TypeFalse:
		fallthrough
	case TypeTrue:
		var result bool
		set = reflect.Indirect(reflect.New(reflect.TypeOf(result)))
	case TypeFixnum:
		var result int
		set = reflect.Indirect(reflect.New(reflect.TypeOf(result)))
	case TypeFloat:
		var result float64
		set = reflect.Indirect(reflect.New(reflect.TypeOf(result)))
	case TypeString:
		set = reflect.Indirect(reflect.New(reflect.TypeOf("")))
	default:
		return fmt.Errorf(
			"%s: cannot decode into interface: %s",
			name, t)
	}

	// Set the result to what its supposed to be, then reset
	// result so we don't reflect into this method anymore.
	result.Set(set)

	if redecode {
		// Revisit the node so that we can use the newly instantiated
		// thing and populate it.
		if err := d.decode(name, v, result); err != nil {
			return err
		}
	}

	return nil
}
Пример #19
0
func decodeIntoMap(name string, o *Object, result reflect.Value) error {
	if o.Type() != ObjectTypeObject {
		return fmt.Errorf("%s: not an object type, can't decode to map", name)
	}

	resultType := result.Type()
	resultElemType := resultType.Elem()
	resultKeyType := resultType.Key()
	if resultKeyType.Kind() != reflect.String {
		return fmt.Errorf("%s: map must have string keys", name)
	}

	// Make a map to store our result
	resultMap := result
	if result.IsNil() {
		resultMap = reflect.MakeMap(
			reflect.MapOf(resultKeyType, resultElemType))
	}

	outerIter := o.Iterate(false)
	defer outerIter.Close()
	for outer := outerIter.Next(); outer != nil; outer = outerIter.Next() {
		iter := outer.Iterate(true)
		defer iter.Close()
		for elem := iter.Next(); elem != nil; elem = iter.Next() {
			fieldName := fmt.Sprintf("%s[%s]", name, elem.Key())

			key := reflect.ValueOf(elem.Key())

			// The value we have to be decode
			val := reflect.Indirect(reflect.New(resultElemType))

			// If we have a pre-existing value in the map, use that
			oldVal := resultMap.MapIndex(key)
			if oldVal.IsValid() {
				val.Set(oldVal)
			}

			err := decode(fieldName, elem, val)
			elem.Close()
			if err != nil {
				return err
			}

			resultMap.SetMapIndex(key, val)
		}
	}

	// Set the final result
	result.Set(resultMap)

	return nil
}
Пример #20
0
func (w *walker) Map(m reflect.Value) error {
	if w.ignoring() {
		return nil
	}

	// Get the type for the map
	t := m.Type()
	mapType := reflect.MapOf(t.Key(), t.Elem())

	// Create the map. If the map itself is nil, then just make a nil map
	var newMap reflect.Value
	if m.IsNil() {
		newMap = reflect.Indirect(reflect.New(mapType))
	} else {
		newMap = reflect.MakeMap(reflect.MapOf(t.Key(), t.Elem()))
	}

	w.cs = append(w.cs, newMap)
	w.valPush(newMap)
	return nil
}
Пример #21
0
func (t *Job) Reduce(args Args, reply *int) error {
	go func() {
		r := new(task.ReduceCollector)
		elem := reflect.TypeOf(r).Elem()
		key := elem.Field(0).Type
		value := reflect.SliceOf(elem.Field(1).Type)
		m := reflect.MapOf(key, value)
		mp := reflect.MakeMap(m).Interface()

		combine(t.decodeReduce(t.path), mp)

		mpv := reflect.ValueOf(mp)
		keys := mpv.MapKeys()
		length := len(keys)
		chinr := make(chan CombineCollector, length)
		choutr := make(chan task.ReduceCollector, length)
		chfinr := make(chan bool)

		for i := 0; i < t.NumReduce; i++ {
			go reduceRoutine(chinr, choutr, chfinr)
		}

		for i := range keys {
			key := keys[i]
			val := mpv.MapIndex(key)
			chinr <- CombineCollector{key.Interface(), val.Interface()}
		}

		conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", t.Master, t.ReduceDataPort))
		if err != nil {
			log.Fatal("Connection error ", err)
		}
		encoder := gob.NewEncoder(conn)
		err = encoder.Encode(&Port)
		err = encoder.Encode(&length)

		for _ = range keys {
			redData := <-choutr
			err = encoder.Encode(&redData)

		}
		if err != nil {
			panic(err)
		}
		conn.Close()
		for i := 0; i < t.NumReduce; i++ {
			chfinr <- true
		}
	}()

	*reply = 0
	return nil
}
Пример #22
0
// ContainsSameElements compares, without taking order on the
// first level, the contents of two slices of the same type.
// The elements of the slice must have comparisons defined,
// otherwise a panic will result.
func ContainsSameElements(s1, s2 interface{}) bool {
	// TODO add support for chans when needed.
	// Preliminary checks to weed out incompatible inputs.
	if reflect.TypeOf(s1).Kind() != reflect.Slice || reflect.TypeOf(s2).Kind() != reflect.Slice {
		panic("received non-slice argument")
	}
	if reflect.TypeOf(s1) != reflect.TypeOf(s2) {
		panic("received slices with incompatible types")
	}

	// Create a map that keeps a count of how often we see
	// each element in the slices.
	m := reflect.MakeMap(reflect.MapOf(reflect.TypeOf(s1).Elem(), reflect.TypeOf(uint64(0))))

	// Get the actual slices we are comparing.
	rs1 := reflect.ValueOf(s1)
	rs2 := reflect.ValueOf(s2)

	var zeroValue reflect.Value

	if rs1.Len() != rs2.Len() {
		return false
	}

	// Fill the counting hash map using the first slice.
	for i := 0; i < rs1.Len(); i++ {
		v := rs1.Index(i)
		k := m.MapIndex(v)
		if k == zeroValue {
			// The entry did not exist, so the new count is 1.
			m.SetMapIndex(v, reflect.ValueOf(uint64(1)))
		} else {
			m.SetMapIndex(v, reflect.ValueOf(k.Uint()+uint64(1)))
		}
	}

	// Compare the counts from s1 against the second slice.
	for i := 0; i < rs2.Len(); i++ {
		v := rs2.Index(i)
		k := m.MapIndex(v)
		if k == zeroValue {
			return false
		} else if k.Uint() == 1 {
			// Setting the zero value removes the entry.
			m.SetMapIndex(v, zeroValue)
		} else {
			m.SetMapIndex(v, reflect.ValueOf(k.Uint()-uint64(1)))
		}
	}

	// If all went well until here, the map is now empty.
	return m.Len() == 0
}
Пример #23
0
// MapTypeParserExt  定义了带环境的映射类型解析逻辑
func MapTypeParserExt(env Env) p.P {
	return func(st p.State) (interface{}, error) {
		key, err := p.Between(p.Str("map["), p.Chr(']'), ExtTypeParser(env))(st)
		if err != nil {
			return nil, err
		}
		value, err := ExtTypeParser(env)(st)
		if err != nil {
			return nil, err
		}
		return reflect.MapOf(key.(Type).Type, value.(Type).Type), nil
	}
}
Пример #24
0
// The subkeyType() function is used to choose types when none is specified
// by the input. When overwriting into an interface{}, a concrete type is
// chosen here. It will be a map[string]interface{}, []interface{}, or string
// depending on whether the subkey is a field, index, or terminal.
func (k fieldKey) subkeyType() reflect.Type {
	var i interface{}
	switch k.subkey.(type) {
	case fieldKey:
		return reflect.MapOf(reflect.TypeOf("string"), reflect.TypeOf(&i).Elem())
	case indexKey:
		return reflect.SliceOf(reflect.TypeOf(&i).Elem())
	case terminalKey:
		return reflect.TypeOf("")
	default:
		panic("unreachable")
	}
}
Пример #25
0
func (d *Decoder) decodeMap(n int) (interface{}, error) {
	var err error
	var keyType, valType reflect.Type

	keys := [16]interface{}{}
	keyType = nil
	vals := [16]interface{}{}
	valType = nil

	for i := 0; i < n; i++ {
		keys[i], err = d.decode()
		if err != nil {
			return nil, err
		}
		vals[i], err = d.decode()
		if err != nil {
			return nil, err
		}

		_keyType := reflect.TypeOf(keys[i])
		if _keyType.Kind() == reflect.Map {
			return nil, fmt.Errorf("Map is don't be map key.")
		}
		if keyType == nil {
			keyType = _keyType
		} else if keyType != _keyType {
			keyType = _interfaceType
		}

		_valType := reflect.TypeOf(vals[i])
		if valType == nil {
			valType = _valType
		} else if valType != _valType {
			valType = _interfaceType
		}
	}

	if keyType == nil {
		keyType = _interfaceType
	}
	if valType == nil {
		valType = _interfaceType
	}

	result := reflect.MakeMap(reflect.MapOf(keyType, valType))
	for i := 0; i < n; i++ {
		result.SetMapIndex(reflect.ValueOf(keys[i]), reflect.ValueOf(vals[i]))
	}

	return result.Interface(), nil
}
Пример #26
0
// StreamJSON uses the supplied client to POST the given proto request as JSON
// to the supplied streaming grpc-gw endpoint; the response type serves only to
// create the values passed to the callback (which is invoked for every message
// in the stream with a value of the supplied response type masqueraded as an
// interface).
func StreamJSON(
	httpClient http.Client,
	path string,
	request proto.Message,
	dest proto.Message,
	callback func(proto.Message),
) error {
	str, err := (&jsonpb.Marshaler{}).MarshalToString(request)
	if err != nil {
		return err
	}

	resp, err := httpClient.Post(path, JSONContentType, strings.NewReader(str))
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		b, err := ioutil.ReadAll(resp.Body)
		return errors.Errorf("status: %s, body: %s, error: %s", resp.Status, b, err)
	}

	// grpc-gw/runtime's JSONpb {en,de}coder is pretty half-baked. Essentially
	// we must pass a *map[string]*concreteType or it won't work (in
	// particular, using a struct or replacing `*concreteType` with either
	// `concreteType` or `proto.Message` leads to errors). This method should do
	// a decent enough job at encapsulating this away; should this change, we
	// should consider cribbing and fixing up the marshaling code.
	m := reflect.New(reflect.MapOf(reflect.TypeOf(""), reflect.TypeOf(dest)))
	// TODO(tschottdorf,tamird): We have cribbed parts of this object to deal
	// with varying proto imports, and should technically use them here. We can
	// get away with not cribbing more here for now though.
	marshaler := runtime.JSONPb{}
	decoder := marshaler.NewDecoder(resp.Body)
	for {
		if err := decoder.Decode(m.Interface()); err == io.EOF {
			break
		} else if err != nil {
			return err
		}
		v := m.Elem().MapIndex(reflect.ValueOf("result"))
		if !v.IsValid() {
			// TODO(tschottdorf): recover actual JSON.
			return errors.Errorf("unexpected JSON response: %+v", m)
		}
		callback(v.Interface().(proto.Message))
	}
	return nil
}
Пример #27
0
func ArrayColumnMap(data interface{}, columnNames string) interface{} {
	//提取信息
	name := Explode(columnNames, ",")
	nameInfo := []arrayColumnMapInfo{}
	dataValue := reflect.ValueOf(data)
	dataType := dataValue.Type().Elem()
	for _, singleName := range name {
		singleField, ok := getFieldByName(dataType, singleName)
		if !ok {
			panic(dataType.Name() + " struct has not field " + singleName)
		}
		nameInfo = append(nameInfo, arrayColumnMapInfo{
			Index: singleField.Index,
			Type:  singleField.Type,
		})
	}
	prevType := dataType
	for i := len(nameInfo) - 1; i >= 0; i-- {
		nameInfo[i].MapType = reflect.MapOf(
			nameInfo[i].Type,
			prevType,
		)
		prevType = nameInfo[i].MapType
	}

	//整合map
	result := reflect.MakeMap(nameInfo[0].MapType)
	dataLen := dataValue.Len()
	for i := 0; i != dataLen; i++ {
		singleValue := dataValue.Index(i)
		prevValue := result
		for singleNameIndex, singleNameInfo := range nameInfo {
			var nextValue reflect.Value
			singleField := singleValue.FieldByIndex(singleNameInfo.Index)
			nextValue = prevValue.MapIndex(singleField)
			if !nextValue.IsValid() {
				if singleNameIndex+1 < len(nameInfo) {
					nextValue = reflect.MakeMap(nameInfo[singleNameIndex+1].MapType)
				} else {
					nextValue = singleValue
				}
				prevValue.SetMapIndex(singleField, nextValue)
			}
			prevValue = nextValue
		}
	}
	return result.Interface()
}
Пример #28
0
func Serialize(input interface{}) string {
	switch reflect.ValueOf(input).Kind() {
	case reflect.Int:
		return strconv.Itoa(input.(int))
	case reflect.Uint8:
		return Serialize(int(input.(uint8)))
	case reflect.Int8:
		return Serialize(int(input.(int8)))
	case reflect.Uint16:
		return Serialize(int(input.(uint16)))
	case reflect.Int16:
		return Serialize(int(input.(int16)))
	case reflect.Uint32:
		return Serialize(int64(input.(uint32)))
	case reflect.Int32:
		return Serialize(int(input.(int32)))
	case reflect.Int64:
		return strconv.FormatInt(input.(int64), 10)
	case reflect.Float64:
		return strconv.FormatFloat(input.(float64), 'f', 6, 64)
	case reflect.String:
		return "\"" + strings.Replace(input.(string), "\"", "\\\"", -1) + "\""
	case reflect.Map:
		t := reflect.TypeOf(input)
		v := reflect.ValueOf(input)
		it := reflect.TypeOf((*interface{})(nil)).Elem()
		m := reflect.MakeMap(reflect.MapOf(t.Key(), it))

		for _, mk := range v.MapKeys() {
			m.SetMapIndex(mk, v.MapIndex(mk))
		}

		return mapSerialize(m.Interface().(map[string]interface{}))
	case reflect.Slice:
		s := reflect.ValueOf(input)
		ret := make([]interface{}, s.Len())

		for i := 0; i < s.Len(); i++ {
			ret[i] = s.Index(i).Interface()
		}

		return arraySerialize(ret)
	case reflect.Struct:
		return structSerialize(input)
	default:
		panic("Attempt to serialize unsupported type.")
	}
}
Пример #29
0
// GroupByParam groups by the given page parameter key's value and with the given order.
// Valid values for order is asc, desc, rev and reverse.
func (p Pages) GroupByParam(key string, order ...string) (PagesGroup, error) {
	if len(p) < 1 {
		return nil, nil
	}

	direction := "asc"

	if len(order) > 0 && (strings.ToLower(order[0]) == "desc" || strings.ToLower(order[0]) == "rev" || strings.ToLower(order[0]) == "reverse") {
		direction = "desc"
	}

	var tmp reflect.Value
	var keyt reflect.Type
	for _, e := range p {
		param := e.GetParam(key)
		if param != nil {
			if _, ok := param.([]string); !ok {
				keyt = reflect.TypeOf(param)
				tmp = reflect.MakeMap(reflect.MapOf(keyt, reflect.SliceOf(pagePtrType)))
				break
			}
		}
	}
	if !tmp.IsValid() {
		return nil, errors.New("There is no such a param")
	}

	for _, e := range p {
		param := e.getParam(key, false)
		if param == nil || reflect.TypeOf(param) != keyt {
			continue
		}
		v := reflect.ValueOf(param)
		if !tmp.MapIndex(v).IsValid() {
			tmp.SetMapIndex(v, reflect.MakeSlice(reflect.SliceOf(pagePtrType), 0, 0))
		}
		tmp.SetMapIndex(v, reflect.Append(tmp.MapIndex(v), reflect.ValueOf(e)))
	}

	var r []PageGroup
	for _, k := range sortKeys(tmp.MapKeys(), direction) {
		r = append(r, PageGroup{Key: k.Interface(), Pages: tmp.MapIndex(k).Interface().([]*Page)})
	}

	return r, nil
}
Пример #30
-1
// Memoize takes a function and returns a function of the same type. The
// returned function remembers the return value(s) of the function call.
// Any pointer values will be used as an address, so functions that modify
// their arguments or programs that modify returned values will not work.
//
// The returned function is safe to call from multiple goroutines if the
// original function is. Panics are handled, so calling panic from a function
// will call panic with the same value on future invocations with the same
// arguments.
//
// The arguments to the function must be of comparable types. Slices, maps,
// functions, and structs or arrays that contain slices, maps, or functions
// cause a runtime panic if they are arguments to a memoized function.
// See also: https://golang.org/ref/spec#Comparison_operators
//
// As a special case, variadic functions (func(x, y, ...z)) are allowed.
func Memoize(fn interface{}) interface{} {
	v := reflect.ValueOf(fn)
	t := v.Type()

	keyType := reflect.ArrayOf(t.NumIn(), interfaceType)
	cache := reflect.MakeMap(reflect.MapOf(keyType, valueType))
	var mtx sync.Mutex

	return reflect.MakeFunc(t, func(args []reflect.Value) (results []reflect.Value) {
		key := reflect.New(keyType).Elem()
		for i, v := range args {
			if i == len(args)-1 && t.IsVariadic() {
				a := reflect.New(reflect.ArrayOf(v.Len(), v.Type().Elem())).Elem()
				for j, l := 0, v.Len(); j < l; j++ {
					a.Index(j).Set(v.Index(j))
				}
				v = a
			}
			vi := v.Interface()
			key.Index(i).Set(reflect.ValueOf(&vi).Elem())
		}
		mtx.Lock()
		val := cache.MapIndex(key)
		if val.IsValid() {
			mtx.Unlock()
			c := val.Interface().(*call)
			<-c.wait
			if c.panicked.IsValid() {
				panic(c.panicked.Interface())
			}
			return c.results
		}
		w := make(chan struct{})
		c := &call{wait: w}
		cache.SetMapIndex(key, reflect.ValueOf(c))
		mtx.Unlock()

		panicked := true
		defer func() {
			if panicked {
				p := recover()
				c.panicked = reflect.ValueOf(p)
				close(w)
				panic(p)
			}
		}()

		if t.IsVariadic() {
			results = v.CallSlice(args)
		} else {
			results = v.Call(args)
		}
		panicked = false
		c.results = results
		close(w)

		return
	}).Interface()
}