76 lines
1.6 KiB
TypeScript
76 lines
1.6 KiB
TypeScript
import { OPS } from './ops';
|
|
|
|
export function encodingLength(i: number): number {
|
|
return i < OPS.OP_PUSHDATA1 ? 1 : i <= 0xff ? 2 : i <= 0xffff ? 3 : 5;
|
|
}
|
|
|
|
export function encode(buffer: Buffer, num: number, offset: number): number {
|
|
const size = encodingLength(num);
|
|
|
|
// ~6 bit
|
|
if (size === 1) {
|
|
buffer.writeUInt8(num, offset);
|
|
|
|
// 8 bit
|
|
} else if (size === 2) {
|
|
buffer.writeUInt8(OPS.OP_PUSHDATA1, offset);
|
|
buffer.writeUInt8(num, offset + 1);
|
|
|
|
// 16 bit
|
|
} else if (size === 3) {
|
|
buffer.writeUInt8(OPS.OP_PUSHDATA2, offset);
|
|
buffer.writeUInt16LE(num, offset + 1);
|
|
|
|
// 32 bit
|
|
} else {
|
|
buffer.writeUInt8(OPS.OP_PUSHDATA4, offset);
|
|
buffer.writeUInt32LE(num, offset + 1);
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
export function decode(
|
|
buffer: Buffer,
|
|
offset: number,
|
|
): {
|
|
opcode: number;
|
|
number: number;
|
|
size: number;
|
|
} | null {
|
|
const opcode = buffer.readUInt8(offset);
|
|
let num: number;
|
|
let size: number;
|
|
|
|
// ~6 bit
|
|
if (opcode < OPS.OP_PUSHDATA1) {
|
|
num = opcode;
|
|
size = 1;
|
|
|
|
// 8 bit
|
|
} else if (opcode === OPS.OP_PUSHDATA1) {
|
|
if (offset + 2 > buffer.length) return null;
|
|
num = buffer.readUInt8(offset + 1);
|
|
size = 2;
|
|
|
|
// 16 bit
|
|
} else if (opcode === OPS.OP_PUSHDATA2) {
|
|
if (offset + 3 > buffer.length) return null;
|
|
num = buffer.readUInt16LE(offset + 1);
|
|
size = 3;
|
|
|
|
// 32 bit
|
|
} else {
|
|
if (offset + 5 > buffer.length) return null;
|
|
if (opcode !== OPS.OP_PUSHDATA4) throw new Error('Unexpected opcode');
|
|
|
|
num = buffer.readUInt32LE(offset + 1);
|
|
size = 5;
|
|
}
|
|
|
|
return {
|
|
opcode,
|
|
number: num,
|
|
size,
|
|
};
|
|
}
|