"use strict";
class Arena {
constructor() {
this.inner = [];
this.lastRemove = null;
}
insert(e) {
if(this.lastRemove != null) {
let vacancy = this.lastRemove;
this.inner[vacancy] = e;
this.lastRemove = null;
return vacancy;
} else {
for(let i = 0; i < this.inner.length; i++) {
if(this.inner[i] == null) {
this.inner[i] = e;
return i;
}
}
return this.inner.push(e) - 1;
}
}
remove(i) {
if(i >= this.inner.length) {
return null;
}
let result = this.inner[i];
this.inner[i] = null;
return result;
}
get(i) {
if(i >= this.inner.length) {
return null;
}
return this.inner[i];
}
}
const APPEND = 0b0000_0001;
const CREATE = 0b0000_0010;
const CREATE_NEW = 0b0000_0100;
const READ = 0b0000_1000;
const TRUNCATE = 0b0001_0000;
const WRITE = 0b0010_0000;
let opened = new Arena();
onmessage = async (e) => {
let msg = e.data;
if(msg.Open != undefined) {
let openMsg = msg.Open;
let openOptions;
if((openMsg.options & WRITE) > 0) {
openOptions = {
mode: "readwrite"
}
} else {
openOptions = {
mode: "read-only"
}
}
let response = {
0: {
index: openMsg.index,
}
};
try {
let accessHandle = await openMsg.handle.createSyncAccessHandle(openOptions);
let fd = opened.insert(accessHandle);
if(openMsg.options & TRUNCATE | openMsg.options & CREATE_NEW | openMsg.options & CREATE) {
accessHandle.truncate(0);
}
let size = accessHandle.getSize();
response[0].fd = fd;
response[0].size = size;
} catch (error) {
response.error = error.toString() + JSON.stringify(openMsg);
} finally {
postMessage(response);
}
} else if(msg.Drop != undefined) {
let dropMsg = msg.Drop;
let accessHandle = opened.remove(dropMsg.fd);
accessHandle.close();
} else if(msg.Read != undefined) {
let readMsg = msg.Read;
let response = {
1: {
index: readMsg.index,
}
};
try {
let accessHandle = opened.get(readMsg.fd);
let buffer = new Uint8Array(readMsg.size);
let size = accessHandle.read(buffer, { at: readMsg.cursor });
response[1].buf = buffer.buffer;
response[1].size = size;
} catch (error) {
response.error = error.toString();
} finally {
postMessage(response);
}
} else if(msg.Write != undefined) {
let writeMsg = msg.Write;
let response = {
2: {
index: writeMsg.index,
}
};
try {
let accessHandle = opened.get(writeMsg.fd);
let dataView = new DataView(writeMsg.buf);
let size = accessHandle.write(dataView, { at: writeMsg.cursor });
response[2].size = size;
} catch (error) {
response.error = error.toString();
} finally {
postMessage(response);
}
} else if(msg.Flush != undefined) {
let flushMsg = msg.Flush;
let response = {
3: {
index: flushMsg.index,
}
};
try {
let accessHandle = opened.get(flushMsg.fd);
accessHandle.flush();
} catch (error) {
response.error = error.toString();
} finally {
postMessage(response);
}
} else if(msg.Close != undefined) {
let closeMsg = msg.Close;
let response = {
4: {
index: closeMsg.index
}
};
try {
let accessHandle = opened.get(closeMsg.fd);
accessHandle.close();
} catch (error) {
response.error = error.toString();
} finally {
postMessage(response);
}
} else if(msg.Truncate != undefined) {
let truncateMsg = msg.Truncate;
let response = {
5: {
index: truncateMsg.index
}
}
try {
let accessHandle = opened.get(truncateMsg.fd);
accessHandle.truncate(truncateMsg.size);
} catch (error) {
response.error = error.toString();
} finally {
postMessage(response);
}
}
}