UNPKG

taglib-wasm

Version:

TagLib for TypeScript platforms: Deno, Node.js, Bun, Electron, browsers, and Cloudflare Workers

185 lines (184 loc) 5.64 kB
var __typeError = (msg) => { throw TypeError(msg); }; var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg); var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)); var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value); var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value); var _wasm, _ptr, _size, _wasm2, _allocs; const heapViews = (mem) => ({ u8: new Uint8Array(mem.buffer), i8: new Int8Array(mem.buffer), u16: new Uint16Array(mem.buffer), i16: new Int16Array(mem.buffer), u32: new Uint32Array(mem.buffer), dv: new DataView(mem.buffer) }); class WasmAlloc { constructor(wasm, size) { __privateAdd(this, _wasm); __privateAdd(this, _ptr); __privateAdd(this, _size); __privateSet(this, _wasm, wasm); __privateSet(this, _ptr, wasm.malloc(size)); if (__privateGet(this, _ptr) === 0) { throw new Error(`malloc(${size}) failed`); } __privateSet(this, _size, size); } get ptr() { return __privateGet(this, _ptr); } get size() { return __privateGet(this, _size); } /** * Write bytes to allocation */ write(bytes, offset = 0) { if (offset + bytes.length > __privateGet(this, _size)) { throw new Error(`Write would exceed allocation bounds`); } const { u8 } = heapViews(__privateGet(this, _wasm).memory); u8.set(bytes, __privateGet(this, _ptr) + offset); } /** * Read bytes from allocation (zero-copy view) */ read(len = __privateGet(this, _size), offset = 0) { if (offset + len > __privateGet(this, _size)) { throw new Error(`Read would exceed allocation bounds`); } const { u8 } = heapViews(__privateGet(this, _wasm).memory); return u8.subarray(__privateGet(this, _ptr) + offset, __privateGet(this, _ptr) + offset + len); } /** * Write C string with null terminator */ writeCString(str) { const bytes = new TextEncoder().encode(str); if (bytes.length >= __privateGet(this, _size)) { throw new Error(`String too long for allocation`); } const { u8 } = heapViews(__privateGet(this, _wasm).memory); u8.set(bytes, __privateGet(this, _ptr)); u8[__privateGet(this, _ptr) + bytes.length] = 0; } /** * Read C string (null-terminated) */ readCString() { const { u8 } = heapViews(__privateGet(this, _wasm).memory); let end = __privateGet(this, _ptr); while (end < __privateGet(this, _ptr) + __privateGet(this, _size) && u8[end] !== 0) { end++; } return new TextDecoder().decode(u8.subarray(__privateGet(this, _ptr), end)); } /** * Write 32-bit integer (little-endian) */ writeUint32(value, offset = 0) { if (offset + 4 > __privateGet(this, _size)) { throw new Error(`Write would exceed allocation bounds`); } const { dv } = heapViews(__privateGet(this, _wasm).memory); dv.setUint32(__privateGet(this, _ptr) + offset, value, true); } /** * Read 32-bit integer (little-endian) */ readUint32(offset = 0) { if (offset + 4 > __privateGet(this, _size)) { throw new Error(`Read would exceed allocation bounds`); } const { dv } = heapViews(__privateGet(this, _wasm).memory); return dv.getUint32(__privateGet(this, _ptr) + offset, true); } /** * Automatic cleanup via Symbol.dispose */ [Symbol.dispose]() { if (__privateGet(this, _ptr) !== 0) { __privateGet(this, _wasm).free(__privateGet(this, _ptr)); __privateSet(this, _ptr, 0); } } } _wasm = new WeakMap(); _ptr = new WeakMap(); _size = new WeakMap(); class WasmArena { constructor(wasm) { __privateAdd(this, _wasm2); __privateAdd(this, _allocs, []); __privateSet(this, _wasm2, wasm); } /** * Allocate memory within this arena */ alloc(size) { const allocation = new WasmAlloc(__privateGet(this, _wasm2), size); __privateGet(this, _allocs).push(allocation); return allocation; } /** * Allocate and write string */ allocString(str) { const bytes = new TextEncoder().encode(str); const allocation = this.alloc(bytes.length + 1); allocation.writeCString(str); return allocation; } /** * Allocate and write buffer */ allocBuffer(buffer) { const allocation = this.alloc(buffer.length); allocation.write(buffer); return allocation; } /** * Allocate 32-bit integer */ allocUint32(value = 0) { const allocation = this.alloc(4); allocation.writeUint32(value); return allocation; } /** * Automatic cleanup of all allocations */ [Symbol.dispose]() { for (const alloc of __privateGet(this, _allocs)) { alloc[Symbol.dispose](); } __privateGet(this, _allocs).length = 0; } } _wasm2 = new WeakMap(); _allocs = new WeakMap(); class WasmMemoryError extends Error { constructor(message, operation, errorCode) { super( `${operation}: ${message}${errorCode !== void 0 ? ` (code ${errorCode})` : ""}` ); this.operation = operation; this.errorCode = errorCode; this.name = "WasmMemoryError"; } } function refreshHeapViews(wasm, currentViews) { if (currentViews.u8.buffer !== wasm.memory.buffer) { return heapViews(wasm.memory); } return currentViews; } export { WasmAlloc, WasmArena, WasmMemoryError, heapViews, refreshHeapViews };