taglib-wasm
Version:
TagLib for TypeScript platforms: Deno, Node.js, Bun, Electron, browsers, and Cloudflare Workers
185 lines (184 loc) • 5.64 kB
JavaScript
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
};