UNPKG

4.63 kBJavaScriptView Raw
1'use strict';
2Object.defineProperty(exports, '__esModule', { value: true });
3exports.BufferReader =
4 exports.BufferWriter =
5 exports.cloneBuffer =
6 exports.reverseBuffer =
7 exports.writeUInt64LE =
8 exports.readUInt64LE =
9 exports.varuint =
10 void 0;
11const types = require('./types');
12const { typeforce } = types;
13const varuint = require('varuint-bitcoin');
14exports.varuint = varuint;
15// https://github.com/feross/buffer/blob/master/index.js#L1127
16function verifuint(value, max) {
17 if (typeof value !== 'number')
18 throw new Error('cannot write a non-number as a number');
19 if (value < 0)
20 throw new Error('specified a negative value for writing an unsigned value');
21 if (value > max) throw new Error('RangeError: value out of range');
22 if (Math.floor(value) !== value)
23 throw new Error('value has a fractional component');
24}
25function readUInt64LE(buffer, offset) {
26 const a = buffer.readUInt32LE(offset);
27 let b = buffer.readUInt32LE(offset + 4);
28 b *= 0x100000000;
29 verifuint(b + a, 0x001fffffffffffff);
30 return b + a;
31}
32exports.readUInt64LE = readUInt64LE;
33function writeUInt64LE(buffer, value, offset) {
34 verifuint(value, 0x001fffffffffffff);
35 buffer.writeInt32LE(value & -1, offset);
36 buffer.writeUInt32LE(Math.floor(value / 0x100000000), offset + 4);
37 return offset + 8;
38}
39exports.writeUInt64LE = writeUInt64LE;
40function reverseBuffer(buffer) {
41 if (buffer.length < 1) return buffer;
42 let j = buffer.length - 1;
43 let tmp = 0;
44 for (let i = 0; i < buffer.length / 2; i++) {
45 tmp = buffer[i];
46 buffer[i] = buffer[j];
47 buffer[j] = tmp;
48 j--;
49 }
50 return buffer;
51}
52exports.reverseBuffer = reverseBuffer;
53function cloneBuffer(buffer) {
54 const clone = Buffer.allocUnsafe(buffer.length);
55 buffer.copy(clone);
56 return clone;
57}
58exports.cloneBuffer = cloneBuffer;
59/**
60 * Helper class for serialization of bitcoin data types into a pre-allocated buffer.
61 */
62class BufferWriter {
63 static withCapacity(size) {
64 return new BufferWriter(Buffer.alloc(size));
65 }
66 constructor(buffer, offset = 0) {
67 this.buffer = buffer;
68 this.offset = offset;
69 typeforce(types.tuple(types.Buffer, types.UInt32), [buffer, offset]);
70 }
71 writeUInt8(i) {
72 this.offset = this.buffer.writeUInt8(i, this.offset);
73 }
74 writeInt32(i) {
75 this.offset = this.buffer.writeInt32LE(i, this.offset);
76 }
77 writeUInt32(i) {
78 this.offset = this.buffer.writeUInt32LE(i, this.offset);
79 }
80 writeUInt64(i) {
81 this.offset = writeUInt64LE(this.buffer, i, this.offset);
82 }
83 writeVarInt(i) {
84 varuint.encode(i, this.buffer, this.offset);
85 this.offset += varuint.encode.bytes;
86 }
87 writeSlice(slice) {
88 if (this.buffer.length < this.offset + slice.length) {
89 throw new Error('Cannot write slice out of bounds');
90 }
91 this.offset += slice.copy(this.buffer, this.offset);
92 }
93 writeVarSlice(slice) {
94 this.writeVarInt(slice.length);
95 this.writeSlice(slice);
96 }
97 writeVector(vector) {
98 this.writeVarInt(vector.length);
99 vector.forEach(buf => this.writeVarSlice(buf));
100 }
101 end() {
102 if (this.buffer.length === this.offset) {
103 return this.buffer;
104 }
105 throw new Error(`buffer size ${this.buffer.length}, offset ${this.offset}`);
106 }
107}
108exports.BufferWriter = BufferWriter;
109/**
110 * Helper class for reading of bitcoin data types from a buffer.
111 */
112class BufferReader {
113 constructor(buffer, offset = 0) {
114 this.buffer = buffer;
115 this.offset = offset;
116 typeforce(types.tuple(types.Buffer, types.UInt32), [buffer, offset]);
117 }
118 readUInt8() {
119 const result = this.buffer.readUInt8(this.offset);
120 this.offset++;
121 return result;
122 }
123 readInt32() {
124 const result = this.buffer.readInt32LE(this.offset);
125 this.offset += 4;
126 return result;
127 }
128 readUInt32() {
129 const result = this.buffer.readUInt32LE(this.offset);
130 this.offset += 4;
131 return result;
132 }
133 readUInt64() {
134 const result = readUInt64LE(this.buffer, this.offset);
135 this.offset += 8;
136 return result;
137 }
138 readVarInt() {
139 const vi = varuint.decode(this.buffer, this.offset);
140 this.offset += varuint.decode.bytes;
141 return vi;
142 }
143 readSlice(n) {
144 if (this.buffer.length < this.offset + n) {
145 throw new Error('Cannot read slice out of bounds');
146 }
147 const result = this.buffer.slice(this.offset, this.offset + n);
148 this.offset += n;
149 return result;
150 }
151 readVarSlice() {
152 return this.readSlice(this.readVarInt());
153 }
154 readVector() {
155 const count = this.readVarInt();
156 const vector = [];
157 for (let i = 0; i < count; i++) vector.push(this.readVarSlice());
158 return vector;
159 }
160}
161exports.BufferReader = BufferReader;