frame.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. package cli
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "io"
  6. "math"
  7. "time"
  8. )
  9. const (
  10. PacketTypeCompleter byte = 0x01
  11. PacketTypeCommand = 0x02
  12. PacketTypeHandshake = 0x03
  13. )
  14. const (
  15. FlagPortion = 0x00
  16. FlagComplete = 0x01
  17. )
  18. type (
  19. Frame struct {
  20. Feature []byte
  21. Type byte `json:"type"`
  22. Flag byte `json:"flag"`
  23. Seq uint16 `json:"seq"`
  24. Data []byte `json:"data"`
  25. Error string `json:"error"`
  26. Timeout int64 `json:"timeout"`
  27. Timestamp int64 `json:"timestamp"`
  28. }
  29. )
  30. func readFrame(r io.Reader) (frame *Frame, err error) {
  31. var (
  32. n int
  33. dataLength uint16
  34. errorLength uint16
  35. errBuf []byte
  36. )
  37. frame = &Frame{Feature: make([]byte, 3)}
  38. if _, err = io.ReadFull(r, frame.Feature); err != nil {
  39. return
  40. }
  41. if !bytes.Equal(frame.Feature, Feature) {
  42. err = io.ErrUnexpectedEOF
  43. return
  44. }
  45. if err = binary.Read(r, binary.LittleEndian, &frame.Type); err != nil {
  46. return
  47. }
  48. if err = binary.Read(r, binary.LittleEndian, &frame.Flag); err != nil {
  49. return
  50. }
  51. if err = binary.Read(r, binary.LittleEndian, &frame.Seq); err != nil {
  52. return
  53. }
  54. if err = binary.Read(r, binary.LittleEndian, &frame.Timeout); err != nil {
  55. return
  56. }
  57. if err = binary.Read(r, binary.LittleEndian, &frame.Timestamp); err != nil {
  58. return
  59. }
  60. if err = binary.Read(r, binary.LittleEndian, &dataLength); err != nil {
  61. return
  62. }
  63. if err = binary.Read(r, binary.LittleEndian, &errorLength); err != nil {
  64. return
  65. }
  66. if dataLength > 0 {
  67. frame.Data = make([]byte, dataLength)
  68. if n, err = io.ReadFull(r, frame.Data); err == nil {
  69. if n < int(dataLength) {
  70. err = io.ErrShortBuffer
  71. }
  72. }
  73. }
  74. if errorLength > 0 {
  75. errBuf = make([]byte, errorLength)
  76. if n, err = io.ReadFull(r, errBuf); err == nil {
  77. if n < int(dataLength) {
  78. err = io.ErrShortBuffer
  79. } else {
  80. frame.Error = string(errBuf)
  81. }
  82. }
  83. }
  84. return
  85. }
  86. func writeFrame(w io.Writer, frame *Frame) (err error) {
  87. var (
  88. n int
  89. dl int
  90. dataLength uint16
  91. errorLength uint16
  92. errBuf []byte
  93. )
  94. if _, err = w.Write(Feature); err != nil {
  95. return
  96. }
  97. if frame.Data != nil {
  98. dl = len(frame.Data)
  99. if dl > math.MaxUint16 {
  100. return io.ErrNoProgress
  101. }
  102. dataLength = uint16(dl)
  103. }
  104. if frame.Error != "" {
  105. errBuf = []byte(frame.Error)
  106. errorLength = uint16(len(errBuf))
  107. }
  108. if err = binary.Write(w, binary.LittleEndian, frame.Type); err != nil {
  109. return
  110. }
  111. if err = binary.Write(w, binary.LittleEndian, frame.Flag); err != nil {
  112. return
  113. }
  114. if err = binary.Write(w, binary.LittleEndian, frame.Seq); err != nil {
  115. return
  116. }
  117. if err = binary.Write(w, binary.LittleEndian, frame.Timeout); err != nil {
  118. return
  119. }
  120. if err = binary.Write(w, binary.LittleEndian, frame.Timestamp); err != nil {
  121. return
  122. }
  123. if err = binary.Write(w, binary.LittleEndian, dataLength); err != nil {
  124. return
  125. }
  126. if err = binary.Write(w, binary.LittleEndian, errorLength); err != nil {
  127. return
  128. }
  129. if dataLength > 0 {
  130. if n, err = w.Write(frame.Data); err == nil {
  131. if n < int(dataLength) {
  132. err = io.ErrShortWrite
  133. }
  134. }
  135. }
  136. if errorLength > 0 {
  137. if n, err = w.Write(errBuf); err == nil {
  138. if n < int(errorLength) {
  139. err = io.ErrShortWrite
  140. }
  141. }
  142. }
  143. return
  144. }
  145. func newFrame(t, f byte, seq uint16, timeout time.Duration, data []byte) *Frame {
  146. return &Frame{
  147. Feature: Feature,
  148. Type: t,
  149. Flag: f,
  150. Seq: seq,
  151. Data: data,
  152. Timeout: int64(timeout),
  153. Timestamp: time.Now().Unix(),
  154. }
  155. }