You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

232 lines
4.8 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. package binary
  2. import (
  3. "encoding/binary"
  4. "errors"
  5. "io"
  6. )
  7. // Byte
  8. func WriteByte(w io.Writer, b byte, n *int64, err *error) {
  9. WriteTo(w, []byte{b}, n, err)
  10. }
  11. func ReadByte(r io.Reader, n *int64, err *error) byte {
  12. buf := make([]byte, 1)
  13. ReadFull(r, buf, n, err)
  14. return buf[0]
  15. }
  16. // Int8
  17. func WriteInt8(w io.Writer, i int8, n *int64, err *error) {
  18. WriteByte(w, byte(i), n, err)
  19. }
  20. func ReadInt8(r io.Reader, n *int64, err *error) int8 {
  21. return int8(ReadByte(r, n, err))
  22. }
  23. // UInt8
  24. func WriteUInt8(w io.Writer, i uint8, n *int64, err *error) {
  25. WriteByte(w, byte(i), n, err)
  26. }
  27. func ReadUInt8(r io.Reader, n *int64, err *error) uint8 {
  28. return uint8(ReadByte(r, n, err))
  29. }
  30. // Int16
  31. func WriteInt16(w io.Writer, i int16, n *int64, err *error) {
  32. buf := make([]byte, 2)
  33. binary.LittleEndian.PutUint16(buf, uint16(i))
  34. *n += 2
  35. WriteTo(w, buf, n, err)
  36. }
  37. func ReadInt16(r io.Reader, n *int64, err *error) int16 {
  38. buf := make([]byte, 2)
  39. ReadFull(r, buf, n, err)
  40. return int16(binary.LittleEndian.Uint16(buf))
  41. }
  42. // UInt16
  43. func WriteUInt16(w io.Writer, i uint16, n *int64, err *error) {
  44. buf := make([]byte, 2)
  45. binary.LittleEndian.PutUint16(buf, uint16(i))
  46. *n += 2
  47. WriteTo(w, buf, n, err)
  48. }
  49. func ReadUInt16(r io.Reader, n *int64, err *error) uint16 {
  50. buf := make([]byte, 2)
  51. ReadFull(r, buf, n, err)
  52. return uint16(binary.LittleEndian.Uint16(buf))
  53. }
  54. // []UInt16
  55. func WriteUInt16s(w io.Writer, iz []uint16, n *int64, err *error) {
  56. WriteUInt32(w, uint32(len(iz)), n, err)
  57. for _, i := range iz {
  58. WriteUInt16(w, i, n, err)
  59. if *err != nil {
  60. return
  61. }
  62. }
  63. }
  64. func ReadUInt16s(r io.Reader, n *int64, err *error) []uint16 {
  65. length := ReadUInt32(r, n, err)
  66. if *err != nil {
  67. return nil
  68. }
  69. iz := make([]uint16, length)
  70. for j := uint32(0); j < length; j++ {
  71. ii := ReadUInt16(r, n, err)
  72. if *err != nil {
  73. return nil
  74. }
  75. iz[j] = ii
  76. }
  77. return iz
  78. }
  79. // Int32
  80. func WriteInt32(w io.Writer, i int32, n *int64, err *error) {
  81. buf := make([]byte, 4)
  82. binary.LittleEndian.PutUint32(buf, uint32(i))
  83. *n += 4
  84. WriteTo(w, buf, n, err)
  85. }
  86. func ReadInt32(r io.Reader, n *int64, err *error) int32 {
  87. buf := make([]byte, 4)
  88. ReadFull(r, buf, n, err)
  89. return int32(binary.LittleEndian.Uint32(buf))
  90. }
  91. // UInt32
  92. func WriteUInt32(w io.Writer, i uint32, n *int64, err *error) {
  93. buf := make([]byte, 4)
  94. binary.LittleEndian.PutUint32(buf, uint32(i))
  95. *n += 4
  96. WriteTo(w, buf, n, err)
  97. }
  98. func ReadUInt32(r io.Reader, n *int64, err *error) uint32 {
  99. buf := make([]byte, 4)
  100. ReadFull(r, buf, n, err)
  101. return uint32(binary.LittleEndian.Uint32(buf))
  102. }
  103. // Int64
  104. func WriteInt64(w io.Writer, i int64, n *int64, err *error) {
  105. buf := make([]byte, 8)
  106. binary.LittleEndian.PutUint64(buf, uint64(i))
  107. *n += 8
  108. WriteTo(w, buf, n, err)
  109. }
  110. func ReadInt64(r io.Reader, n *int64, err *error) int64 {
  111. buf := make([]byte, 8)
  112. ReadFull(r, buf, n, err)
  113. return int64(binary.LittleEndian.Uint64(buf))
  114. }
  115. // UInt64
  116. func WriteUInt64(w io.Writer, i uint64, n *int64, err *error) {
  117. buf := make([]byte, 8)
  118. binary.LittleEndian.PutUint64(buf, uint64(i))
  119. *n += 8
  120. WriteTo(w, buf, n, err)
  121. }
  122. func ReadUInt64(r io.Reader, n *int64, err *error) uint64 {
  123. buf := make([]byte, 8)
  124. ReadFull(r, buf, n, err)
  125. return uint64(binary.LittleEndian.Uint64(buf))
  126. }
  127. // VarInt
  128. func WriteVarInt(w io.Writer, i int, n *int64, err *error) {
  129. buf := make([]byte, 9)
  130. n_ := int64(binary.PutVarint(buf, int64(i)))
  131. *n += n_
  132. WriteTo(w, buf[:n_], n, err)
  133. }
  134. func ReadVarInt(r io.Reader, n *int64, err *error) int {
  135. res, n_, err_ := readVarint(r)
  136. *n += n_
  137. *err = err_
  138. return int(res)
  139. }
  140. // UVarInt
  141. func WriteUVarInt(w io.Writer, i uint, n *int64, err *error) {
  142. buf := make([]byte, 9)
  143. n_ := int64(binary.PutUvarint(buf, uint64(i)))
  144. *n += n_
  145. WriteTo(w, buf[:n_], n, err)
  146. }
  147. func ReadUVarInt(r io.Reader, n *int64, err *error) uint {
  148. res, n_, err_ := readUvarint(r)
  149. *n += n_
  150. *err = err_
  151. return uint(res)
  152. }
  153. //-----------------------------------------------------------------------------
  154. var overflow = errors.New("binary: varint overflows a 64-bit integer")
  155. // Modified to return number of bytes read, from
  156. // http://golang.org/src/pkg/encoding/binary/varint.go?s=3652:3699#L116
  157. func readUvarint(r io.Reader) (uint64, int64, error) {
  158. var x uint64
  159. var s uint
  160. var buf = make([]byte, 1)
  161. for i := 0; ; i++ {
  162. for {
  163. n, err := r.Read(buf)
  164. if err != nil {
  165. return x, int64(i), err
  166. }
  167. if n > 0 {
  168. break
  169. }
  170. }
  171. b := buf[0]
  172. if b < 0x80 {
  173. if i > 9 || i == 9 && b > 1 {
  174. return x, int64(i), overflow
  175. }
  176. return x | uint64(b)<<s, int64(i), nil
  177. }
  178. x |= uint64(b&0x7f) << s
  179. s += 7
  180. }
  181. }
  182. // Modified to return number of bytes read, from
  183. // http://golang.org/src/pkg/encoding/binary/varint.go?s=3652:3699#L116
  184. func readVarint(r io.Reader) (int64, int64, error) {
  185. ux, n, err := readUvarint(r) // ok to continue in presence of error
  186. x := int64(ux >> 1)
  187. if ux&1 != 0 {
  188. x = ^x
  189. }
  190. return x, n, err
  191. }