// deserializeStructInternal is a helper function for deserializeStruct. // It takes a gob decoder and struct field metadata, and then assigns the correct value to the specified struct field. func deserializeStructInternal(dec *gob.Decoder, fi *fieldInfo, fieldName string, nameParts []string, slice, zeroValue bool, structHistory map[string]map[string]bool, v reflect.Value, t reflect.Type) error { if len(fi.sliceIndex) > 0 { v = v.FieldByIndex(fi.sliceIndex) t = v.Type() var sv reflect.Value createNew := false nameIdx := len(fi.sliceIndex) absName, childName := strings.Join(nameParts[:nameIdx], "."), strings.Join(nameParts[nameIdx:], ".") sh, ok := structHistory[absName] if !ok || sh[childName] { sh = make(map[string]bool, 8) structHistory[absName] = sh createNew = true } else if len(sh) == 0 { createNew = true } if createNew { structType := t.Elem() sv = reflect.New(structType).Elem() v.Set(reflect.Append(v, sv)) } sv = v.Index(v.Len() - 1) sh[childName] = true v = sv t = v.Type() } vf := v.FieldByIndex(fi.fieldIndex) if vf.Kind() == reflect.Slice && !slice { elemType := vf.Type().Elem() if elemType.Kind() == reflect.Uint8 { if !zeroValue { if err := dec.DecodeValue(vf); err != nil { return fmt.Errorf("goon: Failed to decode field %v - %v", fieldName, err) } } } else { ev := reflect.New(elemType).Elem() if !zeroValue { if err := dec.DecodeValue(ev); err != nil { return fmt.Errorf("goon: Failed to decode field %v - %v", fieldName, err) } } vf.Set(reflect.Append(vf, ev)) } } else if !zeroValue { if err := dec.DecodeValue(vf); err != nil { return fmt.Errorf("goon: Failed to decode field %v - %v", fieldName, err) } } return nil }
func (scope *Scope) getColumnAsScope(column string) *Scope { indirectScopeValue := scope.IndirectValue() switch indirectScopeValue.Kind() { case reflect.Slice: if fieldStruct, ok := scope.GetModelStruct().ModelType.FieldByName(column); ok { fieldType := fieldStruct.Type if fieldType.Kind() == reflect.Slice || fieldType.Kind() == reflect.Ptr { fieldType = fieldType.Elem() } results := reflect.New(reflect.SliceOf(reflect.PtrTo(fieldType))).Elem() for i := 0; i < indirectScopeValue.Len(); i++ { result := indirect(indirect(indirectScopeValue.Index(i)).FieldByName(column)) if result.Kind() == reflect.Slice { for j := 0; j < result.Len(); j++ { if elem := result.Index(j); elem.CanAddr() { results = reflect.Append(results, elem.Addr()) } } } else if result.CanAddr() { results = reflect.Append(results, result.Addr()) } } return scope.New(results.Interface()) } case reflect.Struct: if field := indirectScopeValue.FieldByName(column); field.CanAddr() { return scope.New(field.Addr().Interface()) } } return nil }
func (scope *Scope) getColumnsAsScope(column string) *Scope { values := scope.IndirectValue() switch values.Kind() { case reflect.Slice: modelType := values.Type().Elem() if modelType.Kind() == reflect.Ptr { modelType = modelType.Elem() } fieldStruct, _ := modelType.FieldByName(column) var columns reflect.Value if fieldStruct.Type.Kind() == reflect.Slice || fieldStruct.Type.Kind() == reflect.Ptr { columns = reflect.New(reflect.SliceOf(reflect.PtrTo(fieldStruct.Type.Elem()))).Elem() } else { columns = reflect.New(reflect.SliceOf(reflect.PtrTo(fieldStruct.Type))).Elem() } for i := 0; i < values.Len(); i++ { column := reflect.Indirect(values.Index(i)).FieldByName(column) if column.Kind() == reflect.Ptr { column = column.Elem() } if column.Kind() == reflect.Slice { for i := 0; i < column.Len(); i++ { columns = reflect.Append(columns, column.Index(i).Addr()) } } else { columns = reflect.Append(columns, column.Addr()) } } return scope.New(columns.Interface()) case reflect.Struct: return scope.New(values.FieldByName(column).Addr().Interface()) } return nil }
func (processor *processor) decode() (errors []error) { if processor.checkSkipLeft() || processor.MetaValues == nil { return } for _, metaValue := range processor.MetaValues.Values { meta := metaValue.Meta if meta == nil { continue } if processor.newRecord && !meta.HasPermission(roles.Create, processor.Context) { continue } else if !meta.HasPermission(roles.Update, processor.Context) { continue } if setter := meta.GetSetter(); setter != nil { setter(processor.Result, metaValue, processor.Context) continue } res := metaValue.Meta.GetResource() if res == nil { continue } field := reflect.Indirect(reflect.ValueOf(processor.Result)).FieldByName(meta.GetFieldName()) if field.Kind() == reflect.Struct { value := reflect.New(field.Type()) associationProcessor := DecodeToResource(res, value.Interface(), metaValue.MetaValues, processor.Context) associationProcessor.Start() if !associationProcessor.SkipLeft { field.Set(value.Elem()) } } else if field.Kind() == reflect.Slice { var fieldType = field.Type().Elem() var isPtr bool if fieldType.Kind() == reflect.Ptr { fieldType = fieldType.Elem() isPtr = true } value := reflect.New(fieldType) associationProcessor := DecodeToResource(res, value.Interface(), metaValue.MetaValues, processor.Context) associationProcessor.Start() if !associationProcessor.SkipLeft { if !reflect.DeepEqual(reflect.Zero(fieldType).Interface(), value.Elem().Interface()) { if isPtr { field.Set(reflect.Append(field, value)) } else { field.Set(reflect.Append(field, value.Elem())) } } } } } return }
func (l *listSink) add(i *item) (bool, error) { if l.limit == 0 { return true, nil } if l.skip > 0 { l.skip-- return false, nil } if !l.results.IsValid() { l.results = reflect.MakeSlice(reflect.Indirect(l.ref).Type(), 0, 0) } if l.limit > 0 { l.limit-- } if l.idx == l.results.Len() { if l.isPtr { l.results = reflect.Append(l.results, *i.value) } else { l.results = reflect.Append(l.results, reflect.Indirect(*i.value)) } } l.idx++ return l.limit == 0, nil }
//MultiQuery executes given query and returns slice of all the entities it returns, with their keys set. func MultiQuery(c appengine.Context, typ reflect.Type, kind string, query *datastore.Query) (ms interface{}, err error) { is := reflect.MakeSlice(reflect.SliceOf(reflect.PtrTo(typ)), 0, 0) iter := query.Run(c) for { val := reflect.New(typ) var key *datastore.Key key, err = iter.Next(val.Interface()) if err != nil { if err == datastore.Done { err = nil val.MethodByName("SetKey").Call([]reflect.Value{reflect.ValueOf(key)}) reflect.Append(is, val) break } return } val.MethodByName("SetKey").Call([]reflect.Value{reflect.ValueOf(key)}) is = reflect.Append(is, val) } ms = is.Interface() return }
// 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() }
func ArrayMerge(arrayData interface{}, arrayData2 interface{}, arrayOther ...interface{}) interface{} { arrayOther = append([]interface{}{arrayData2}, arrayOther...) arrayOtherMap := sliceToMap(arrayOther) arrayValue := reflect.ValueOf(arrayData) arrayType := arrayValue.Type() arrayLen := arrayValue.Len() result := reflect.MakeSlice(arrayType, 0, 0) for i := 0; i != arrayLen; i++ { singleArrayDataValue := arrayValue.Index(i) singleArrayDataValueInterface := singleArrayDataValue.Interface() isFirst, isExist := arrayOtherMap[singleArrayDataValueInterface] if isExist == true && isFirst == false { continue } result = reflect.Append(result, singleArrayDataValue) arrayOtherMap[singleArrayDataValueInterface] = false } for single, isFirst := range arrayOtherMap { if isFirst == false { continue } result = reflect.Append(result, reflect.ValueOf(single)) } return result.Interface() }
func _partition(values []reflect.Value) []reflect.Value { slice := interfaceToValue(values[0]) fn := values[1] var t, f reflect.Value if values[0].Kind() == reflect.Interface { t = reflect.ValueOf(make([]interface{}, 0)) f = reflect.ValueOf(make([]interface{}, 0)) } else { t = reflect.MakeSlice(slice.Type(), 0, 0) f = reflect.MakeSlice(slice.Type(), 0, 0) } for i := 0; i < slice.Len(); i++ { e := slice.Index(i) r := fn.Call([]reflect.Value{e}) if r[0].Bool() { t = reflect.Append(t, e) } else { f = reflect.Append(f, e) } } return []reflect.Value{t, f} }
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) }
//This will execute the SQL and append results to the slice. // var ids []uint32 // if err := From("test").Select("id").ScanVals(&ids); err != nil{ // panic(err.Error() // } // //i: Takes a pointer to a slice of primitive values. func (me CrudExec) ScanVals(i interface{}) error { if me.err != nil { return me.err } val := reflect.ValueOf(i) if val.Kind() != reflect.Ptr { return NewGoquError("Type must be a pointer to a slice when calling ScanVals") } val = reflect.Indirect(val) if val.Kind() != reflect.Slice { return NewGoquError("Type must be a pointer to a slice when calling ScanVals") } t, _, isSliceOfPointers := getTypeInfo(i, val) rows, err := me.database.Query(me.Sql, me.Args...) if err != nil { return err } defer rows.Close() for rows.Next() { row := reflect.New(t) if err := rows.Scan(row.Interface()); err != nil { return err } if isSliceOfPointers { val.Set(reflect.Append(val, row)) } else { val.Set(reflect.Append(val, reflect.Indirect(row))) } } if err := rows.Err(); err != nil { return err } return nil }
// Remove duplicate element of a slice. // If error occurs, return value of r will be nil. func UniqueWithError(s interface{}) (r interface{}, err error) { v := reflect.ValueOf(s) if v.Kind() != reflect.Slice { err = fmt.Errorf("Parameter a must be a slice.") return } rest := reflect.MakeSlice(reflect.TypeOf(s), 0, 0) for i := v.Len() - 1; i >= 0; i-- { current := reflect.ValueOf(s).Slice(0, i) exist, e := InWithError(current.Interface(), v.Index(i).Interface()) if e != nil { err = e return } if !exist { rest = reflect.Append(rest, v.Index(i)) } s = current.Interface() } n := reflect.ValueOf(s) for i := rest.Len() - 1; i >= 0; i-- { n = reflect.Append(n, rest.Index(i)) } r = n.Interface() return }
func (d *Decoder) decodeSlice(s *decodStatus, v reflect.Value, t reflect.Type, tg tag) error { if _, isInline := tg.Modifiers["inline"]; isInline { val, ok := s.GetValue(d.env) if !ok { return nil } elements := d.arrSep.Split(val, -1) slice := reflect.MakeSlice(t, 0, len(elements)) for _, s := range elements { mv := reflect.New(t.Elem()) err := d.decodeField(mv.Elem(), s) if err != nil { return err } slice = reflect.Append(slice, mv.Elem()) } v.Set(slice) return nil } index := s.GetIndex() slice := reflect.MakeSlice(t, 0, len(index)) for _, i := range index { mv := reflect.New(t.Elem()) err := d.decodeElement(s, mv.Elem(), mv.Elem().Type(), tag{Name: strconv.Itoa(i), Modifiers: tg.Modifiers}) if err != nil { return err } slice = reflect.Append(slice, mv.Elem()) } v.Set(slice) return nil }
func (p *partitioner) partitionate(val, idx_or_key reflect.Value) { if ok := callPredicate(p.fn, val, idx_or_key); ok { p.t = reflect.Append(p.t, val) } else { p.f = reflect.Append(p.f, val) } }
func GetSliceConvert(c *Convertors) func(*Params, string, reflect.Type) reflect.Value { return func(p *Params, name string, typ reflect.Type) reflect.Value { var values ItemByIndex var maxIdx = 0 var noindex = 0 processItem := func(key string, vals []string) { var idx int var err error if !strings.HasPrefix(key, name+"[") { return } lIdx, rIdx := len(name), strings.IndexByte(key[len(name):], ']')+len(name) if rIdx == -1 { //not have ] char in key return } //process e.g. name[] if lIdx == rIdx-1 { noindex++ goto END } idx, err = strconv.Atoi(key[lIdx+1 : rIdx]) if err != nil { return } if idx > maxIdx { maxIdx = idx } END: value := c.Convert(p, key[:rIdx+1], typ.Elem()) values = append(values, &item{idx, value}) } for k, vals := range p.Values { processItem(k, vals) } //if array len small than 10000, keep index if maxIdx < 10000 { slice := reflect.MakeSlice(typ, maxIdx+1, maxIdx+noindex+1) for _, val := range values { if val.index > -1 { slice.Index(val.index).Set(val.value) } else { slice = reflect.Append(slice, val.value) } } return slice } sort.Sort(values) slice := reflect.MakeSlice(typ, 0, len(values)) for _, val := range values { slice = reflect.Append(slice, val.value) } return slice } }
// Fully scan a sql.Rows result into the dest slice. StructScan destinations MUST // have fields that map to every column in the result, and they MAY have fields // in addition to those. Fields are mapped to column names by lowercasing the // field names by default: use the struct tag `db` to specify exact column names // for each field. // // StructScan will scan in the entire rows result, so if you need do not want to // allocate structs for the entire result, use Queryx and see sqlx.Rows.StructScan. func StructScan(rows *sql.Rows, dest interface{}) error { var v, vp reflect.Value var isPtr bool value := reflect.ValueOf(dest) if value.Kind() != reflect.Ptr { return errors.New("Must pass a pointer, not a value, to StructScan destination.") } direct := reflect.Indirect(value) slice, err := BaseSliceType(value.Type()) if err != nil { return err } isPtr = slice.Elem().Kind() == reflect.Ptr base, err := BaseStructType(slice.Elem()) if err != nil { return err } fm, err := getFieldmap(base) if err != nil { return err } columns, err := rows.Columns() if err != nil { return err } fields, err := getFields(fm, columns) if err != nil { return err } // this will hold interfaces which are pointers to each field in the struct values := make([]interface{}, len(columns)) for rows.Next() { // create a new struct type (which returns PtrTo) and indirect it vp = reflect.New(base) v = reflect.Indirect(vp) setValues(fields, v, values) // scan into the struct field pointers and append to our results err = rows.Scan(values...) if err != nil { return err } if isPtr { direct.Set(reflect.Append(direct, vp)) } else { direct.Set(reflect.Append(direct, v)) } } return nil }
func extractResponse(body []byte, results interface{}, structType reflect.Type) (err error) { if structType == nil { structType = validateResultsType(results) } // results is now guaranteed to be a pointer to a slice of structs. sliceValue := reflect.ValueOf(results).Elem() // decode JSON response body: yrsp := new(yqlResponse) err = json.Unmarshal(body, yrsp) if err != nil { // debugging info: log.Printf("response: %s\n", body) return } // Decode the Results map as either an array of objects or a single object: quote := yrsp.Query.Results["quote"] if quote == nil { // TODO(jsd): clear the sliceValue pointer to nil? return } switch t := quote.(type) { default: panic(errors.New("unexpected JSON result type for 'quote'")) case []interface{}: sl := sliceValue for j, n := range t { // Append to the slice for each array element: m := n.(map[string]interface{}) sl = reflect.Append(sl, reflect.Zero(structType)) el := sl.Index(j) for i := 0; i < structType.NumField(); i++ { f := structType.Field(i) if v, ok := m[f.Name]; ok { el.Field(i).Set(reflect.ValueOf(v)) } } } sliceValue.Set(sl) case map[string]interface{}: // Insert the only element of the slice: sl := reflect.Append(sliceValue, reflect.Zero(structType)) el0 := sl.Index(0) for i := 0; i < structType.NumField(); i++ { f := structType.Field(i) if v, ok := t[f.Name]; ok { el0.Field(i).Set(reflect.ValueOf(v)) } } sliceValue.Set(sl) } return }
func newList(p parser.Interface, typ reflect.Type) (reflect.Value, error) { list := reflect.MakeSlice(typ, 0, 0) for { if err := p.Next(); err != nil { if err == io.EOF { return list, nil } else { panic(err) } } if p.IsLeaf() { return reflect.ValueOf(nil), fmt.Errorf("list: did not expect leaf") } _, err := p.Int() if err != nil { return reflect.ValueOf(nil), err } elemType := typ.Elem() elemKind := elemType.Kind() elemIsPtr := false if elemKind == reflect.Ptr { elemIsPtr = true elemType = typ.Elem().Elem() elemKind = elemType.Kind() } p.Down() switch elemKind { case reflect.Struct: if !p.IsLeaf() { elem := reflect.New(elemType).Elem() if err := encodeStruct(p, elem); err != nil { return reflect.ValueOf(nil), err } if elemIsPtr { elem = elem.Addr() } list = reflect.Append(list, elem) } else { list = reflect.Append(list, reflect.Zero(typ.Elem())) } case reflect.Slice: newList, err := newList(p, elemType) if err != nil { return reflect.ValueOf(nil), err } list = reflect.Append(list, newList) default: elem, err := newValue(p, typ.Elem()) if err != nil { return reflect.ValueOf(nil), err } list = reflect.Append(list, elem) } p.Up() } }
// subtractRepeatedMessage subtracts protos in list2 from the corresponding protos in list1. // The input lists should only contain protos, and the protos should have their identifiers // be their first field. func subtractRepeatedMessage(list1, list2 interface{}) reflect.Value { if list1 == nil && list2 == nil { return reflect.ValueOf([]proto.Message{}) } l1 := genericListOrDie(list1) if list2 == nil { return l1 } l2 := genericListOrDie(list2) if list1 == nil { // Need to make negatives of the elements in list2, so can't just return here. l1 = reflect.MakeSlice(l2.Type(), 0, 0) } t1, t2 := l1.Type(), l2.Type() if t1 != t2 { log.Fatalf("Mismatched list types: %v vs %v", t1, t2) } // All entries may not occur in both files, so use maps to keep track of everything. m1, m2 := make(map[string]proto.Message), make(map[string]proto.Message) for i := 0; i < l1.Len(); i++ { item := l1.Index(i) m1[name(item)] = item.Interface().(proto.Message) } for i := 0; i < l2.Len(); i++ { item := l2.Index(i) m2[name(item)] = item.Interface().(proto.Message) } out := reflect.MakeSlice(t1, 0, l1.Len()+l2.Len()) for n, p1 := range m1 { p2, ok := m2[n] if !ok { // In list1 but not list2. out = reflect.Append(out, reflect.ValueOf(proto.Clone(p1))) continue } if diff := subtractMessage(p1, p2); diff != nil { out = reflect.Append(out, reflect.ValueOf(diff)) } } for n, p2 := range m2 { if _, ok := m1[n]; !ok { // In list2 but not list1. Subtract to get negative values. if diff := subtractMessage(nil, p2); diff != nil { out = reflect.Append(out, reflect.ValueOf(diff)) } } } if out.Len() == 0 { return reflect.Zero(l1.Type()) } return out }
// all populates all rows of query result into a slice of struct or NullStringMap. // Note that the slice must be given as a pointer. func (r *Rows) all(slice interface{}) error { defer r.Close() v := reflect.ValueOf(slice) if v.Kind() != reflect.Ptr || v.IsNil() { return VarTypeError("must be a pointer") } v = indirect(v) if v.Kind() != reflect.Slice { return VarTypeError("must be a slice of struct or NullStringMap") } t := v.Type() et := t.Elem() if et.Kind() == reflect.Map { for r.Next() { ev, ok := reflect.MakeMap(et).Interface().(NullStringMap) if !ok { return VarTypeError("must be a slice of struct or NullStringMap") } if err := r.ScanMap(ev); err != nil { return err } v.Set(reflect.Append(v, reflect.ValueOf(ev))) } return r.Close() } if et.Kind() != reflect.Struct { return VarTypeError("must be a slice of struct or NullStringMap") } si := getStructInfo(t.Elem(), r.fieldMapFunc) cols, _ := r.Columns() for r.Next() { ev := reflect.New(et).Elem() refs := make([]interface{}, len(cols)) for i, col := range cols { if fi, ok := si.dbNameMap[col]; ok { refs[i] = fi.getField(ev).Addr().Interface() } else { refs[i] = &sql.NullString{} } } if err := r.Scan(refs...); err != nil { return err } v.Set(reflect.Append(v, ev)) } return r.Close() }
// unmarshal for when rv's Kind is Slice func unmarshalSlice(av *dynamodb.AttributeValue, rv reflect.Value) error { switch { case av.B != nil: rv.SetBytes(av.B) return nil case av.L != nil: slicev := reflect.MakeSlice(rv.Type(), 0, len(av.L)) for _, innerAV := range av.L { innerRV := reflect.New(rv.Type().Elem()).Elem() if err := unmarshalReflect(innerAV, innerRV); err != nil { return err } slicev = reflect.Append(slicev, innerRV) } rv.Set(slicev) return nil // there's probably a better way to do these case av.BS != nil: slicev := reflect.MakeSlice(rv.Type(), 0, len(av.L)) for _, b := range av.BS { innerRV := reflect.New(rv.Type().Elem()).Elem() if err := unmarshalReflect(&dynamodb.AttributeValue{B: b}, innerRV); err != nil { return err } slicev = reflect.Append(slicev, innerRV) } rv.Set(slicev) return nil case av.SS != nil: slicev := reflect.MakeSlice(rv.Type(), 0, len(av.L)) for _, str := range av.SS { innerRV := reflect.New(rv.Type().Elem()).Elem() if err := unmarshalReflect(&dynamodb.AttributeValue{S: str}, innerRV); err != nil { return err } slicev = reflect.Append(slicev, innerRV) } rv.Set(slicev) return nil case av.NS != nil: slicev := reflect.MakeSlice(rv.Type(), 0, len(av.L)) for _, n := range av.NS { innerRV := reflect.New(rv.Type().Elem()).Elem() if err := unmarshalReflect(&dynamodb.AttributeValue{N: n}, innerRV); err != nil { return err } slicev = reflect.Append(slicev, innerRV) } rv.Set(slicev) return nil } return errors.New("dynamo: unmarshal slice: B, L, BS, SS, NS are nil") }
// intersect returns the common elements in the given sets, l1 and l2. l1 and // l2 must be of the same type and may be either arrays or slices. func intersect(l1, l2 interface{}) (interface{}, error) { if l1 == nil || l2 == nil { return make([]interface{}, 0), nil } l1v := reflect.ValueOf(l1) l2v := reflect.ValueOf(l2) switch l1v.Kind() { case reflect.Array, reflect.Slice: switch l2v.Kind() { case reflect.Array, reflect.Slice: r := reflect.MakeSlice(l1v.Type(), 0, 0) for i := 0; i < l1v.Len(); i++ { l1vv := l1v.Index(i) for j := 0; j < l2v.Len(); j++ { l2vv := l2v.Index(j) switch l1vv.Kind() { case reflect.String: if l1vv.Type() == l2vv.Type() && l1vv.String() == l2vv.String() && !in(r.Interface(), l2vv.Interface()) { r = reflect.Append(r, l2vv) } case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: switch l2vv.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: if l1vv.Int() == l2vv.Int() && !in(r.Interface(), l2vv.Interface()) { r = reflect.Append(r, l2vv) } } case reflect.Float32, reflect.Float64: switch l2vv.Kind() { case reflect.Float32, reflect.Float64: if l1vv.Float() == l2vv.Float() && !in(r.Interface(), l2vv.Interface()) { r = reflect.Append(r, l2vv) } } } } } return r.Interface(), nil default: return nil, errors.New( "can't iterate over " + reflect.ValueOf(l2).Type().String()) } default: return nil, errors.New( "can't iterate over " + reflect.ValueOf(l1).Type().String()) } }
func (d *decodeState) sliceValue(v reflect.Value, s string) { //fmt.Printf(":SLICE(%s, %s)\n", v.Kind(), s) switch v.Type().Elem().Kind() { case reflect.String: v.Set(reflect.Append(v, reflect.ValueOf(s))) case reflect.Bool: v.Set(reflect.Append(v, reflect.ValueOf(boolValue(s)))) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: // Hardcoding of []int temporarily n, err := strconv.ParseInt(s, 10, 64) if err != nil { d.saveError(&IniError{d.lineNum, d.line, "Invalid int"}) return } n1 := reflect.ValueOf(n) n2 := n1.Convert(v.Type().Elem()) v.Set(reflect.Append(v, n2)) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: n, err := strconv.ParseUint(s, 10, 64) if err != nil { d.saveError(&IniError{d.lineNum, d.line, "Invalid uint"}) return } n1 := reflect.ValueOf(n) n2 := n1.Convert(v.Type().Elem()) v.Set(reflect.Append(v, n2)) case reflect.Float32, reflect.Float64: n, err := strconv.ParseFloat(s, 64) if err != nil { d.saveError(&IniError{d.lineNum, d.line, "Invalid float"}) return } n1 := reflect.ValueOf(n) n2 := n1.Convert(v.Type().Elem()) v.Set(reflect.Append(v, n2)) default: d.saveError(&IniError{d.lineNum, d.line, fmt.Sprintf("Can't set value in array of type %s", v.Type().Elem().Kind())}) } }
// Handle decoding of slices func (de *decoder) slice(slval reflect.Value, vb []byte) error { // Find the element type, and create a temporary instance of it. eltype := slval.Type().Elem() val := reflect.New(eltype).Elem() // Decide on the wiretype to use for decoding. var wiretype int switch eltype.Kind() { case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64: switch eltype { case sfixed32type: wiretype = 5 // Packed 32-bit representation case sfixed64type: wiretype = 1 // Packed 64-bit representation case ufixed32type: wiretype = 5 // Packed 32-bit representation case ufixed64type: wiretype = 1 // Packed 64-bit representation default: wiretype = 0 // Packed varint representation } case reflect.Float32: wiretype = 5 // Packed 32-bit representation case reflect.Float64: wiretype = 1 // Packed 64-bit representation case reflect.Uint8: // Unpacked byte-slice slval.SetBytes(vb) return nil default: // Other unpacked repeated types // Just unpack and append one value from vb. if err := de.putvalue(2, val, 0, vb); err != nil { return err } slval.Set(reflect.Append(slval, val)) return nil } // Decode packed values from the buffer and append them to the slice. for len(vb) > 0 { rem, err := de.value(wiretype, vb, val) if err != nil { return err } slval.Set(reflect.Append(slval, val)) vb = rem } return nil }
func sliceNextElemValue(v reflect.Value) reflect.Value { if v.Type().Elem().Kind() == reflect.Ptr { elem := reflect.New(v.Type().Elem().Elem()) v.Set(reflect.Append(v, elem)) return elem.Elem() } elem := reflect.New(v.Type().Elem()).Elem() v.Set(reflect.Append(v, elem)) elem = v.Index(v.Len() - 1) return elem }
func iterateSlice(v reflect.Value) reflect.Value { result := reflect.MakeSlice(v.Type(), 0, v.Len()) for i := 0; i < v.Len(); i++ { value := v.Index(i) vi := copyStruct(value) if value.Kind() == reflect.Ptr { result = reflect.Append(result, vi.Addr()) } else { result = reflect.Append(result, vi) } } return result }
func (coll *sliceCollection) newValue() reflect.Value { switch coll.v.Type().Elem().Kind() { case reflect.Ptr: elem := reflect.New(coll.v.Type().Elem().Elem()) coll.v.Set(reflect.Append(coll.v, elem)) return elem.Elem() case reflect.Struct: elem := reflect.New(coll.v.Type().Elem()).Elem() coll.v.Set(reflect.Append(coll.v, elem)) elem = coll.v.Index(coll.v.Len() - 1) return elem default: panic("not reached") } }
// Union outputs a collection that holds unique values of in and values collections func Union(in Collection, values Collection, out Pointer) error { if !IsCollection(in) { return NotACollection("Value %v is not a collection", in) } if !IsCollection(values) { return NotACollection("Value %v is not a collection", values) } if !IsPointer(out) { return NotPointer("Value %v is not a pointer", out) } inVal := reflect.ValueOf(in) valuesVal := reflect.ValueOf(values) outVal := reflect.ValueOf(out) if a, b := inVal.Type(), valuesVal.Type(); a != b { return NotAssignable("Collection of type '%v' doesn't match type ", a, b) } if a, c := inVal.Type(), outVal.Elem().Type(); !a.AssignableTo(c) { return NotAssignable("Collection of type '%v' is not assignable to output of type '%v'", a, c) } for i := 0; i < valuesVal.Len(); i++ { inVal = reflect.Append(inVal, valuesVal.Index(i)) } if err := Unique(inVal.Interface(), out); err != nil { return err } return nil }
// Unique filters remove duplicate values from an array func Unique(in Collection, out Pointer) error { if !IsCollection(in) { return NotACollection("Value '%v' is not a collection", in) } if !IsPointer(out) { return NotPointer("Value '%v' is not a pointer", out) } inValue := reflect.ValueOf(in) inType := inValue.Type() outValue := reflect.ValueOf(out) outType := outValue.Type() if !inType.AssignableTo(outType.Elem()) { return NotAssignable("Value in of type '%v' can't be assigned to out of type '%v' ", inType, outType.Elem()) } newCollection := reflect.MakeSlice(inType, 0, 0) inLen := inValue.Len() for i := 0; i < inLen; i++ { if index, err := IndexOf(newCollection.Interface(), inValue.Index(i).Interface(), 0); err != nil { return err } else if index == -1 { newCollection = reflect.Append(newCollection, inValue.Index(i)) } } outValue.Elem().Set(newCollection) return nil }
func sliceAppend(L *lua.State) int { slice, _ := valueOfProxy(L, 1) val := luaToGoValue(L, nil, 2) newslice := reflect.Append(slice, val) makeValueProxy(L, newslice, cSLICE_META) return 1 }