signed.js 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. const Bn = require('bn.js')
  2. const Pipe = require('buffer-pipe')
  3. module.exports = {
  4. encode,
  5. decode,
  6. write,
  7. read,
  8. readBn
  9. }
  10. function read (stream) {
  11. return readBn(stream).toString()
  12. }
  13. function readBn (stream) {
  14. const num = new Bn(0)
  15. let shift = 0
  16. let byt
  17. while (true) {
  18. byt = stream.read(1)[0]
  19. num.ior(new Bn(byt & 0x7f).shln(shift))
  20. shift += 7
  21. if (byt >> 7 === 0) {
  22. break
  23. }
  24. }
  25. // sign extend if negitive
  26. if (byt & 0x40) {
  27. num.setn(shift)
  28. }
  29. return num.fromTwos(shift)
  30. }
  31. function write (number, stream) {
  32. let num = new Bn(number)
  33. const isNeg = num.isNeg()
  34. if (isNeg) {
  35. // add 8 bits for padding
  36. num = num.toTwos(num.bitLength() + 8)
  37. }
  38. while (true) {
  39. const i = num.maskn(7).toNumber()
  40. num.ishrn(7)
  41. if ((isNegOne(num) && (i & 0x40) !== 0) ||
  42. (num.isZero() && (i & 0x40) === 0)) {
  43. stream.write([i])
  44. break
  45. } else {
  46. stream.write([i | 0x80])
  47. }
  48. }
  49. function isNegOne (num) {
  50. return isNeg && num.toString(2).indexOf('0') < 0
  51. }
  52. }
  53. /**
  54. * LEB128 encodeds an interger
  55. * @param {String|Number} num
  56. * @return {Buffer}
  57. */
  58. function encode (num) {
  59. const stream = new Pipe()
  60. write(num, stream)
  61. return stream.buffer
  62. }
  63. /**
  64. * decodes a LEB128 encoded interger
  65. * @param {Buffer} buffer
  66. * @return {String}
  67. */
  68. function decode (buffer) {
  69. const stream = new Pipe(buffer)
  70. return read(stream)
  71. }