github.com/xmplusdev/xray-core@v1.8.10/common/reflect/marshal.go (about) 1 package reflect 2 3 import ( 4 "encoding/json" 5 "reflect" 6 7 cserial "github.com/xmplusdev/xray-core/common/serial" 8 ) 9 10 func MarshalToJson(v interface{}) (string, bool) { 11 if itf := marshalInterface(v, true); itf != nil { 12 if b, err := json.MarshalIndent(itf, "", " "); err == nil { 13 return string(b[:]), true 14 } 15 } 16 return "", false 17 } 18 19 func marshalTypedMessage(v *cserial.TypedMessage, ignoreNullValue bool) interface{} { 20 if v == nil { 21 return nil 22 } 23 tmsg, err := v.GetInstance() 24 if err != nil { 25 return nil 26 } 27 r := marshalInterface(tmsg, ignoreNullValue) 28 if msg, ok := r.(map[string]interface{}); ok { 29 msg["_TypedMessage_"] = v.Type 30 } 31 return r 32 } 33 34 func marshalSlice(v reflect.Value, ignoreNullValue bool) interface{} { 35 r := make([]interface{}, 0) 36 for i := 0; i < v.Len(); i++ { 37 rv := v.Index(i) 38 if rv.CanInterface() { 39 value := rv.Interface() 40 r = append(r, marshalInterface(value, ignoreNullValue)) 41 } 42 } 43 return r 44 } 45 46 func marshalStruct(v reflect.Value, ignoreNullValue bool) interface{} { 47 r := make(map[string]interface{}) 48 t := v.Type() 49 for i := 0; i < v.NumField(); i++ { 50 rv := v.Field(i) 51 if rv.CanInterface() { 52 ft := t.Field(i) 53 name := ft.Name 54 value := rv.Interface() 55 tv := marshalInterface(value, ignoreNullValue) 56 if tv != nil || !ignoreNullValue { 57 r[name] = tv 58 } 59 } 60 } 61 return r 62 } 63 64 func marshalMap(v reflect.Value, ignoreNullValue bool) interface{} { 65 // policy.level is map[uint32] *struct 66 kt := v.Type().Key() 67 vt := reflect.TypeOf((*interface{})(nil)) 68 mt := reflect.MapOf(kt, vt) 69 r := reflect.MakeMap(mt) 70 for _, key := range v.MapKeys() { 71 rv := v.MapIndex(key) 72 if rv.CanInterface() { 73 iv := rv.Interface() 74 tv := marshalInterface(iv, ignoreNullValue) 75 if tv != nil || !ignoreNullValue { 76 r.SetMapIndex(key, reflect.ValueOf(&tv)) 77 } 78 } 79 } 80 return r.Interface() 81 } 82 83 func marshalIString(v interface{}) (r string, ok bool) { 84 defer func() { 85 if err := recover(); err != nil { 86 r = "" 87 ok = false 88 } 89 }() 90 91 if iStringFn, ok := v.(interface{ String() string }); ok { 92 return iStringFn.String(), true 93 } 94 return "", false 95 } 96 97 func marshalKnownType(v interface{}, ignoreNullValue bool) (interface{}, bool) { 98 switch ty := v.(type) { 99 case cserial.TypedMessage: 100 return marshalTypedMessage(&ty, ignoreNullValue), true 101 case *cserial.TypedMessage: 102 return marshalTypedMessage(ty, ignoreNullValue), true 103 case map[string]json.RawMessage: 104 return ty, true 105 case []json.RawMessage: 106 return ty, true 107 case *json.RawMessage: 108 return ty, true 109 case json.RawMessage: 110 return ty, true 111 default: 112 return nil, false 113 } 114 } 115 116 func isValueKind(kind reflect.Kind) bool { 117 switch kind { 118 case reflect.Bool, 119 reflect.Int, 120 reflect.Int8, 121 reflect.Int16, 122 reflect.Int32, 123 reflect.Int64, 124 reflect.Uint, 125 reflect.Uint8, 126 reflect.Uint16, 127 reflect.Uint32, 128 reflect.Uint64, 129 reflect.Uintptr, 130 reflect.Float32, 131 reflect.Float64, 132 reflect.Complex64, 133 reflect.Complex128, 134 reflect.String: 135 return true 136 default: 137 return false 138 } 139 } 140 141 func marshalInterface(v interface{}, ignoreNullValue bool) interface{} { 142 143 if r, ok := marshalKnownType(v, ignoreNullValue); ok { 144 return r 145 } 146 147 rv := reflect.ValueOf(v) 148 if rv.Kind() == reflect.Ptr { 149 rv = rv.Elem() 150 } 151 k := rv.Kind() 152 if k == reflect.Invalid { 153 return nil 154 } 155 if isValueKind(k) { 156 return v 157 } 158 159 switch k { 160 case reflect.Struct: 161 return marshalStruct(rv, ignoreNullValue) 162 case reflect.Slice: 163 return marshalSlice(rv, ignoreNullValue) 164 case reflect.Array: 165 return marshalSlice(rv, ignoreNullValue) 166 case reflect.Map: 167 return marshalMap(rv, ignoreNullValue) 168 default: 169 break 170 } 171 172 if str, ok := marshalIString(v); ok { 173 return str 174 } 175 return nil 176 }