xints.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. package model
  2. import (
  3. "database/sql/driver"
  4. "encoding/binary"
  5. )
  6. // Ints be used to MySql\Protobuf varbinary converting.
  7. type Ints []int64
  8. // MarshalTo marshal int64 slice to bytes,each int64 will occupy Fixed 8 bytes.
  9. // if the argument data not supplied with the full size,it will return the actual written size
  10. func (is Ints) MarshalTo(data []byte) (int, error) {
  11. for i, n := range is {
  12. start := i * 8
  13. end := (i + 1) * 8
  14. if len(data) < end {
  15. return start, nil
  16. }
  17. bs := data[start:end]
  18. binary.BigEndian.PutUint64(bs, uint64(n))
  19. }
  20. return 8 * len(is), nil
  21. }
  22. // Size return the total size it will occupy in bytes
  23. func (is Ints) Size() int {
  24. return len(is) * 8
  25. }
  26. // Unmarshal parse the data into int64 slice
  27. func (is *Ints) Unmarshal(data []byte) error {
  28. return is.Scan(data)
  29. }
  30. // Scan parse the data into int64 slice
  31. func (is *Ints) Scan(src interface{}) (err error) {
  32. switch sc := src.(type) {
  33. case []byte:
  34. var res []int64
  35. for i := 0; i < len(sc) && i+8 <= len(sc); i += 8 {
  36. ui := binary.BigEndian.Uint64(sc[i : i+8])
  37. res = append(res, int64(ui))
  38. }
  39. *is = res
  40. }
  41. return
  42. }
  43. // Value marshal int64 slice to driver.Value,each int64 will occupy Fixed 8 bytes
  44. func (is Ints) Value() (driver.Value, error) {
  45. return is.Bytes(), nil
  46. }
  47. // Bytes marshal int64 slice to bytes,each int64 will occupy Fixed 8 bytes
  48. func (is Ints) Bytes() []byte {
  49. res := make([]byte, 0, 8*len(is))
  50. for _, i := range is {
  51. bs := make([]byte, 8)
  52. binary.BigEndian.PutUint64(bs, uint64(i))
  53. res = append(res, bs...)
  54. }
  55. return res
  56. }
  57. // Evict get rid of the sepcified num from the slice
  58. func (is *Ints) Evict(e int64) (ok bool) {
  59. res := make([]int64, len(*is)-1)
  60. for _, v := range *is {
  61. if v != e {
  62. res = append(res, v)
  63. } else {
  64. ok = true
  65. }
  66. }
  67. *is = res
  68. return
  69. }
  70. // Exist judge the sepcified num is in the slice or not
  71. func (is Ints) Exist(i int64) (e bool) {
  72. for _, v := range is {
  73. if v == i {
  74. e = true
  75. return
  76. }
  77. }
  78. return
  79. }