packet.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. package cli
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "io"
  6. "math"
  7. "git.nspix.com/golang/micro/helper/unsafestr"
  8. )
  9. var (
  10. feature = []byte{67, 76, 73}
  11. )
  12. const (
  13. PacketTypeCompleter byte = 0x01
  14. PacketTypeData = 0x02
  15. PacketTypeEcho = 0x03
  16. )
  17. type Frame struct {
  18. Feature []byte
  19. Type byte `json:"type"`
  20. Data []byte `json:"data"`
  21. Error string `json:"error"`
  22. Timestamp int64 `json:"timestamp"`
  23. }
  24. func nextFrame(r io.Reader) (frame *Frame, err error) {
  25. var (
  26. n int
  27. dataLength uint16
  28. errorLength uint16
  29. errBuf []byte
  30. )
  31. frame = &Frame{Feature: make([]byte, 3)}
  32. if _, err = io.ReadFull(r, frame.Feature); err != nil {
  33. return
  34. }
  35. if !bytes.Equal(frame.Feature, feature) {
  36. err = io.ErrUnexpectedEOF
  37. return
  38. }
  39. if err = binary.Read(r, binary.LittleEndian, &frame.Type); err != nil {
  40. return
  41. }
  42. if err = binary.Read(r, binary.LittleEndian, &frame.Timestamp); err != nil {
  43. return
  44. }
  45. if err = binary.Read(r, binary.LittleEndian, &dataLength); err != nil {
  46. return
  47. }
  48. if err = binary.Read(r, binary.LittleEndian, &errorLength); err != nil {
  49. return
  50. }
  51. if dataLength > 0 {
  52. frame.Data = make([]byte, dataLength)
  53. if n, err = io.ReadFull(r, frame.Data); err == nil {
  54. if n < int(dataLength) {
  55. err = io.ErrShortBuffer
  56. }
  57. }
  58. }
  59. if errorLength > 0 {
  60. errBuf = make([]byte, errorLength)
  61. if n, err = io.ReadFull(r, errBuf); err == nil {
  62. if n < int(dataLength) {
  63. err = io.ErrShortBuffer
  64. } else {
  65. frame.Error = unsafestr.BytesToString(errBuf)
  66. }
  67. }
  68. }
  69. return
  70. }
  71. func writeFrame(w io.Writer, frame *Frame) (err error) {
  72. var (
  73. n int
  74. dl int
  75. dataLength uint16
  76. errorLength uint16
  77. errBuf []byte
  78. )
  79. if _, err = w.Write(feature); err != nil {
  80. return
  81. }
  82. if frame.Data != nil {
  83. dl = len(frame.Data)
  84. if dl > math.MaxUint16 {
  85. return io.ErrNoProgress
  86. }
  87. dataLength = uint16(dl)
  88. }
  89. if frame.Error != "" {
  90. errBuf = unsafestr.StringToBytes(frame.Error)
  91. errorLength = uint16(len(errBuf))
  92. }
  93. if err = binary.Write(w, binary.LittleEndian, frame.Type); err != nil {
  94. return
  95. }
  96. if err = binary.Write(w, binary.LittleEndian, frame.Timestamp); err != nil {
  97. return
  98. }
  99. if err = binary.Write(w, binary.LittleEndian, dataLength); err != nil {
  100. return
  101. }
  102. if err = binary.Write(w, binary.LittleEndian, errorLength); err != nil {
  103. return
  104. }
  105. if dataLength > 0 {
  106. if n, err = w.Write(frame.Data); err == nil {
  107. if n < int(dataLength) {
  108. err = io.ErrShortWrite
  109. }
  110. }
  111. }
  112. if errorLength > 0 {
  113. if n, err = w.Write(errBuf); err == nil {
  114. if n < int(errorLength) {
  115. err = io.ErrShortWrite
  116. }
  117. }
  118. }
  119. return
  120. }