base64_vlq.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package base64vlq
  2. import (
  3. "io"
  4. )
  5. const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
  6. const (
  7. vlqBaseShift = 5
  8. vlqBase = 1 << vlqBaseShift
  9. vlqBaseMask = vlqBase - 1
  10. vlqSignBit = 1
  11. vlqContinuationBit = vlqBase
  12. )
  13. var decodeMap [256]byte
  14. func init() {
  15. for i := 0; i < len(encodeStd); i++ {
  16. decodeMap[encodeStd[i]] = byte(i)
  17. }
  18. }
  19. func toVLQSigned(n int) int {
  20. if n < 0 {
  21. return -n<<1 + 1
  22. }
  23. return n << 1
  24. }
  25. func fromVLQSigned(n int) int {
  26. isNeg := n&vlqSignBit != 0
  27. n >>= 1
  28. if isNeg {
  29. return -n
  30. }
  31. return n
  32. }
  33. type Encoder struct {
  34. w io.ByteWriter
  35. }
  36. func NewEncoder(w io.ByteWriter) *Encoder {
  37. return &Encoder{
  38. w: w,
  39. }
  40. }
  41. func (enc Encoder) Encode(n int) error {
  42. n = toVLQSigned(n)
  43. for digit := vlqContinuationBit; digit&vlqContinuationBit != 0; {
  44. digit = n & vlqBaseMask
  45. n >>= vlqBaseShift
  46. if n > 0 {
  47. digit |= vlqContinuationBit
  48. }
  49. err := enc.w.WriteByte(encodeStd[digit])
  50. if err != nil {
  51. return err
  52. }
  53. }
  54. return nil
  55. }
  56. type Decoder struct {
  57. r io.ByteReader
  58. }
  59. func NewDecoder(r io.ByteReader) *Decoder {
  60. return &Decoder{
  61. r: r,
  62. }
  63. }
  64. func (dec Decoder) Decode() (n int, err error) {
  65. shift := uint(0)
  66. for continuation := true; continuation; {
  67. c, err := dec.r.ReadByte()
  68. if err != nil {
  69. return 0, err
  70. }
  71. c = decodeMap[c]
  72. continuation = c&vlqContinuationBit != 0
  73. n += int(c&vlqBaseMask) << shift
  74. shift += vlqBaseShift
  75. }
  76. return fromVLQSigned(n), nil
  77. }