varint.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package utils
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io"
  6. "v2ray.com/core/external/github.com/lucas-clemente/quic-go/internal/protocol"
  7. )
  8. // taken from the QUIC draft
  9. const (
  10. maxVarInt1 = 63
  11. maxVarInt2 = 16383
  12. maxVarInt4 = 1073741823
  13. maxVarInt8 = 4611686018427387903
  14. )
  15. // ReadVarInt reads a number in the QUIC varint format
  16. func ReadVarInt(b io.ByteReader) (uint64, error) {
  17. firstByte, err := b.ReadByte()
  18. if err != nil {
  19. return 0, err
  20. }
  21. // the first two bits of the first byte encode the length
  22. len := 1 << ((firstByte & 0xc0) >> 6)
  23. b1 := firstByte & (0xff - 0xc0)
  24. if len == 1 {
  25. return uint64(b1), nil
  26. }
  27. b2, err := b.ReadByte()
  28. if err != nil {
  29. return 0, err
  30. }
  31. if len == 2 {
  32. return uint64(b2) + uint64(b1)<<8, nil
  33. }
  34. b3, err := b.ReadByte()
  35. if err != nil {
  36. return 0, err
  37. }
  38. b4, err := b.ReadByte()
  39. if err != nil {
  40. return 0, err
  41. }
  42. if len == 4 {
  43. return uint64(b4) + uint64(b3)<<8 + uint64(b2)<<16 + uint64(b1)<<24, nil
  44. }
  45. b5, err := b.ReadByte()
  46. if err != nil {
  47. return 0, err
  48. }
  49. b6, err := b.ReadByte()
  50. if err != nil {
  51. return 0, err
  52. }
  53. b7, err := b.ReadByte()
  54. if err != nil {
  55. return 0, err
  56. }
  57. b8, err := b.ReadByte()
  58. if err != nil {
  59. return 0, err
  60. }
  61. return uint64(b8) + uint64(b7)<<8 + uint64(b6)<<16 + uint64(b5)<<24 + uint64(b4)<<32 + uint64(b3)<<40 + uint64(b2)<<48 + uint64(b1)<<56, nil
  62. }
  63. // WriteVarInt writes a number in the QUIC varint format
  64. func WriteVarInt(b *bytes.Buffer, i uint64) {
  65. if i <= maxVarInt1 {
  66. b.WriteByte(uint8(i))
  67. } else if i <= maxVarInt2 {
  68. b.Write([]byte{uint8(i>>8) | 0x40, uint8(i)})
  69. } else if i <= maxVarInt4 {
  70. b.Write([]byte{uint8(i>>24) | 0x80, uint8(i >> 16), uint8(i >> 8), uint8(i)})
  71. } else if i <= maxVarInt8 {
  72. b.Write([]byte{
  73. uint8(i>>56) | 0xc0, uint8(i >> 48), uint8(i >> 40), uint8(i >> 32),
  74. uint8(i >> 24), uint8(i >> 16), uint8(i >> 8), uint8(i),
  75. })
  76. } else {
  77. panic(fmt.Sprintf("%#x doesn't fit into 62 bits", i))
  78. }
  79. }
  80. // VarIntLen determines the number of bytes that will be needed to write a number
  81. func VarIntLen(i uint64) protocol.ByteCount {
  82. if i <= maxVarInt1 {
  83. return 1
  84. }
  85. if i <= maxVarInt2 {
  86. return 2
  87. }
  88. if i <= maxVarInt4 {
  89. return 4
  90. }
  91. if i <= maxVarInt8 {
  92. return 8
  93. }
  94. panic(fmt.Sprintf("%#x doesn't fit into 62 bits", i))
  95. }