You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

167 lines
4.0 KiB

  1. package msgpack
  2. import (
  3. "fmt"
  4. "reflect"
  5. )
  6. var valueEncoders []encoderFunc
  7. func init() {
  8. valueEncoders = []encoderFunc{
  9. reflect.Bool: encodeBoolValue,
  10. reflect.Int: encodeInt64Value,
  11. reflect.Int8: encodeInt64Value,
  12. reflect.Int16: encodeInt64Value,
  13. reflect.Int32: encodeInt64Value,
  14. reflect.Int64: encodeInt64Value,
  15. reflect.Uint: encodeUint64Value,
  16. reflect.Uint8: encodeUint64Value,
  17. reflect.Uint16: encodeUint64Value,
  18. reflect.Uint32: encodeUint64Value,
  19. reflect.Uint64: encodeUint64Value,
  20. reflect.Float32: encodeFloat32Value,
  21. reflect.Float64: encodeFloat64Value,
  22. reflect.Complex64: encodeUnsupportedValue,
  23. reflect.Complex128: encodeUnsupportedValue,
  24. reflect.Array: encodeArrayValue,
  25. reflect.Chan: encodeUnsupportedValue,
  26. reflect.Func: encodeUnsupportedValue,
  27. reflect.Interface: encodeInterfaceValue,
  28. reflect.Map: encodeMapValue,
  29. reflect.Ptr: encodeUnsupportedValue,
  30. reflect.Slice: encodeSliceValue,
  31. reflect.String: encodeStringValue,
  32. reflect.Struct: encodeStructValue,
  33. reflect.UnsafePointer: encodeUnsupportedValue,
  34. }
  35. }
  36. func getEncoder(typ reflect.Type) encoderFunc {
  37. if encoder, ok := typEncMap[typ]; ok {
  38. return encoder
  39. }
  40. if typ.Implements(customEncoderType) {
  41. return encodeCustomValue
  42. }
  43. if typ.Implements(marshalerType) {
  44. return marshalValue
  45. }
  46. kind := typ.Kind()
  47. // Addressable struct field value.
  48. if kind != reflect.Ptr {
  49. ptr := reflect.PtrTo(typ)
  50. if ptr.Implements(customEncoderType) {
  51. return encodeCustomValuePtr
  52. }
  53. if ptr.Implements(marshalerType) {
  54. return marshalValuePtr
  55. }
  56. }
  57. if typ == errorType {
  58. return encodeErrorValue
  59. }
  60. switch kind {
  61. case reflect.Ptr:
  62. return ptrEncoderFunc(typ)
  63. case reflect.Slice:
  64. if typ.Elem().Kind() == reflect.Uint8 {
  65. return encodeByteSliceValue
  66. }
  67. case reflect.Array:
  68. if typ.Elem().Kind() == reflect.Uint8 {
  69. return encodeByteArrayValue
  70. }
  71. case reflect.Map:
  72. if typ.Key() == stringType {
  73. switch typ.Elem() {
  74. case stringType:
  75. return encodeMapStringStringValue
  76. case interfaceType:
  77. return encodeMapStringInterfaceValue
  78. }
  79. }
  80. }
  81. return valueEncoders[kind]
  82. }
  83. func ptrEncoderFunc(typ reflect.Type) encoderFunc {
  84. encoder := getEncoder(typ.Elem())
  85. return func(e *Encoder, v reflect.Value) error {
  86. if v.IsNil() {
  87. return e.EncodeNil()
  88. }
  89. return encoder(e, v.Elem())
  90. }
  91. }
  92. func encodeCustomValuePtr(e *Encoder, v reflect.Value) error {
  93. if !v.CanAddr() {
  94. return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface())
  95. }
  96. encoder := v.Addr().Interface().(CustomEncoder)
  97. return encoder.EncodeMsgpack(e)
  98. }
  99. func encodeCustomValue(e *Encoder, v reflect.Value) error {
  100. switch v.Kind() {
  101. case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
  102. if v.IsNil() {
  103. return e.EncodeNil()
  104. }
  105. }
  106. encoder := v.Interface().(CustomEncoder)
  107. return encoder.EncodeMsgpack(e)
  108. }
  109. func marshalValuePtr(e *Encoder, v reflect.Value) error {
  110. if !v.CanAddr() {
  111. return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface())
  112. }
  113. return marshalValue(e, v.Addr())
  114. }
  115. func marshalValue(e *Encoder, v reflect.Value) error {
  116. switch v.Kind() {
  117. case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
  118. if v.IsNil() {
  119. return e.EncodeNil()
  120. }
  121. }
  122. marshaler := v.Interface().(Marshaler)
  123. b, err := marshaler.MarshalMsgpack()
  124. if err != nil {
  125. return err
  126. }
  127. _, err = e.w.Write(b)
  128. return err
  129. }
  130. func encodeBoolValue(e *Encoder, v reflect.Value) error {
  131. return e.EncodeBool(v.Bool())
  132. }
  133. func encodeInterfaceValue(e *Encoder, v reflect.Value) error {
  134. if v.IsNil() {
  135. return e.EncodeNil()
  136. }
  137. return e.EncodeValue(v.Elem())
  138. }
  139. func encodeErrorValue(e *Encoder, v reflect.Value) error {
  140. if v.IsNil() {
  141. return e.EncodeNil()
  142. }
  143. return e.EncodeString(v.Interface().(error).Error())
  144. }
  145. func encodeUnsupportedValue(e *Encoder, v reflect.Value) error {
  146. return fmt.Errorf("msgpack: Encode(unsupported %s)", v.Type())
  147. }