// Wire // ==== // TCP on bytes: a List of octets in and out. After bend-kit-wire (MIT-0). function gw_list(b, n) { let xs = { $: "Nil" }; for (let i = n; i > 0; i -= 1) { xs = { $: "Con", head: b[i - 1], tail: xs }; } return xs; } function wire_recv(socket, max, k) { const sys = io_sys(); const fd = socket; const b = new Uint8Array(Math.max(Number(max), 1)); const again = sys.mac ? 35 : 11; const go = () => { const n = Number(sys.recv(fd, sys.ptr(b), Number(max), 0)); if (n < 0) { const code = sys.errno(); if (code === again) { io_park_on(fd, false, k, go); return undefined; } return io_tup(socket, io_fail(code)); } return io_tup(socket, io_done(gw_list(b, n))); }; return go(); } function wire_recv_need() { return { read: true }; } // wire_recv with a deadline, as Base's TCP.poll: None past it function wire_recv_timeout(socket, max, ms, k) { const sys = io_sys(); const fd = socket; const b = new Uint8Array(Math.max(Number(max), 1)); const again = sys.mac ? 35 : 11; const at = performance.now() + Number(ms); const go = () => { const n = Number(sys.recv(fd, sys.ptr(b), Number(max), 0)); if (n >= 0) { return io_tup(socket, io_done({ $: "Some", value: gw_list(b, n) })); } const code = sys.errno(); if (code !== again) { return io_tup(socket, io_fail(code)); } if (performance.now() >= at) { return io_tup(socket, io_done({ $: "None" })); } io_park_on(fd, false, k, go, at); return undefined; }; return go(); } function wire_send(socket, data, k) { const sys = io_sys(); const fd = socket; const bytes = []; for (let xs = data; xs.$ === "Con"; xs = xs.tail) { bytes.push(xs.head); } if (bytes.some((x) => x > 255)) { return io_tup(socket, io_fail(22)); } const b = Uint8Array.from(bytes); const again = sys.mac ? 35 : 11; const go = (at) => { while (at < b.length) { const part = b.subarray(at); const n = Number(sys.send(fd, sys.ptr(part), part.length, 0)); if (n < 0) { const code = sys.errno(); if (code === again) { io_park_on(fd, true, k, () => go(at)); return undefined; } return io_tup(socket, io_fail(code)); } at += n; } return io_tup(socket, io_done({ $: "Unit" })); }; return go(0); }