Пример #1
0
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)
		}
	}()
}
Пример #2
0
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
}
Пример #3
0
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
}
Пример #4
0
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
}
Пример #5
0
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
}
Пример #6
0
// 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
}
Пример #7
0
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
}
Пример #8
0
// 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
}
Пример #9
0
func createSliceByType(t reflect.Type) interface{} {
	return reflect.New(reflect.Type(reflect.SliceOf(t))).Interface()
}