@haneullabs/bcs 2.1.2 → 2.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/writer.ts CHANGED
@@ -34,6 +34,7 @@ export interface BcsWriterOptions {
34
34
  */
35
35
  export class BcsWriter {
36
36
  private dataView: DataView<ArrayBuffer>;
37
+ private bytes: Uint8Array<ArrayBuffer>;
37
38
  private bytePosition: number = 0;
38
39
  private size: number;
39
40
  private maxSize: number;
@@ -48,6 +49,7 @@ export class BcsWriter {
48
49
  this.maxSize = maxSize;
49
50
  this.allocateSize = allocateSize;
50
51
  this.dataView = new DataView(new ArrayBuffer(initialSize));
52
+ this.bytes = new Uint8Array(this.dataView.buffer);
51
53
  }
52
54
 
53
55
  private ensureSizeOrGrow(bytes: number) {
@@ -65,8 +67,10 @@ export class BcsWriter {
65
67
 
66
68
  this.size = nextSize;
67
69
  const nextBuffer = new ArrayBuffer(this.size);
68
- new Uint8Array(nextBuffer).set(new Uint8Array(this.dataView.buffer));
70
+ const nextBytes = new Uint8Array(nextBuffer);
71
+ nextBytes.set(this.bytes);
69
72
  this.dataView = new DataView(nextBuffer);
73
+ this.bytes = nextBytes;
70
74
  }
71
75
  }
72
76
 
@@ -87,7 +91,7 @@ export class BcsWriter {
87
91
  */
88
92
  write8(value: number | bigint): this {
89
93
  this.ensureSizeOrGrow(1);
90
- this.dataView.setUint8(this.bytePosition, Number(value));
94
+ this.bytes[this.bytePosition] = Number(value);
91
95
  return this.shift(1);
92
96
  }
93
97
 
@@ -98,10 +102,7 @@ export class BcsWriter {
98
102
  */
99
103
  writeBytes(bytes: Uint8Array): this {
100
104
  this.ensureSizeOrGrow(bytes.length);
101
-
102
- for (let i = 0; i < bytes.length; i++) {
103
- this.dataView.setUint8(this.bytePosition + i, bytes[i]);
104
- }
105
+ this.bytes.set(bytes, this.bytePosition);
105
106
 
106
107
  return this.shift(bytes.length);
107
108
  }
@@ -131,9 +132,7 @@ export class BcsWriter {
131
132
  * @returns {this}
132
133
  */
133
134
  write64(value: number | bigint): this {
134
- toLittleEndian(BigInt(value), 8).forEach((el) => this.write8(el));
135
-
136
- return this;
135
+ return this.writeBigLittleEndian(BigInt(value), 8);
137
136
  }
138
137
  /**
139
138
  * Write a U128 value into a buffer and shift cursor position by 16.
@@ -142,9 +141,7 @@ export class BcsWriter {
142
141
  * @returns {this}
143
142
  */
144
143
  write128(value: number | bigint): this {
145
- toLittleEndian(BigInt(value), 16).forEach((el) => this.write8(el));
146
-
147
- return this;
144
+ return this.writeBigLittleEndian(BigInt(value), 16);
148
145
  }
149
146
  /**
150
147
  * Write a U256 value into a buffer and shift cursor position by 16.
@@ -153,9 +150,19 @@ export class BcsWriter {
153
150
  * @returns {this}
154
151
  */
155
152
  write256(value: number | bigint): this {
156
- toLittleEndian(BigInt(value), 32).forEach((el) => this.write8(el));
153
+ return this.writeBigLittleEndian(BigInt(value), 32);
154
+ }
157
155
 
158
- return this;
156
+ // Negative values encode as zero and values that overflow `size` keep their low bytes
157
+ private writeBigLittleEndian(value: bigint, size: number): this {
158
+ this.ensureSizeOrGrow(size);
159
+ let remaining = value > 0n ? value : 0n;
160
+ for (let offset = 0; offset < size; offset += 8) {
161
+ this.dataView.setBigUint64(this.bytePosition + offset, BigInt.asUintN(64, remaining), true);
162
+ remaining >>= 64n;
163
+ }
164
+
165
+ return this.shift(size);
159
166
  }
160
167
  /**
161
168
  * Write a ULEB value into a buffer and shift cursor position by number of bytes
@@ -164,6 +171,15 @@ export class BcsWriter {
164
171
  * @returns {this}
165
172
  */
166
173
  writeULEB(value: number): this {
174
+ if (value >= 0 && Number.isSafeInteger(value)) {
175
+ let remaining = value;
176
+ while (remaining >= 0x80) {
177
+ this.write8((remaining % 0x80) | 0x80);
178
+ remaining = Math.floor(remaining / 0x80);
179
+ }
180
+ return this.write8(remaining);
181
+ }
182
+
167
183
  ulebEncode(value).forEach((el) => this.write8(el));
168
184
  return this;
169
185
  }
@@ -209,14 +225,3 @@ export class BcsWriter {
209
225
  return encodeStr(this.toBytes(), encoding);
210
226
  }
211
227
  }
212
-
213
- function toLittleEndian(bigint: bigint, size: number) {
214
- const result = new Uint8Array(size);
215
- let i = 0;
216
- while (bigint > 0) {
217
- result[i] = Number(bigint % BigInt(256));
218
- bigint = bigint / BigInt(256);
219
- i += 1;
220
- }
221
- return result;
222
- }