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 3.0 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
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package codec
  18. import (
  19. "bytes"
  20. "sync"
  21. "github.com/seata/seata-go/pkg/protocol/message"
  22. "github.com/seata/seata-go/pkg/util/log"
  23. "vimagination.zapto.org/byteio"
  24. )
  25. type CodecType byte
  26. const (
  27. CodecTypeSeata = CodecType(0x1)
  28. CodecTypeProtobuf = CodecType(0x2)
  29. CodecTypeKRYO = CodecType(0x4)
  30. CodecTypeFST = CodecType(0x8)
  31. )
  32. type Codec interface {
  33. Encode(in interface{}) []byte
  34. Decode(in []byte) interface{}
  35. GetMessageType() message.MessageType
  36. }
  37. var (
  38. codecManager *CodecManager
  39. onceCodecManager = &sync.Once{}
  40. )
  41. func GetCodecManager() *CodecManager {
  42. if codecManager == nil {
  43. onceCodecManager.Do(func() {
  44. codecManager = &CodecManager{
  45. codecMap: make(map[CodecType]map[message.MessageType]Codec, 0),
  46. }
  47. })
  48. }
  49. return codecManager
  50. }
  51. type CodecManager struct {
  52. mutex sync.Mutex
  53. codecMap map[CodecType]map[message.MessageType]Codec
  54. }
  55. func (c *CodecManager) RegisterCodec(codecType CodecType, codec Codec) {
  56. c.mutex.Lock()
  57. defer c.mutex.Unlock()
  58. codecTypeMap := c.codecMap[codecType]
  59. if codecTypeMap == nil {
  60. codecTypeMap = make(map[message.MessageType]Codec, 0)
  61. c.codecMap[codecType] = codecTypeMap
  62. }
  63. codecTypeMap[codec.GetMessageType()] = codec
  64. }
  65. func (c *CodecManager) GetCodec(codecType CodecType, msgType message.MessageType) Codec {
  66. if m := c.codecMap[codecType]; m != nil {
  67. return m[msgType]
  68. }
  69. return nil
  70. }
  71. func (c *CodecManager) Decode(codecType CodecType, in []byte) interface{} {
  72. r := byteio.BigEndianReader{Reader: bytes.NewReader(in)}
  73. typeCode, _, _ := r.ReadInt16()
  74. codec := c.GetCodec(codecType, message.MessageType(typeCode))
  75. if codec == nil {
  76. log.Errorf("This message type [%v] has no codec to decode", typeCode)
  77. return nil
  78. }
  79. return codec.Decode(in[2:])
  80. }
  81. func (c *CodecManager) Encode(codecType CodecType, in interface{}) []byte {
  82. result := make([]byte, 0)
  83. msg := in.(message.MessageTypeAware)
  84. typeCode := msg.GetTypeCode()
  85. codec := c.GetCodec(codecType, typeCode)
  86. if codec == nil {
  87. log.Errorf("This message type [%v] has no codec to encode", typeCode)
  88. return nil
  89. }
  90. body := codec.Encode(in)
  91. typeC := uint16(typeCode)
  92. result = append(result, []byte{byte(typeC >> 8), byte(typeC)}...)
  93. result = append(result, body...)
  94. return result
  95. }