parser.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. package redis
  2. import (
  3. "fmt"
  4. "net"
  5. "strconv"
  6. "time"
  7. "github.com/go-redis/redis/internal/proto"
  8. )
  9. // Implements proto.MultiBulkParse
  10. func sliceParser(rd *proto.Reader, n int64) (interface{}, error) {
  11. vals := make([]interface{}, 0, n)
  12. for i := int64(0); i < n; i++ {
  13. v, err := rd.ReadReply(sliceParser)
  14. if err != nil {
  15. if err == Nil {
  16. vals = append(vals, nil)
  17. continue
  18. }
  19. if err, ok := err.(proto.RedisError); ok {
  20. vals = append(vals, err)
  21. continue
  22. }
  23. return nil, err
  24. }
  25. switch v := v.(type) {
  26. case []byte:
  27. vals = append(vals, string(v))
  28. default:
  29. vals = append(vals, v)
  30. }
  31. }
  32. return vals, nil
  33. }
  34. // Implements proto.MultiBulkParse
  35. func boolSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
  36. bools := make([]bool, 0, n)
  37. for i := int64(0); i < n; i++ {
  38. n, err := rd.ReadIntReply()
  39. if err != nil {
  40. return nil, err
  41. }
  42. bools = append(bools, n == 1)
  43. }
  44. return bools, nil
  45. }
  46. // Implements proto.MultiBulkParse
  47. func stringSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
  48. ss := make([]string, 0, n)
  49. for i := int64(0); i < n; i++ {
  50. s, err := rd.ReadStringReply()
  51. if err == Nil {
  52. ss = append(ss, "")
  53. } else if err != nil {
  54. return nil, err
  55. } else {
  56. ss = append(ss, s)
  57. }
  58. }
  59. return ss, nil
  60. }
  61. // Implements proto.MultiBulkParse
  62. func stringStringMapParser(rd *proto.Reader, n int64) (interface{}, error) {
  63. m := make(map[string]string, n/2)
  64. for i := int64(0); i < n; i += 2 {
  65. key, err := rd.ReadStringReply()
  66. if err != nil {
  67. return nil, err
  68. }
  69. value, err := rd.ReadStringReply()
  70. if err != nil {
  71. return nil, err
  72. }
  73. m[key] = value
  74. }
  75. return m, nil
  76. }
  77. // Implements proto.MultiBulkParse
  78. func stringIntMapParser(rd *proto.Reader, n int64) (interface{}, error) {
  79. m := make(map[string]int64, n/2)
  80. for i := int64(0); i < n; i += 2 {
  81. key, err := rd.ReadStringReply()
  82. if err != nil {
  83. return nil, err
  84. }
  85. n, err := rd.ReadIntReply()
  86. if err != nil {
  87. return nil, err
  88. }
  89. m[key] = n
  90. }
  91. return m, nil
  92. }
  93. // Implements proto.MultiBulkParse
  94. func stringStructMapParser(rd *proto.Reader, n int64) (interface{}, error) {
  95. m := make(map[string]struct{}, n)
  96. for i := int64(0); i < n; i++ {
  97. key, err := rd.ReadStringReply()
  98. if err != nil {
  99. return nil, err
  100. }
  101. m[key] = struct{}{}
  102. }
  103. return m, nil
  104. }
  105. // Implements proto.MultiBulkParse
  106. func zSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
  107. zz := make([]Z, n/2)
  108. for i := int64(0); i < n; i += 2 {
  109. var err error
  110. z := &zz[i/2]
  111. z.Member, err = rd.ReadStringReply()
  112. if err != nil {
  113. return nil, err
  114. }
  115. z.Score, err = rd.ReadFloatReply()
  116. if err != nil {
  117. return nil, err
  118. }
  119. }
  120. return zz, nil
  121. }
  122. // Implements proto.MultiBulkParse
  123. func clusterSlotsParser(rd *proto.Reader, n int64) (interface{}, error) {
  124. slots := make([]ClusterSlot, n)
  125. for i := 0; i < len(slots); i++ {
  126. n, err := rd.ReadArrayLen()
  127. if err != nil {
  128. return nil, err
  129. }
  130. if n < 2 {
  131. err := fmt.Errorf("redis: got %d elements in cluster info, expected at least 2", n)
  132. return nil, err
  133. }
  134. start, err := rd.ReadIntReply()
  135. if err != nil {
  136. return nil, err
  137. }
  138. end, err := rd.ReadIntReply()
  139. if err != nil {
  140. return nil, err
  141. }
  142. nodes := make([]ClusterNode, n-2)
  143. for j := 0; j < len(nodes); j++ {
  144. n, err := rd.ReadArrayLen()
  145. if err != nil {
  146. return nil, err
  147. }
  148. if n != 2 && n != 3 {
  149. err := fmt.Errorf("got %d elements in cluster info address, expected 2 or 3", n)
  150. return nil, err
  151. }
  152. ip, err := rd.ReadStringReply()
  153. if err != nil {
  154. return nil, err
  155. }
  156. port, err := rd.ReadIntReply()
  157. if err != nil {
  158. return nil, err
  159. }
  160. nodes[j].Addr = net.JoinHostPort(ip, strconv.FormatInt(port, 10))
  161. if n == 3 {
  162. id, err := rd.ReadStringReply()
  163. if err != nil {
  164. return nil, err
  165. }
  166. nodes[j].Id = id
  167. }
  168. }
  169. slots[i] = ClusterSlot{
  170. Start: int(start),
  171. End: int(end),
  172. Nodes: nodes,
  173. }
  174. }
  175. return slots, nil
  176. }
  177. func newGeoLocationParser(q *GeoRadiusQuery) proto.MultiBulkParse {
  178. return func(rd *proto.Reader, n int64) (interface{}, error) {
  179. var loc GeoLocation
  180. var err error
  181. loc.Name, err = rd.ReadStringReply()
  182. if err != nil {
  183. return nil, err
  184. }
  185. if q.WithDist {
  186. loc.Dist, err = rd.ReadFloatReply()
  187. if err != nil {
  188. return nil, err
  189. }
  190. }
  191. if q.WithGeoHash {
  192. loc.GeoHash, err = rd.ReadIntReply()
  193. if err != nil {
  194. return nil, err
  195. }
  196. }
  197. if q.WithCoord {
  198. n, err := rd.ReadArrayLen()
  199. if err != nil {
  200. return nil, err
  201. }
  202. if n != 2 {
  203. return nil, fmt.Errorf("got %d coordinates, expected 2", n)
  204. }
  205. loc.Longitude, err = rd.ReadFloatReply()
  206. if err != nil {
  207. return nil, err
  208. }
  209. loc.Latitude, err = rd.ReadFloatReply()
  210. if err != nil {
  211. return nil, err
  212. }
  213. }
  214. return &loc, nil
  215. }
  216. }
  217. func newGeoLocationSliceParser(q *GeoRadiusQuery) proto.MultiBulkParse {
  218. return func(rd *proto.Reader, n int64) (interface{}, error) {
  219. locs := make([]GeoLocation, 0, n)
  220. for i := int64(0); i < n; i++ {
  221. v, err := rd.ReadReply(newGeoLocationParser(q))
  222. if err != nil {
  223. return nil, err
  224. }
  225. switch vv := v.(type) {
  226. case []byte:
  227. locs = append(locs, GeoLocation{
  228. Name: string(vv),
  229. })
  230. case *GeoLocation:
  231. locs = append(locs, *vv)
  232. default:
  233. return nil, fmt.Errorf("got %T, expected string or *GeoLocation", v)
  234. }
  235. }
  236. return locs, nil
  237. }
  238. }
  239. func geoPosParser(rd *proto.Reader, n int64) (interface{}, error) {
  240. var pos GeoPos
  241. var err error
  242. pos.Longitude, err = rd.ReadFloatReply()
  243. if err != nil {
  244. return nil, err
  245. }
  246. pos.Latitude, err = rd.ReadFloatReply()
  247. if err != nil {
  248. return nil, err
  249. }
  250. return &pos, nil
  251. }
  252. func geoPosSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
  253. positions := make([]*GeoPos, 0, n)
  254. for i := int64(0); i < n; i++ {
  255. v, err := rd.ReadReply(geoPosParser)
  256. if err != nil {
  257. if err == Nil {
  258. positions = append(positions, nil)
  259. continue
  260. }
  261. return nil, err
  262. }
  263. switch v := v.(type) {
  264. case *GeoPos:
  265. positions = append(positions, v)
  266. default:
  267. return nil, fmt.Errorf("got %T, expected *GeoPos", v)
  268. }
  269. }
  270. return positions, nil
  271. }
  272. func commandInfoParser(rd *proto.Reader, n int64) (interface{}, error) {
  273. var cmd CommandInfo
  274. var err error
  275. if n != 6 {
  276. return nil, fmt.Errorf("redis: got %d elements in COMMAND reply, wanted 6", n)
  277. }
  278. cmd.Name, err = rd.ReadStringReply()
  279. if err != nil {
  280. return nil, err
  281. }
  282. arity, err := rd.ReadIntReply()
  283. if err != nil {
  284. return nil, err
  285. }
  286. cmd.Arity = int8(arity)
  287. flags, err := rd.ReadReply(stringSliceParser)
  288. if err != nil {
  289. return nil, err
  290. }
  291. cmd.Flags = flags.([]string)
  292. firstKeyPos, err := rd.ReadIntReply()
  293. if err != nil {
  294. return nil, err
  295. }
  296. cmd.FirstKeyPos = int8(firstKeyPos)
  297. lastKeyPos, err := rd.ReadIntReply()
  298. if err != nil {
  299. return nil, err
  300. }
  301. cmd.LastKeyPos = int8(lastKeyPos)
  302. stepCount, err := rd.ReadIntReply()
  303. if err != nil {
  304. return nil, err
  305. }
  306. cmd.StepCount = int8(stepCount)
  307. for _, flag := range cmd.Flags {
  308. if flag == "readonly" {
  309. cmd.ReadOnly = true
  310. break
  311. }
  312. }
  313. return &cmd, nil
  314. }
  315. // Implements proto.MultiBulkParse
  316. func commandInfoSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
  317. m := make(map[string]*CommandInfo, n)
  318. for i := int64(0); i < n; i++ {
  319. v, err := rd.ReadReply(commandInfoParser)
  320. if err != nil {
  321. return nil, err
  322. }
  323. vv := v.(*CommandInfo)
  324. m[vv.Name] = vv
  325. }
  326. return m, nil
  327. }
  328. // Implements proto.MultiBulkParse
  329. func timeParser(rd *proto.Reader, n int64) (interface{}, error) {
  330. if n != 2 {
  331. return nil, fmt.Errorf("got %d elements, expected 2", n)
  332. }
  333. sec, err := rd.ReadInt()
  334. if err != nil {
  335. return nil, err
  336. }
  337. microsec, err := rd.ReadInt()
  338. if err != nil {
  339. return nil, err
  340. }
  341. return time.Unix(sec, microsec*1000), nil
  342. }