encode_value.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. package msgpack
  2. import (
  3. "encoding"
  4. "fmt"
  5. "reflect"
  6. )
  7. var valueEncoders []encoderFunc
  8. //nolint:gochecknoinits
  9. func init() {
  10. valueEncoders = []encoderFunc{
  11. reflect.Bool: encodeBoolValue,
  12. reflect.Int: encodeIntValue,
  13. reflect.Int8: encodeInt8CondValue,
  14. reflect.Int16: encodeInt16CondValue,
  15. reflect.Int32: encodeInt32CondValue,
  16. reflect.Int64: encodeInt64CondValue,
  17. reflect.Uint: encodeUintValue,
  18. reflect.Uint8: encodeUint8CondValue,
  19. reflect.Uint16: encodeUint16CondValue,
  20. reflect.Uint32: encodeUint32CondValue,
  21. reflect.Uint64: encodeUint64CondValue,
  22. reflect.Float32: encodeFloat32Value,
  23. reflect.Float64: encodeFloat64Value,
  24. reflect.Complex64: encodeUnsupportedValue,
  25. reflect.Complex128: encodeUnsupportedValue,
  26. reflect.Array: encodeArrayValue,
  27. reflect.Chan: encodeUnsupportedValue,
  28. reflect.Func: encodeUnsupportedValue,
  29. reflect.Interface: encodeInterfaceValue,
  30. reflect.Map: encodeMapValue,
  31. reflect.Ptr: encodeUnsupportedValue,
  32. reflect.Slice: encodeSliceValue,
  33. reflect.String: encodeStringValue,
  34. reflect.Struct: encodeStructValue,
  35. reflect.UnsafePointer: encodeUnsupportedValue,
  36. }
  37. }
  38. func getEncoder(typ reflect.Type) encoderFunc {
  39. if v, ok := typeEncMap.Load(typ); ok {
  40. return v.(encoderFunc)
  41. }
  42. fn := _getEncoder(typ)
  43. typeEncMap.Store(typ, fn)
  44. return fn
  45. }
  46. func _getEncoder(typ reflect.Type) encoderFunc {
  47. kind := typ.Kind()
  48. if kind == reflect.Ptr {
  49. if _, ok := typeEncMap.Load(typ.Elem()); ok {
  50. return ptrEncoderFunc(typ)
  51. }
  52. }
  53. if typ.Implements(customEncoderType) {
  54. return encodeCustomValue
  55. }
  56. if typ.Implements(marshalerType) {
  57. return marshalValue
  58. }
  59. if typ.Implements(binaryMarshalerType) {
  60. return marshalBinaryValue
  61. }
  62. if typ.Implements(textMarshalerType) {
  63. return marshalTextValue
  64. }
  65. // Addressable struct field value.
  66. if kind != reflect.Ptr {
  67. ptr := reflect.PtrTo(typ)
  68. if ptr.Implements(customEncoderType) {
  69. return encodeCustomValuePtr
  70. }
  71. if ptr.Implements(marshalerType) {
  72. return marshalValuePtr
  73. }
  74. if ptr.Implements(binaryMarshalerType) {
  75. return marshalBinaryValueAddr
  76. }
  77. if ptr.Implements(textMarshalerType) {
  78. return marshalTextValueAddr
  79. }
  80. }
  81. if typ == errorType {
  82. return encodeErrorValue
  83. }
  84. switch kind {
  85. case reflect.Ptr:
  86. return ptrEncoderFunc(typ)
  87. case reflect.Slice:
  88. elem := typ.Elem()
  89. if elem.Kind() == reflect.Uint8 {
  90. return encodeByteSliceValue
  91. }
  92. if elem == stringType {
  93. return encodeStringSliceValue
  94. }
  95. case reflect.Array:
  96. if typ.Elem().Kind() == reflect.Uint8 {
  97. return encodeByteArrayValue
  98. }
  99. case reflect.Map:
  100. if typ.Key() == stringType {
  101. switch typ.Elem() {
  102. case stringType:
  103. return encodeMapStringStringValue
  104. case interfaceType:
  105. return encodeMapStringInterfaceValue
  106. }
  107. }
  108. }
  109. return valueEncoders[kind]
  110. }
  111. func ptrEncoderFunc(typ reflect.Type) encoderFunc {
  112. encoder := getEncoder(typ.Elem())
  113. return func(e *Encoder, v reflect.Value) error {
  114. if v.IsNil() {
  115. return e.EncodeNil()
  116. }
  117. return encoder(e, v.Elem())
  118. }
  119. }
  120. func encodeCustomValuePtr(e *Encoder, v reflect.Value) error {
  121. if !v.CanAddr() {
  122. return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface())
  123. }
  124. encoder := v.Addr().Interface().(CustomEncoder)
  125. return encoder.EncodeMsgpack(e)
  126. }
  127. func encodeCustomValue(e *Encoder, v reflect.Value) error {
  128. if nilable(v.Kind()) && v.IsNil() {
  129. return e.EncodeNil()
  130. }
  131. encoder := v.Interface().(CustomEncoder)
  132. return encoder.EncodeMsgpack(e)
  133. }
  134. func marshalValuePtr(e *Encoder, v reflect.Value) error {
  135. if !v.CanAddr() {
  136. return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface())
  137. }
  138. return marshalValue(e, v.Addr())
  139. }
  140. func marshalValue(e *Encoder, v reflect.Value) error {
  141. if nilable(v.Kind()) && v.IsNil() {
  142. return e.EncodeNil()
  143. }
  144. marshaler := v.Interface().(Marshaler)
  145. b, err := marshaler.MarshalMsgpack()
  146. if err != nil {
  147. return err
  148. }
  149. _, err = e.w.Write(b)
  150. return err
  151. }
  152. func encodeBoolValue(e *Encoder, v reflect.Value) error {
  153. return e.EncodeBool(v.Bool())
  154. }
  155. func encodeInterfaceValue(e *Encoder, v reflect.Value) error {
  156. if v.IsNil() {
  157. return e.EncodeNil()
  158. }
  159. return e.EncodeValue(v.Elem())
  160. }
  161. func encodeErrorValue(e *Encoder, v reflect.Value) error {
  162. if v.IsNil() {
  163. return e.EncodeNil()
  164. }
  165. return e.EncodeString(v.Interface().(error).Error())
  166. }
  167. func encodeUnsupportedValue(e *Encoder, v reflect.Value) error {
  168. return fmt.Errorf("msgpack: Encode(unsupported %s)", v.Type())
  169. }
  170. func nilable(kind reflect.Kind) bool {
  171. switch kind {
  172. case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
  173. return true
  174. }
  175. return false
  176. }
  177. //------------------------------------------------------------------------------
  178. func marshalBinaryValueAddr(e *Encoder, v reflect.Value) error {
  179. if !v.CanAddr() {
  180. return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface())
  181. }
  182. return marshalBinaryValue(e, v.Addr())
  183. }
  184. func marshalBinaryValue(e *Encoder, v reflect.Value) error {
  185. if nilable(v.Kind()) && v.IsNil() {
  186. return e.EncodeNil()
  187. }
  188. marshaler := v.Interface().(encoding.BinaryMarshaler)
  189. data, err := marshaler.MarshalBinary()
  190. if err != nil {
  191. return err
  192. }
  193. return e.EncodeBytes(data)
  194. }
  195. //------------------------------------------------------------------------------
  196. func marshalTextValueAddr(e *Encoder, v reflect.Value) error {
  197. if !v.CanAddr() {
  198. return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface())
  199. }
  200. return marshalTextValue(e, v.Addr())
  201. }
  202. func marshalTextValue(e *Encoder, v reflect.Value) error {
  203. if nilable(v.Kind()) && v.IsNil() {
  204. return e.EncodeNil()
  205. }
  206. marshaler := v.Interface().(encoding.TextMarshaler)
  207. data, err := marshaler.MarshalText()
  208. if err != nil {
  209. return err
  210. }
  211. return e.EncodeBytes(data)
  212. }