context.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package cli
  2. import (
  3. "context"
  4. "fmt"
  5. "io"
  6. "math"
  7. "sync"
  8. )
  9. type Context struct {
  10. Id int64
  11. seq uint16
  12. ctx context.Context
  13. wc io.WriteCloser
  14. params map[string]string
  15. locker sync.RWMutex
  16. variables map[string]any
  17. args []string
  18. }
  19. func (ctx *Context) reset(id int64, wc io.WriteCloser) {
  20. ctx.Id = id
  21. ctx.wc = wc
  22. ctx.seq = 0
  23. ctx.ctx = context.Background()
  24. ctx.args = make([]string, 0)
  25. ctx.params = make(map[string]string)
  26. ctx.variables = make(map[string]any)
  27. }
  28. func (ctx *Context) setArgs(args []string) {
  29. ctx.args = args
  30. }
  31. func (ctx *Context) setParam(ps map[string]string) {
  32. ctx.params = ps
  33. }
  34. func (ctx *Context) Bind(v any) (err error) {
  35. return
  36. }
  37. func (ctx *Context) setContext(c context.Context) {
  38. ctx.ctx = c
  39. }
  40. func (ctx *Context) Context() context.Context {
  41. return ctx.ctx
  42. }
  43. func (ctx *Context) Argument(index int) string {
  44. if index >= len(ctx.args) || index < 0 {
  45. return ""
  46. }
  47. return ctx.args[index]
  48. }
  49. func (ctx *Context) Param(s string) string {
  50. if v, ok := ctx.params[s]; ok {
  51. return v
  52. }
  53. return ""
  54. }
  55. func (ctx *Context) SetValue(name string, value any) {
  56. ctx.locker.Lock()
  57. if ctx.variables == nil {
  58. ctx.variables = make(map[string]any)
  59. }
  60. ctx.variables[name] = value
  61. ctx.locker.Unlock()
  62. }
  63. func (ctx *Context) GetValue(name string) (val any, ok bool) {
  64. ctx.locker.RLock()
  65. defer ctx.locker.RUnlock()
  66. val, ok = ctx.variables[name]
  67. return
  68. }
  69. func (ctx *Context) Success(v any) (err error) {
  70. return ctx.send(responsePayload{Type: PacketTypeCommand, Data: v})
  71. }
  72. func (ctx *Context) Error(code int, reason string) (err error) {
  73. return ctx.send(responsePayload{Type: PacketTypeCommand, Code: code, Reason: reason})
  74. }
  75. func (ctx *Context) Close() (err error) {
  76. return ctx.wc.Close()
  77. }
  78. func (ctx *Context) send(res responsePayload) (err error) {
  79. var (
  80. ok bool
  81. buf []byte
  82. marshal encoder
  83. )
  84. if res.Code > 0 {
  85. err = writeFrame(ctx.wc, &Frame{
  86. Feature: Feature,
  87. Type: res.Type,
  88. Seq: ctx.seq,
  89. Flag: FlagComplete,
  90. Error: fmt.Sprintf("ERROR(%d): %s", res.Code, res.Reason),
  91. })
  92. return
  93. }
  94. if res.Data == nil {
  95. buf = OK
  96. goto __END
  97. }
  98. if marshal, ok = res.Data.(encoder); ok {
  99. buf, err = marshal.Marshal()
  100. goto __END
  101. }
  102. buf, err = serialize(res.Data)
  103. __END:
  104. if err != nil {
  105. return
  106. }
  107. offset := 0
  108. chunkSize := math.MaxInt16 - 1
  109. n := len(buf) / chunkSize
  110. for i := 0; i < n; i++ {
  111. if err = writeFrame(ctx.wc, newFrame(res.Type, FlagPortion, ctx.seq, 0, buf[offset:chunkSize+offset])); err != nil {
  112. return
  113. }
  114. offset += chunkSize
  115. }
  116. err = writeFrame(ctx.wc, newFrame(res.Type, FlagComplete, ctx.seq, 0, buf[offset:]))
  117. return
  118. }
  119. func newContext(id int64, wc io.WriteCloser) *Context {
  120. return &Context{
  121. Id: id,
  122. wc: wc,
  123. }
  124. }