예제 #1
0
파일: clone.go 프로젝트: zwczou/goserver
func deepCopyMap(src, dst reflect.Value, t reflect.Type) {
	for _, key := range src.MapKeys() {
		var nkey, nval reflect.Value
		if key.IsValid() && key.CanSet() {
			if key.Kind() == reflect.Ptr {
				nkey = reflect.New(key.Elem().Type())
			} else {
				nkey = reflect.New(key.Type())
				nkey = reflect.Indirect(nkey)
			}
			s := reflect.Indirect(key)
			d := reflect.Indirect(nkey)
			tt := s.Type()
			deepCopy(s, d, tt)
		} else {
			nkey = key
		}
		if val := src.MapIndex(key); val.IsValid() && val.CanSet() {
			if val.Kind() == reflect.Ptr {
				nval = reflect.New(val.Elem().Type())
			} else {
				nval = reflect.New(val.Type())
				nval = reflect.Indirect(nval)
			}
			s := reflect.Indirect(val)
			d := reflect.Indirect(nval)
			tt := s.Type()
			deepCopy(s, d, tt)
		} else {
			nval = val
		}
		dst.SetMapIndex(nkey, nval)
	}
}
예제 #2
0
파일: decode.go 프로젝트: amasses/form
func decodeMap(v reflect.Value, x interface{}) {
	t := v.Type()
	if v.IsNil() {
		v.Set(reflect.MakeMap(t))
	}
	for k, c := range getNode(x) {
		i := reflect.New(t.Key()).Elem()
		decodeValue(i, k)

		w := v.MapIndex(i)
		if w.IsValid() { // We have an actual element value to decode into.
			if w.Kind() == reflect.Interface {
				w = w.Elem()
			}
			w = reflect.New(w.Type()).Elem()
		} else if t.Elem().Kind() != reflect.Interface { // The map's element type is concrete.
			w = reflect.New(t.Elem()).Elem()
		} else {
			// The best we can do here is to decode as either a string (for scalars) or a map[string]interface {} (for the rest).
			// We could try to guess the type based on the string (e.g. true/false => bool) but that'll get ugly fast,
			// especially if we have to guess the kind (slice vs. array vs. map) and index type (e.g. string, int, etc.)
			switch c.(type) {
			case node:
				w = reflect.MakeMap(stringMapType)
			case string:
				w = reflect.New(stringType).Elem()
			default:
				panic("value is neither node nor string")
			}
		}

		decodeValue(w, c)
		v.SetMapIndex(i, w)
	}
}
예제 #3
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})
	}
}
예제 #4
0
func display(name string, v reflect.Value) {
	switch v.Kind() { //uint
	case reflect.Invalid:
		fmt.Printf("%s = invalid\n", name)
	case reflect.Slice, reflect.Array:
		for i := 0; i < v.Len(); i++ {
			display(fmt.Sprintf("%s[%d]", name, i), v.Index(i))
		}
	case reflect.Struct:
		for i := 0; i < v.NumField(); i++ {
			fieldPath := fmt.Sprintf("%s.%s", name, v.Type().Field(i).Name)
			display(fieldPath, v.Field(i))
		}
	case reflect.Map:
		for _, key := range v.MapKeys() {
			display(fmt.Sprintf("%s[%s]", name,
				formatAtom(key)), v.MapIndex(key))
		}
	case reflect.Ptr:
		if v.IsNil() {
			fmt.Printf("%s = nil\n", name)
		} else {
			display(fmt.Sprintf("(*%s)", name), v.Elem())
		}
	case reflect.Interface:
		if v.IsNil() {
			fmt.Printf("%s = nil\n", name)
		} else {
			fmt.Printf("%s.type = %s\n", name, v.Elem().Type())
			display(name+".value", v.Elem())
		}
	default: // basic types, channels, funcs
		fmt.Printf("%s = %s\n", name, formatAtom(v))
	}
}
예제 #5
0
파일: exec.go 프로젝트: bibbyflyaway/go
// evalField evaluates an expression like (.Field) or (.Field arg1 arg2).
// The 'final' argument represents the return value from the preceding
// value of the pipeline, if any.
func (s *state) evalField(dot reflect.Value, fieldName string, node parse.Node, args []parse.Node, final, receiver reflect.Value) reflect.Value {
	if !receiver.IsValid() {
		return zero
	}
	typ := receiver.Type()
	receiver, _ = indirect(receiver)
	// Unless it's an interface, need to get to a value of type *T to guarantee
	// we see all methods of T and *T.
	ptr := receiver
	if ptr.Kind() != reflect.Interface && ptr.CanAddr() {
		ptr = ptr.Addr()
	}
	if method := ptr.MethodByName(fieldName); method.IsValid() {
		return s.evalCall(dot, method, node, fieldName, args, final)
	}
	hasArgs := len(args) > 1 || final.IsValid()
	// It's not a method; must be a field of a struct or an element of a map. The receiver must not be nil.
	receiver, isNil := indirect(receiver)
	if isNil {
		s.errorf("nil pointer evaluating %s.%s", typ, fieldName)
	}
	switch receiver.Kind() {
	case reflect.Struct:
		tField, ok := receiver.Type().FieldByName(fieldName)
		if ok {
			field := receiver.FieldByIndex(tField.Index)
			if tField.PkgPath != "" { // field is unexported
				s.errorf("%s is an unexported field of struct type %s", fieldName, typ)
			}
			// If it's a function, we must call it.
			if hasArgs {
				s.errorf("%s has arguments but cannot be invoked as function", fieldName)
			}
			return field
		}
		s.errorf("%s is not a field of struct type %s", fieldName, typ)
	case reflect.Map:
		// If it's a map, attempt to use the field name as a key.
		nameVal := reflect.ValueOf(fieldName)
		if nameVal.Type().AssignableTo(receiver.Type().Key()) {
			if hasArgs {
				s.errorf("%s is not a method but has arguments", fieldName)
			}
			result := receiver.MapIndex(nameVal)
			if !result.IsValid() {
				switch s.tmpl.option.missingKey {
				case mapInvalid:
					// Just use the invalid value.
				case mapZeroValue:
					result = reflect.Zero(receiver.Type().Elem())
				case mapError:
					s.errorf("map has no entry for key %q", fieldName)
				}
			}
			return result
		}
	}
	s.errorf("can't evaluate field %s in type %s", fieldName, typ)
	panic("not reached")
}
예제 #6
0
파일: encode.go 프로젝트: 2thetop/go
func (me *mapEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
	if v.IsNil() {
		e.WriteString("null")
		return
	}
	e.WriteByte('{')

	// Extract and sort the keys.
	keys := v.MapKeys()
	sv := make([]reflectWithString, len(keys))
	for i, v := range keys {
		sv[i].v = v
		if err := sv[i].resolve(); err != nil {
			e.error(&MarshalerError{v.Type(), err})
		}
	}
	sort.Sort(byString(sv))

	for i, kv := range sv {
		if i > 0 {
			e.WriteByte(',')
		}
		e.string(kv.s, opts.escapeHTML)
		e.WriteByte(':')
		me.elemEnc(e, v.MapIndex(kv.v), opts)
	}
	e.WriteByte('}')
}
예제 #7
0
파일: encoder.go 프로젝트: imvu/Tetra
func encodeMap(val reflect.Value) ([]byte, error) {
	var t = val.Type()

	if t.Key().Kind() != reflect.String {
		return nil, fmt.Errorf("xmlrpc encode error: only maps with string keys are supported")
	}

	var b bytes.Buffer

	b.WriteString("<struct>")

	keys := val.MapKeys()

	for i := 0; i < val.Len(); i++ {
		key := keys[i]
		kval := val.MapIndex(key)

		b.WriteString("<member>")
		b.WriteString(fmt.Sprintf("<name>%s</name>", key.String()))

		p, err := encodeValue(kval)

		if err != nil {
			return nil, err
		}

		b.Write(p)
		b.WriteString("</member>")
	}

	b.WriteString("</struct>")

	return b.Bytes(), nil
}
예제 #8
0
func (d *mapAsStructDecoder) decode(dv, sv reflect.Value) {
	for _, kv := range sv.MapKeys() {
		var f *field
		var fieldDec decoderFunc
		key := []byte(kv.String())
		for i := range d.fields {
			ff := &d.fields[i]
			ffd := d.fieldDecs[i]
			if bytes.Equal(ff.nameBytes, key) {
				f = ff
				fieldDec = ffd
				break
			}
			if f == nil && ff.equalFold(ff.nameBytes, key) {
				f = ff
				fieldDec = ffd
			}
		}

		if f == nil {
			continue
		}

		dElemVal := fieldByIndex(dv, f.index)
		sElemVal := sv.MapIndex(kv)

		if !sElemVal.IsValid() || !dElemVal.CanSet() {
			continue
		}

		fieldDec(dElemVal, sElemVal)
	}
}
예제 #9
0
파일: equal.go 프로젝트: Rachine/imposm3
// v1 and v2 are known to have the same type.
func equalAny(v1, v2 reflect.Value) bool {
	if v1.Type() == protoMessageType {
		m1, _ := v1.Interface().(Message)
		m2, _ := v2.Interface().(Message)
		return Equal(m1, m2)
	}
	switch v1.Kind() {
	case reflect.Bool:
		return v1.Bool() == v2.Bool()
	case reflect.Float32, reflect.Float64:
		return v1.Float() == v2.Float()
	case reflect.Int32, reflect.Int64:
		return v1.Int() == v2.Int()
	case reflect.Map:
		if v1.Len() != v2.Len() {
			return false
		}
		for _, key := range v1.MapKeys() {
			val2 := v2.MapIndex(key)
			if !val2.IsValid() {
				// This key was not found in the second map.
				return false
			}
			if !equalAny(v1.MapIndex(key), val2) {
				return false
			}
		}
		return true
	case reflect.Ptr:
		return equalAny(v1.Elem(), v2.Elem())
	case reflect.Slice:
		if v1.Type().Elem().Kind() == reflect.Uint8 {
			// short circuit: []byte
			if v1.IsNil() != v2.IsNil() {
				return false
			}
			return bytes.Equal(v1.Interface().([]byte), v2.Interface().([]byte))
		}

		if v1.Len() != v2.Len() {
			return false
		}
		for i := 0; i < v1.Len(); i++ {
			if !equalAny(v1.Index(i), v2.Index(i)) {
				return false
			}
		}
		return true
	case reflect.String:
		return v1.Interface().(string) == v2.Interface().(string)
	case reflect.Struct:
		return equalStruct(v1, v2)
	case reflect.Uint32, reflect.Uint64:
		return v1.Uint() == v2.Uint()
	}

	// unknown type, so not a protocol buffer
	log.Printf("proto: don't know how to compare %v", v1)
	return false
}
예제 #10
0
func (d *decoder) mapCopy(src reflect.Value, dst reflect.Value) error {
	sv := src.MapKeys()
	dt := dst.Type().Elem()

	for i := range sv {
		ot := reflect.New(dt)

		if dt.Kind() == reflect.Ptr {
			ot = reflect.New(ot.Type().Elem())
		}

		d.pushPath(sv[i].String())
		err := d.decode(src.MapIndex(sv[i]), ot)
		if err != nil && err != ErrIncompatStruct {
			err = errors.New(d.pathString() + err.Error())
			d.path = nil
			return err
		}
		d.popPath()

		if err == nil {
			dst.SetMapIndex(sv[i], ot.Elem())
		}
	}
	return nil
}
예제 #11
0
func (d *mapAsMapDecoder) decode(dv, sv reflect.Value) {
	dt := dv.Type()
	dv.Set(reflect.MakeMap(reflect.MapOf(dt.Key(), dt.Elem())))

	var mapKey reflect.Value
	var mapElem reflect.Value

	keyType := dv.Type().Key()
	elemType := dv.Type().Elem()

	for _, sElemKey := range sv.MapKeys() {
		var dElemKey reflect.Value
		var dElemVal reflect.Value

		if !mapKey.IsValid() {
			mapKey = reflect.New(keyType).Elem()
		} else {
			mapKey.Set(reflect.Zero(keyType))
		}
		dElemKey = mapKey

		if !mapElem.IsValid() {
			mapElem = reflect.New(elemType).Elem()
		} else {
			mapElem.Set(reflect.Zero(elemType))
		}
		dElemVal = mapElem

		d.keyDec(dElemKey, sElemKey)
		d.elemDec(dElemVal, sv.MapIndex(sElemKey))

		dv.SetMapIndex(dElemKey, dElemVal)
	}
}
예제 #12
0
파일: compare.go 프로젝트: freedmand/doc.vu
func reflectMap(v reflect.Value) map[interface{}]interface{} {
	switch v.Kind() {
	case reflect.Struct:
		m := map[interface{}]interface{}{}
		for i := 0; i < v.NumField(); i++ {
			sf := v.Type().Field(i)
			if sf.PkgPath != "" && !sf.Anonymous {
				continue // unexported
			}

			k := sf.Name
			v := v.Field(i).Interface()

			m[k] = v
		}
		return m
	case reflect.Map:
		m := map[interface{}]interface{}{}
		for _, mk := range v.MapKeys() {
			k := ""
			if mk.Interface() != nil {
				k = fmt.Sprintf("%v", mk.Interface())
			}
			v := v.MapIndex(mk).Interface()

			m[k] = v
		}
		return m
	default:
		return nil
	}
}
예제 #13
0
func printMap(w io.Writer, tv reflect.Value, depth string) {
	fmt.Fprintf(w, "{\n")
	ss := make(sort.StringSlice, tv.Len())
	i := 0
	for _, kval := range tv.MapKeys() {
		if kval.Kind() == reflect.Interface {
			kval = kval.Elem()
		}

		if kval.Kind() != reflect.String {
			continue
		}

		ss[i] = kval.String()
		i++
	}
	sort.Sort(ss)
	for _, k := range ss {
		val := tv.MapIndex(reflect.ValueOf(k))
		v := val.Interface()
		nd := depth + "  "
		for i := 0; i < len(k)+2; i++ {
			nd += " "
		}
		fmt.Fprintf(w, "  %s%s: ", depth, k)
		printValue(w, v, nd)
	}
	fmt.Fprintf(w, "%s}\n", depth)
}
예제 #14
0
func (m Master) retrieveValues(db *sql.DB, rv reflect.Value, cfgs ...interface{}) (idField reflect.Value, fields []string, holders []string, values []interface{}, table string, err error) {
	table = strings.ToLower(rv.Type().Name()) + "s"
	// var insertNull bool
	for _, c := range cfgs {
		switch c.(type) {
		// case InsertNull:
		// 	insertNull = true
		case TableName:
			table = string(c.(TableName))
		}
	}

	// _ = insertNull
	switch rv.Kind() {
	case reflect.Struct:
		idField, fields, holders, values, err = m.walkStruct(rv)
	case reflect.Map:
		if rv.Type().Key().Kind() != reflect.String {
			err = fmt.Errorf("sqlkungfu: Insert(map key is %s, want string)", rv.Type().Key().Kind())
			return
		}
		for _, k := range rv.MapKeys() {
			fields = append(fields, m.quoteColumn(k.String()))
			holders = append(holders, "?")
			values = append(values, rv.MapIndex(k).Interface())
		}
	}
	return
}
예제 #15
0
파일: reify.go 프로젝트: ChongFeng/beats
func reifyMap(opts *options, to reflect.Value, from *Config) Error {
	if to.Type().Key().Kind() != reflect.String {
		return raiseKeyInvalidTypeUnpack(to.Type(), from)
	}

	if len(from.fields.fields) == 0 {
		return nil
	}

	if to.IsNil() {
		to.Set(reflect.MakeMap(to.Type()))
	}
	for k, value := range from.fields.fields {
		key := reflect.ValueOf(k)

		old := to.MapIndex(key)
		var v reflect.Value
		var err Error

		if !old.IsValid() {
			v, err = reifyValue(fieldOptions{opts: opts}, to.Type().Elem(), value)
		} else {
			v, err = reifyMergeValue(fieldOptions{opts: opts}, old, value)
		}

		if err != nil {
			return err
		}
		to.SetMapIndex(key, v)
	}

	return nil
}
예제 #16
0
// Pretty-print any random data we get back from the server
func genericLogData(name string, v reflect.Value, indent string, skip int) {
	prefix := "->" + indent
	if name != "" {
		prefix = "-> " + indent + name + ":"
	}

	// For pointers and interfaces, just grab the underlying value and try again
	if v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface {
		genericLogData(name, v.Elem(), indent, skip)
		return
	}

	// Only print if skip is 0.  Recursive calls should indent or decrement skip, depending on if anything was
	// printed.
	var skipped bool
	if skip == 0 {
		skipped = false
		indent = indent + "  "
	} else {
		skipped = true
		skip = skip - 1
	}

	switch v.Kind() {
	case reflect.Struct:
		if !skipped {
			Log("%s\n", prefix)
		}
		for f := 0; f < v.NumField(); f++ {
			name := v.Type().Field(f).Name
			genericLogData(name, v.Field(f), indent, skip)
		}
	case reflect.Array:
		fallthrough
	case reflect.Slice:
		if !skipped {
			Log("%s\n", prefix)
		}
		for i := 0; i < v.Len(); i++ {
			genericLogData("", v.Index(i), indent, skip)
		}
	case reflect.Map:
		if !skipped {
			Log("%s\n", prefix)
		}
		for _, k := range v.MapKeys() {
			if name, ok := k.Interface().(string); ok {
				genericLogData(name, v.MapIndex(k), indent, skip)
			} else {
				genericLogData("Unknown field", v.MapIndex(k), indent, skip)
			}
		}
	default:
		if v.CanInterface() {
			Log("%s %v", prefix, v.Interface())
		} else {
			Log("%s <Invalid>", prefix)
		}
	}
}
예제 #17
0
파일: encode.go 프로젝트: JasperTimm/toml
func (enc *Encoder) eMap(key Key, rv reflect.Value) {
	rt := rv.Type()
	if rt.Key().Kind() != reflect.String {
		encPanic(errNonString)
	}

	// Sort keys so that we have deterministic output. And write keys directly
	// underneath this key first, before writing sub-structs or sub-maps.
	var mapKeysDirect, mapKeysSub []string
	for _, mapKey := range rv.MapKeys() {
		k := mapKey.String()
		if typeIsHash(tomlTypeOfGo(rv.MapIndex(mapKey))) {
			mapKeysSub = append(mapKeysSub, k)
		} else {
			mapKeysDirect = append(mapKeysDirect, k)
		}
	}

	var writeMapKeys = func(mapKeys []string) {
		sort.Strings(mapKeys)
		for _, mapKey := range mapKeys {
			mrv := rv.MapIndex(reflect.ValueOf(mapKey))
			if isNil(mrv) {
				// Don't write anything for nil fields.
				continue
			}
			enc.encode(key.add(mapKey), mrv)
		}
	}
	writeMapKeys(mapKeysDirect)
	writeMapKeys(mapKeysSub)
}
예제 #18
0
func quietOutput(prefix string, v reflect.Value) {
	// For pointers and interfaces, just grab the underlying value and try again
	if v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface {
		quietOutput(prefix, v.Elem())
		return
	}

	switch v.Kind() {
	case reflect.Struct:
		for f := 0; f < v.NumField(); f++ {
			name := v.Type().Field(f).Name
			quietOutput(prefix+name+" ", v.Field(f))
		}
	case reflect.Array:
		fallthrough
	case reflect.Slice:
		for i := 0; i < v.Len(); i++ {
			quietOutput(prefix, v.Index(i))
		}
	case reflect.Map:
		for _, k := range v.MapKeys() {
			if name, ok := k.Interface().(string); ok {
				quietOutput(prefix+name+" ", v.MapIndex(k))
			} else {
				quietOutput(prefix+"UnknownField", v.MapIndex(k))
			}
		}
	default:
		if v.CanInterface() {
			fmt.Printf("%s%v\n", prefix, v.Interface())
		} else {
			fmt.Printf("%s <Invalid>", prefix)
		}
	}
}
예제 #19
0
// mapIndex returns an element value of a map at the specified index.
// If the value is an interface, the underlying value will be returned.
func mapIndex(mp reflect.Value, index reflect.Value) reflect.Value {
	v := mp.MapIndex(index)
	if v.Kind() == reflect.Interface {
		v = v.Elem()
	}
	return v
}
예제 #20
0
파일: encode.go 프로젝트: bartekn/go-xdr
// encodeMap treats the map represented by the passed reflection value as a
// variable-length array of 2-element structures whose fields are of the same
// type as the map keys and elements and appends its XDR encoded representation
// to the Encoder's data.
//
// A MarshalError is returned if any issues are encountered while encoding
// the elements.
func (enc *Encoder) encodeMap(v reflect.Value) (err error) {
	dataLen := v.Len()
	if uint(dataLen) > math.MaxUint32 {
		err = marshalError("encodeMap", ErrOverflow, errMaxXdr, dataLen)
		return
	}
	err = enc.EncodeUint(uint32(dataLen))
	if err != nil {
		return
	}

	// Encode each key and value according to their type.
	for _, key := range v.MapKeys() {
		err = enc.encode(key)
		if err != nil {
			return
		}

		err = enc.encode(v.MapIndex(key))
		if err != nil {
			return
		}
	}
	return
}
예제 #21
0
// decodeObjectInterface decodes the source value into map[string]interface{}
func decodeObjectInterface(s *decodeState, sv reflect.Value) map[string]interface{} {
	m := map[string]interface{}{}
	for _, key := range sv.MapKeys() {
		m[key.Interface().(string)] = decodeInterface(s, sv.MapIndex(key))
	}
	return m
}
예제 #22
0
func approxDataSize(rv reflect.Value) (sum int) {
	switch rk := rv.Kind(); rk {
	case reflect.Invalid:
	case reflect.Ptr, reflect.Interface:
		sum += int(rv.Type().Size())
		sum += approxDataSize(rv.Elem())
	case reflect.Slice:
		sum += int(rv.Type().Size())
		for j := 0; j < rv.Len(); j++ {
			sum += approxDataSize(rv.Index(j))
		}
	case reflect.String:
		sum += int(rv.Type().Size())
		sum += rv.Len()
	case reflect.Map:
		sum += int(rv.Type().Size())
		for _, mk := range rv.MapKeys() {
			sum += approxDataSize(mk)
			sum += approxDataSize(rv.MapIndex(mk))
		}
	case reflect.Struct:
		//struct size already includes the full data size.
		//sum += int(rv.Type().Size())
		for j := 0; j < rv.NumField(); j++ {
			sum += approxDataSize(rv.Field(j))
		}
	default:
		//pure value types
		sum += int(rv.Type().Size())
	}
	return
}
예제 #23
0
func (e *Encoder) encodeMap(av *dynamodb.AttributeValue, v reflect.Value, fieldTag tag) error {
	av.M = map[string]*dynamodb.AttributeValue{}
	for _, key := range v.MapKeys() {
		keyName := fmt.Sprint(key.Interface())
		if keyName == "" {
			return &InvalidMarshalError{msg: "map key cannot be empty"}
		}

		elemVal := v.MapIndex(key)
		elem := &dynamodb.AttributeValue{}
		err := e.encode(elem, elemVal, tag{})
		skip, err := keepOrOmitEmpty(fieldTag.OmitEmptyElem, elem, err)
		if err != nil {
			return err
		} else if skip {
			continue
		}

		av.M[keyName] = elem
	}
	if len(av.M) == 0 {
		encodeNull(av)
	}

	return nil
}
// FindValueTypesInKnownMap finds out all value types in this level in a known map.
func (s StringKeyMapTypeSections) FindValueTypesInKnownMap(key string, v reflect.Value, noOfArrayLv int) (section StringKeyMapTypeSection, isMap bool) {
	if v.Kind() == reflect.Map {
		i := reflect.Invalid
		if len(v.MapKeys()) > 0 {
			i = reflect.Map
		}
		r := StringKeyMapTypeSection{key, noOfArrayLv, StringKeyMapTypeMap{}, i}
		newTypeFound := false
		for _, x := range v.MapKeys() {
			t, known := s.CheckIfValueTypeAlreadyKnown(x.String(), noOfArrayLv)
			if known {
				r.TypeMap[x.String()] = t
			} else {
				k := FindTypeForValue(v.MapIndex(x))
				if k == reflect.Invalid {
					return StringKeyMapTypeSection{}, false
				}
				r.TypeMap[x.String()] = k
				newTypeFound = true
			}
		}
		if newTypeFound {
			s.RemoveElemInSections(key, noOfArrayLv)
		}
		return r, true
	}
	return StringKeyMapTypeSection{}, false
}
예제 #25
0
파일: encode.go 프로젝트: kxtry/Sereal
func (e *Encoder) encodeMap(by []byte, m reflect.Value, isRefNext bool, strTable map[string]int, ptrTable map[uintptr]int) ([]byte, error) {
	if e.PerlCompat && !isRefNext {
		by = append(by, typeREFN)
	}

	keys := m.MapKeys()
	by = append(by, typeHASH)
	by = varint(by, uint(len(keys)))

	var err error
	if e.PerlCompat {
		for _, k := range keys {
			by = e.encodeString(by, k.String(), true, strTable)
			if by, err = e.encode(by, m.MapIndex(k), false, false, strTable, ptrTable); err != nil {
				return by, err
			}
		}
	} else {
		for _, k := range keys {
			if by, err = e.encode(by, k, true, false, strTable, ptrTable); err != nil {
				return by, err
			}

			if by, err = e.encode(by, m.MapIndex(k), false, false, strTable, ptrTable); err != nil {
				return by, err
			}
		}
	}

	return by, nil
}
예제 #26
0
파일: struct.go 프로젝트: skycoin/skycoin
func writeMap(w io.Writer, val reflect.Value) (err error) {
	key := val.Type().Key()
	if key.Kind() != reflect.String {
		return &MarshalError{val.Type()}
	}
	_, err = fmt.Fprint(w, "d")
	if err != nil {
		return
	}

	keys := val.MapKeys()

	// Sort keys

	svList := make(stringValueArray, len(keys))
	for i, key := range keys {
		svList[i].key = key.String()
		svList[i].value = val.MapIndex(key)
	}

	err = writeSVList(w, svList)
	if err != nil {
		return
	}

	_, err = fmt.Fprint(w, "e")
	if err != nil {
		return
	}
	return
}
예제 #27
0
파일: convert.go 프로젝트: jcf/go-osx-plist
func convertMapToCFDictionaryHelper(m reflect.Value, helper func(reflect.Value) (cfTypeRef, error)) (C.CFDictionaryRef, error) {
	// assume m is a map, because our caller already checked
	if m.Type().Key().Kind() != reflect.String {
		// the map keys aren't strings
		return nil, &UnsupportedTypeError{m.Type()}
	}
	mapKeys := m.MapKeys()
	keys := make([]cfTypeRef, len(mapKeys))
	values := make([]cfTypeRef, len(mapKeys))
	// defer the release
	defer func() {
		for _, cfKey := range keys {
			cfRelease(cfTypeRef(cfKey))
		}
		for _, cfVal := range values {
			cfRelease(cfTypeRef(cfVal))
		}
	}()
	// create the keys and values slices
	for i, keyVal := range mapKeys {
		// keyVal is a Value representing a string
		cfStr := convertStringToCFString(keyVal.String())
		if cfStr == nil {
			return nil, errors.New("plist: could not convert string to CFStringRef")
		}
		keys[i] = cfTypeRef(cfStr)
		cfObj, err := helper(m.MapIndex(keyVal))
		if err != nil {
			return nil, err
		}
		values[i] = cfObj
	}
	return createCFDictionary(keys, values), nil
}
예제 #28
0
파일: encode.go 프로젝트: paxan/go-edn
func (me *mapEncoder) encode(e *encodeState, v reflect.Value) {
	isSet := v.Type() == setType
	isKMap := v.Type() == keywordMapType
	sep := ", "
	if isSet {
		e.WriteByte('#')
		sep = " "
	}
	if v.IsNil() {
		e.WriteString("{}")
		return
	}
	e.WriteByte('{')
	for i, k := range v.MapKeys() {
		if i > 0 {
			e.WriteString(sep)
		}
		if !isKMap {
			me.keyEnc(e, k)
		} else {
			me.keyEnc(e, reflect.ValueOf(Keyword(k.String())))
		}
		if !isSet {
			e.WriteByte(' ')
			me.elemEnc(e, v.MapIndex(k))
		}
	}
	e.WriteByte('}')
}
예제 #29
0
파일: writer.go 프로젝트: hprose/hprose-go
func (w *Writer) writeMap(v interface{}, rv reflect.Value) (err error) {
	w.setRef(v)
	s := w.Stream
	if err = s.WriteByte(TagMap); err == nil {
		if count := rv.Len(); count > 0 {
			if err = w.writeInt(count); err == nil {
				if err = s.WriteByte(TagOpenbrace); err == nil {
					keys := rv.MapKeys()
					for i := range keys {
						if err = w.WriteValue(keys[i]); err != nil {
							return err
						}
						if err = w.WriteValue(rv.MapIndex(keys[i])); err != nil {
							return err
						}
					}
					err = s.WriteByte(TagClosebrace)
				}
			}
		} else if err = s.WriteByte(TagOpenbrace); err == nil {
			err = s.WriteByte(TagClosebrace)
		}
	}
	return err
}
예제 #30
0
파일: types.go 프로젝트: fcavani/monlite
//AnySettableValue find if exist one value that you can set.
func AnySettableValue(val reflect.Value) bool {
	switch val.Kind() {
	case reflect.Array:
		for i := 0; i < val.Type().Len(); i++ {
			if AnySettableValue(val.Index(i)) {
				return true
			}
		}
	case reflect.Interface:
		return AnySettableValue(val.Elem())
	case reflect.Map:
		for _, key := range val.MapKeys() {
			if AnySettableValue(val.MapIndex(key)) {
				return true
			}
		}
	case reflect.Ptr:
		return AnySettableValue(val.Elem())
	case reflect.Slice:
		for i := 0; i < val.Len(); i++ {
			if AnySettableValue(val.Index(i)) {
				return true
			}
		}
	case reflect.Struct:
		for i := 0; i < val.Type().NumField(); i++ {
			if AnySettableValue(val.Field(i)) {
				return true
			}
		}
	default:
		return val.CanSet()
	}
	return false
}