func()

in nimo-shake/protocal/raw_converter.go [31:135]


func (rc *RawConverter) dfs(v reflect.Value) interface{} {
	switch v.Kind() {
	case reflect.Invalid:
		return nil
	case reflect.Slice, reflect.Array:
		if v.Len() == 0 {
			return nil
		}

		size := 0
		ret := make([]interface{}, 0, v.Len())
		for i := 0; i < v.Len(); i++ {
			out := rc.dfs(v.Index(i))
			md := out.(RawData)
			size += md.Size
			ret = append(ret, md.Data)
		}
		return RawData{size, ret}
	case reflect.Struct:
		if v.NumField() == 0 {
			return nil
		}

		size := 0
		ret := make(bson2.M)
		for i := 0; i < v.NumField(); i++ {
			name := v.Type().Field(i).Name
			if out := rc.dfs(v.Field(i)); out != nil {
				md := out.(RawData)
				size += md.Size
				size += len(name)
				if _, ok := md.Data.([]interface{}); ok {
					// is type array
					md.Data = rc.convertListToDetailList(name, md.Data)
				}
				ret[name] = md.Data
			}
		}
		return RawData{size, ret}
	case reflect.Map:
		if len(v.MapKeys()) == 0 {
			return nil
		}

		size := 0
		ret := make(bson2.M)
		for _, key := range v.MapKeys() {
			name := key.String()
			name = conf.ConvertIdFunc(name)
			if out := rc.dfs(v.MapIndex(key)); out != nil {
				md := out.(RawData)
				size += md.Size
				size += len(name)
				if _, ok := md.Data.([]interface{}); ok {
					// is type array
					out = rc.convertListToDetailList(name, md.Data)
				}
				ret[name] = md.Data
			}
		}
		return RawData{size, ret}
	case reflect.Ptr:
		if v.IsNil() {
			return nil
		} else {
			return rc.dfs(v.Elem())
		}
	case reflect.Interface:
		if v.IsNil() {
			return nil
		} else {
			return rc.dfs(v.Elem())
		}
	case reflect.String:
		out := v.String()
		return RawData{len(out), out}
	case reflect.Int:
		fallthrough
	case reflect.Int64:
		return RawData{8, v.Int()}
	case reflect.Int8:
		return RawData{1, int8(v.Int())}
	case reflect.Int16:
		return RawData{2, int16(v.Int())}
	case reflect.Int32:
		return RawData{4, int32(v.Int())}
	case reflect.Uint:
		fallthrough
	case reflect.Uint64:
		return RawData{8, v.Uint()}
	case reflect.Uint8:
		return RawData{1, uint8(v.Uint())}
	case reflect.Uint16:
		return RawData{2, uint16(v.Uint())}
	case reflect.Uint32:
		return RawData{4, uint32(v.Uint())}
	case reflect.Bool:
		// fake size
		return RawData{1, v.Bool()}
	default:
		// not support
		LOG.Error("unknown type[%v]", v.Kind())
		return nil
	}
}