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
}
}