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

codec.go 2.3 kB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package codec
  2. import (
  3. "bytes"
  4. "sync"
  5. )
  6. import (
  7. "vimagination.zapto.org/byteio"
  8. )
  9. import (
  10. "github.com/seata/seata-go/pkg/common/log"
  11. "github.com/seata/seata-go/pkg/protocol/message"
  12. )
  13. type CodecType byte
  14. // TODO 待重构
  15. const (
  16. CodeTypeSeata = CodecType(0x1)
  17. CodeTypeProtobuf = CodecType(0x2)
  18. CodeTypeKRYO = CodecType(0x4)
  19. CodeTypeFST = CodecType(0x8)
  20. )
  21. type Codec interface {
  22. Encode(in interface{}) []byte
  23. Decode(in []byte) interface{}
  24. GetMessageType() message.MessageType
  25. }
  26. var (
  27. codecManager *CodecManager
  28. onceCodecManager = &sync.Once{}
  29. )
  30. func GetCodecManager() *CodecManager {
  31. if codecManager == nil {
  32. onceCodecManager.Do(func() {
  33. codecManager = &CodecManager{
  34. codecMap: make(map[CodecType]map[message.MessageType]Codec, 0),
  35. }
  36. })
  37. }
  38. return codecManager
  39. }
  40. type CodecManager struct {
  41. mutex sync.Mutex
  42. codecMap map[CodecType]map[message.MessageType]Codec
  43. }
  44. func (c *CodecManager) RegisterCodec(codecType CodecType, codec Codec) {
  45. c.mutex.Lock()
  46. defer c.mutex.Unlock()
  47. codecTypeMap := c.codecMap[codecType]
  48. if codecTypeMap == nil {
  49. codecTypeMap = make(map[message.MessageType]Codec, 0)
  50. c.codecMap[codecType] = codecTypeMap
  51. }
  52. codecTypeMap[codec.GetMessageType()] = codec
  53. }
  54. func (c *CodecManager) GetCodec(codecType CodecType, msgType message.MessageType) Codec {
  55. if m := c.codecMap[codecType]; m != nil {
  56. return m[msgType]
  57. }
  58. return nil
  59. }
  60. func (c *CodecManager) Decode(codecType CodecType, in []byte) interface{} {
  61. r := byteio.BigEndianReader{Reader: bytes.NewReader(in)}
  62. typeCode, _, _ := r.ReadInt16()
  63. codec := c.GetCodec(codecType, message.MessageType(typeCode))
  64. if codec == nil {
  65. log.Errorf("This message type [%v] has no codec to decode", typeCode)
  66. return nil
  67. }
  68. return codec.Decode(in[2:])
  69. }
  70. func (c *CodecManager) Encode(codecType CodecType, in interface{}) []byte {
  71. var result = make([]byte, 0)
  72. msg := in.(message.MessageTypeAware)
  73. typeCode := msg.GetTypeCode()
  74. codec := c.GetCodec(codecType, typeCode)
  75. if codec == nil {
  76. log.Errorf("This message type [%v] has no codec to encode", typeCode)
  77. return nil
  78. }
  79. body := codec.Encode(in)
  80. typeC := uint16(typeCode)
  81. result = append(result, []byte{byte(typeC >> 8), byte(typeC)}...)
  82. result = append(result, body...)
  83. return result
  84. }

Go Implementation For Seata