import { Bytes, BytesLike, underlying } from "./bytes"; export type IOList = number | BytesLike | IOList[] | false | CountedIOList; class CountedIOList { value: IOList; length: number; constructor(i: IOList) { this.value = i; this.length = iolistLength(i); } } export function pushByte(i: IOList, b: number): IOList { if (Array.isArray(i)) { i.push(b); return i; } else { return [i, b]; } } export function append(i: IOList, j: IOList): IOList { if (i === false) return j; if (j === false) return i; return [i, j]; } export function iolistLength(i: IOList, acc = 0): number { if (typeof(i) === 'number') return acc + 1; if (i === false) return acc; if (Array.isArray(i)) return i.reduce((acc, j) => iolistLength(j, acc), acc); if (i instanceof CountedIOList) return acc + i.length; return acc + i.length; } export function countIOList(i: IOList): CountedIOList { if (i instanceof CountedIOList) return i; return new CountedIOList(i); } export function ioListBytes(i: IOList): Bytes { if (i instanceof Bytes) return i; const buffer = new Bytes(iolistLength(i)); function fill(i: IOList, offset: number): number { while (i instanceof CountedIOList) i = i.value; if (typeof(i) === 'number') { buffer._view[offset] = i; return offset + 1; } if (i === false) { return offset; } if (Array.isArray(i)) { i.forEach(j => offset = fill(j, offset)); return offset; } const bs = underlying(i); buffer._view.set(bs, offset); return offset + bs.length; } fill(i, 0); return buffer; }