func NewOutChan(dec *Decoder, typ interface{}, buffer int) (ch <-chan interface{}) { t_ch := &reflect.MakeChan(reflect.Type(typ), buffer-1) p := t_ch.(unsafe.Pointer) ch = *p.(*chan interface{}) go func() { var err error for err != nil { i := &reflect.New(reflect.Type(typ)) err = dec.Decode(i) ch <- i.(unsafe.Pointer) } }() }
func (p *structPLS) Load(propMap PropertyMap) error { if err := p.Problem(); err != nil { return err } convFailures := errors.MultiError(nil) t := reflect.Type(nil) for name, props := range propMap { multiple := len(props) > 1 for i, prop := range props { if reason := loadInner(p.c, p.o, i, name, prop, multiple); reason != "" { if t == nil { t = p.o.Type() } convFailures = append(convFailures, &ErrFieldMismatch{ StructType: t, FieldName: name, Reason: reason, }) } } } if len(convFailures) > 0 { return convFailures } return nil }
func NewClient(connStr string) (Client, error) { methods := map[string]reflect.Type{ "insert": reflect.Type(reflect.ValueOf(insertMethod).Type()), "search": reflect.Type(reflect.ValueOf(searchMethod).Type()), } serviceGlobalConfig := new(client.ServiceConfig) serviceGlobalConfig.ConnectionTimeout = 10 serviceGlobalConfig.ServerAddr = connStr clientApi, err := client.NewServiceClient(make(map[string]string), methods, serviceGlobalConfig) if err != nil { log.Fatalln(err) return nil, err } return &clientImpl{ Client: clientApi, }, nil }
func NewInChan(enc *Encoder, typ interface{}, buffer int) (ch chan<- interface{}) { //ch = make(chan interface{}) // t_ch := &reflect.MakeChan(reflect.Type(typ), buffer-1) p := t_ch.(unsafe.Pointer) ch = *p.(*chan interface{}) go func() { var err error for err != nil { i := <-ch err = enc.Encode(i) } }() return }
func (p *structPLS) Load(propMap PropertyMap) error { convFailures := errors.MultiError(nil) useExtra := false extra := (*PropertyMap)(nil) if i, ok := p.c.bySpecial["extra"]; ok { useExtra = true f := p.c.byIndex[i] if f.canSet { extra = p.o.Field(i).Addr().Interface().(*PropertyMap) } } t := reflect.Type(nil) for name, props := range propMap { multiple := len(props) > 1 for i, prop := range props { if reason := loadInner(p.c, p.o, i, name, prop, multiple); reason != "" { if useExtra { if extra != nil { if *extra == nil { *extra = make(PropertyMap, 1) } (*extra)[name] = props } break // go to the next property in propMap } else { if t == nil { t = p.o.Type() } convFailures = append(convFailures, &ErrFieldMismatch{ StructType: t, FieldName: name, Reason: reason, }) } } } } if len(convFailures) > 0 { return convFailures } return nil }
// getStructCodecLocked implements getStructCodec. The structCodecsMutex must // be held when calling this function. func getStructCodecLocked(t reflect.Type) (ret *structCodec, retErr error) { c, ok := structCodecs[t] if ok { return c, nil } c = &structCodec{ byIndex: make([]structTag, t.NumField()), byName: make(map[string]fieldCodec), } // Add c to the structCodecs map before we are sure it is good. If t is // a recursive type, it needs to find the incomplete entry for itself in // the map. structCodecs[t] = c defer func() { if retErr != nil { delete(structCodecs, t) } }() for i := range c.byIndex { f := t.Field(i) name, opts := f.Tag.Get("datastore"), "" if i := strings.Index(name, ","); i != -1 { name, opts = name[:i], name[i+1:] } if name == "" { if !f.Anonymous { name = f.Name } } else if name == "-" { c.byIndex[i] = structTag{name: name} continue } else if !validPropertyName(name) { return nil, fmt.Errorf("datastore: struct tag has invalid property name: %q", name) } substructType, fIsSlice := reflect.Type(nil), false switch f.Type.Kind() { case reflect.Struct: substructType = f.Type case reflect.Slice: if f.Type.Elem().Kind() == reflect.Struct { substructType = f.Type.Elem() } fIsSlice = f.Type != typeOfByteSlice c.hasSlice = c.hasSlice || fIsSlice } if substructType != nil && substructType != typeOfTime { if name != "" { name = name + "." } sub, err := getStructCodecLocked(substructType) if err != nil { return nil, err } if !sub.complete { return nil, fmt.Errorf("datastore: recursive struct: field %q", f.Name) } if fIsSlice && sub.hasSlice { return nil, fmt.Errorf( "datastore: flattening nested structs leads to a slice of slices: field %q", f.Name) } c.hasSlice = c.hasSlice || sub.hasSlice for relName := range sub.byName { absName := name + relName if _, ok := c.byName[absName]; ok { return nil, fmt.Errorf("datastore: struct tag has repeated property name: %q", absName) } c.byName[absName] = fieldCodec{index: i, substructCodec: sub} } } else { if _, ok := c.byName[name]; ok { return nil, fmt.Errorf("datastore: struct tag has repeated property name: %q", name) } c.byName[name] = fieldCodec{index: i} } c.byIndex[i] = structTag{ name: name, noIndex: opts == "noindex", } } c.complete = true return c, nil }
func getStructCodecLocked(t reflect.Type) (c *structCodec) { if c, ok := structCodecs[t]; ok { return c } me := func(fmtStr string, args ...interface{}) error { return fmt.Errorf(fmtStr, args...) } c = &structCodec{ byIndex: make([]structTag, t.NumField()), byName: make(map[string]int, t.NumField()), byMeta: make(map[string]int, t.NumField()), bySpecial: make(map[string]int, 1), problem: errRecursiveStruct, // we'll clear this later if it's not recursive } defer func() { // If the codec has a problem, free up the indexes if c.problem != nil { c.byIndex = nil c.byName = nil c.byMeta = nil } }() structCodecs[t] = c for i := range c.byIndex { st := &c.byIndex[i] f := t.Field(i) ft := f.Type name := f.Tag.Get("gae") opts := "" if i := strings.Index(name, ","); i != -1 { name, opts = name[:i], name[i+1:] } st.canSet = f.PkgPath == "" // blank == exported if opts == "extra" { if _, ok := c.bySpecial["extra"]; ok { c.problem = me("struct has multiple fields tagged as 'extra'") return } if name != "" && name != "-" { c.problem = me("struct 'extra' field has invalid name %s, expecing `` or `-`", name) return } if ft != typeOfPropertyMap { c.problem = me("struct 'extra' field has invalid type %s, expecing PropertyMap", ft) return } st.isExtra = true st.name = name c.bySpecial["extra"] = i continue } st.convert = reflect.PtrTo(ft).Implements(typeOfPropertyConverter) switch { case name == "": if !f.Anonymous { name = f.Name } case name[0] == '$': name = name[1:] if _, ok := c.byMeta[name]; ok { c.problem = me("meta field %q set multiple times", "$"+name) return } c.byMeta[name] = i if !st.convert { mv, err := convertMeta(opts, ft) if err != nil { c.problem = me("meta field %q has bad type: %s", "$"+name, err) return } st.metaVal = mv } fallthrough case name == "-": st.name = "-" continue default: if !validPropertyName(name) { c.problem = me("struct tag has invalid property name: %q", name) return } } if !st.canSet { st.name = "-" continue } substructType := reflect.Type(nil) if !st.convert { switch ft.Kind() { case reflect.Struct: if ft != typeOfTime && ft != typeOfGeoPoint { substructType = ft } case reflect.Slice: if reflect.PtrTo(ft.Elem()).Implements(typeOfPropertyConverter) { st.convert = true } else if ft.Elem().Kind() == reflect.Struct { substructType = ft.Elem() } st.isSlice = ft.Elem().Kind() != reflect.Uint8 c.hasSlice = c.hasSlice || st.isSlice case reflect.Interface: c.problem = me("field %q has non-concrete interface type %s", f.Name, ft) return } } if substructType != nil { sub := getStructCodecLocked(substructType) if sub.problem != nil { if sub.problem == errRecursiveStruct { c.problem = me("field %q is recursively defined", f.Name) } else { c.problem = me("field %q has problem: %s", f.Name, sub.problem) } return } st.substructCodec = sub if st.isSlice && sub.hasSlice { c.problem = me( "flattening nested structs leads to a slice of slices: field %q", f.Name) return } c.hasSlice = c.hasSlice || sub.hasSlice if name != "" { name += "." } for relName := range sub.byName { absName := name + relName if _, ok := c.byName[absName]; ok { c.problem = me("struct tag has repeated property name: %q", absName) return } c.byName[absName] = i } } else { if !st.convert { // check the underlying static type of the field t := ft if st.isSlice { t = t.Elem() } v := UpconvertUnderlyingType(reflect.New(t).Elem().Interface()) if _, err := PropertyTypeOf(v, false); err != nil { c.problem = me("field %q has invalid type: %s", name, ft) return } } if _, ok := c.byName[name]; ok { c.problem = me("struct tag has repeated property name: %q", name) return } c.byName[name] = i } st.name = name if opts == "noindex" { st.idxSetting = NoIndex } } if c.problem == errRecursiveStruct { c.problem = nil } return }
// getStructCodecLocked implements getStructCodec. The structCodecsMutex must // be held when calling this function. func getStructCodecLocked(t reflect.Type) (ret *structCodec, retErr error) { c, ok := structCodecs[t] if ok { return c, nil } c = &structCodec{ fields: make(map[string]fieldCodec), // We initialize keyField to -1 so that the zero-value is not // misinterpreted as index 0. keyField: -1, } // Add c to the structCodecs map before we are sure it is good. If t is // a recursive type, it needs to find the incomplete entry for itself in // the map. structCodecs[t] = c defer func() { if retErr != nil { delete(structCodecs, t) } }() for i := 0; i < t.NumField(); i++ { f := t.Field(i) // Skip unexported fields. // Note that if f is an anonymous, unexported struct field, // we will not promote its fields. We will skip f entirely. if f.PkgPath != "" { continue } tags := strings.Split(f.Tag.Get("datastore"), ",") name := tags[0] opts := make(map[string]bool) for _, t := range tags[1:] { opts[t] = true } switch { case name == "": if !f.Anonymous { name = f.Name } case name == "-": continue case name == "__key__": if f.Type != typeOfKeyPtr { return nil, fmt.Errorf("datastore: __key__ field on struct %v is not a *datastore.Key", t) } c.keyField = i case !validPropertyName(name): return nil, fmt.Errorf("datastore: struct tag has invalid property name: %q", name) } substructType, fIsSlice := reflect.Type(nil), false switch f.Type.Kind() { case reflect.Struct: substructType = f.Type case reflect.Slice: if f.Type.Elem().Kind() == reflect.Struct { substructType = f.Type.Elem() } fIsSlice = f.Type != typeOfByteSlice c.hasSlice = c.hasSlice || fIsSlice } var sub *structCodec if substructType != nil && substructType != typeOfTime && substructType != typeOfGeoPoint { var err error sub, err = getStructCodecLocked(substructType) if err != nil { return nil, err } if !sub.complete { return nil, fmt.Errorf("datastore: recursive struct: field %q", f.Name) } if fIsSlice && sub.hasSlice { return nil, fmt.Errorf( "datastore: flattening nested structs leads to a slice of slices: field %q", f.Name) } c.hasSlice = c.hasSlice || sub.hasSlice // If name is empty at this point, f is an anonymous struct field. // In this case, we promote the substruct's fields up to this level // in the linked list of struct codecs. if name == "" { for subname, subfield := range sub.fields { if _, ok := c.fields[subname]; ok { return nil, fmt.Errorf("datastore: struct tag has repeated property name: %q", subname) } c.fields[subname] = fieldCodec{ path: append([]int{i}, subfield.path...), noIndex: subfield.noIndex || opts["noindex"], structCodec: subfield.structCodec, } } continue } } if _, ok := c.fields[name]; ok { return nil, fmt.Errorf("datastore: struct tag has repeated property name: %q", name) } c.fields[name] = fieldCodec{ path: []int{i}, noIndex: opts["noindex"], structCodec: sub, } } c.complete = true return c, nil }
func createSliceByType(t reflect.Type) interface{} { return reflect.New(reflect.Type(reflect.SliceOf(t))).Interface() }