marshal.go 3.6 KB

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