@ecash/lib
Version:
Library for eCash transaction building
88 lines (78 loc) • 2.98 kB
text/typescript
// Copyright (c) 2024 The Bitcoin developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
import { Endian, endianToBool } from './bytes.js';
import { Int } from './int.js';
import { Writer } from './writer.js';
/**
* Implementation of `Writer` which writes to an array of pre-allocated size.
* It's intended to be used in unison with `WriterLength`, which first finds
* out the length of the serialized object and then the actual data is written
* using this class.
**/
export class WriterBytes implements Writer {
public data: Uint8Array;
public view: DataView;
public idx: number;
/** Create a new WriterBytes with the given pre-allocated size */
public constructor(length: number) {
this.data = new Uint8Array(length);
this.view = new DataView(
this.data.buffer,
this.data.byteOffset,
this.data.byteLength,
);
this.idx = 0;
}
/** Write a single byte */
public putU8(value: Int): void {
if (value < 0 || value > 0xff) {
throw new Error(`Cannot fit ${value} into a u8`);
}
this.ensureSize(1);
this.data[this.idx] = Number(value);
this.idx++;
}
/** Write a 2-byte little-endian integer (uint16_t) */
public putU16(value: Int, endian?: Endian): void {
if (value < 0 || value > 0xffff) {
throw new Error(`Cannot fit ${value} into a u16`);
}
this.ensureSize(2);
this.view.setUint16(this.idx, Number(value), endianToBool(endian));
this.idx += 2;
}
/** Write a 4-byte little-endian integer (uint32_t) */
public putU32(value: Int, endian?: Endian): void {
if (value < 0 || value > 0xffffffff) {
throw new Error(`Cannot fit ${value} into a u32`);
}
this.ensureSize(4);
this.view.setUint32(this.idx, Number(value), endianToBool(endian));
this.idx += 4;
}
/** Write an 8-byte little-endian integer (uint64_t) */
public putU64(value: Int, endian?: Endian): void {
if (value < 0 || value > 0xffffffffffffffffn) {
throw new Error(`Cannot fit ${value} into a u64`);
}
this.ensureSize(8);
this.view.setBigUint64(this.idx, BigInt(value), endianToBool(endian));
this.idx += 8;
}
/** Write the given bytes */
public putBytes(bytes: Uint8Array): void {
this.ensureSize(bytes.length);
this.data.set(bytes, this.idx);
this.idx += bytes.length;
}
private ensureSize(extraBytes: number) {
if (this.data.length < this.idx + extraBytes) {
throw new Error(
`Not enough bytes: Tried writing ${extraBytes} byte(s), but ` +
`only ${this.data.length - this.idx} byte(s) have been ` +
`pre-allocated`,
);
}
}
}