codecs.go 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. package native
  2. import (
  3. "github.com/ziutek/mymysql/mysql"
  4. "time"
  5. )
  6. // Integers
  7. func DecodeU16(buf []byte) uint16 {
  8. return uint16(buf[1])<<8 | uint16(buf[0])
  9. }
  10. func (pr *pktReader) readU16() uint16 {
  11. buf := pr.buf[:2]
  12. pr.readFull(buf)
  13. return DecodeU16(buf)
  14. }
  15. func DecodeU24(buf []byte) uint32 {
  16. return (uint32(buf[2])<<8|uint32(buf[1]))<<8 | uint32(buf[0])
  17. }
  18. func (pr *pktReader) readU24() uint32 {
  19. buf := pr.buf[:3]
  20. pr.readFull(buf)
  21. return DecodeU24(buf)
  22. }
  23. func DecodeU32(buf []byte) uint32 {
  24. return ((uint32(buf[3])<<8|uint32(buf[2]))<<8|
  25. uint32(buf[1]))<<8 | uint32(buf[0])
  26. }
  27. func (pr *pktReader) readU32() uint32 {
  28. buf := pr.buf[:4]
  29. pr.readFull(buf)
  30. return DecodeU32(buf)
  31. }
  32. func DecodeU64(buf []byte) (rv uint64) {
  33. for ii, vv := range buf {
  34. rv |= uint64(vv) << uint(ii*8)
  35. }
  36. return
  37. }
  38. func (pr *pktReader) readU64() (rv uint64) {
  39. buf := pr.buf[:8]
  40. pr.readFull(buf)
  41. return DecodeU64(buf)
  42. }
  43. func EncodeU16(buf []byte, val uint16) {
  44. buf[0] = byte(val)
  45. buf[1] = byte(val >> 8)
  46. }
  47. func (pw *pktWriter) writeU16(val uint16) {
  48. buf := pw.buf[:2]
  49. EncodeU16(buf, val)
  50. pw.write(buf)
  51. }
  52. func EncodeU24(buf []byte, val uint32) {
  53. buf[0] = byte(val)
  54. buf[1] = byte(val >> 8)
  55. buf[2] = byte(val >> 16)
  56. }
  57. func (pw *pktWriter) writeU24(val uint32) {
  58. buf := pw.buf[:3]
  59. EncodeU24(buf, val)
  60. pw.write(buf)
  61. }
  62. func EncodeU32(buf []byte, val uint32) {
  63. buf[0] = byte(val)
  64. buf[1] = byte(val >> 8)
  65. buf[2] = byte(val >> 16)
  66. buf[3] = byte(val >> 24)
  67. }
  68. func (pw *pktWriter) writeU32(val uint32) {
  69. buf := pw.buf[:4]
  70. EncodeU32(buf, val)
  71. pw.write(buf)
  72. }
  73. func EncodeU64(buf []byte, val uint64) {
  74. buf[0] = byte(val)
  75. buf[1] = byte(val >> 8)
  76. buf[2] = byte(val >> 16)
  77. buf[3] = byte(val >> 24)
  78. buf[4] = byte(val >> 32)
  79. buf[5] = byte(val >> 40)
  80. buf[6] = byte(val >> 48)
  81. buf[7] = byte(val >> 56)
  82. }
  83. func (pw *pktWriter) writeU64(val uint64) {
  84. buf := pw.buf[:8]
  85. EncodeU64(buf, val)
  86. pw.write(buf)
  87. }
  88. // Variable length values
  89. func (pr *pktReader) readNullLCB() (lcb uint64, null bool) {
  90. bb := pr.readByte()
  91. switch bb {
  92. case 251:
  93. null = true
  94. case 252:
  95. lcb = uint64(pr.readU16())
  96. case 253:
  97. lcb = uint64(pr.readU24())
  98. case 254:
  99. lcb = pr.readU64()
  100. default:
  101. lcb = uint64(bb)
  102. }
  103. return
  104. }
  105. func (pr *pktReader) readLCB() uint64 {
  106. lcb, null := pr.readNullLCB()
  107. if null {
  108. panic(mysql.ErrUnexpNullLCB)
  109. }
  110. return lcb
  111. }
  112. func (pw *pktWriter) writeLCB(val uint64) {
  113. switch {
  114. case val <= 250:
  115. pw.writeByte(byte(val))
  116. case val <= 0xffff:
  117. pw.writeByte(252)
  118. pw.writeU16(uint16(val))
  119. case val <= 0xffffff:
  120. pw.writeByte(253)
  121. pw.writeU24(uint32(val))
  122. default:
  123. pw.writeByte(254)
  124. pw.writeU64(val)
  125. }
  126. }
  127. func lenLCB(val uint64) int {
  128. switch {
  129. case val <= 250:
  130. return 1
  131. case val <= 0xffff:
  132. return 3
  133. case val <= 0xffffff:
  134. return 4
  135. }
  136. return 9
  137. }
  138. func (pr *pktReader) readNullBin() (buf []byte, null bool) {
  139. var l uint64
  140. l, null = pr.readNullLCB()
  141. if null {
  142. return
  143. }
  144. buf = make([]byte, l)
  145. pr.readFull(buf)
  146. return
  147. }
  148. func (pr *pktReader) readBin() []byte {
  149. buf, null := pr.readNullBin()
  150. if null {
  151. panic(mysql.ErrUnexpNullLCS)
  152. }
  153. return buf
  154. }
  155. func (pr *pktReader) skipBin() {
  156. n, _ := pr.readNullLCB()
  157. pr.skipN(int(n))
  158. }
  159. func (pw *pktWriter) writeBin(buf []byte) {
  160. pw.writeLCB(uint64(len(buf)))
  161. pw.write(buf)
  162. }
  163. func lenBin(buf []byte) int {
  164. return lenLCB(uint64(len(buf))) + len(buf)
  165. }
  166. func lenStr(str string) int {
  167. return lenLCB(uint64(len(str))) + len(str)
  168. }
  169. func (pw *pktWriter) writeLC(v interface{}) {
  170. switch val := v.(type) {
  171. case []byte:
  172. pw.writeBin(val)
  173. case *[]byte:
  174. pw.writeBin(*val)
  175. case string:
  176. pw.writeBin([]byte(val))
  177. case *string:
  178. pw.writeBin([]byte(*val))
  179. default:
  180. panic("Unknown data type for write as length coded string")
  181. }
  182. }
  183. func lenLC(v interface{}) int {
  184. switch val := v.(type) {
  185. case []byte:
  186. return lenBin(val)
  187. case *[]byte:
  188. return lenBin(*val)
  189. case string:
  190. return lenStr(val)
  191. case *string:
  192. return lenStr(*val)
  193. }
  194. panic("Unknown data type for write as length coded string")
  195. }
  196. func (pr *pktReader) readNTB() (buf []byte) {
  197. for {
  198. ch := pr.readByte()
  199. if ch == 0 {
  200. break
  201. }
  202. buf = append(buf, ch)
  203. }
  204. return
  205. }
  206. func (pw *pktWriter) writeNTB(buf []byte) {
  207. pw.write(buf)
  208. pw.writeByte(0)
  209. }
  210. func (pw *pktWriter) writeNT(v interface{}) {
  211. switch val := v.(type) {
  212. case []byte:
  213. pw.writeNTB(val)
  214. case string:
  215. pw.writeNTB([]byte(val))
  216. default:
  217. panic("Unknown type for write as null terminated data")
  218. }
  219. }
  220. // Date and time
  221. func (pr *pktReader) readDuration() time.Duration {
  222. dlen := pr.readByte()
  223. switch dlen {
  224. case 251:
  225. // Null
  226. panic(mysql.ErrUnexpNullTime)
  227. case 0:
  228. // 00:00:00
  229. return 0
  230. case 5, 8, 12:
  231. // Properly time length
  232. default:
  233. panic(mysql.ErrWrongDateLen)
  234. }
  235. buf := pr.buf[:dlen]
  236. pr.readFull(buf)
  237. tt := int64(0)
  238. switch dlen {
  239. case 12:
  240. // Nanosecond part
  241. tt += int64(DecodeU32(buf[8:]))
  242. fallthrough
  243. case 8:
  244. // HH:MM:SS part
  245. tt += int64(int(buf[5])*3600+int(buf[6])*60+int(buf[7])) * 1e9
  246. fallthrough
  247. case 5:
  248. // Day part
  249. tt += int64(DecodeU32(buf[1:5])) * (24 * 3600 * 1e9)
  250. }
  251. if buf[0] != 0 {
  252. tt = -tt
  253. }
  254. return time.Duration(tt)
  255. }
  256. func EncodeDuration(buf []byte, d time.Duration) int {
  257. buf[0] = 0
  258. if d < 0 {
  259. buf[1] = 1
  260. d = -d
  261. }
  262. if ns := uint32(d % 1e9); ns != 0 {
  263. EncodeU32(buf[9:13], ns) // nanosecond
  264. buf[0] += 4
  265. }
  266. d /= 1e9
  267. if hms := int(d % (24 * 3600)); buf[0] != 0 || hms != 0 {
  268. buf[8] = byte(hms % 60) // second
  269. hms /= 60
  270. buf[7] = byte(hms % 60) // minute
  271. buf[6] = byte(hms / 60) // hour
  272. buf[0] += 3
  273. }
  274. if day := uint32(d / (24 * 3600)); buf[0] != 0 || day != 0 {
  275. EncodeU32(buf[2:6], day) // day
  276. buf[0] += 4
  277. }
  278. buf[0]++ // For sign byte
  279. return int(buf[0] + 1)
  280. }
  281. func (pw *pktWriter) writeDuration(d time.Duration) {
  282. buf := pw.buf[:13]
  283. n := EncodeDuration(buf, d)
  284. pw.write(buf[:n])
  285. }
  286. func lenDuration(d time.Duration) int {
  287. if d == 0 {
  288. return 2
  289. }
  290. if d%1e9 != 0 {
  291. return 13
  292. }
  293. d /= 1e9
  294. if d%(24*3600) != 0 {
  295. return 9
  296. }
  297. return 6
  298. }
  299. func (pr *pktReader) readTime() time.Time {
  300. dlen := pr.readByte()
  301. switch dlen {
  302. case 251:
  303. // Null
  304. panic(mysql.ErrUnexpNullDate)
  305. case 0:
  306. // return 0000-00-00 converted to time.Time zero
  307. return time.Time{}
  308. case 4, 7, 11:
  309. // Properly datetime length
  310. default:
  311. panic(mysql.ErrWrongDateLen)
  312. }
  313. buf := pr.buf[:dlen]
  314. pr.readFull(buf)
  315. var y, mon, d, h, m, s, u int
  316. switch dlen {
  317. case 11:
  318. // 2006-01-02 15:04:05.001004005
  319. u = int(DecodeU32(buf[7:]))
  320. fallthrough
  321. case 7:
  322. // 2006-01-02 15:04:05
  323. h = int(buf[4])
  324. m = int(buf[5])
  325. s = int(buf[6])
  326. fallthrough
  327. case 4:
  328. // 2006-01-02
  329. y = int(DecodeU16(buf[0:2]))
  330. mon = int(buf[2])
  331. d = int(buf[3])
  332. }
  333. n := u * int(time.Microsecond)
  334. return time.Date(y, time.Month(mon), d, h, m, s, n, time.Local)
  335. }
  336. func encodeNonzeroTime(buf []byte, y int16, mon, d, h, m, s byte, u uint32) int {
  337. buf[0] = 0
  338. switch {
  339. case u != 0:
  340. EncodeU32(buf[8:12], u)
  341. buf[0] += 4
  342. fallthrough
  343. case s != 0 || m != 0 || h != 0:
  344. buf[7] = s
  345. buf[6] = m
  346. buf[5] = h
  347. buf[0] += 3
  348. }
  349. buf[4] = d
  350. buf[3] = mon
  351. EncodeU16(buf[1:3], uint16(y))
  352. buf[0] += 4
  353. return int(buf[0] + 1)
  354. }
  355. func getTimeMicroseconds(t time.Time) int {
  356. return (t.Nanosecond() + int(time.Microsecond/2)) / int(time.Microsecond)
  357. }
  358. func EncodeTime(buf []byte, t time.Time) int {
  359. if t.IsZero() {
  360. // MySQL zero
  361. buf[0] = 0
  362. return 1 // MySQL zero
  363. }
  364. y, mon, d := t.Date()
  365. h, m, s := t.Clock()
  366. u:= getTimeMicroseconds(t)
  367. return encodeNonzeroTime(
  368. buf,
  369. int16(y), byte(mon), byte(d),
  370. byte(h), byte(m), byte(s), uint32(u),
  371. )
  372. }
  373. func (pw *pktWriter) writeTime(t time.Time) {
  374. buf := pw.buf[:12]
  375. n := EncodeTime(buf, t)
  376. pw.write(buf[:n])
  377. }
  378. func lenTime(t time.Time) int {
  379. switch {
  380. case t.IsZero():
  381. return 1
  382. case getTimeMicroseconds(t) != 0:
  383. return 12
  384. case t.Second() != 0 || t.Minute() != 0 || t.Hour() != 0:
  385. return 8
  386. }
  387. return 5
  388. }
  389. func (pr *pktReader) readDate() mysql.Date {
  390. y, m, d := pr.readTime().Date()
  391. return mysql.Date{int16(y), byte(m), byte(d)}
  392. }
  393. func EncodeDate(buf []byte, d mysql.Date) int {
  394. if d.IsZero() {
  395. // MySQL zero
  396. buf[0] = 0
  397. return 1
  398. }
  399. return encodeNonzeroTime(buf, d.Year, d.Month, d.Day, 0, 0, 0, 0)
  400. }
  401. func (pw *pktWriter) writeDate(d mysql.Date) {
  402. buf := pw.buf[:5]
  403. n := EncodeDate(buf, d)
  404. pw.write(buf[:n])
  405. }
  406. func lenDate(d mysql.Date) int {
  407. if d.IsZero() {
  408. return 1
  409. }
  410. return 5
  411. }