tools.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package rest
  2. import (
  3. "io"
  4. "git.ali33.ru/fcg-xvii/go-tools/json"
  5. )
  6. // конверторы
  7. // Int64ToBytes упаковывает int64 в срез байтов заданной длины
  8. func Int64ToBytes(num int64, byteCount int) []byte {
  9. bytes := make([]byte, byteCount)
  10. for i := 0; i < byteCount; i++ {
  11. shift := uint((byteCount - 1 - i) * 8)
  12. bytes[i] = byte(num >> shift)
  13. }
  14. return bytes
  15. }
  16. // BytesToInt64 конвертирует срез байтов в int64
  17. func BytesToInt64(bytes []byte) int64 {
  18. var num int64
  19. for _, b := range bytes {
  20. num = (num << 8) | int64(b)
  21. }
  22. return num
  23. }
  24. // ioError возвращает ошибку ввода выввода
  25. func ioError(field string, err error) IErrorArgs {
  26. return NewError(
  27. "ErrIO",
  28. json.Map{
  29. "field": field,
  30. "error": err.Error(),
  31. },
  32. )
  33. }
  34. // чтение
  35. // ReadBuf считывает срез заданного колличества байт и возвращает его
  36. func ReadBuf(r io.Reader, size int, field string) ([]byte, IErrorArgs) {
  37. buf := make([]byte, size)
  38. if _, err := r.Read(buf); err != nil {
  39. return nil, ioError(field, err)
  40. }
  41. return buf, nil
  42. }
  43. // ReadBufSize считывает размер байтового среза, затем сам срез и возвращает его.
  44. // lenSize - количество байтов, которыми описывается размер основного среза (см. ReadInt64)
  45. func ReadBufSize(r io.Reader, lenSize int, field string) ([]byte, IErrorArgs) {
  46. var size int64
  47. if err := ReadInt64(r, lenSize, field+"_size", &size); err != nil {
  48. return nil, err
  49. }
  50. buf, err := ReadBuf(r, int(size), field)
  51. return buf, err
  52. }
  53. // ReadInt64 Считывает срез заданного размера, который конвертируется в число типа int64.
  54. // size - размер среза (может быть от 1 до 8 байт).
  55. // Результат записывается в значение указателя result
  56. func ReadInt64(r io.Reader, size int, field string, result *int64) IErrorArgs {
  57. buf := make([]byte, size)
  58. if _, err := r.Read(buf); err != nil {
  59. return ioError(field, err)
  60. }
  61. *result = BytesToInt64(buf)
  62. return nil
  63. }
  64. // ReadString считывает строку (длина строки, затем строку), см. ReadBufSize
  65. func ReadString(r io.Reader, lenSize int, field string, result *string) IErrorArgs {
  66. strBuf, err := ReadBufSize(r, lenSize, field)
  67. if err != nil {
  68. return err
  69. }
  70. *result = string(strBuf)
  71. return nil
  72. }
  73. // ReadByte считывает 1 байт
  74. func ReadByte(r io.Reader, field string, result *byte) IErrorArgs {
  75. buf, err := ReadBuf(r, 1, field)
  76. if err != nil {
  77. return err
  78. }
  79. *result = buf[0]
  80. return nil
  81. }
  82. // запись
  83. // WriteBuf записывает срез байтов
  84. func WriteBuf(w io.Writer, buf []byte, field string) IErrorArgs {
  85. if _, err := w.Write(buf); err != nil {
  86. return ioError(field, err)
  87. }
  88. return nil
  89. }
  90. // WriteInt64 конвертирует число типа int64 в срез заданного размера и записывает его
  91. func WriteInt64(w io.Writer, val int64, size int, field string) IErrorArgs {
  92. buf := Int64ToBytes(val, size)
  93. return WriteBuf(w, buf, field)
  94. }
  95. // WriteString записывает строку в поток.
  96. // Сначала записывается размер строки (lenSize - количество байт в срезе размера).
  97. // Далее строка конвертируется в байтовый срез и записывается в поток
  98. func WriteString(w io.Writer, val, field string, lenSize int) IErrorArgs {
  99. // длина
  100. if err := WriteInt64(w, int64(len(val)), lenSize, field+"_size"); err != nil {
  101. return err
  102. }
  103. // строка
  104. if len(val) == 0 {
  105. return nil
  106. }
  107. return WriteBuf(w, []byte(val), field)
  108. }
  109. // WriteBuf записывает 1 байт в поток
  110. func WriteByte(w io.Writer, val byte, field string) IErrorArgs {
  111. return WriteBuf(w, []byte{val}, field)
  112. }
  113. // WriteBufSize записывает срез байтов в поток.
  114. // Сначала записывается размер среза (lenSize - количество байт в срезе размера).
  115. // Далее в поток записывается сам срез
  116. func WriteBufSize(w io.Writer, val []byte, lenSize int, field string) IErrorArgs {
  117. // длина
  118. if err := WriteInt64(w, int64(len(val)), lenSize, field+"_size"); err != nil {
  119. return err
  120. }
  121. // буфер
  122. return WriteBuf(w, val, field)
  123. }