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.

72 lines
1.6 KiB

  1. package p2p
  2. import "encoding/binary"
  3. // boost varint can encode upto 1 gb size
  4. func Decode_Boost_Varint(buf []byte) (uint64, int) {
  5. first_byte := buf[0]
  6. num_bytes := first_byte & 3 // lower 2 bits contain bytes count, which follow current byte
  7. // grab full 4 bytes
  8. value := binary.LittleEndian.Uint32(buf)
  9. switch num_bytes {
  10. case 0:
  11. value &= 0xff
  12. case 1:
  13. value &= 0xffff
  14. case 2:
  15. value &= 0xffffff
  16. case 3:
  17. value &= 0xffffffff
  18. }
  19. value = value >> 2 // discard lower 2 bits
  20. if num_bytes == 2 { // holy hell, let god have mercy on this boost parser
  21. num_bytes = 3
  22. }
  23. return uint64(value), int(num_bytes + 1)
  24. }
  25. // this function encodes Value to bu in boost varint style
  26. func Encode_Boost_Varint(buf []byte, Value uint64) int {
  27. bytes_required := byte(0)
  28. switch {
  29. case Value > 1073741823:
  30. panic("Exceeded boost varint capacity while encoding\n") // (2^30) -1
  31. case Value > 4194303:
  32. bytes_required = 4
  33. case Value > 16383:
  34. bytes_required = 3
  35. case Value > 63:
  36. bytes_required = 2
  37. default:
  38. bytes_required = 1
  39. }
  40. first_byte := (Value % 64) << 2
  41. Value = Value >> 6
  42. second_byte := Value % 256
  43. Value = Value >> 8
  44. third_byte := Value % 256
  45. Value = Value >> 8
  46. fourth_byte := Value % 256
  47. Value = Value >> 8
  48. // encode bytes length in lower 2 bits of first byte
  49. first_byte |= uint64(byte(bytes_required - 1))
  50. buf[0] = byte(first_byte)
  51. buf[1] = byte(second_byte)
  52. buf[2] = byte(third_byte)
  53. buf[3] = byte(fourth_byte)
  54. if bytes_required == 3 { // thank god we are soon going to migrate from boost hell, once and for all
  55. bytes_required = 4
  56. }
  57. return int(bytes_required)
  58. }