binary.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. package gocql
  2. import (
  3. "errors"
  4. "net"
  5. )
  6. const (
  7. protoRequest byte = 0x02
  8. protoResponse byte = 0x82
  9. opError byte = 0x00
  10. opStartup byte = 0x01
  11. opReady byte = 0x02
  12. opAuthenticate byte = 0x03
  13. opOptions byte = 0x05
  14. opSupported byte = 0x06
  15. opQuery byte = 0x07
  16. opResult byte = 0x08
  17. opPrepare byte = 0x09
  18. opExecute byte = 0x0A
  19. opRegister byte = 0x0B
  20. opEvent byte = 0x0C
  21. opBatch byte = 0x0D
  22. opAuthChallenge byte = 0x0E
  23. opAuthResponse byte = 0x0F
  24. opAuthSuccess byte = 0x10
  25. resultKindVoid = 1
  26. resultKindRows = 2
  27. resultKindKeyspace = 3
  28. resultKindPrepared = 4
  29. resultKindSchemaChanged = 5
  30. flagQueryValues uint8 = 1
  31. headerSize = 8
  32. )
  33. var ErrInvalid = errors.New("invalid response")
  34. type buffer []byte
  35. func (b *buffer) writeInt(v int32) {
  36. p := b.grow(4)
  37. (*b)[p] = byte(v >> 24)
  38. (*b)[p+1] = byte(v >> 16)
  39. (*b)[p+2] = byte(v >> 8)
  40. (*b)[p+3] = byte(v)
  41. }
  42. func (b *buffer) writeShort(v uint16) {
  43. p := b.grow(2)
  44. (*b)[p] = byte(v >> 8)
  45. (*b)[p+1] = byte(v)
  46. }
  47. func (b *buffer) writeString(v string) {
  48. b.writeShort(uint16(len(v)))
  49. p := b.grow(len(v))
  50. copy((*b)[p:], v)
  51. }
  52. func (b *buffer) writeLongString(v string) {
  53. b.writeInt(int32(len(v)))
  54. p := b.grow(len(v))
  55. copy((*b)[p:], v)
  56. }
  57. func (b *buffer) writeUUID() {
  58. }
  59. func (b *buffer) writeStringList(v []string) {
  60. b.writeShort(uint16(len(v)))
  61. for i := range v {
  62. b.writeString(v[i])
  63. }
  64. }
  65. func (b *buffer) writeByte(v byte) {
  66. p := b.grow(1)
  67. (*b)[p] = v
  68. }
  69. func (b *buffer) writeBytes(v []byte) {
  70. if v == nil {
  71. b.writeInt(-1)
  72. return
  73. }
  74. b.writeInt(int32(len(v)))
  75. p := b.grow(len(v))
  76. copy((*b)[p:], v)
  77. }
  78. func (b *buffer) writeShortBytes(v []byte) {
  79. b.writeShort(uint16(len(v)))
  80. p := b.grow(len(v))
  81. copy((*b)[p:], v)
  82. }
  83. func (b *buffer) writeInet(ip net.IP, port int) {
  84. p := b.grow(1 + len(ip))
  85. (*b)[p] = byte(len(ip))
  86. copy((*b)[p+1:], ip)
  87. b.writeInt(int32(port))
  88. }
  89. func (b *buffer) writeConsistency() {
  90. }
  91. func (b *buffer) writeStringMap(v map[string]string) {
  92. b.writeShort(uint16(len(v)))
  93. for key, value := range v {
  94. b.writeString(key)
  95. b.writeString(value)
  96. }
  97. }
  98. func (b *buffer) writeStringMultimap(v map[string][]string) {
  99. b.writeShort(uint16(len(v)))
  100. for key, values := range v {
  101. b.writeString(key)
  102. b.writeStringList(values)
  103. }
  104. }
  105. func (b *buffer) setHeader(version, flags, stream, opcode uint8) {
  106. (*b)[0] = version
  107. (*b)[1] = flags
  108. (*b)[2] = stream
  109. (*b)[3] = opcode
  110. }
  111. func (b *buffer) setLength(length int) {
  112. (*b)[4] = byte(length >> 24)
  113. (*b)[5] = byte(length >> 16)
  114. (*b)[6] = byte(length >> 8)
  115. (*b)[7] = byte(length)
  116. }
  117. func (b *buffer) Length() int {
  118. return int((*b)[4])<<24 | int((*b)[5])<<16 | int((*b)[6])<<8 | int((*b)[7])
  119. }
  120. func (b *buffer) grow(n int) int {
  121. if len(*b)+n >= cap(*b) {
  122. buf := make(buffer, len(*b), len(*b)*2+n)
  123. copy(buf, *b)
  124. *b = buf
  125. }
  126. p := len(*b)
  127. *b = (*b)[:p+n]
  128. return p
  129. }
  130. func (b *buffer) skipHeader() {
  131. *b = (*b)[headerSize:]
  132. }
  133. func (b *buffer) readInt() int {
  134. if len(*b) < 4 {
  135. panic(ErrInvalid)
  136. }
  137. v := int((*b)[0])<<24 | int((*b)[1])<<16 | int((*b)[2])<<8 | int((*b)[3])
  138. *b = (*b)[4:]
  139. return v
  140. }
  141. func (b *buffer) readShort() uint16 {
  142. if len(*b) < 2 {
  143. panic(ErrInvalid)
  144. }
  145. v := uint16((*b)[0])<<8 | uint16((*b)[1])
  146. *b = (*b)[2:]
  147. return v
  148. }
  149. func (b *buffer) readString() string {
  150. n := int(b.readShort())
  151. if len(*b) < n {
  152. panic(ErrInvalid)
  153. }
  154. v := string((*b)[:n])
  155. *b = (*b)[n:]
  156. return v
  157. }
  158. func (b *buffer) readBytes() []byte {
  159. n := b.readInt()
  160. if n < 0 {
  161. return nil
  162. }
  163. if len(*b) < n {
  164. panic(ErrInvalid)
  165. }
  166. v := (*b)[:n]
  167. *b = (*b)[n:]
  168. return v
  169. }
  170. func (b *buffer) readShortBytes() []byte {
  171. n := int(b.readShort())
  172. if len(*b) < n {
  173. panic(ErrInvalid)
  174. }
  175. v := (*b)[:n]
  176. *b = (*b)[n:]
  177. return v
  178. }
  179. func (b *buffer) readTypeInfo() *TypeInfo {
  180. x := b.readShort()
  181. typ := &TypeInfo{Type: Type(x)}
  182. switch typ.Type {
  183. case TypeCustom:
  184. typ.Custom = b.readString()
  185. case TypeMap:
  186. typ.Key = b.readTypeInfo()
  187. fallthrough
  188. case TypeList, TypeSet:
  189. typ.Value = b.readTypeInfo()
  190. }
  191. return typ
  192. }
  193. func (b *buffer) readMetaData() []columnInfo {
  194. flags := b.readInt()
  195. numColumns := b.readInt()
  196. globalKeyspace := ""
  197. globalTable := ""
  198. if flags&1 != 0 {
  199. globalKeyspace = b.readString()
  200. globalTable = b.readString()
  201. }
  202. info := make([]columnInfo, numColumns)
  203. for i := 0; i < numColumns; i++ {
  204. info[i].Keyspace = globalKeyspace
  205. info[i].Table = globalTable
  206. if flags&1 == 0 {
  207. info[i].Keyspace = b.readString()
  208. info[i].Table = b.readString()
  209. }
  210. info[i].Name = b.readString()
  211. info[i].TypeInfo = b.readTypeInfo()
  212. }
  213. return info
  214. }