UNPKG

3.73 kBJavaScriptView Raw
1/**
2 * Buffer Reader
3 * =============
4 *
5 * This is a convenience class for reading VarInts and other basic types from a
6 * buffer. This class is most useful for reading VarInts, and also for signed
7 * or unsigned integers of various types. It can also read a buffer in reverse
8 * order, which is useful in bitcoin which uses little endian numbers a lot so
9 * you find that you must reverse things. You probably want to use it like:
10 * varInt = new Br(buf).readnew VarInt()
11 */
12'use strict'
13
14import { Bn } from './bn'
15
16class Br {
17 constructor (buf) {
18 this.fromObject({ buf })
19 }
20
21 fromObject (obj) {
22 this.buf = obj.buf || this.buf || undefined
23 this.pos = obj.pos || this.pos || 0
24 return this
25 }
26
27 eof () {
28 return this.pos >= this.buf.length
29 }
30
31 read (len = this.buf.length) {
32 const buf = this.buf.slice(this.pos, this.pos + len)
33 this.pos = this.pos + len
34 return buf
35 }
36
37 readReverse (len = this.buf.length) {
38 const buf = this.buf.slice(this.pos, this.pos + len)
39 this.pos = this.pos + len
40 const buf2 = Buffer.alloc(buf.length)
41 for (let i = 0; i < buf2.length; i++) {
42 buf2[i] = buf[buf.length - 1 - i]
43 }
44 return buf2
45 }
46
47 readUInt8 () {
48 const val = this.buf.readUInt8(this.pos)
49 this.pos = this.pos + 1
50 return val
51 }
52
53 readInt8 () {
54 const val = this.buf.readInt8(this.pos)
55 this.pos = this.pos + 1
56 return val
57 }
58
59 readUInt16BE () {
60 const val = this.buf.readUInt16BE(this.pos)
61 this.pos = this.pos + 2
62 return val
63 }
64
65 readInt16BE () {
66 const val = this.buf.readInt16BE(this.pos)
67 this.pos = this.pos + 2
68 return val
69 }
70
71 readUInt16LE () {
72 const val = this.buf.readUInt16LE(this.pos)
73 this.pos = this.pos + 2
74 return val
75 }
76
77 readInt16LE () {
78 const val = this.buf.readInt16LE(this.pos)
79 this.pos = this.pos + 2
80 return val
81 }
82
83 readUInt32BE () {
84 const val = this.buf.readUInt32BE(this.pos)
85 this.pos = this.pos + 4
86 return val
87 }
88
89 readInt32BE () {
90 const val = this.buf.readInt32BE(this.pos)
91 this.pos = this.pos + 4
92 return val
93 }
94
95 readUInt32LE () {
96 const val = this.buf.readUInt32LE(this.pos)
97 this.pos = this.pos + 4
98 return val
99 }
100
101 readInt32LE () {
102 const val = this.buf.readInt32LE(this.pos)
103 this.pos = this.pos + 4
104 return val
105 }
106
107 readUInt64BEBn () {
108 const buf = this.buf.slice(this.pos, this.pos + 8)
109 const bn = new Bn().fromBuffer(buf)
110 this.pos = this.pos + 8
111 return bn
112 }
113
114 readUInt64LEBn () {
115 const buf = this.readReverse(8)
116 const bn = new Bn().fromBuffer(buf)
117 return bn
118 }
119
120 readVarIntNum () {
121 const first = this.readUInt8()
122 let bn, n
123 switch (first) {
124 case 0xfd:
125 return this.readUInt16LE()
126 case 0xfe:
127 return this.readUInt32LE()
128 case 0xff:
129 bn = this.readUInt64LEBn()
130 n = bn.toNumber()
131 if (n <= Math.pow(2, 53)) {
132 return n
133 } else {
134 throw new Error(
135 'number too large to retain precision - use readVarIntBn'
136 )
137 }
138 default:
139 return first
140 }
141 }
142
143 readVarIntBuf () {
144 const first = this.buf.readUInt8(this.pos)
145 switch (first) {
146 case 0xfd:
147 return this.read(1 + 2)
148 case 0xfe:
149 return this.read(1 + 4)
150 case 0xff:
151 return this.read(1 + 8)
152 default:
153 return this.read(1)
154 }
155 }
156
157 readVarIntBn () {
158 const first = this.readUInt8()
159 switch (first) {
160 case 0xfd:
161 return new Bn(this.readUInt16LE())
162 case 0xfe:
163 return new Bn(this.readUInt32LE())
164 case 0xff:
165 return this.readUInt64LEBn()
166 default:
167 return new Bn(first)
168 }
169 }
170}
171
172export { Br }