proto_encode.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. //协议序列化
  2. package util
  3. import (
  4. "bytes"
  5. "encoding/binary"
  6. "errors"
  7. "fmt"
  8. "math"
  9. "reflect"
  10. "runtime/debug"
  11. "sync"
  12. )
  13. //协议转为二进制
  14. func Pack(v interface{}) ([]byte, error) {
  15. e := newEncodeState()
  16. err := e.marshal(v)
  17. if err != nil {
  18. return nil, err
  19. }
  20. buf := append([]byte(nil), e.Bytes()...)
  21. encodeStatePool.Put(e)
  22. return buf, nil
  23. }
  24. var encodeStatePool sync.Pool
  25. type encodeState struct {
  26. bytes.Buffer
  27. }
  28. //写入数字类型(v需要明确数字类型,不能为int,uint)
  29. func (e *encodeState) WriteInt(v interface{}) {
  30. err := binary.Write(e, binary.BigEndian, v)
  31. if err != nil {
  32. panic(err)
  33. }
  34. }
  35. func (e *encodeState) reflectValue(v reflect.Value) {
  36. typeEncoder(v.Type())(e, v)
  37. }
  38. func (e *encodeState) marshal(v interface{}) (err error) {
  39. defer func() {
  40. if r := recover(); r != nil {
  41. if je, ok := r.(error); ok {
  42. err = je
  43. } else {
  44. err = errors.New("pack error:" + fmt.Sprint(r) + " debug:" + string(debug.Stack()))
  45. }
  46. }
  47. }()
  48. rv := reflect.ValueOf(v)
  49. if rv.Kind() == reflect.Ptr {
  50. rv = rv.Elem()
  51. }
  52. e.reflectValue(rv)
  53. return
  54. }
  55. func newEncodeState() *encodeState {
  56. if v := encodeStatePool.Get(); v != nil {
  57. e := v.(*encodeState)
  58. e.Reset()
  59. return e
  60. }
  61. return &encodeState{}
  62. }
  63. type protoError struct{ error }
  64. type encoderFunc func(e *encodeState, v reflect.Value)
  65. var encoderCache sync.Map // map[reflect.Type]encoderFunc
  66. func typeEncoder(t reflect.Type) encoderFunc {
  67. if fi, ok := encoderCache.Load(t); ok {
  68. return fi.(encoderFunc)
  69. }
  70. var (
  71. wg sync.WaitGroup
  72. f encoderFunc
  73. )
  74. wg.Add(1)
  75. fi, loaded := encoderCache.LoadOrStore(t, encoderFunc(func(e *encodeState, v reflect.Value) {
  76. wg.Wait()
  77. f(e, v)
  78. }))
  79. if loaded {
  80. return fi.(encoderFunc)
  81. }
  82. f = newTypeEncoder(t)
  83. wg.Done()
  84. encoderCache.Store(t, f)
  85. return f
  86. }
  87. func newTypeEncoder(t reflect.Type) encoderFunc {
  88. switch t.Kind() {
  89. case reflect.Bool:
  90. return boolEncoder
  91. case reflect.Int:
  92. return intEncoder
  93. case reflect.Uint:
  94. return uintEncoder
  95. case reflect.Int32, reflect.Int8, reflect.Int16, reflect.Int64, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  96. return intComEncoder
  97. case reflect.Float32:
  98. return float32Encoder
  99. case reflect.Float64:
  100. return float64Encoder
  101. case reflect.String:
  102. return stringEncoder
  103. case reflect.Struct:
  104. return newStructEncoder(t)
  105. case reflect.Slice:
  106. return newSliceEncoder(t)
  107. case reflect.Array:
  108. return newArrayEncoder(t)
  109. default:
  110. panic(errors.New("proto: unsupported type: " + t.String()))
  111. }
  112. }
  113. func boolEncoder(e *encodeState, v reflect.Value) {
  114. if v.Bool() {
  115. e.WriteByte(1)
  116. } else {
  117. e.WriteByte(0)
  118. }
  119. }
  120. //通用
  121. func intComEncoder(e *encodeState, v reflect.Value) {
  122. e.WriteInt(v.Interface())
  123. }
  124. //4字节
  125. func intEncoder(e *encodeState, v reflect.Value) {
  126. e.WriteInt(int32(v.Int()))
  127. }
  128. //4字节
  129. func uintEncoder(e *encodeState, v reflect.Value) {
  130. e.WriteInt(uint32(v.Uint()))
  131. }
  132. //float32
  133. func float32Encoder(e *encodeState, v reflect.Value) {
  134. e.WriteInt(math.Float32bits((float32)(v.Float())))
  135. }
  136. //float64
  137. func float64Encoder(e *encodeState, v reflect.Value) {
  138. e.WriteInt(math.Float64bits((v.Float())))
  139. }
  140. //string
  141. func stringEncoder(e *encodeState, v reflect.Value) {
  142. buf := []byte(v.String())
  143. l := len(buf)
  144. if l > 70000 {
  145. panic(errors.New(fmt.Sprint("proto: stringLen len > 70000 l:", l)))
  146. }
  147. e.WriteInt(uint32(l))
  148. e.Write(buf)
  149. }
  150. func encodeByteSlice(e *encodeState, v reflect.Value) {
  151. res := v.Bytes()
  152. l := len(res)
  153. if l >= 5000000 {
  154. panic(errors.New(fmt.Sprint("proto: []uint8 len > 5000000 l:", l)))
  155. }
  156. e.WriteInt(uint32(l))
  157. e.Write(res)
  158. }
  159. type sliceEncoder struct {
  160. arrayEnc encoderFunc
  161. }
  162. func (se sliceEncoder) encode(e *encodeState, v reflect.Value) {
  163. if v.IsNil() {
  164. e.WriteInt(uint32(0))
  165. return
  166. }
  167. se.arrayEnc(e, v)
  168. }
  169. func newSliceEncoder(t reflect.Type) encoderFunc {
  170. // Byte slices get special treatment; arrays don't.
  171. if t.Elem().Kind() == reflect.Uint8 {
  172. return encodeByteSlice
  173. }
  174. enc := sliceEncoder{newArrayEncoder(t)}
  175. return enc.encode
  176. }
  177. type arrayEncoder struct {
  178. elemEnc encoderFunc
  179. }
  180. func (ae arrayEncoder) encode(e *encodeState, v reflect.Value) {
  181. l := v.Len()
  182. if l > 5000000 {
  183. panic(errors.New("proto: not support arrLen> 5000000 type:" + v.Type().String()))
  184. }
  185. e.WriteInt(uint32(l))
  186. for i := 0; i < l; i++ {
  187. ae.elemEnc(e, v.Index(i))
  188. }
  189. }
  190. func newArrayEncoder(t reflect.Type) encoderFunc {
  191. enc := arrayEncoder{typeEncoder(t.Elem())}
  192. return enc.encode
  193. }
  194. type structEncoder struct {
  195. fields []field
  196. }
  197. func (se structEncoder) encode(e *encodeState, v reflect.Value) {
  198. for i := range se.fields {
  199. f := &se.fields[i]
  200. f.encoder(e, v.Field(i))
  201. }
  202. }
  203. func newStructEncoder(t reflect.Type) encoderFunc {
  204. return cachedTypeFields(t).encode
  205. }
  206. type field struct {
  207. encoder encoderFunc
  208. }
  209. func typeFields(t reflect.Type) structEncoder {
  210. var fields []field
  211. for i := 0; i < t.NumField(); i++ {
  212. sf := t.Field(i)
  213. st := sf.Type
  214. if st == t {
  215. panic("proto:not support recursive type:" + st.String())
  216. }
  217. if sf.PkgPath != "" {
  218. panic("proto:not support type:" + t.String() + ",name:" + sf.Name)
  219. }
  220. fields = append(fields, field{encoder: typeEncoder(st)})
  221. }
  222. return structEncoder{fields}
  223. }
  224. var fieldCache sync.Map // map[reflect.Type]structEncoder
  225. func cachedTypeFields(t reflect.Type) structEncoder {
  226. if f, ok := fieldCache.Load(t); ok {
  227. return f.(structEncoder)
  228. }
  229. f, _ := fieldCache.LoadOrStore(t, typeFields(t))
  230. return f.(structEncoder)
  231. }