示例#1
0
// writeExtensions writes all the extensions in pv.
// pv is assumed to be a pointer to a protocol message struct that is extendable.
func writeExtensions(w *textWriter, pv reflect.Value) error {
	emap := extensionMaps[pv.Type().Elem()]
	ep := pv.Interface().(extendableProto)

	// Order the extensions by ID.
	// This isn't strictly necessary, but it will give us
	// canonical output, which will also make testing easier.
	var m map[int32]Extension
	if em, ok := ep.(extensionsMap); ok {
		m = em.ExtensionMap()
	} else if em, ok := ep.(extensionsBytes); ok {
		eb := em.GetExtensions()
		var err error
		m, err = BytesToExtensionsMap(*eb)
		if err != nil {
			return err
		}
	}

	ids := make([]int32, 0, len(m))
	for id := range m {
		ids = append(ids, id)
	}
	sort.Sort(int32Slice(ids))

	for _, extNum := range ids {
		ext := m[extNum]
		var desc *ExtensionDesc
		if emap != nil {
			desc = emap[extNum]
		}
		if desc == nil {
			// Unknown extension.
			if err := writeUnknownStruct(w, ext.enc); err != nil {
				return err
			}
			continue
		}

		pb, err := GetExtension(ep, desc)
		if err != nil {
			return fmt.Errorf("failed getting extension: %v", err)
		}

		// Repeated extensions will appear as a slice.
		if !desc.repeated() {
			if err := writeExtension(w, desc.Name, pb); err != nil {
				return err
			}
		} else {
			v := reflect.ValueOf(pb)
			for i := 0; i < v.Len(); i++ {
				if err := writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil {
					return err
				}
			}
		}
	}
	return nil
}
示例#2
0
文件: sphinxql.go 项目: Carbyn/sphinx
// 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
}
示例#3
0
文件: yaml.go 项目: samsalisbury/yaml
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
}
示例#4
0
文件: parsers.go 项目: rymis/parse
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
}
示例#5
0
// 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)
		}
	}
}
示例#6
0
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()))
}
示例#7
0
文件: print.go 项目: varialus/godfly
// printValue is like printArg but starts with a reflect value, not an interface{} value.
func (p *pp) printValue(value reflect.Value, verb rune, plus, goSyntax bool, depth int) (wasString bool) {
	if !value.IsValid() {
		if verb == 'T' || verb == 'v' {
			p.buf.Write(nilAngleBytes)
		} else {
			p.badVerb(verb)
		}
		return false
	}

	// Special processing considerations.
	// %T (the value's type) and %p (its address) are special; we always do them first.
	switch verb {
	case 'T':
		p.printArg(value.Type().String(), 's', false, false, 0)
		return false
	case 'p':
		p.fmtPointer(value, verb, goSyntax)
		return false
	}

	// Handle values with special methods.
	// Call always, even when arg == nil, because handleMethods clears p.fmt.plus for us.
	p.arg = nil // Make sure it's cleared, for safety.
	if value.CanInterface() {
		p.arg = value.Interface()
	}
	if isString, handled := p.handleMethods(verb, plus, goSyntax, depth); handled {
		return isString
	}

	return p.printReflectValue(value, verb, plus, goSyntax, depth)
}
示例#8
0
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})
	}
}
示例#9
0
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})
	}
}
示例#10
0
func (e *Encoder) encode(v reflect.Value, dst map[string][]string) error {
	var opts string
	var value string
	t := v.Type()

	for i := 0; i < v.NumField(); i++ {
		tag := t.Field(i).Tag.Get(e.TagID)
		name := tag
		if idx := strings.Index(tag, ","); idx != -1 {
			name = tag[:idx]
			opts = tag[idx+1:]
		}
		if name == "-" {
			continue
		}

		encFunc, recurse := encoder(v.Field(i).Type())
		if recurse {
			e.encode(v.Field(i), dst)
			continue
		}

		value = encFunc(v.Field(i))

		if value == "" && strings.Contains(opts, "omitempty") {
			continue
		}

		dst[name] = []string{value}
	}

	return nil
}
示例#11
0
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
}
示例#12
0
func (q *queryParser) parseScalar(v url.Values, r reflect.Value, name string, tag reflect.StructTag) error {
	switch value := r.Interface().(type) {
	case string:
		v.Set(name, value)
	case []byte:
		if !r.IsNil() {
			v.Set(name, base64.StdEncoding.EncodeToString(value))
		}
	case bool:
		v.Set(name, strconv.FormatBool(value))
	case int64:
		v.Set(name, strconv.FormatInt(value, 10))
	case int:
		v.Set(name, strconv.Itoa(value))
	case float64:
		v.Set(name, strconv.FormatFloat(value, 'f', -1, 64))
	case float32:
		v.Set(name, strconv.FormatFloat(float64(value), 'f', -1, 32))
	case time.Time:
		const ISO8601UTC = "2006-01-02T15:04:05Z"
		v.Set(name, value.UTC().Format(ISO8601UTC))
	default:
		return fmt.Errorf("unsupported value for param %s: %v (%s)", name, r.Interface(), r.Type().Name())
	}
	return nil
}
示例#13
0
func (p *untypedParamBinder) setSliceFieldValue(target reflect.Value, defaultValue interface{}, data []string) error {
	if len(data) == 0 && p.parameter.Required && p.parameter.Default == nil {
		return errors.Required(p.Name, p.parameter.In)
	}
	defVal := reflect.Zero(target.Type())
	if defaultValue != nil {
		defVal = reflect.ValueOf(defaultValue)
	}
	if len(data) == 0 {
		target.Set(defVal)
		return nil
	}

	sz := len(data)
	value := reflect.MakeSlice(reflect.SliceOf(target.Type().Elem()), sz, sz)

	for i := 0; i < sz; i++ {
		if err := p.setFieldValue(value.Index(i), nil, data[i]); err != nil {
			return err
		}
	}

	target.Set(value)

	return nil
}
示例#14
0
// apply replaces each AST field x in val with f(x), returning val.
// To avoid extra conversions, f operates on the reflect.Value form.
func apply(f func(reflect.Value) reflect.Value, val reflect.Value) reflect.Value {
	if !val.IsValid() {
		return reflect.Value{}
	}

	// *ast.Objects introduce cycles and are likely incorrect after
	// rewrite; don't follow them but replace with nil instead
	if val.Type() == objectPtrType {
		return objectPtrNil
	}

	// similarly for scopes: they are likely incorrect after a rewrite;
	// replace them with nil
	if val.Type() == scopePtrType {
		return scopePtrNil
	}

	switch v := reflect.Indirect(val); v.Kind() {
	case reflect.Slice:
		for i := 0; i < v.Len(); i++ {
			e := v.Index(i)
			setValue(e, f(e))
		}
	case reflect.Struct:
		for i := 0; i < v.NumField(); i++ {
			e := v.Field(i)
			setValue(e, f(e))
		}
	case reflect.Interface:
		e := v.Elem()
		setValue(v, f(e))
	}
	return val
}
示例#15
0
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()))
}
示例#16
0
文件: query.go 项目: mirrr/Sleep
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()
}
示例#17
0
// IsZero returns true when the value is a zero for the type
func isZero(data reflect.Value) bool {
	if !data.CanInterface() {
		return true
	}
	tpe := data.Type()
	return reflect.DeepEqual(data.Interface(), reflect.Zero(tpe).Interface())
}
示例#18
0
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()
}
示例#19
0
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)
	}

}
// Evaluate interfaces and pointers looking for a value that can look up the name, via a
// struct field, method, or map key, and return the result of the lookup.
func (t *Template) lookup(st *state, v reflect.Value, name string) reflect.Value {
	for v != nil {
		typ := v.Type()
		if n := v.Type().NumMethod(); n > 0 {
			for i := 0; i < n; i++ {
				m := typ.Method(i)
				mtyp := m.Type
				if m.Name == name && mtyp.NumIn() == 1 && mtyp.NumOut() == 1 {
					if !isExported(name) {
						t.execError(st, t.linenum, "name not exported: %s in type %s", name, st.data.Type())
					}
					return v.Method(i).Call(nil)[0]
				}
			}
		}
		switch av := v.(type) {
		case *reflect.PtrValue:
			v = av.Elem()
		case *reflect.InterfaceValue:
			v = av.Elem()
		case *reflect.StructValue:
			if !isExported(name) {
				t.execError(st, t.linenum, "name not exported: %s in type %s", name, st.data.Type())
			}
			return av.FieldByName(name)
		case *reflect.MapValue:
			return av.Elem(reflect.NewValue(name))
		default:
			return nil
		}
	}
	return v
}
示例#21
0
// See if name is a method of the value at some level of indirection.
// The return values are the result of the call (which may be nil if
// there's trouble) and whether a method of the right name exists with
// any signature.
func callMethod(data reflect.Value, name string) (result reflect.Value, found bool) {
	found = false
	// Method set depends on pointerness, and the value may be arbitrarily
	// indirect.  Simplest approach is to walk down the pointer chain and
	// see if we can find the method at each step.
	// Most steps will see NumMethod() == 0.
	for {
		typ := data.Type()
		if nMethod := data.Type().NumMethod(); nMethod > 0 {
			for i := 0; i < nMethod; i++ {
				method := typ.Method(i)
				if method.Name == name {

					found = true // we found the name regardless
					// does receiver type match? (pointerness might be off)
					if typ == method.Type.In(0) {
						return call(data, method), found
					}
				}
			}
		}
		if nd := data; nd.Kind() == reflect.Ptr {
			data = nd.Elem()
		} else {
			break
		}
	}
	return
}
func (g *Group) scanSubGroupHandler(realval reflect.Value, sfield *reflect.StructField) (bool, error) {
	mtag := newMultiTag(string(sfield.Tag))

	if err := mtag.Parse(); err != nil {
		return true, err
	}

	subgroup := mtag.Get("group")

	if len(subgroup) != 0 {
		ptrval := reflect.NewAt(realval.Type(), unsafe.Pointer(realval.UnsafeAddr()))
		description := mtag.Get("description")

		group, err := g.AddGroup(subgroup, description, ptrval.Interface())
		if err != nil {
			return true, err
		}

		group.Namespace = mtag.Get("namespace")
		group.Hidden = mtag.Get("hidden") != ""

		return true, nil
	}

	return false, nil
}
示例#23
0
文件: parsers.go 项目: rymis/parse
func (par *intParser) ParseValue(ctx *parseContext, valueOf reflect.Value, location int, err *Error) int {
	if valueOf.Type().Bits() == 32 && location < len(ctx.str) && ctx.str[location] == '\'' {
		location++
		r, location := ctx.parseUnicodeValue(location, err)
		if location < 0 {
			return location
		}

		if location >= len(ctx.str) || ctx.str[location] != '\'' {
			err.Message = "Waiting for closing quote in unicode character"
			err.Location = location
			return -1
		}
		location++

		valueOf.SetInt(int64(r))

		return location
	}

	r, l := ctx.parseInt64(location, uint(valueOf.Type().Bits()), err)
	if l < 0 {
		return l
	}

	valueOf.SetInt(r)
	return l
}
示例#24
0
func decodeMapStringInterface(d *decodeState, kind int, v reflect.Value) {
	if kind != kindDocument {
		d.saveErrorAndSkip(kind, v.Type())
	}
	if v.IsNil() {
		v.Set(reflect.MakeMap(v.Type()))
	}

	var m map[string]interface{}
	switch mm := v.Interface().(type) {
	case map[string]interface{}:
		m = mm
	case M:
		m = (map[string]interface{})(mm)
	}

	offset := d.beginDoc()
	for {
		kind, name := d.scanKindName()
		if kind == 0 {
			break
		}
		if kind == kindNull {
			continue
		}
		m[string(name)] = d.decodeValueInterface(kind)
	}
	d.endDoc(offset)
}
示例#25
0
文件: sphinxql.go 项目: Carbyn/sphinx
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
}
示例#26
0
func decodeMap(d *decodeState, kind int, v reflect.Value) {
	t := v.Type()
	if t.Key().Kind() != reflect.String || kind != kindDocument {
		d.saveErrorAndSkip(kind, t)
		return
	}
	if v.IsNil() {
		v.Set(reflect.MakeMap(t))
	}
	subv := reflect.New(t.Elem()).Elem()
	offset := d.beginDoc()
	for {
		kind, name := d.scanKindName()
		if kind == 0 {
			break
		}
		if kind == kindNull {
			continue
		}
		subv.Set(reflect.Zero(t.Elem()))
		d.decodeValue(kind, subv)
		v.SetMapIndex(reflect.ValueOf(string(name)), subv)
	}
	d.endDoc(offset)
}
// EncodeValue transmits the data item represented by the reflection value,
// guaranteeing that all necessary type information has been transmitted first.
func (enc *Encoder) EncodeValue(value reflect.Value) os.Error {
	// Make sure we're single-threaded through here, so multiple
	// goroutines can share an encoder.
	enc.mutex.Lock()
	defer enc.mutex.Unlock()

	enc.err = nil
	rt, _ := indirect(value.Type())

	// Sanity check only: encoder should never come in with data present.
	if enc.state.b.Len() > 0 || enc.countState.b.Len() > 0 {
		enc.err = os.ErrorString("encoder: buffer not empty")
		return enc.err
	}

	enc.sendTypeDescriptor(rt)
	if enc.err != nil {
		return enc.err
	}

	// Encode the object.
	err := enc.encode(enc.state.b, value)
	if err != nil {
		enc.setError(err)
	} else {
		enc.send()
	}

	return enc.err
}
示例#28
0
func convertType(v reflect.Value) (*string, error) {
	v = reflect.Indirect(v)
	if !v.IsValid() {
		return nil, nil
	}

	var str string
	switch value := v.Interface().(type) {
	case string:
		str = value
	case []byte:
		str = base64.StdEncoding.EncodeToString(value)
	case bool:
		str = strconv.FormatBool(value)
	case int64:
		str = strconv.FormatInt(value, 10)
	case float64:
		str = strconv.FormatFloat(value, 'f', -1, 64)
	case time.Time:
		str = value.UTC().Format(RFC822)
	default:
		err := fmt.Errorf("Unsupported value for param %v (%s)", v.Interface(), v.Type())
		return nil, err
	}
	return &str, nil
}
示例#29
0
文件: starexpr.go 项目: raff/eval
func evalStarExpr(ctx *Ctx, starExpr *StarExpr, env *Env) (*reflect.Value, bool, error) {
	// return nil, false, errors.New("Star expressions not done yet")
	var cexpr Expr
	var errs []error
	if cexpr, errs = CheckExpr(ctx, starExpr.X, env); len(errs) != 0 {
		for _, cerr := range errs {
			fmt.Printf("%v\n", cerr)
		}
		return nil, false, errors.New("Something wrong checking * expression")
	}

	xs, _, err := EvalExpr(ctx, cexpr, env)
	if err != nil {
		return nil, false, err
	} else if xs == nil {
		// XXX temporary error until typed evaluation of nil
		return nil, false, errors.New("Cannot dereferece nil type")
	}

	var x reflect.Value
	if x, err = expectSingleValue(ctx, *xs, starExpr.X); err != nil {
		return nil, false, err
	}

	switch x.Type().Kind() {
	case reflect.Interface, reflect.Ptr:
		val := x.Elem()
		return &val, true, nil
	default:
		return nil, true, ErrInvalidIndirect{x.Type()}
	}
}
示例#30
0
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
}