func (cfg *PageHeader) SetValue(key string, value string, s *reflect.Value) { // put unknown fields into a map if _, ok := s.Type().FieldByName(key); !ok { cfg.Other[key] = strings.TrimSpace(value) return } // Set value f := s.FieldByName(key) switch f.Interface().(type) { default: errhandle(fmt.Errorf("Unknown type of field %s", key)) case string: f.SetString(value) case []string: values := strings.Split(value, ",") for i, v := range values { values[i] = strings.TrimSpace(v) } f.Set(reflect.ValueOf(values)) case time.Time: var t time.Time var err error for _, fmt := range DATEFORMATS { t, err = time.Parse(fmt, value) if err == nil { break } } errhandle(err) f.Set(reflect.ValueOf(t)) } }
func (scan *Scan) ScanToStruct(rows *sql.Rows, record reflect.Value) error { columns, err := rows.Columns() if err != nil { return err } values := make([]interface{}, len(columns)) for i, column := range columns { var field reflect.Value fieldName := scan.SQLColumnDict[column] if scan.ToPointers { field = record.Elem().FieldByName(fieldName) } else { field = record.FieldByName(fieldName) } if field.IsValid() { values[i] = field.Addr().Interface() } else { values[i] = &values[i] } } return rows.Scan(values...) }
func (q *Query) findPopulatePath(path string) { parts := strings.Split(path, ".") resultVal := reflect.ValueOf(q.parentStruct).Elem() var refVal reflect.Value partsLen := len(parts) for i := 0; i < partsLen; i++ { elem := parts[i] if i == 0 { refVal = resultVal.FieldByName(elem) structTag, _ := resultVal.Type().FieldByName(elem) q.popSchema = structTag.Tag.Get(q.z.modelTag) } else if i == partsLen-1 { structTag, _ := refVal.Type().FieldByName(elem) q.popSchema = structTag.Tag.Get(q.z.modelTag) refVal = refVal.FieldByName(elem) } else { //refVal = handleSlice(refVal, elem, path) refVal = refVal.FieldByName(elem) } if !refVal.IsValid() { panic("field `" + elem + "` not found in populate path `" + path + "`") } } if refVal.Kind() == reflect.Slice { q.isSlice = true } q.populateField = refVal.Interface() }
func getFields(v reflect.Value, tagName string) []*Field { if v.Kind() == reflect.Ptr { v = v.Elem() } t := v.Type() var fields []*Field for i := 0; i < t.NumField(); i++ { field := t.Field(i) if tag := field.Tag.Get(tagName); tag == "-" { continue } f := &Field{ field: field, value: v.FieldByName(field.Name), } fields = append(fields, f) } return fields }
func (j *JSONPath) findFieldInValue(value *reflect.Value, node *FieldNode) (reflect.Value, error) { t := value.Type() var inlineValue *reflect.Value for ix := 0; ix < t.NumField(); ix++ { f := t.Field(ix) jsonTag := f.Tag.Get("json") parts := strings.Split(jsonTag, ",") if len(parts) == 0 { continue } if parts[0] == node.Value { return value.Field(ix), nil } if len(parts[0]) == 0 { val := value.Field(ix) inlineValue = &val } } if inlineValue != nil { if inlineValue.Kind() == reflect.Struct { // handle 'inline' match, err := j.findFieldInValue(inlineValue, node) if err != nil { return reflect.Value{}, err } if match.IsValid() { return match, nil } } } return value.FieldByName(node.Value), nil }
// unmarshalSettings sets for all its settings the relating field of v. func unmarshalSettings(settings SettingList, v reflect.Value) { for _, s := range settings { field := v.FieldByName(upperFirst(s.Name())) if !field.CanSet() { continue } switch s.Type() { case String: if field.Kind() == reflect.String { field.SetString(s.AsString()) } case Integer: switch field.Kind() { case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: if s.AsInteger() >= 0 { field.SetUint(uint64(s.AsInteger())) } case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: field.SetInt(s.AsInteger()) } case Real: if field.Kind() == reflect.Float32 || field.Kind() == reflect.Float64 { field.SetFloat(s.AsReal()) } } } }
func mergeStruct(out, in reflect.Value) { sprop := GetProperties(in.Type()) for i := 0; i < in.NumField(); i++ { f := in.Type().Field(i) if strings.HasPrefix(f.Name, "XXX_") { continue } mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i]) } if emIn, ok := in.Addr().Interface().(extensionsMap); ok { emOut := out.Addr().Interface().(extensionsMap) mergeExtension(emOut.ExtensionMap(), emIn.ExtensionMap()) } else if emIn, ok := in.Addr().Interface().(extensionsBytes); ok { emOut := out.Addr().Interface().(extensionsBytes) bIn := emIn.GetExtensions() bOut := emOut.GetExtensions() *bOut = append(*bOut, *bIn...) } uf := in.FieldByName("XXX_unrecognized") if !uf.IsValid() { return } uin := uf.Bytes() if len(uin) > 0 { out.FieldByName("XXX_unrecognized").SetBytes(append([]byte(nil), uin...)) } }
// DelQuery will delete (from datastore and memcache) all entities of type src that matches q. // src must be a pointer to a struct type. func DelQuery(c PersistenceContext, src interface{}, q *datastore.Query) (err error) { var dataIds []*datastore.Key results := reflect.New(reflect.SliceOf(reflect.TypeOf(src).Elem())) dataIds, err = q.GetAll(c, results.Interface()) if err = FilterOkErrors(err); err != nil { return } memcacheKeys := []string{} var el reflect.Value resultsSlice := results.Elem() for index, dataId := range dataIds { el = resultsSlice.Index(index) var k key.Key if k, err = gaekey.FromGAE(dataId); err != nil { return } el.FieldByName("Id").Set(reflect.ValueOf(k)) if _, err = MemcacheKeys(c, el.Addr().Interface(), &memcacheKeys); err != nil { return } if err = runProcess(c, el.Addr().Interface(), BeforeDeleteName, nil); err != nil { return } } if err = datastore.DeleteMulti(c, dataIds); err != nil { return } for index, _ := range dataIds { el = resultsSlice.Index(index) if err = runProcess(c, el.Addr().Interface(), AfterDeleteName, nil); err != nil { return } } return memcache.Del(c, memcacheKeys...) }
func setFieldDefaults(v reflect.Value, sf reflect.StructField, s reflect.Value) { if v.CanInterface() && reflect.DeepEqual( v.Interface(), reflect.Zero(v.Type()).Interface()) { tag := sf.Tag.Get("ebmldef") if tag != "" { switch v.Kind() { case reflect.Int, reflect.Int64: u, _ := strconv.ParseInt(tag, 10, 0) v.SetInt(int64(u)) case reflect.Uint, reflect.Uint64: u, _ := strconv.ParseUint(tag, 10, 0) v.SetUint(u) case reflect.Float32, reflect.Float64: f, _ := strconv.ParseFloat(tag, 64) v.SetFloat(f) case reflect.String: v.SetString(tag) default: log.Panic("Unsupported default value") } } ltag := sf.Tag.Get("ebmldeflink") if ltag != "" { v.Set(s.FieldByName(ltag)) } } }
func (d *decoder) decodeStruct(src hl7.Data, dst reflect.Value) { typ := dst.Type() for i := 0; i < typ.NumField(); i++ { field := typ.Field(i) fieldName := field.Name fieldValue := dst.FieldByName(fieldName) // So just skip it. if !fieldValue.CanSet() { d.err.append(fmt.Errorf("%s.%s is not settable", typ.Name(), fieldName)) continue } index := i if _, ok := src.(hl7.Segment); ok { index += 1 } newSrc, ok := src.Index(index) if !ok { //d.err.append(fmt.Errorf("could not find src index for %s.%s", typ.Name(), fieldName)) continue } d.decode(newSrc, fieldValue) } }
func (e *encoder) encodeStruct(val reflect.Value) { fmt.Fprint(e, "<struct>") t := val.Type() for i := 0; i < t.NumField(); i++ { f := t.Field(i) v := val.FieldByName(f.Name) if e.isNil(v) { continue } fmt.Fprintf(e, "<member>") name := f.Tag.Get("xmlrpc") if name == "" { name = f.Name } fmt.Fprintf(e, "<name>%s</name>", name) e.encodeValue(v) fmt.Fprintf(e, "</member>") } fmt.Fprint(e, "</struct>") }
func applyToStruct(obj reflect.Value, head P, mid string, tail P, ctx *Context) error { if mid != "*" { result := obj.FieldByName(mid) if result.Kind() == reflect.Invalid { result = obj.MethodByName(mid) } if result.Kind() == reflect.Invalid { return fmt.Errorf("no field '%s' in type '%s' at '%s'", mid, obj.Type(), head) } return apply(result, append(head, mid), tail, ctx) } typ := obj.Type() for i := 0; i < typ.NumField() && !ctx.stop; i++ { if err := applyToStruct(obj, head, typ.Field(i).Name, tail, ctx); err != nil && err != ErrMissing { return err } } return nil }
func skipField(v reflect.Value, f reflect.StructField) bool { // no tag on the structure field name := f.Tag.Get("when") if name == "" { return false } // invalid field in tag f1 := v.FieldByName(name) if !f1.IsValid() { return false } // target field is not a string if f1.Type().Kind() != reflect.String { return false } target := f1.String() value := f.Tag.Get("value") switch f.Tag.Get("cond") { case "is": // skip when target equals value return (target == value) case "not": return (target != value) } return false }
func setDefaults(properties []PropertyDocs, defaults reflect.Value) { for i := range properties { prop := &properties[i] fieldName := proptools.FieldNameForProperty(prop.Name) f := defaults.FieldByName(fieldName) if (f == reflect.Value{}) { panic(fmt.Errorf("property %q does not exist in %q", fieldName, defaults.Type())) } if reflect.DeepEqual(f.Interface(), reflect.Zero(f.Type()).Interface()) { continue } if f.Type().Kind() == reflect.Interface { f = f.Elem() } if f.Type().Kind() == reflect.Ptr { f = f.Elem() } if f.Type().Kind() == reflect.Struct { setDefaults(prop.Properties, f) } else { prop.Default = fmt.Sprintf("%v", f.Interface()) } } }
// model中类型提取其中的 idField(int 类型) 属性组成 slice 返回 func Models2Intslice(models interface{}, idField string) []int { if models == nil { return []int{} } // 类型检查 modelsValue := reflect.ValueOf(models) if modelsValue.Kind() != reflect.Slice { return []int{} } var modelValue reflect.Value length := modelsValue.Len() ids := make([]int, 0, length) for i := 0; i < length; i++ { modelValue = reflect.Indirect(modelsValue.Index(i)) if modelValue.Kind() != reflect.Struct { continue } val := modelValue.FieldByName(idField) if val.Kind() != reflect.Int { continue } ids = append(ids, int(val.Int())) } return ids }
// Required a struct type func (g *Graph) findFieldValue(parent reflect.Value, path structPath, linneage *[]reflect.Value) (reflect.Value, error) { *linneage = append(*linneage, parent) // Dereference incoming values if parent.Kind() == reflect.Ptr { parent = parent.Elem() } // Only accept structs if parent.Kind() != reflect.Struct { return parent, fmt.Errorf("Type is %s, not struct", parent.Kind().String()) } // Take the first entry from the path stub, path := path.Shift() // Try to get the field f := parent.FieldByName(stub) if !f.IsValid() { return f, fmt.Errorf("Can't find field %s in %s", stub, parent) } // If that's the end of the path, return the value if path.Empty() { return f, nil } // Otherwise recurse return g.findFieldValue(f, path, linneage) }
func extractCost(v reflect.Value) int64 { v = v.FieldByName("Cost") if v.Kind() != reflect.Ptr { return 0 } v = v.Elem() if v.Kind() != reflect.Struct { return 0 } extract := func(name string) int64 { w := v.FieldByName(name) if w.Kind() != reflect.Ptr { return 0 } w = w.Elem() switch w.Kind() { case reflect.Int, reflect.Int32, reflect.Int64: return w.Int() } return 0 } return (extract("IndexWrites") + extract("EntityWrites")) * cost.Write }
func unmarshalStruct(data string, v reflect.Value) error { structType := v.Type() var name string for len(data) > 0 { typ, content, n := readElement(data) data = data[n:] if typ != ',' { return errors.New("tnetstring: non-string key in dictionary") } name = content field := v.FieldByName(name) if !field.IsValid() { for i := 0; i < structType.NumField(); i++ { f := structType.Field(i) if f.Tag.Get("tnetstring") == name { field = v.Field(i) break } } if !field.IsValid() { // skip the field _, _, n := readElement(data) data = data[n:] continue } } n, err := unmarshal(data, field) data = data[n:] if err != nil { return err } } return nil }
func convertStruct(in interface{}, val reflect.Value) *ConfigError { dict, ok := in.(map[string]interface{}) if !ok || len(dict) != val.NumField() { return &ConfigError{ErrInvalidType, ""} } for k, from := range dict { to := val.FieldByName(strings.ToTitle(k[:1]) + k[1:]) if !to.IsValid() { return &ConfigError{ErrInvalidType, ""} } convertor := convertFuncs.get(to) if convertor == nil { return &ConfigError{ErrInvalidType, ""} } if err := convertor(from, to); err != nil { if len(err.Field) > 0 { err.Field = fmt.Sprintf("%s.%s", k, err.Field) } else { err.Field = k } return err } } return nil }
// extractFromObjectMeta extracts pointers to metadata fields from an object func extractFromObjectMeta(v reflect.Value, a *genericAccessor) error { if err := runtime.FieldPtr(v, "Namespace", &a.namespace); err != nil { return err } if err := runtime.FieldPtr(v, "Name", &a.name); err != nil { return err } if err := runtime.FieldPtr(v, "GenerateName", &a.generateName); err != nil { return err } if err := runtime.FieldPtr(v, "UID", &a.uid); err != nil { return err } if err := runtime.FieldPtr(v, "ResourceVersion", &a.resourceVersion); err != nil { return err } if err := runtime.FieldPtr(v, "SelfLink", &a.selfLink); err != nil { return err } if err := runtime.FieldPtr(v, "Labels", &a.labels); err != nil { return err } if err := runtime.FieldPtr(v, "Annotations", &a.annotations); err != nil { return err } ownerReferences := v.FieldByName("OwnerReferences") if !ownerReferences.IsValid() { return fmt.Errorf("struct %#v lacks OwnerReferences type", v) } if ownerReferences.Kind() != reflect.Slice { return fmt.Errorf("expect %v to be a slice", ownerReferences.Kind()) } a.ownerReferences = ownerReferences.Addr() return nil }
func encodeStruct(val reflect.Value) ([]byte, error) { var b bytes.Buffer b.WriteString("<struct>") t := val.Type() for i := 0; i < t.NumField(); i++ { b.WriteString("<member>") f := t.Field(i) name := f.Tag.Get("xmlrpc") if name == "" { name = f.Name } b.WriteString(fmt.Sprintf("<name>%s</name>", name)) p, err := encodeValue(val.FieldByName(f.Name)) if err != nil { return nil, err } b.Write(p) b.WriteString("</member>") } b.WriteString("</struct>") return b.Bytes(), nil }
func copyType(rv reflect.Value, name string) (reflect.Value, error) { field := rv.FieldByName(name) if !field.IsValid() { return rv, errors.New("Internal error: " + rv.Type().String() + " missing field " + name) } return reflect.New(field.Type()), nil }
func addFields(m *Model, t reflect.Type, v reflect.Value) { for i := 0; i < t.NumField(); i++ { field := t.Field(i) sqlTag := field.Tag.Get("sql") if sqlTag == "-" { continue } if field.Anonymous && field.Type.Kind() == reflect.Struct { addFields(m, field.Type, v.Field(i)) continue } parsedSqlTags := parseTags(sqlTag) rawValidateTag := field.Tag.Get("validate") parsedValidateTags := make(map[string]string) if len(rawValidateTag) > 0 { if rawValidateTag[:1] == "^" { parsedValidateTags["regexp"] = rawValidateTag } else { parsedValidateTags = parseTags(rawValidateTag) } } fd := &ModelField{ Name: toSnake(field.Name), Value: v.FieldByName(field.Name).Interface(), SqlTags: parsedSqlTags, ValidateTags: parsedValidateTags, RawTag: field.Tag, } if fd.PrimaryKey() { m.Pk = fd } m.Fields = append(m.Fields, fd) } }
// isSameUnknownStruct returns true if the two struct values are the same length // and have the same contents as defined by IsSame. This function explicitly // ignores the declared type of the struct. func isSameStruct(x, y reflect.Value) bool { sx, okx := x.Interface().(StringConvertable) sy, oky := x.Interface().(StringConvertable) if okx && oky { //log.Println("Stringable", x, y) return sx.String() == sy.String() } numFields := x.NumField() if numFields != y.NumField() { return false } typeX := x.Type() for i := 0; i < numFields; i++ { path := []int{i} vx := x.FieldByIndex(path) vy := y.FieldByName(typeX.Field(i).Name) if vx.CanInterface() && vy.CanInterface() { if !IsSame(vx.Interface(), vy.Interface()) { return false } } } return true }
func Validate(validation *revel.Validation, obj interface{}) { // Get reflection data to parse validation tag data var v reflect.Value = reflect.Indirect(reflect.ValueOf(obj)) // We only want to validate structs and their tagged fields if v.Kind() != reflect.Struct { panic(fmt.Sprintf("Object is not a struct. Actual kind is: %s", v.Kind())) } // Go through each field in the struct and check for the // validation tag. Apply appropriate revel check as needed. t := v.Type() for i := 0; i < t.NumField(); i++ { field := t.Field(i) fieldId := fmt.Sprintf("%s.%s", t.Name(), field.Name) var fieldValidators []revel.Validator fieldValidators, ok := validationCache[fieldId] if tag := field.Tag.Get(TagName); !ok && len(tag) > 0 { fieldValidators = parseTag(tag) validationCache[fieldId] = fieldValidators } else if !ok { fieldValidators = nil validationCache[fieldId] = nil } if len(fieldValidators) > 0 { validation.Check(v.FieldByName(field.Name).Interface(), fieldValidators...).Key(fieldId) } } }
// Search for a field named 'ID' in the provided struct // - The 'ID' field must be of type Int | String, any other type // results in an error func reflectKey(val reflect.Value) (*Key, error) { if val.Kind() == reflect.Ptr && val.IsNil() { return nil, fmt.Errorf("Key: <nil> pointer of type %s", val.String()) } if val.Kind() == reflect.Ptr { val = Indirect(val) } // TODO: for static-only states (meaning no mutability) // this might be too limiting. if val.Kind() != reflect.Struct { return nil, errors.New("Key: only structs can have a Key") } id_field := val.FieldByName("ID") if !id_field.IsValid() { return nil, fmt.Errorf("%s does not have field with name = 'ID'", val.Type().String()) } switch id_field.Kind() { case reflect.String: return NewStringKey(id_field.String()) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return NewIntKey(int(id_field.Int())) default: return nil, fmt.Errorf("Field 'ID' is of invalid type: %v\n", id_field.Kind()) } }
// scan the value by fields, and set to v func rawScanStruct(v reflect.Value, fields []string, scanner rowScaner) (err error) { if v.IsNil() { e := fmt.Sprintf("struct can not be nil, but got %#v", v.Interface()) return errors.New(e) } dest := make([]interface{}, len(fields)) for v.Kind() == reflect.Ptr { v = v.Elem() } // Loop over column names and find field in s to bind to // based on column name. all returned columns must match // a field in the s struct for x, fieldName := range fields { f := v.FieldByName(fieldName) if f == zeroVal { e := fmt.Sprintf("Scanner: No field %s in type %s", fieldName, v.Type()) return errors.New(e) } else { dest[x] = f.Addr().Interface() } } err = scanner.Scan(dest...) return }
func lookup(v reflect.Value, s string) reflect.Value { var ret reflect.Value v = reflect.Indirect(v) switch v.Kind() { case reflect.Array, reflect.Slice: if idx, err := strconv.Atoi(s); err == nil { ret = v.Index(idx) } case reflect.Map: keyt := v.Type().Key() switch keyt.Kind() { case reflect.String: ret = v.MapIndex(reflect.ValueOf(s)) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: if idx, err := strconv.ParseInt(s, 10, 64); err == nil { idxVal := reflect.New(keyt).Elem() idxVal.SetInt(idx) ret = v.MapIndex(idxVal) } case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: if idx, err := strconv.ParseUint(s, 10, 64); err == nil { idxVal := reflect.New(keyt).Elem() idxVal.SetUint(idx) ret = v.MapIndex(idxVal) } } case reflect.Struct: ret = v.FieldByName(s) } // TODO: Find a way to look up methods by name return ret }
// validateStruct will validate the struct value's fields. If the structure has // nested types those types will be validated also. func (v *validator) validateStruct(value reflect.Value, path string) { prefix := "." if path == "" { prefix = "" } for i := 0; i < value.Type().NumField(); i++ { f := value.Type().Field(i) if strings.ToLower(f.Name[0:1]) == f.Name[0:1] { continue } fvalue := value.FieldByName(f.Name) notset := false if f.Tag.Get("required") != "" { switch fvalue.Kind() { case reflect.Ptr, reflect.Slice, reflect.Map: if fvalue.IsNil() { notset = true } default: if !fvalue.IsValid() { notset = true } } } if notset { msg := "missing required parameter: " + path + prefix + f.Name v.errors = append(v.errors, msg) } else { v.validateAny(fvalue, path+prefix+f.Name) } } }
func mergeStruct(out, in reflect.Value) { sprop := GetProperties(in.Type()) for i := 0; i < in.NumField(); i++ { f := in.Type().Field(i) if strings.HasPrefix(f.Name, "XXX_") { continue } mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i]) } if emIn, ok := extendable(in.Addr().Interface()); ok { emOut, _ := extendable(out.Addr().Interface()) mIn, muIn := emIn.extensionsRead() if mIn != nil { mOut := emOut.extensionsWrite() muIn.Lock() mergeExtension(mOut, mIn) muIn.Unlock() } } uf := in.FieldByName("XXX_unrecognized") if !uf.IsValid() { return } uin := uf.Bytes() if len(uin) > 0 { out.FieldByName("XXX_unrecognized").SetBytes(append([]byte(nil), uin...)) } }