// Copy matching Lua table entries to a struct, given the struct type // and the index on the Lua stack. func CopyTableToStruct(L *lua.State, t reflect.Type, idx int) interface{} { was_ptr := t.Kind() == reflect.Ptr if was_ptr { t = t.Elem() } s := reflect.New(t) // T -> *T ref := s.Elem() L.PushNil() if idx < 0 { idx-- } for L.Next(idx) != 0 { key := L.ToString(-2) f := ref.FieldByName(strings.Title(key)) if f.IsValid() { val := luaToGoValue(L, f.Type(), -1) f.Set(val) } L.Pop(1) } if was_ptr { return s.Interface() } return s.Elem().Interface() }
func sampleFormat(b reflect.Type) (f C.PaSampleFormat) { if b.Kind() != reflect.Slice { return 0 } b = b.Elem() if b.Kind() == reflect.Slice { f = C.paNonInterleaved b = b.Elem() } switch b.Kind() { case reflect.Float32: f |= C.paFloat32 case reflect.Int32: f |= C.paInt32 default: if b == reflect.TypeOf(Int24{}) { f |= C.paInt24 } else { return 0 } case reflect.Int16: f |= C.paInt16 case reflect.Int8: f |= C.paInt8 case reflect.Uint8: f |= C.paUInt8 } return f }
func newMapEncoder(t reflect.Type) encoderFunc { if t.Key().Kind() != reflect.String { return unsupportedTypeEncoder } me := &mapEncoder{typeEncoder(t.Elem())} return me.encode }
func New(t interface{}, tags []string, conf Configurator) (*Struct, error) { var typ reflect.Type if tt, ok := t.(reflect.Type); ok { typ = tt } else { typ = reflect.TypeOf(t) } for typ.Kind() == reflect.Ptr { typ = typ.Elem() } if typ.Kind() != reflect.Struct { return nil, ErrNoStruct } if typ.NumField() == 0 { return nil, ErrNoFields } s := &Struct{ Type: typ, MNameMap: make(map[string]int), QNameMap: make(map[string]int), tags: tags, conf: conf, } if err := s.initialize(typ); err != nil { return nil, err } return s, nil }
func decodeArray(r io.Reader, t reflect.Type) (reflect.Value, error) { var sz uint32 if err := binary.Read(r, byteOrder, &sz); err != nil { return nullValue, err } ksz := int(kindSize(t.Elem().Kind())) data := make([]byte, int(sz)*ksz) _, err := r.Read(data) if err != nil { return nullValue, err } slice := reflect.MakeSlice(t, int(sz), int(sz)) for i := 0; i < int(sz); i++ { from := data[i*ksz:] var val uint64 switch ksz { case 1: val = uint64(from[0]) case 2: val = uint64(byteOrder.Uint16(from[0:])) case 4: val = uint64(byteOrder.Uint32(from[0:])) default: panic("unimp") } slice.Index(i).SetUint(val) } return slice, nil }
// verifyHandler ensures that the given t is a function with the following signature: // func(json.Context, *ArgType)(*ResType, error) func verifyHandler(t reflect.Type) error { if t.NumIn() != 2 || t.NumOut() != 2 { return fmt.Errorf("handler should be of format func(json.Context, *ArgType) (*ResType, error)") } isStructPtr := func(t reflect.Type) bool { return t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct } isMap := func(t reflect.Type) bool { return t.Kind() == reflect.Map && t.Key().Kind() == reflect.String } validateArgRes := func(t reflect.Type, name string) error { if !isStructPtr(t) && !isMap(t) { return fmt.Errorf("%v should be a pointer to a struct, or a map[string]interface{}", name) } return nil } if t.In(0) != typeOfContext { return fmt.Errorf("arg0 should be of type json.Context") } if err := validateArgRes(t.In(1), "second argument"); err != nil { return err } if err := validateArgRes(t.Out(0), "first return value"); err != nil { return err } if !t.Out(1).AssignableTo(typeOfError) { return fmt.Errorf("second return value should be an error") } return nil }
// sizeof returns the size >= 0 of variables for the given type or -1 if the type is not acceptable. func sizeof(t reflect.Type) int { switch t.Kind() { case reflect.Array: if s := sizeof(t.Elem()); s >= 0 { return s * t.Len() } case reflect.Struct: sum := 0 for i, n := 0, t.NumField(); i < n; i++ { s := sizeof(t.Field(i).Type) if s < 0 { return -1 } sum += s } return sum case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.Ptr: return int(t.Size()) } return -1 }
func (d SqliteDialect) ToSqlType(val reflect.Type, maxsize int, isAutoIncr bool) string { switch val.Kind() { case reflect.Ptr: return d.ToSqlType(val.Elem(), maxsize, isAutoIncr) case reflect.Bool: return "integer" case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: return "integer" case reflect.Float64, reflect.Float32: return "real" case reflect.Slice: if val.Elem().Kind() == reflect.Uint8 { return "blob" } } switch val.Name() { case "NullInt64": return "integer" case "NullFloat64": return "real" case "NullBool": return "integer" case "Time": return "datetime" } if maxsize < 1 { maxsize = 255 } return fmt.Sprintf("varchar(%d)", maxsize) }
func fieldType(t reflect.Type) byte { switch t.Kind() { case reflect.Bool: return TypeBool case reflect.Int8, reflect.Uint8: return TypeByte case reflect.Int16: return TypeI16 case reflect.Int32, reflect.Int: return TypeI32 case reflect.Int64: return TypeI64 case reflect.Float64: return TypeDouble case reflect.Map: return TypeMap case reflect.Slice: elemType := t.Elem() if elemType.Kind() == reflect.Uint8 { return TypeString } else { return TypeList } case reflect.Struct: return TypeStruct case reflect.String: return TypeString case reflect.Interface, reflect.Ptr: return fieldType(t.Elem()) } panic(&UnsupportedTypeError{t}) }
func getSetter(outt reflect.Type, out reflect.Value) Setter { setterMutex.RLock() style := setterStyle[outt] setterMutex.RUnlock() if style == setterNone { return nil } if style == setterUnknown { setterMutex.Lock() defer setterMutex.Unlock() if outt.Implements(setterIface) { setterStyle[outt] = setterType } else if reflect.PtrTo(outt).Implements(setterIface) { setterStyle[outt] = setterAddr } else { setterStyle[outt] = setterNone return nil } style = setterStyle[outt] } if style == setterAddr { if !out.CanAddr() { return nil } out = out.Addr() } else if outt.Kind() == reflect.Ptr && out.IsNil() { out.Set(reflect.New(outt.Elem())) } return out.Interface().(Setter) }
// defaultStart returns the default start element to use, // given the reflect type, field info, and start template. func (p *printer) defaultStart(typ reflect.Type, finfo *fieldInfo, startTemplate *StartElement) StartElement { var start StartElement // Precedence for the XML element name is as above, // except that we do not look inside structs for the first field. if startTemplate != nil { start.Name = startTemplate.Name start.Attr = append(start.Attr, startTemplate.Attr...) } else if finfo != nil && finfo.name != "" { start.Name.Local = finfo.name start.Name.Space = finfo.xmlns } else if typ.Name() != "" { start.Name.Local = typ.Name() } else { // Must be a pointer to a named type, // since it has the Marshaler methods. start.Name.Local = typ.Elem().Name() } // Historic behaviour: elements use the name space of // the element they are contained in by default. if start.Name.Space == "" { start.Name.Space = p.defaultNS } start.setDefaultNamespace() return start }
// makeOptionalPtrDecoder creates a decoder that decodes empty values // as nil. Non-empty values are decoded into a value of the element type, // just like makePtrDecoder does. // // This decoder is used for pointer-typed struct fields with struct tag "nil". func makeOptionalPtrDecoder(typ reflect.Type) (decoder, error) { etype := typ.Elem() etypeinfo, err := cachedTypeInfo1(etype, tags{}) if err != nil { return nil, err } dec := func(s *Stream, val reflect.Value) (err error) { kind, size, err := s.Kind() if err != nil || size == 0 && kind != Byte { // rearm s.Kind. This is important because the input // position must advance to the next value even though // we don't read anything. s.kind = -1 // set the pointer to nil. val.Set(reflect.Zero(typ)) return err } newval := val if val.IsNil() { newval = reflect.New(etype) } if err = etypeinfo.decoder(s, newval.Elem()); err == nil { val.Set(newval) } return err } return dec, nil }
// formFromGoType returns a suitable FITS TFORM string from a reflect.Type func formFromGoType(rt reflect.Type, htype HDUType) string { hdr := "" var t reflect.Type switch rt.Kind() { case reflect.Array: hdr = fmt.Sprintf("%d", rt.Len()) t = rt.Elem() case reflect.Slice: hdr = "Q" t = rt.Elem() default: t = rt } dict, ok := g_gotype2FITS[t.Kind()] if !ok { return "" } form, ok := dict[htype] if !ok { return "" } return hdr + form }
func makeListDecoder(typ reflect.Type, tag tags) (decoder, error) { etype := typ.Elem() if etype.Kind() == reflect.Uint8 && !reflect.PtrTo(etype).Implements(decoderInterface) { if typ.Kind() == reflect.Array { return decodeByteArray, nil } else { return decodeByteSlice, nil } } etypeinfo, err := cachedTypeInfo1(etype, tags{}) if err != nil { return nil, err } var dec decoder switch { case typ.Kind() == reflect.Array: dec = func(s *Stream, val reflect.Value) error { return decodeListArray(s, val, etypeinfo.decoder) } case tag.tail: // A slice with "tail" tag can occur as the last field // of a struct and is upposed to swallow all remaining // list elements. The struct decoder already called s.List, // proceed directly to decoding the elements. dec = func(s *Stream, val reflect.Value) error { return decodeSliceElems(s, val, etypeinfo.decoder) } default: dec = func(s *Stream, val reflect.Value) error { return decodeListSlice(s, val, etypeinfo.decoder) } } return dec, nil }
func getFields(t reflect.Type) []reflect.StructField { fields := make([]reflect.StructField, 0) if t.Kind() == reflect.Ptr { t = t.Elem() } for i := 0; i < t.NumField(); i++ { f := t.Field(i) ft := f.Type if ft.Kind() == reflect.Ptr { ft = ft.Elem() } switch ft.Kind() { case reflect.Struct: if f.Anonymous { fields = append(fields, getFields(ft)...) } else if len(f.PkgPath) == 0 { fields = append(fields, f) } default: if len(f.PkgPath) == 0 { fields = append(fields, f) } } } return fields }
func checkStructs(c *C, t reflect.Type, structsChecked map[string]struct{}) { for t.Kind() == reflect.Ptr || t.Kind() == reflect.Map || t.Kind() == reflect.Slice { t = t.Elem() } if t.Kind() != reflect.Struct { return } if _, present := structsChecked[t.String()]; present { // Already checked this type return } structsChecked[t.String()] = struct{}{} byUpperCase := make(map[string]int) for i := 0; i < t.NumField(); i++ { sf := t.Field(i) // Check that the yaml tag does not contain an _. yamlTag := sf.Tag.Get("yaml") if strings.Contains(yamlTag, "_") { c.Fatalf("yaml field name includes _ character: %s", yamlTag) } upper := strings.ToUpper(sf.Name) if _, present := byUpperCase[upper]; present { c.Fatalf("field name collision in configuration object: %s", sf.Name) } byUpperCase[upper] = i checkStructs(c, sf.Type, structsChecked) } }
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 (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 (m MySQLDialect) ToSqlType(val reflect.Type, maxsize int, isAutoIncr bool) string { switch val.Kind() { case reflect.Int, reflect.Int16, reflect.Int32: return "int" case reflect.Int64: return "bigint" case reflect.Float64, reflect.Float32: return "double" case reflect.Slice: if val.Elem().Kind() == reflect.Uint8 { return "mediumblob" } } switch val.Name() { case "NullableInt64": return "bigint" case "NullableFloat64": return "double" case "NullableBool": return "tinyint" case "NullableBytes": return "mediumblob" } if maxsize < 1 { maxsize = 255 } return fmt.Sprintf("varchar(%d)", maxsize) }
func generatemethodsEx(t reflect.Type, ignorefunc func(name string) bool, callobject string, name func(t reflect.Type, m reflect.Method) string) (methods string) { t2 := t if t.Kind() == reflect.Ptr { t2 = t.Elem() } for i := 0; i < t.NumMethod(); i++ { var ( m = t.Method(i) reason string ) if m.Name[0] != strings.ToUpper(m.Name[:1])[0] { reason = "unexported" goto skip } if ignorefunc != nil && ignorefunc(m.Name) { reason = "in skip list" goto skip } if m, err := generatemethod(m, t2, callobject, name(t2, m)); err != nil { reason = err.Error() goto skip } else { methods += m } continue skip: fmt.Printf("Skipping method %s.%s: %s\n", t2, m.Name, reason) } return }
// makeWriter creates a writer function for the given type. func makeWriter(typ reflect.Type) (writer, error) { kind := typ.Kind() switch { case typ.Implements(encoderInterface): return writeEncoder, nil case kind != reflect.Ptr && reflect.PtrTo(typ).Implements(encoderInterface): return writeEncoderNoPtr, nil case kind == reflect.Interface: return writeInterface, nil case typ.AssignableTo(reflect.PtrTo(bigInt)): return writeBigIntPtr, nil case typ.AssignableTo(bigInt): return writeBigIntNoPtr, nil case isUint(kind): return writeUint, nil case kind == reflect.Bool: return writeBool, nil case kind == reflect.String: return writeString, nil case kind == reflect.Slice && isByte(typ.Elem()): return writeBytes, nil case kind == reflect.Array && isByte(typ.Elem()): return writeByteArray, nil case kind == reflect.Slice || kind == reflect.Array: return makeSliceWriter(typ) case kind == reflect.Struct: return makeStructWriter(typ) case kind == reflect.Ptr: return makePtrWriter(typ) default: return nil, fmt.Errorf("rlp: type %v is not RLP-serializable", typ) } }
// Add all necessary imports for the type, recursing as appropriate. func addImportsForType(imports importMap, t reflect.Type) { // Add any import needed for the type itself. addImportForType(imports, t) // Handle special cases where recursion is needed. switch t.Kind() { case reflect.Array, reflect.Chan, reflect.Ptr, reflect.Slice: addImportsForType(imports, t.Elem()) case reflect.Func: // Input parameters. for i := 0; i < t.NumIn(); i++ { addImportsForType(imports, t.In(i)) } // Return values. for i := 0; i < t.NumOut(); i++ { addImportsForType(imports, t.Out(i)) } case reflect.Map: addImportsForType(imports, t.Key()) addImportsForType(imports, t.Elem()) } }
func defaultType(t reflect.Type) TypeDesc { switch t.Kind() { case reflect.Bool: return BooleanType case reflect.String: return UTF8Type case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return LongType case reflect.Float32: return FloatType case reflect.Float64: return DoubleType case reflect.Array: if t.Name() == "UUID" && t.Size() == 16 { return UUIDType } return UnknownType case reflect.Struct: if t.Name() == "Time" && t.PkgPath() == "time" { return DateType } return UnknownType case reflect.Slice: if et := t.Elem(); et.Kind() == reflect.Uint8 { return BytesType } return UnknownType } return UnknownType }
func (d decoder) decodeField(sf reflect.StructField, t reflect.Type, v reflect.Value) MessageRejectError { if sf.Tag.Get("fix") != "" { fixTag, err := strconv.Atoi(sf.Tag.Get("fix")) if err != nil { panic(err) } if !d.FieldMap.Has(Tag(fixTag)) { return nil } return d.decodeValue(Tag(fixTag), t, v) } switch t.Kind() { case reflect.Ptr: v.Set(reflect.New(t.Elem())) return d.decodeField(sf, t.Elem(), v.Elem()) case reflect.Struct: for i := 0; i < t.NumField(); i++ { if err := d.decodeField(t.Field(i), t.Field(i).Type, v.Field(i)); err != nil { return err } } } return nil }
// hasUnrecognizedKeys finds unrecognized keys and warns about them on stderr. // returns false when no unrecognized keys were found, true otherwise. func hasUnrecognizedKeys(inCfg interface{}, refType reflect.Type) (warnings bool) { if refType.Kind() == reflect.Ptr { refType = refType.Elem() } switch inCfg.(type) { case map[interface{}]interface{}: ks := inCfg.(map[interface{}]interface{}) keys: for key := range ks { for i := 0; i < refType.NumField(); i++ { sf := refType.Field(i) tv := sf.Tag.Get("yaml") if tv == key { if warn := hasUnrecognizedKeys(ks[key], sf.Type); warn { warnings = true } continue keys } } glog.Errorf("Unrecognized keyword: %v", key) warnings = true } case []interface{}: ks := inCfg.([]interface{}) for i := range ks { if warn := hasUnrecognizedKeys(ks[i], refType.Elem()); warn { warnings = true } } default: } return }
// 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 }
// reflectTypeToJSONType returns a string that represents the JSON type // associated with the provided Go type. func reflectTypeToJSONType(xT descLookupFunc, rt reflect.Type) string { kind := rt.Kind() if isNumeric(kind) { return xT("json-type-numeric") } switch kind { case reflect.String: return xT("json-type-string") case reflect.Bool: return xT("json-type-bool") case reflect.Array, reflect.Slice: return xT("json-type-array") + reflectTypeToJSONType(xT, rt.Elem()) case reflect.Struct: return xT("json-type-object") case reflect.Map: return xT("json-type-object") } return xT("json-type-value") }
// alignment returns the alignment of values of type t. func alignment(t reflect.Type) int { switch t { case variantType: return 1 case objectPathType: return 4 case signatureType: return 1 case interfacesType: return 4 } switch t.Kind() { case reflect.Uint8: return 1 case reflect.Uint16, reflect.Int16: return 2 case reflect.Uint32, reflect.Int32, reflect.String, reflect.Array, reflect.Slice, reflect.Map: return 4 case reflect.Uint64, reflect.Int64, reflect.Float64, reflect.Struct: return 8 case reflect.Ptr: return alignment(t.Elem()) } return 1 }
func sizeof(t reflect.Type) (int, error) { switch t.Kind() { case reflect.Array: n, err := sizeof(t.Elem()) if err != nil { return 0, err } return t.Len() * n, nil case reflect.Struct: sum := 0 for i, n := 0, t.NumField(); i < n; i++ { s, err := sizeof(t.Field(i).Type) if err != nil { return 0, err } sum += s } return sum, nil case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128: return int(t.Size()), nil } return 0, errors.New("invalid type " + t.String()) }
func getDecoder(typ reflect.Type) decoderFunc { kind := typ.Kind() // Addressable struct field value. if kind != reflect.Ptr && reflect.PtrTo(typ).Implements(decoderType) { return decodeCustomValuePtr } if typ.Implements(decoderType) { return decodeCustomValue } if typ.Implements(unmarshalerType) { return unmarshalValue } if decoder, ok := typDecMap[typ]; ok { return decoder } if kind == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 { return decodeBytesValue } return valueDecoders[kind] }