encode_value.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  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 boolType:
  105. return encodeMapStringBoolValue
  106. case interfaceType:
  107. return encodeMapStringInterfaceValue
  108. }
  109. }
  110. }
  111. return valueEncoders[kind]
  112. }
  113. func ptrEncoderFunc(typ reflect.Type) encoderFunc {
  114. encoder := getEncoder(typ.Elem())
  115. return func(e *Encoder, v reflect.Value) error {
  116. if v.IsNil() {
  117. return e.EncodeNil()
  118. }
  119. return encoder(e, v.Elem())
  120. }
  121. }
  122. func encodeCustomValuePtr(e *Encoder, v reflect.Value) error {
  123. if !v.CanAddr() {
  124. return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface())
  125. }
  126. encoder := v.Addr().Interface().(CustomEncoder)
  127. return encoder.EncodeMsgpack(e)
  128. }
  129. func encodeCustomValue(e *Encoder, v reflect.Value) error {
  130. if nilable(v.Kind()) && v.IsNil() {
  131. return e.EncodeNil()
  132. }
  133. encoder := v.Interface().(CustomEncoder)
  134. return encoder.EncodeMsgpack(e)
  135. }
  136. func marshalValuePtr(e *Encoder, v reflect.Value) error {
  137. if !v.CanAddr() {
  138. return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface())
  139. }
  140. return marshalValue(e, v.Addr())
  141. }
  142. func marshalValue(e *Encoder, v reflect.Value) error {
  143. if nilable(v.Kind()) && v.IsNil() {
  144. return e.EncodeNil()
  145. }
  146. marshaler := v.Interface().(Marshaler)
  147. b, err := marshaler.MarshalMsgpack()
  148. if err != nil {
  149. return err
  150. }
  151. _, err = e.w.Write(b)
  152. return err
  153. }
  154. func encodeBoolValue(e *Encoder, v reflect.Value) error {
  155. return e.EncodeBool(v.Bool())
  156. }
  157. func encodeInterfaceValue(e *Encoder, v reflect.Value) error {
  158. if v.IsNil() {
  159. return e.EncodeNil()
  160. }
  161. return e.EncodeValue(v.Elem())
  162. }
  163. func encodeErrorValue(e *Encoder, v reflect.Value) error {
  164. if v.IsNil() {
  165. return e.EncodeNil()
  166. }
  167. return e.EncodeString(v.Interface().(error).Error())
  168. }
  169. func encodeUnsupportedValue(e *Encoder, v reflect.Value) error {
  170. return fmt.Errorf("msgpack: Encode(unsupported %s)", v.Type())
  171. }
  172. func nilable(kind reflect.Kind) bool {
  173. switch kind {
  174. case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
  175. return true
  176. }
  177. return false
  178. }
  179. func nilableType(t reflect.Type) bool {
  180. if t.Kind() == reflect.Ptr {
  181. t = t.Elem()
  182. }
  183. return nilable(t.Kind())
  184. }
  185. //------------------------------------------------------------------------------
  186. func marshalBinaryValueAddr(e *Encoder, v reflect.Value) error {
  187. if !v.CanAddr() {
  188. return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface())
  189. }
  190. return marshalBinaryValue(e, v.Addr())
  191. }
  192. func marshalBinaryValue(e *Encoder, v reflect.Value) error {
  193. if nilable(v.Kind()) && v.IsNil() {
  194. return e.EncodeNil()
  195. }
  196. marshaler := v.Interface().(encoding.BinaryMarshaler)
  197. data, err := marshaler.MarshalBinary()
  198. if err != nil {
  199. return err
  200. }
  201. return e.EncodeBytes(data)
  202. }
  203. //------------------------------------------------------------------------------
  204. func marshalTextValueAddr(e *Encoder, v reflect.Value) error {
  205. if !v.CanAddr() {
  206. return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface())
  207. }
  208. return marshalTextValue(e, v.Addr())
  209. }
  210. func marshalTextValue(e *Encoder, v reflect.Value) error {
  211. if nilable(v.Kind()) && v.IsNil() {
  212. return e.EncodeNil()
  213. }
  214. marshaler := v.Interface().(encoding.TextMarshaler)
  215. data, err := marshaler.MarshalText()
  216. if err != nil {
  217. return err
  218. }
  219. return e.EncodeBytes(data)
  220. }