func (p *printer) marshalSimple(typ reflect.Type, val reflect.Value) (string, []byte, error) { switch val.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return strconv.FormatInt(val.Int(), 10), nil, nil case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return strconv.FormatUint(val.Uint(), 10), nil, nil case reflect.Float32, reflect.Float64: return strconv.FormatFloat(val.Float(), 'g', -1, val.Type().Bits()), nil, nil case reflect.String: return val.String(), nil, nil case reflect.Bool: return strconv.FormatBool(val.Bool()), nil, nil case reflect.Array: if typ.Elem().Kind() != reflect.Uint8 { break } // [...]byte var bytes []byte if val.CanAddr() { bytes = val.Slice(0, val.Len()).Bytes() } else { bytes = make([]byte, val.Len()) reflect.Copy(reflect.ValueOf(bytes), val) } return "", bytes, nil case reflect.Slice: if typ.Elem().Kind() != reflect.Uint8 { break } // []byte return "", val.Bytes(), nil } return "", nil, &UnsupportedTypeError{typ} }
func GetColVals(val reflect.Value, cols []string) (values []string, err error) { typ := val.Type() // if not struct, then must just have one column. if val.Kind() != reflect.Struct && len(cols) != 1 { return nil, fmt.Errorf("GetColVals> If not a struct(%s), must have one column: %v", val.Kind(), cols) } values = make([]string, len(cols)) for i, col := range cols { var fieldVal reflect.Value if val.Kind() == reflect.Struct { fieldIndex := getFieldIndexByName(typ, col) if fieldIndex[0] < 0 { return nil, fmt.Errorf("GetColVals> Can't found struct field(column): '%s'\n", col) } fieldVal = val.FieldByIndex(fieldIndex) } else { fieldVal = val } if values[i], err = GetValQuoteStr(fieldVal); err != nil { return } } return }
func ReturnWhenSet(a, k interface{}) interface{} { av, isNil := indirect(reflect.ValueOf(a)) if isNil { return "" } var avv reflect.Value switch av.Kind() { case reflect.Array, reflect.Slice: index, ok := k.(int) if ok && av.Len() > index { avv = av.Index(index) } case reflect.Map: kv := reflect.ValueOf(k) if kv.Type().AssignableTo(av.Type().Key()) { avv = av.MapIndex(kv) } } if avv.IsValid() { switch avv.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return avv.Int() case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: return avv.Uint() case reflect.Float32, reflect.Float64: return avv.Float() case reflect.String: return avv.String() } } return "" }
func setValue(dstVal reflect.Value, src interface{}) { if dstVal.Kind() == reflect.Ptr { dstVal = reflect.Indirect(dstVal) } srcVal := reflect.ValueOf(src) if !srcVal.IsValid() { // src is literal nil if dstVal.CanAddr() { // Convert to pointer so that pointer's value can be nil'ed // dstVal = dstVal.Addr() } dstVal.Set(reflect.Zero(dstVal.Type())) } else if srcVal.Kind() == reflect.Ptr { if srcVal.IsNil() { srcVal = reflect.Zero(dstVal.Type()) } else { srcVal = reflect.ValueOf(src).Elem() } dstVal.Set(srcVal) } else { dstVal.Set(srcVal) } }
// Validates that if a value is provided for a field, that value must be at // least a minimum length. func validateFieldMin(f reflect.StructField, fvalue reflect.Value) error { minStr := f.Tag.Get("min") if minStr == "" { return nil } min, _ := strconv.ParseInt(minStr, 10, 64) kind := fvalue.Kind() if kind == reflect.Ptr { if fvalue.IsNil() { return nil } fvalue = fvalue.Elem() } switch fvalue.Kind() { case reflect.String: if int64(fvalue.Len()) < min { return fmt.Errorf("field too short, minimum length %d", min) } case reflect.Slice, reflect.Map: if fvalue.IsNil() { return nil } if int64(fvalue.Len()) < min { return fmt.Errorf("field too short, minimum length %d", min) } // TODO min can also apply to number minimum value. } return nil }
// rv must be a non-nil pointer or a settable value func indirect(rv reflect.Value) (reflect.Value, error) { for { if rv.Kind() == reflect.Interface && !rv.IsNil() { if e := rv.Elem(); e.Kind() == reflect.Ptr && !e.IsNil() { rv = e.Elem() } } if rv.Kind() == reflect.Map && rv.IsNil() { rv.Set(reflect.MakeMap(rv.Type())) } if rv.Kind() != reflect.Ptr { break } if rv.IsNil() { rv.Set(reflect.New(rv.Type().Elem())) } rv = rv.Elem() } if k := rv.Kind(); k != reflect.Struct && k != reflect.Map { return reflect.Value{}, &InvalidIndirectError{rv.Type()} } if rv.Kind() == reflect.Map { if t := rv.Type(); t.Key().Kind() != reflect.String || t.Elem().Kind() != reflect.String { return reflect.Value{}, &InvalidIndirectError{t} } } return rv, nil }
func (mssql) SqlTag(value reflect.Value, size int, autoIncrease bool) string { switch value.Kind() { case reflect.Bool: return "bit" case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uintptr: if autoIncrease { return "int IDENTITY(1,1)" } return "int" case reflect.Int64, reflect.Uint64: if autoIncrease { return "bigint IDENTITY(1,1)" } return "bigint" case reflect.Float32, reflect.Float64: return "float" case reflect.String: if size > 0 && size < 65532 { return fmt.Sprintf("nvarchar(%d)", size) } return "text" case reflect.Struct: if _, ok := value.Interface().(time.Time); ok { return "datetime2" } default: if _, ok := value.Interface().([]byte); ok { if size > 0 && size < 65532 { return fmt.Sprintf("varchar(%d)", size) } return "text" } } panic(fmt.Sprintf("invalid sql type %s (%s) for mssql", value.Type().Name(), value.Kind().String())) }
func encodeField(w io.Writer, f reflect.Value) error { if f.Type() == timeType { return encodeTime(w, f) } switch f.Kind() { case reflect.Uint8: fallthrough case reflect.Uint16: fallthrough case reflect.Uint32: fallthrough case reflect.Uint64: fallthrough case reflect.Int64: fallthrough case reflect.Int32: fallthrough case reflect.Int16: fallthrough case reflect.Int8: return binary.Write(w, byteOrder, f.Interface()) case reflect.String: return encodeStrField(w, f) case reflect.Slice: return encodeArray(w, f) case reflect.Interface: return encodeField(w, f.Elem()) default: panic(fmt.Sprintf("unimplemented kind %v", f)) } }
func unflattenValue(v reflect.Value, t reflect.Type) reflect.Value { // When t is an Interface, we can't do much, since we don't know the // original (unflattened) type of the value placed in v, so we just nop it. if t.Kind() == reflect.Interface { return v } // v can be invalid, if it holds the nil value for pointer type if !v.IsValid() { return v } // Make sure v is indeed flat if v.Kind() == reflect.Ptr { panic("unflattening non-flat value") } // Add a *, one at a time for t.Kind() == reflect.Ptr { if v.CanAddr() { v = v.Addr() } else { pw := reflect.New(v.Type()) pw.Elem().Set(v) v = pw } t = t.Elem() } return v }
func (m *mapper) unpackValue(keys []string, values []interface{}, out reflect.Value) error { switch out.Kind() { case reflect.Ptr: if out.IsNil() { out.Set(reflect.New(out.Type().Elem())) } return m.unpackValue(keys, values, reflect.Indirect(out)) case reflect.Slice: if keys == nil { return m.unpackSimple(nil, values, out) } else { return m.unpackSlice(keys, values, out) } case reflect.Struct: return m.unpackStruct(keys, values, out) case reflect.Map: if keys == nil { return m.unpackSimple(nil, values, out) } else { return m.unpackMap(keys, values, out) } default: return m.unpackSimple(nil, values, out) } return fmt.Errorf("cannot unpack result to %T (%s)", out, out.Kind()) }
// NotNilFilter returns true for field values that are not nil; // it returns false otherwise. func NotNilFilter(_ string, v reflect.Value) bool { switch v.Kind() { case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: return !v.IsNil() } return true }
func (scope *Scope) callMethod(methodName string, reflectValue reflect.Value) { // Only get address from non-pointer if reflectValue.CanAddr() && reflectValue.Kind() != reflect.Ptr { reflectValue = reflectValue.Addr() } if methodValue := reflectValue.MethodByName(methodName); methodValue.IsValid() { switch method := methodValue.Interface().(type) { case func(): method() case func(*Scope): method(scope) case func(*DB): newDB := scope.NewDB() method(newDB) scope.Err(newDB.Error) case func() error: scope.Err(method()) case func(*Scope) error: scope.Err(method(scope)) case func(*DB) error: newDB := scope.NewDB() scope.Err(method(newDB)) scope.Err(newDB.Error) default: scope.Err(fmt.Errorf("unsupported function %v", methodName)) } } }
// callSliceRequired returns true if CallSlice is required instead of Call. func callSliceRequired(param reflect.Type, val reflect.Value) bool { vt := val.Type() for param.Kind() == reflect.Slice { if val.Kind() == reflect.Interface { val = reflect.ValueOf(val.Interface()) vt = val.Type() } if vt.Kind() != reflect.Slice { return false } vt = vt.Elem() if val.Kind() != reflect.Invalid { if val.Len() > 0 { val = val.Index(0) } else { val = reflect.Value{} } } param = param.Elem() } return true }
func (d *decoder) parse_unmarshaler(v reflect.Value) bool { m, ok := v.Interface().(Unmarshaler) if !ok { // T doesn't work, try *T if v.Kind() != reflect.Ptr && v.CanAddr() { m, ok = v.Addr().Interface().(Unmarshaler) if ok { v = v.Addr() } } } if ok && (v.Kind() != reflect.Ptr || !v.IsNil()) { if d.read_one_value() { err := m.UnmarshalBencode(d.buf.Bytes()) d.buf.Reset() if err != nil { panic(&UnmarshalerError{v.Type(), err}) } return true } d.buf.Reset() } return false }
// All protocol buffer fields are nillable, but be careful. func isNil(v reflect.Value) bool { switch v.Kind() { case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: return v.IsNil() } return false }
func visitStruct(val reflect.Value, visitor structVisitor) error { if val.Kind() != reflect.Ptr { return errNoPointer } val = reflect.Indirect(val) if val.Kind() != reflect.Struct { return errNoStruct } typ := val.Type() for ii := 0; ii < typ.NumField(); ii++ { field := typ.Field(ii) fieldVal := val.Field(ii) ptr := fieldVal.Addr().Interface() name := defaultFieldName(field.Name) var help string if n := field.Tag.Get("name"); n != "" { name = n } if h := field.Tag.Get("help"); h != "" { help = h } if name == "" { return fmt.Errorf("no name provided for field %s in type %s", field.Name, typ) } if err := visitor(name, help, &field, fieldVal, ptr); err != nil { return err } } return nil }
func testSetNilMapsToEmpties(curr reflect.Value) { actualCurrValue := curr if curr.Kind() == reflect.Ptr { actualCurrValue = curr.Elem() } switch actualCurrValue.Kind() { case reflect.Map: for _, mapKey := range actualCurrValue.MapKeys() { currMapValue := actualCurrValue.MapIndex(mapKey) testSetNilMapsToEmpties(currMapValue) } case reflect.Struct: for fieldIndex := 0; fieldIndex < actualCurrValue.NumField(); fieldIndex++ { currFieldValue := actualCurrValue.Field(fieldIndex) if currFieldValue.Kind() == reflect.Map && currFieldValue.IsNil() { newValue := reflect.MakeMap(currFieldValue.Type()) currFieldValue.Set(newValue) } else { testSetNilMapsToEmpties(currFieldValue.Addr()) } } } }
func (q *queryParser) parseValue(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error { value = elemOf(value) // no need to handle zero values if !value.IsValid() { return nil } t := tag.Get("type") if t == "" { switch value.Kind() { case reflect.Struct: t = "structure" case reflect.Slice: t = "list" case reflect.Map: t = "map" } } switch t { case "structure": return q.parseStruct(v, value, prefix) case "list": return q.parseList(v, value, prefix, tag) case "map": return q.parseMap(v, value, prefix, tag) default: return q.parseScalar(v, value, prefix, tag) } }
func unwrap(v *reflect.Value) *reflect.Value { if v.Kind() == reflect.Interface { org := v.Elem() // Get rid of the wrapping interface return &org } return v }
func (p *Decoder) unmarshalArray(pval *plistValue, val reflect.Value) { subvalues := pval.value.([]*plistValue) var n int if val.Kind() == reflect.Slice { // Slice of element values. // Grow slice. cnt := len(subvalues) + val.Len() if cnt >= val.Cap() { ncap := 2 * cnt if ncap < 4 { ncap = 4 } new := reflect.MakeSlice(val.Type(), val.Len(), ncap) reflect.Copy(new, val) val.Set(new) } n = val.Len() val.SetLen(cnt) } else if val.Kind() == reflect.Array { if len(subvalues) > val.Cap() { panic(fmt.Errorf("plist: attempted to unmarshal %d values into an array of size %d", len(subvalues), val.Cap())) } } else { panic(&incompatibleDecodeTypeError{val.Type(), pval.kind}) } // Recur to read element into slice. for _, sval := range subvalues { p.unmarshal(sval, val.Index(n)) n++ } return }
func (d *commonDialect) SqlTag(value reflect.Value, size int) string { switch value.Kind() { case reflect.Bool: return "BOOLEAN" case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uintptr: return "INTEGER" case reflect.Int64, reflect.Uint64: return "BIGINT" case reflect.Float32, reflect.Float64: return "FLOAT" case reflect.String: if size > 0 && size < 65532 { return fmt.Sprintf("VARCHAR(%d)", size) } else { return "VARCHAR(65532)" } case reflect.Struct: if value.Type() == timeType { return "TIMESTAMP" } default: if _, ok := value.Interface().([]byte); ok { if size > 0 && size < 65532 { return fmt.Sprintf("BINARY(%d)", size) } else { return "BINARY(65532)" } } } panic(fmt.Sprintf("invalid sql type %s (%s) for commonDialect", value.Type().Name(), value.Kind().String())) }
func (p *Decoder) unmarshalDictionary(pval *plistValue, val reflect.Value) { typ := val.Type() switch val.Kind() { case reflect.Struct: tinfo, err := getTypeInfo(typ) if err != nil { panic(err) } subvalues := pval.value.(*dictionary).m for _, finfo := range tinfo.fields { p.unmarshal(subvalues[finfo.name], finfo.value(val)) } case reflect.Map: if val.IsNil() { val.Set(reflect.MakeMap(typ)) } subvalues := pval.value.(*dictionary).m for k, sval := range subvalues { keyv := reflect.ValueOf(k).Convert(typ.Key()) mapElem := val.MapIndex(keyv) if !mapElem.IsValid() { mapElem = reflect.New(typ.Elem()).Elem() } p.unmarshal(sval, mapElem) val.SetMapIndex(keyv, mapElem) } default: panic(&incompatibleDecodeTypeError{typ, pval.kind}) } }
func (par *parserParser) ParseValue(ctx *parseContext, valueOf reflect.Value, location int, err *Error) int { var v Parser if par.ptr { v = valueOf.Addr().Interface().(Parser) } else { if valueOf.Kind() == reflect.Ptr { valueOf = reflect.New(valueOf.Type().Elem()) } v = valueOf.Interface().(Parser) } l, e := v.ParseValue(ctx.str, location) if e != nil { switch ev := e.(type) { case Error: err.Location = ev.Location err.Message = ev.Message err.Str = ev.Str return -1 } err.Location = location err.Message = e.Error() return -1 } location = l if location > len(ctx.str) { panic("Invalid parser") } return location }
func (p *Decoder) unmarshalLaxString(s string, val reflect.Value) { switch val.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: i := mustParseInt(s, 10, 64) val.SetInt(i) return case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: i := mustParseUint(s, 10, 64) val.SetUint(i) return case reflect.Float32, reflect.Float64: f := mustParseFloat(s, 64) val.SetFloat(f) return case reflect.Bool: b := mustParseBool(s) val.SetBool(b) return case reflect.Struct: if val.Type() == timeType { t, err := time.Parse(textPlistTimeLayout, s) if err != nil { panic(err) } val.Set(reflect.ValueOf(t.In(time.UTC))) return } fallthrough default: panic(&incompatibleDecodeTypeError{val.Type(), String}) } }
func setField(field reflect.Value, defaultVal string) { var iface interface{} var err error switch field.Kind() { case reflect.Bool: iface, err = strconv.ParseBool(defaultVal) case reflect.Int: iface, err = strconv.ParseInt(defaultVal, 10, 64) iface = int(iface.(int64)) case reflect.Int8: iface, err = strconv.ParseInt(defaultVal, 10, 8) iface = int8(iface.(int64)) case reflect.Int16: iface, err = strconv.ParseInt(defaultVal, 10, 16) iface = int16(iface.(int64)) case reflect.Int32: iface, err = strconv.ParseInt(defaultVal, 10, 32) iface = int32(iface.(int64)) case reflect.Int64: t, err := time.ParseDuration(defaultVal) if err == nil { iface, err = t, nil } else { iface, err = strconv.ParseInt(defaultVal, 10, 64) } case reflect.Uint: iface, err = strconv.ParseUint(defaultVal, 10, 64) iface = uint(iface.(uint64)) case reflect.Uint8: iface, err = strconv.ParseUint(defaultVal, 10, 8) iface = uint8(iface.(uint64)) case reflect.Uint16: iface, err = strconv.ParseUint(defaultVal, 10, 16) iface = uint16(iface.(uint64)) case reflect.Uint32: iface, err = strconv.ParseUint(defaultVal, 10, 32) iface = uint32(iface.(uint64)) case reflect.Uint64: iface, err = strconv.ParseUint(defaultVal, 10, 64) case reflect.Uintptr: iface, err = strconv.ParseUint(defaultVal, 10, 64) iface = uintptr(iface.(uint64)) case reflect.Float32: iface, err = strconv.ParseFloat(defaultVal, 32) iface = float32(iface.(float64)) case reflect.Float64: iface, err = strconv.ParseFloat(defaultVal, 64) case reflect.String: iface = defaultVal default: err = errInvalidFieldType } if err == nil { if field.CanSet() { field.Set(reflect.ValueOf(iface)) } } }
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() }
// for insert and update // If already assigned, then just ignore tag func GetValQuoteStr(val reflect.Value) (string, error) { switch val.Kind() { case reflect.Bool: boolStr := "N" if val.Bool() { boolStr = "Y" } return boolStr, nil case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return strconv.FormatInt(val.Int(), 10), nil case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return strconv.FormatUint(val.Uint(), 10), nil case reflect.Float32, reflect.Float64: return strconv.FormatFloat(val.Float(), 'f', -1, 64), nil case reflect.String: return QuoteStr(val.String()), nil case reflect.Slice: //[]byte if val.Type().Elem().Name() != "uint8" { return "", fmt.Errorf("GetValQuoteStr> slicetype is not []byte: %v", val.Interface()) } return QuoteStr(string(val.Interface().([]byte))), nil default: return "", fmt.Errorf("GetValQuoteStr> reflect.Value is not a string/int/uint/float/bool/[]byte!\nval: %v", val) } return "", nil }
func isZero(v reflect.Value) bool { switch v.Kind() { case reflect.Func, reflect.Map, reflect.Slice: return v.IsNil() case reflect.Array: z := true for i := 0; i < v.Len(); i++ { z = z && isZero(v.Index(i)) } return z case reflect.Struct: if v.Type() == reflect.TypeOf(t) { if v.Interface().(time.Time).IsZero() { return true } return false } z := true for i := 0; i < v.NumField(); i++ { z = z && isZero(v.Field(i)) } return z } // Compare other types directly: z := reflect.Zero(v.Type()) return v.Interface() == z.Interface() }
func isZero(v reflect.Value) bool { switch v.Kind() { case reflect.String: return len(v.String()) == 0 case reflect.Interface, reflect.Ptr: return v.IsNil() case reflect.Slice: return v.Len() == 0 case reflect.Map: return v.Len() == 0 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return v.Int() == 0 case reflect.Float32, reflect.Float64: return v.Float() == 0 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return v.Uint() == 0 case reflect.Bool: return !v.Bool() case reflect.Struct: vt := v.Type() for i := v.NumField() - 1; i >= 0; i-- { if vt.Field(i).PkgPath != "" { continue // Private field } if !isZero(v.Field(i)) { return false } } return true } return false }
func (e *Encoder) preEncodeValue(rv reflect.Value) (rv2 reflect.Value, proceed bool) { LOOP: for { switch rv.Kind() { case reflect.Ptr, reflect.Interface: if rv.IsNil() { e.e.EncodeNil() return } rv = rv.Elem() continue LOOP case reflect.Slice, reflect.Map: if rv.IsNil() { e.e.EncodeNil() return } case reflect.Invalid, reflect.Func: e.e.EncodeNil() return } break } return rv, true }