taglib-wasm
Version:
TagLib-Wasm is the universal tagging library for TypeScript/JavaScript platforms: Browsers, Node.js, Deno, Bun, Cloudflare Workers, and Electron apps
250 lines (249 loc) • 7.59 kB
JavaScript
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : /* @__PURE__ */ Symbol.for("Symbol." + name);
var __typeError = (msg) => {
throw TypeError(msg);
};
var __using = (stack, value, async) => {
if (value != null) {
if (typeof value !== "object" && typeof value !== "function") __typeError("Object expected");
var dispose, inner;
if (async) dispose = value[__knownSymbol("asyncDispose")];
if (dispose === void 0) {
dispose = value[__knownSymbol("dispose")];
if (async) inner = dispose;
}
if (typeof dispose !== "function") __typeError("Object not disposable");
if (inner) dispose = function() {
try {
inner.call(this);
} catch (e) {
return Promise.reject(e);
}
};
stack.push([async, dispose, value]);
} else if (async) {
stack.push([async]);
}
return value;
};
var __callDispose = (stack, error, hasError) => {
var E = typeof SuppressedError === "function" ? SuppressedError : function(e, s, m, _) {
return _ = Error(m), _.name = "SuppressedError", _.error = e, _.suppressed = s, _;
};
var fail = (e) => error = hasError ? new E(e, error, "An error was suppressed during disposal") : (hasError = true, e);
var next = (it) => {
while (it = stack.pop()) {
try {
var result = it[1] && it[1].call(it[2]);
if (it[0]) return Promise.resolve(result).then(next, (e) => (fail(e), next()));
} catch (e) {
fail(e);
}
}
if (hasError) throw error;
};
return next();
};
import {
WasmArena,
WasmMemoryError
} from "../wasi-memory.js";
import {
InvalidFormatError,
UnsupportedFormatError
} from "../../errors/classes.js";
import { encodeTagData } from "../../msgpack/encoder.js";
import { decodeMessagePack } from "../../msgpack/decoder.js";
const TL_ERROR_UNSUPPORTED_FORMAT = -2;
const TL_ERROR_PARSE_FAILED = -6;
function readTagsFromWasm(wasi, buffer) {
var _stack = [];
try {
const arena = __using(_stack, new WasmArena(wasi));
const inputBuf = arena.allocBuffer(buffer);
const outSizePtr = arena.allocUint32();
const resultPtr = wasi.tl_read_tags(
0,
inputBuf.ptr,
inputBuf.size,
outSizePtr.ptr
);
if (resultPtr === 0) {
const errorCode = wasi.tl_get_last_error_code();
if (errorCode === TL_ERROR_UNSUPPORTED_FORMAT || errorCode === TL_ERROR_PARSE_FAILED) {
throw new InvalidFormatError(
"File may be corrupted or in an unsupported format",
buffer.length
);
}
throw new WasmMemoryError(
`error code ${errorCode}. Buffer size: ${buffer.length} bytes`,
"read tags",
errorCode
);
}
const outSize = outSizePtr.readUint32();
const u8 = new Uint8Array(wasi.memory.buffer);
const result = new Uint8Array(u8.slice(resultPtr, resultPtr + outSize));
wasi.free(resultPtr);
return result;
} catch (_) {
var _error = _, _hasError = true;
} finally {
__callDispose(_stack, _error, _hasError);
}
}
function readTagsFromWasmPath(wasi, path) {
var _stack = [];
try {
const arena = __using(_stack, new WasmArena(wasi));
const pathAlloc = arena.allocString(path);
const outSizePtr = arena.allocUint32();
const resultPtr = wasi.tl_read_tags(pathAlloc.ptr, 0, 0, outSizePtr.ptr);
if (resultPtr === 0) {
const errorCode = wasi.tl_get_last_error_code();
if (errorCode === TL_ERROR_UNSUPPORTED_FORMAT || errorCode === TL_ERROR_PARSE_FAILED) {
throw new InvalidFormatError(
`File may be corrupted or in an unsupported format. Path: ${path}`
);
}
throw new WasmMemoryError(
`error code ${errorCode}. Path: ${path}`,
"read tags from path",
errorCode
);
}
const outSize = outSizePtr.readUint32();
const u8 = new Uint8Array(wasi.memory.buffer);
const result = new Uint8Array(u8.slice(resultPtr, resultPtr + outSize));
wasi.free(resultPtr);
return result;
} catch (_) {
var _error = _, _hasError = true;
} finally {
__callDispose(_stack, _error, _hasError);
}
}
function readId3v2FramesFromWasm(wasi, source, id) {
var _stack = [];
try {
const arena = __using(_stack, new WasmArena(wasi));
const idAlloc = id ? arena.allocString(id) : null;
const outSizePtr = arena.allocUint32();
let resultPtr;
if (typeof source === "string") {
const pathAlloc = arena.allocString(source);
resultPtr = wasi.tl_read_id3v2_frames(
pathAlloc.ptr,
0,
0,
idAlloc?.ptr ?? 0,
outSizePtr.ptr
);
} else {
const inputBuf = arena.allocBuffer(source);
resultPtr = wasi.tl_read_id3v2_frames(
0,
inputBuf.ptr,
inputBuf.size,
idAlloc?.ptr ?? 0,
outSizePtr.ptr
);
}
if (resultPtr === 0) {
const errorCode = wasi.tl_get_last_error_code();
if (errorCode === TL_ERROR_UNSUPPORTED_FORMAT) {
throw new UnsupportedFormatError("non-MP3", ["MP3"], {
operation: "readId3v2Frames"
});
}
throw new WasmMemoryError(
`error code ${errorCode}`,
"read ID3v2 frames",
errorCode
);
}
const outSize = outSizePtr.readUint32();
const u8 = new Uint8Array(wasi.memory.buffer);
const bytes = new Uint8Array(u8.slice(resultPtr, resultPtr + outSize));
wasi.free(resultPtr);
return decodeMessagePack(bytes);
} catch (_) {
var _error = _, _hasError = true;
} finally {
__callDispose(_stack, _error, _hasError);
}
}
function writeTagsToWasmPath(wasi, path, tagData) {
var _stack = [];
try {
const arena = __using(_stack, new WasmArena(wasi));
const pathAlloc = arena.allocString(path);
const tagBytes = encodeTagData(tagData);
const tagBuf = arena.allocBuffer(tagBytes);
const outSizePtr = arena.allocUint32();
const result = wasi.tl_write_tags(
pathAlloc.ptr,
0,
0,
tagBuf.ptr,
tagBuf.size,
0,
outSizePtr.ptr
);
if (result !== 0) {
const errorCode = wasi.tl_get_last_error_code();
throw new WasmMemoryError(
`error code ${errorCode}. Path: ${path}`,
"write tags to path",
errorCode
);
}
return true;
} catch (_) {
var _error = _, _hasError = true;
} finally {
__callDispose(_stack, _error, _hasError);
}
}
function writeTagsToWasm(wasi, fileData, tagData) {
var _stack = [];
try {
const arena = __using(_stack, new WasmArena(wasi));
const tagBytes = encodeTagData(tagData);
const inputBuf = arena.allocBuffer(fileData);
const tagBuf = arena.allocBuffer(tagBytes);
const outBufPtr = arena.allocUint32();
const outSizePtr = arena.allocUint32();
const result = wasi.tl_write_tags(
0,
inputBuf.ptr,
inputBuf.size,
tagBuf.ptr,
tagBuf.size,
outBufPtr.ptr,
outSizePtr.ptr
);
if (result === 0) {
const bufferPtr = outBufPtr.readUint32();
const size = outSizePtr.readUint32();
if (bufferPtr && size > 0) {
const u8 = new Uint8Array(wasi.memory.buffer);
const output = new Uint8Array(u8.slice(bufferPtr, bufferPtr + size));
wasi.free(bufferPtr);
return output;
}
}
return null;
} catch (_) {
var _error = _, _hasError = true;
} finally {
__callDispose(_stack, _error, _hasError);
}
}
export {
readId3v2FramesFromWasm,
readTagsFromWasm,
readTagsFromWasmPath,
writeTagsToWasm,
writeTagsToWasmPath
};