Beispiel #1
0
func (association *Association) Append(values ...interface{}) *Association {
	scope := association.Scope
	field := scope.IndirectValue().FieldByName(association.Column)
	for _, value := range values {
		reflectvalue := reflect.ValueOf(value)
		if reflectvalue.Kind() == reflect.Ptr {
			if reflectvalue.Elem().Kind() == reflect.Struct {
				if field.Type().Elem().Kind() == reflect.Ptr {
					field.Set(reflect.Append(field, reflectvalue))
				} else if field.Type().Elem().Kind() == reflect.Struct {
					field.Set(reflect.Append(field, reflectvalue.Elem()))
				}
			} else if reflectvalue.Elem().Kind() == reflect.Slice {
				if field.Type().Elem().Kind() == reflect.Ptr {
					field.Set(reflect.AppendSlice(field, reflectvalue))
				} else if field.Type().Elem().Kind() == reflect.Struct {
					field.Set(reflect.AppendSlice(field, reflectvalue.Elem()))
				}
			}
		} else if reflectvalue.Kind() == reflect.Struct && field.Type().Elem().Kind() == reflect.Struct {
			field.Set(reflect.Append(field, reflectvalue))
		} else if reflectvalue.Kind() == reflect.Slice && field.Type().Elem() == reflectvalue.Type().Elem() {
			field.Set(reflect.AppendSlice(field, reflectvalue))
		} else {
			association.err(errors.New("invalid association type"))
		}
	}
	scope.callCallbacks(scope.db.parent.callback.updates)
	return association.err(scope.db.Error)
}
Beispiel #2
0
func (s *sequenceType) Build(i *Injector) (Binding, error) {
	binding, err := Annotate(s.v).Build(i)
	if err != nil {
		return Binding{}, err
	}
	if binding.Provides.Kind() != reflect.Slice {
		return Binding{}, fmt.Errorf("Sequence() must be bound to a slice not %s", binding.Provides)
	}
	next, ok := i.bindings[binding.Provides]
	return Binding{
		Provides: binding.Provides,
		Requires: binding.Requires,
		Build: func() (interface{}, error) {
			out := reflect.MakeSlice(binding.Provides, 0, 0)
			if ok {
				v, err := next.Build()
				if err != nil {
					return nil, err
				}
				out = reflect.AppendSlice(out, reflect.ValueOf(v))
			}
			v, err := binding.Build()
			if err != nil {
				return nil, err
			}
			out = reflect.AppendSlice(out, reflect.ValueOf(v))
			return out.Interface(), nil
		},
	}, nil
}
Beispiel #3
0
// DeleteCopy removes the element of the slice at a given index.
// The returned slice references a new array, the original
// array and all referencing slices are un-altered.
//
// The returned slice will be the same type as the given slice, but
// stored in an interface{}.
//
// Uses reflection to perform this action on slices of any type.
// Will panic if:
//	- slice argument is not a slice type
//	- idx is not in the range 0 .. len(slice)-1
//
// Equivalent to:
//	slice = append(append(make([]T,0,len(slice)-1),slice[:idx]...),slice[idx+1]...)
func DeleteCopy(slice interface{}, index int) interface{} {
	sliceVal := checkDelete(slice, index)
	begin := sliceVal.Slice(0, index)
	end := sliceVal.Slice(index+1, sliceVal.Len())
	tmp := reflect.MakeSlice(sliceVal.Type(), 0, sliceVal.Len()-1)
	return reflect.AppendSlice(reflect.AppendSlice(tmp, begin), end).Interface()
}
Beispiel #4
0
// InsertCopy adds an element to a slice at a given index. Always allocates
// a new slice, and never modifies the original memory.
//
// The returned slice will be the same type as the given slice, but
// stored in an interface{}.
//
// Uses reflection to perform this action on slices of any type.
// Will panic if:
//	- slice argument is not a slice type
//	- slice argument's element type doesn't match item's type
//	- idx is not in the range 0 .. len(slice)
//
// Equivalent to:
// 	begin, end := slice[:idx], slice[idx:]
// 	slice = append(append(append(make([]T,0,len(slice)+1), begin...),item),end...)
func InsertCopy(slice interface{}, index int, item interface{}) interface{} {
	sliceVal, itemVal := checkInsert(slice, index, item)
	begin := sliceVal.Slice(0, index)
	end := sliceVal.Slice(index, sliceVal.Len())

	out := reflect.MakeSlice(sliceVal.Type(), 0, sliceVal.Len()+1)
	out = reflect.AppendSlice(reflect.Append(reflect.AppendSlice(out, begin), itemVal), end)
	return out.Interface()
}
Beispiel #5
0
func (f *protoFuzzer) Fuzz(v reflect.Value) {
	if !v.CanSet() {
		return
	}

	switch v.Kind() {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		f.FuzzInt(v)
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		f.FuzzUint(v)
	case reflect.String:
		str := ""
		for i := 0; i < v.Len(); i++ {
			str = str + string(' '+rune(f.r.Intn(94)))
		}
		v.SetString(str)
		return
	case reflect.Ptr:
		if !v.IsNil() {
			f.Fuzz(v.Elem())
		}
		return
	case reflect.Slice:
		mode := f.r.Intn(3)
		switch {
		case v.Len() > 0 && mode == 0:
			// fuzz entry
			f.Fuzz(v.Index(f.r.Intn(v.Len())))
		case v.Len() > 0 && mode == 1:
			// remove entry
			entry := f.r.Intn(v.Len())
			pre := v.Slice(0, entry)
			post := v.Slice(entry+1, v.Len())
			v.Set(reflect.AppendSlice(pre, post))
		default:
			// add entry
			entry := reflect.MakeSlice(v.Type(), 1, 1)
			f.Fuzz(entry) // XXX fill all fields
			v.Set(reflect.AppendSlice(v, entry))
		}
		return
	case reflect.Struct:
		f.Fuzz(v.Field(f.r.Intn(v.NumField())))
		return
	case reflect.Map:
		// TODO fuzz map
	default:
		panic(fmt.Sprintf("Not fuzzing %v %+v", v.Kind(), v))
	}
}
Beispiel #6
0
func main() {
	var a []int
	var value reflect.Value = reflect.ValueOf(&a)

	//判断指针是否指向内存地址
	if !value.CanSet() {
		value = value.Elem() //使指针指向内存地址
	}

	value = reflect.AppendSlice(value, reflect.ValueOf([]int{1, 2}))                //支持切片
	value = reflect.AppendSlice(value, reflect.ValueOf([]int{3, 4, 5, 6, 7, 8, 9})) //支持切片
	fmt.Println(value.Kind(), value.Slice(0, value.Len()).Interface())
	/////  >> slice [1 2 3 4 5 6 7 8 9]

}
Beispiel #7
0
func (s *sliceShrink) Next() (interface{}, bool) {
	if s.chunkLength == 0 {
		return nil, false
	}
	value := reflect.AppendSlice(reflect.MakeSlice(s.original.Type(), 0, s.length-s.chunkLength), s.original.Slice(0, s.offset))
	s.offset += s.chunkLength
	if s.offset < s.length {
		value = reflect.AppendSlice(value, s.original.Slice(s.offset, s.length))
	} else {
		s.offset = 0
		s.chunkLength >>= 1
	}

	return value.Interface(), true
}
Beispiel #8
0
// loadSlice loads url and decodes it into a []elemType, returning the []elemType and error.
func loadSlice(url string, elemType interface{}) (interface{}, error) {
	t := reflect.TypeOf(elemType)
	result := reflect.New(reflect.SliceOf(t)).Elem() // result is []elemType

	link := url
	for link != "" {
		req, err := http.NewRequest("GET", link, nil)
		if err != nil {
			return result.Interface(), err
		}

		resp, err := http.DefaultClient.Do(req)
		if err != nil {
			return result.Interface(), err
		}
		if resp.StatusCode > 299 {
			lr := io.LimitReader(resp.Body, 1024)
			bs, _ := ioutil.ReadAll(lr)
			resp.Body.Close()
			return result.Interface(), fmt.Errorf("http.Get: %v (%s)", resp.Status, bs)
		}

		tmp := reflect.New(reflect.SliceOf(t)) // tmp is *[]elemType
		err = json.NewDecoder(resp.Body).Decode(tmp.Interface())
		resp.Body.Close()
		if err != nil {
			return result.Interface(), err
		}

		result = reflect.AppendSlice(result, tmp.Elem())
		link = parseRel(resp.Header.Get("Link"), "next")
	}

	return result.Interface(), nil
}
Beispiel #9
0
func deStructSlice(dataValue reflect.Value) (interface{}, interface{}, map[string]interface{}) {
	if dataValue.Kind() == reflect.Uint8 {
		newDataValue := reflect.MakeSlice(dataValue.Type(), dataValue.Len(), dataValue.Cap())
		newDataValue = reflect.AppendSlice(newDataValue, dataValue)
		return newDataValue.Interface(), newDataValue.Interface(), nil
	}

	//TODO if the type inside the slice is not a struct, recreate the slice with the same definition
	newData := make([]interface{}, dataValue.Len())
	flatData := make(map[string]interface{})
	for i := 0; i < dataValue.Len(); i++ {
		subDataValue := dataValue.Index(i)
		key := strconv.Itoa(i)

		fieldCopy, fieldScalar, fieldMap := deStructValue(subDataValue)
		newData[i] = fieldCopy

		if fieldScalar != nil {
			flatData[key] = fieldScalar
		}
		for fieldMapKey, fieldMapValue := range fieldMap {
			flatData[key+"."+fieldMapKey] = fieldMapValue
		}
	}

	return newData, nil, flatData
}
Beispiel #10
0
func (node *tagAppendNode) Execute(ctx *p2.ExecutionContext, writer p2.TemplateWriter) *p2.Error {
	var values []interface{}
	var reflectValues reflect.Value
	if o := ctx.Public[node.name]; nil != o {
		values, _ = o.([]interface{})
		if nil == values {
			reflectValues = reflect.ValueOf(o)
			if reflectValues.Kind() == reflect.Ptr {
				reflectValues = reflectValues.Elem()
			}
			if reflectValues.Kind() != reflect.Slice {
				return ctx.Error("'"+node.name+"' isn't a slice.", nil)
			}
		}
	}

	for _, ev := range node.objectEvaluators {
		obj, err := ev.Evaluate(ctx)
		if err != nil {
			return err
		}
		if reflectValues.IsNil() {
			values = append(values, obj)
		} else {
			reflectValues = reflect.AppendSlice(reflectValues, reflect.ValueOf(obj))
		}
	}

	if reflectValues.IsNil() {
		ctx.Public[node.name] = values
	} else {
		ctx.Public[node.name] = reflectValues.Interface()
	}
	return nil
}
Beispiel #11
0
func Delete(element interface{}, slice interface{}) bool {
	valElement := reflect.ValueOf(element)
	typSlice := reflect.TypeOf(slice)
	valSlice := reflect.ValueOf(slice)

	if !valElement.IsValid() || !valSlice.IsValid() {
		return false
	}

	switch typSlice.Kind() {
	case reflect.Slice:
		sliceLen := valSlice.Len()
		for idx := 0; idx < sliceLen; idx++ {
			val := valSlice.Index(idx)
			if !val.IsValid() {
				continue
			}

			if val.Interface() == valElement.Interface() {
				if idx == sliceLen-1 {
					valSlice = valSlice.Slice(0, idx)
				} else {
					valSlice = reflect.AppendSlice(valSlice.Slice(0, idx), valSlice.Slice(idx+1, sliceLen-1))
				}
			}
		}
	case reflect.Map:
	}

	return false
}
Beispiel #12
0
func mergeValue(values []reflect.Value) reflect.Value {
	values = removeZeroValues(values)
	l := len(values)
	if l == 0 {
		return reflect.Value{}
	}

	sample := values[0]
	mergeable := isMergeable(sample)

	t := sample.Type()
	if mergeable {
		t = t.Elem()
	}

	value := reflect.MakeSlice(reflect.SliceOf(t), 0, 0)
	for i := 0; i < l; i++ {
		if !values[i].IsValid() {
			continue
		}

		if mergeable {
			value = reflect.AppendSlice(value, values[i])
		} else {
			value = reflect.Append(value, values[i])
		}
	}

	return value
}
Beispiel #13
0
// A very limited merge. Merges the fields named in the fields parameter,
// replacing most values, but appending to arrays.
func mergeStruct(base, overlay interface{}, fields []string) error {
	baseValue := reflect.ValueOf(base).Elem()
	overlayValue := reflect.ValueOf(overlay).Elem()
	if baseValue.Kind() != reflect.Struct {
		return fmt.Errorf("Tried to merge something that wasn't a struct: type %v was %v",
			baseValue.Type(), baseValue.Kind())
	}
	if baseValue.Type() != overlayValue.Type() {
		return fmt.Errorf("Tried to merge two different types: %v and %v",
			baseValue.Type(), overlayValue.Type())
	}
	for _, field := range fields {
		overlayFieldValue := findField(field, overlayValue)
		if !overlayFieldValue.IsValid() {
			return fmt.Errorf("could not find field in %v matching %v",
				overlayValue.Type(), field)
		}
		baseFieldValue := findField(field, baseValue)
		if overlayFieldValue.Kind() == reflect.Slice {
			baseFieldValue.Set(reflect.AppendSlice(baseFieldValue, overlayFieldValue))
		} else {
			baseFieldValue.Set(overlayFieldValue)
		}
	}
	return nil
}
Beispiel #14
0
// Stitch provides a function that may be used by polymer types to implement Stitcher.
// It makes use of reflection and so may be slower than type-specific implementations.
// This is the reference implementation and should be used to compare type-specific
// implementation against in testing.
func Stitch(pol interface{}, offset int, f feat.FeatureSet) (s interface{}, err error) {
	t := interval.NewTree()
	var i *interval.Interval

	for _, feature := range f {
		i, err = interval.New(emptyString, feature.Start, feature.End, 0, nil)
		if err != nil {
			return
		} else {
			t.Insert(i)
		}
	}

	pv := reflect.ValueOf(pol)
	pLen := pv.Len()
	end := pLen + offset
	span, err := interval.New(emptyString, offset, end, 0, nil)
	if err != nil {
		panic("Sequence.End() < Sequence.Start()")
	}
	fs, _ := t.Flatten(span, 0, 0)
	l := 0

	for _, seg := range fs {
		l += util.Min(seg.End(), end) - util.Max(seg.Start(), offset)
	}
	tv := reflect.MakeSlice(pv.Type(), 0, l)

	for _, seg := range fs {
		tv = reflect.AppendSlice(tv, pv.Slice(util.Max(seg.Start()-offset, 0), util.Min(seg.End()-offset, pLen)))
	}

	return tv.Interface(), nil
}
Beispiel #15
0
// appendStruct is an internal helper function to AppendConfig. Given two values
// of structures (assumed to be the same type), recursively iterate over every
// field in the struct, appending slices, recursively appending structs, and
// overwriting old values with the new for all other types. Individual fields
// are able to override their merge strategy using the "merge" tag. Accepted
// values are "new" or "old": "new" uses the new value, "old" uses the old
// value. These are currently only used for "ignition.config" and
// "ignition.version".
func appendStruct(vOld, vNew reflect.Value) reflect.Value {
	tOld := vOld.Type()
	vRes := reflect.New(tOld)

	for i := 0; i < tOld.NumField(); i++ {
		vfOld := vOld.Field(i)
		vfNew := vNew.Field(i)
		vfRes := vRes.Elem().Field(i)

		switch tOld.Field(i).Tag.Get("merge") {
		case "old":
			vfRes.Set(vfOld)
			continue
		case "new":
			vfRes.Set(vfNew)
			continue
		}

		switch vfOld.Type().Kind() {
		case reflect.Struct:
			vfRes.Set(appendStruct(vfOld, vfNew))
		case reflect.Slice:
			vfRes.Set(reflect.AppendSlice(vfOld, vfNew))
		default:
			vfRes.Set(vfNew)
		}
	}

	return vRes.Elem()
}
Beispiel #16
0
// NextPage retrieves a sequence of items from the iterator and appends them
// to slicep, which must be a pointer to a slice of the iterator's item type.
// Exactly p.pageSize items will be appended, unless fewer remain.
//
// The first return value is the page token to use for the next page of items.
// If empty, there are no more pages. Aside from checking for the end of the
// iteration, the returned page token is only needed if the iteration is to be
// resumed a later time, in another context (possibly another process).
//
// The second return value is non-nil if an error occurred. It will never be
// the special iterator sentinel value Done. To recognize the end of the
// iteration, compare nextPageToken to the empty string.
//
// It is possible for NextPage to return a single zero-length page along with
// an empty page token when there are no more items in the iteration.
func (p *Pager) NextPage(slicep interface{}) (nextPageToken string, err error) {
	p.pageInfo.nextPageCalled = true
	if p.pageInfo.err != nil {
		return "", p.pageInfo.err
	}
	if p.pageInfo.nextCalled {
		p.pageInfo.err = errMixed
		return "", p.pageInfo.err
	}
	if p.pageInfo.bufLen() > 0 {
		return "", errors.New("must call NextPage with an empty buffer")
	}
	// The buffer must be empty here, so takeBuf is a no-op. We call it just to get
	// the buffer's type.
	wantSliceType := reflect.PtrTo(reflect.ValueOf(p.pageInfo.takeBuf()).Type())
	if slicep == nil {
		return "", errors.New("nil passed to Pager.NextPage")
	}
	vslicep := reflect.ValueOf(slicep)
	if vslicep.Type() != wantSliceType {
		return "", fmt.Errorf("slicep should be of type %s, got %T", wantSliceType, slicep)
	}
	for p.pageInfo.bufLen() < p.pageSize {
		if err := p.pageInfo.fill(p.pageSize - p.pageInfo.bufLen()); err != nil {
			p.pageInfo.err = err
			return "", p.pageInfo.err
		}
		if p.pageInfo.Token == "" {
			break
		}
	}
	e := vslicep.Elem()
	e.Set(reflect.AppendSlice(e, reflect.ValueOf(p.pageInfo.takeBuf())))
	return p.pageInfo.Token, nil
}
Beispiel #17
0
func AppendValue(dest interface{}, value ...interface{}) (err error) {
	defer func() {
		tmperr := recover()
		err, _ = tmperr.(error)
	}()
	if lenval := len(value); lenval > 0 {
		sliceval := reflect.ValueOf(dest).Elem()

		newslice := reflect.MakeSlice(sliceval.Type(), 0, lenval)

		if lenval == 1 {
			reflect.Append(newslice, reflect.ValueOf(value[0]).Elem())
		} else {
			reflect.AppendSlice(newslice, reflect.ValueOf(value))
		}

		/*
			for _, val := range value {
				reflect.Append(newslice, reflect.ValueOf(val).Elem())
			}
		*/

		sliceval.Set(newslice)
	}

	return
}
Beispiel #18
0
func sliceFromStrings(value interface{}, type_ interface{}) (vs interface{}, err error) {
	switch value.(type) {
	case string:
		sv := value.(string)
		strs := strings.Split(sv, ",")
		switch type_.(type) {
		case string:
			return strs, err
		case int:
			var ivs []int
			for _, s := range strs {
				var iv int64
				iv, err = strconv.ParseInt(s, 10, 64)
				if err != nil {
					err = fmt.Errorf("Cannot parse %v (int)", s)
					return
				}
				ivs = append(ivs, int(iv))
			}
			return ivs, err
		case float64:
			var fvs []float64
			for _, s := range strs {
				var fv float64
				fv, err = strconv.ParseFloat(s, 64)
				if err != nil {
					err = fmt.Errorf("Cannot parse %v (float64)", s)
					return
				}
				fvs = append(fvs, fv)
			}
			return fvs, err
		default:
			err = fmt.Errorf("Cannot parse %v (%v)", value, reflect.ValueOf(value).Kind())
			return
		}
	case []string:
		// var values interface{}
		for _, sval := range value.([]string) {
			val, err := sliceFromStrings(sval, type_)
			if err != nil {
				return vs, err
			}
			// vs = append(vs, val)

			if reflect.TypeOf(vs) == nil {
				vs = val
			} else {
				vs = reflect.AppendSlice(
					reflect.ValueOf(vs),
					reflect.ValueOf(val),
				).Interface()
			}

		}
	default:
		err = fmt.Errorf("Cannot parse %v (%v)", value, reflect.ValueOf(value).Kind())
	}
	return
}
Beispiel #19
0
// For single values, Add will add (using the + operator) the addend to the existing addend (if found).
// Supports numeric values and strings.
//
// If the first add for a key is an array or slice, then the next value(s) will be appended.
func (c *Scratch) Add(key string, newAddend interface{}) (string, error) {
	var newVal interface{}
	existingAddend, found := c.values[key]
	if found {
		var err error

		addendV := reflect.ValueOf(existingAddend)

		if addendV.Kind() == reflect.Slice || addendV.Kind() == reflect.Array {
			nav := reflect.ValueOf(newAddend)
			if nav.Kind() == reflect.Slice || nav.Kind() == reflect.Array {
				newVal = reflect.AppendSlice(addendV, nav).Interface()
			} else {
				newVal = reflect.Append(addendV, nav).Interface()
			}
		} else {
			newVal, err = helpers.DoArithmetic(existingAddend, newAddend, '+')
			if err != nil {
				return "", err
			}
		}
	} else {
		newVal = newAddend
	}
	c.values[key] = newVal
	return "", nil // have to return something to make it work with the Go templates
}
Beispiel #20
0
func (w *overrideWalker) SliceElem(idx int, v reflect.Value) error {
	if w.depth == 1 && w.currentSectionName == w.o.Section && w.o.Element != "" {
		w.currentElementName = ""
		if w.elementKey == "" {
			return fmt.Errorf("an element key must be specified via the `%s:\",%s<field name>\"` struct tag", structTagKey, elementKeyword)
		}
		// Get current element name via field on current value
		elementField := findFieldByElementKey(v, w.elementKey)
		if !elementField.IsValid() {
			return fmt.Errorf("could not find field with name %q on value of type %s", w.elementKey, v.Type())
		}
		if elementField.Kind() != reflect.String {
			return fmt.Errorf("element key field must be of type string, got %s", elementField.Type())
		}
		w.currentElementName = elementField.String()
		if w.o.Element == w.currentElementName {
			if w.o.Delete {
				// Delete the element from the slice by re-slicing the element out
				w.currentSlice.Set(
					reflect.AppendSlice(
						w.currentSlice.Slice(0, idx),
						w.currentSlice.Slice(idx+1, w.currentSlice.Len()),
					),
				)
			} else {
				w.elementValue = v
			}
		}
	}
	return nil
}
Beispiel #21
0
//复合类型修改示例
func func5() {
	s := make([]int, 0, 10)
	v := reflect.ValueOf(&s).Elem()

	v.SetLen(2)
	v.Index(0).SetInt(100)
	v.Index(1).SetInt(200)

	fmt.Println(v.Interface(), s)

	v2 := reflect.Append(v, reflect.ValueOf(300))
	v2 = reflect.AppendSlice(v2, reflect.ValueOf([]int{400, 500}))

	fmt.Println(v2.Interface())
	//fmt.Println(v2.Interface().([]int))

	fmt.Println("-----------------")

	m := map[string]int{"a": 1}
	v = reflect.ValueOf(&m).Elem()

	v.SetMapIndex(reflect.ValueOf("a"), reflect.ValueOf(100)) //update
	v.SetMapIndex(reflect.ValueOf("b"), reflect.ValueOf(200)) //add

	fmt.Println(v.Interface().(map[string]int))
}
Beispiel #22
0
func decodeSlice(v reflect.Value, x interface{}) {
	t := v.Type()
	if t.Elem().Kind() == reflect.Uint8 {
		// Allow, but don't require, byte slices to be encoded as a single string.
		if s, ok := x.(string); ok {
			v.SetBytes([]byte(s))
			return
		}
	}

	// NOTE: Implicit indexing is currently done at the parseValues level,
	//       so if if an implicitKey reaches here it will always replace the last.
	implicit := 0
	for k, c := range getNode(x) {
		var i int
		if k == implicitKey {
			i = implicit
			implicit++
		} else {
			explicit, err := strconv.Atoi(k)
			if err != nil {
				panic(k + " is not a valid index for type " + t.String())
			}
			i = explicit
			implicit = explicit + 1
		}
		// "Extend" the slice if it's too short.
		if l := v.Len(); i >= l {
			delta := i - l + 1
			v.Set(reflect.AppendSlice(v, reflect.MakeSlice(t, delta, delta)))
		}
		decodeValue(v.Index(i), c)
	}
}
func SliceAppendSlice(slice interface{}, sliceToAppend interface{}) interface{} {
	if reflect.TypeOf(slice).Kind() != reflect.Slice || reflect.TypeOf(sliceToAppend).Kind() != reflect.Slice {
		panic("wrong type")
	}
	newSlice := reflect.ValueOf(slice)
	newSlice = reflect.AppendSlice(newSlice, reflect.ValueOf(sliceToAppend))
	return newSlice.Interface()
}
Beispiel #24
0
func growSliceValue(v reflect.Value, n int) reflect.Value {
	diff := n - v.Len()
	if diff > sliceAllocLimit {
		diff = sliceAllocLimit
	}
	v = reflect.AppendSlice(v, reflect.MakeSlice(v.Type(), diff, diff))
	return v
}
Beispiel #25
0
func DeleteSliceElementVal(sliceVal reflect.Value, idx int) reflect.Value {
	if idx < 0 || idx >= sliceVal.Len() {
		return sliceVal
	}
	before := sliceVal.Slice(0, idx)
	after := sliceVal.Slice(idx+1, sliceVal.Len())
	sliceVal = reflect.AppendSlice(before, after)
	return sliceVal
}
Beispiel #26
0
// FindParallelByCondition executes SELECT query to all of the shards with conditions
func (xpr *XormParallel) FindParallelByCondition(listPtr interface{}, cond FindCondition) error {
	vt := reflect.TypeOf(listPtr)
	if vt.Kind() != reflect.Ptr {
		return errors.NewErrArgType("listPtr must be a pointer")
	}
	elem := vt.Elem()
	if elem.Kind() != reflect.Slice && elem.Kind() != reflect.Map {
		return errors.NewErrArgType("listPtr must be a pointer of slice or map")
	}

	// create session with the condition
	slaves := xpr.orm.Slaves(cond.Table)
	var sessions []Session
	for _, slave := range slaves {
		s := slave.NewSession()
		for _, w := range cond.Where {
			s.And(w.Statement, w.Args...)
		}
		for _, o := range cond.OrderBy {
			if o.OrderByDesc {
				s.Desc(o.Name)
			} else {
				s.Asc(o.Name)
			}
		}
		if cond.Limit > 0 {
			s.Limit(cond.Limit, cond.Offset)
		}
		sessions = append(sessions, s)
	}

	// execute query
	var errList []error
	results := make(chan reflect.Value, len(slaves))
	for _, s := range sessions {
		list := reflect.New(elem)
		go func(s Session, list reflect.Value) {
			err := s.Find(list.Interface())
			if err != nil {
				errList = append(errList, err)
			}
			results <- list
		}(s, list)
	}

	// wait for the results
	e := reflect.ValueOf(listPtr).Elem()
	for range slaves {
		v := <-results
		e.Set(reflect.AppendSlice(e, v.Elem()))
	}
	if len(errList) > 0 {
		return errors.NewErrParallelQuery(errList)
	}

	return nil
}
Beispiel #27
0
func mergeAny(out, in reflect.Value) {
	if in.Type() == protoMessageType {
		if !in.IsNil() {
			if out.IsNil() {
				out.Set(reflect.ValueOf(Clone(in.Interface().(Message))))
			} else {
				Merge(out.Interface().(Message), in.Interface().(Message))
			}
		}
		return
	}
	switch in.Kind() {
	case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
		reflect.String, reflect.Uint32, reflect.Uint64:
		out.Set(in)
	case reflect.Ptr:
		if in.IsNil() {
			return
		}
		if out.IsNil() {
			out.Set(reflect.New(in.Elem().Type()))
		}
		mergeAny(out.Elem(), in.Elem())
	case reflect.Slice:
		if in.IsNil() {
			return
		}
		if in.Type().Elem().Kind() == reflect.Uint8 {
			// []byte is a scalar bytes field, not a repeated field.
			// Make a deep copy.
			// Append to []byte{} instead of []byte(nil) so that we never end up
			// with a nil result.
			out.SetBytes(append([]byte{}, in.Bytes()...))
			return
		}
		n := in.Len()
		if out.IsNil() {
			out.Set(reflect.MakeSlice(in.Type(), 0, n))
		}
		switch in.Type().Elem().Kind() {
		case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
			reflect.String, reflect.Uint32, reflect.Uint64:
			out.Set(reflect.AppendSlice(out, in))
		default:
			for i := 0; i < n; i++ {
				x := reflect.Indirect(reflect.New(in.Type().Elem()))
				mergeAny(x, in.Index(i))
				out.Set(reflect.Append(out, x))
			}
		}
	case reflect.Struct:
		mergeStruct(out, in)
	default:
		// unknown type, so not a protocol buffer
		log.Printf("proto: don't know how to copy %v", in)
	}
}
func removeAt(index int, s interface{}) interface{} {
	t, v := reflect.TypeOf(s), reflect.ValueOf(s)
	cpy := reflect.MakeSlice(t, v.Len(), v.Len())
	reflect.Copy(cpy, v)
	if index == 0 {
		return cpy.Slice(1, cpy.Len()).Interface()
	} else {
		return reflect.AppendSlice(cpy.Slice(0, index), cpy.Slice(index+1, cpy.Len())).Interface()
	}
}
Beispiel #29
0
func appendBytes(intSize int, v reflect.Value, b []byte) reflect.Value {
	length := (len(b) * 8) / intSize

	sh := &reflect.SliceHeader{}
	sh.Cap = length
	sh.Len = length
	sh.Data = uintptr(unsafe.Pointer(&b[0]))
	nslice := reflect.NewAt(v.Type(), unsafe.Pointer(sh)).Elem()

	return reflect.AppendSlice(v, nslice)
}
Beispiel #30
0
func mergeAny(out, in reflect.Value) {
	if in.Type() == protoMessageType {
		if !in.IsNil() {
			if out.IsNil() {
				out.Set(reflect.ValueOf(Clone(in.Interface().(Message))))
			} else {
				Merge(out.Interface().(Message), in.Interface().(Message))
			}
		}
		return
	}
	switch in.Kind() {
	case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
		reflect.String, reflect.Uint32, reflect.Uint64:
		out.Set(in)
	case reflect.Ptr:
		if in.IsNil() {
			return
		}
		if out.IsNil() {
			out.Set(reflect.New(in.Elem().Type()))
		}
		mergeAny(out.Elem(), in.Elem())
	case reflect.Slice:
		if in.IsNil() {
			return
		}
		n := in.Len()
		if out.IsNil() {
			out.Set(reflect.MakeSlice(in.Type(), 0, n))
		}
		switch in.Type().Elem().Kind() {
		case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
			reflect.String, reflect.Uint32, reflect.Uint64:
			out.Set(reflect.AppendSlice(out, in))
		case reflect.Uint8:
			// []byte is a scalar bytes field.
			out.Set(in)
		default:
			for i := 0; i < n; i++ {
				x := reflect.Indirect(reflect.New(in.Type().Elem()))
				mergeAny(x, in.Index(i))
				out.Set(reflect.Append(out, x))
			}
		}
	case reflect.Struct:
		mergeStruct(out, in)
	default:
		// unknown type, so not a protocol buffer
		log.Printf("proto: don't know how to copy %v", in)
	}
}