dumb version
This commit is contained in:
parent
db737af36f
commit
af00baa6bc
|
@ -5,6 +5,19 @@ import { Duplex } from "node:stream";
|
||||||
type WriteCallback = (error: Error | null | undefined) => void;
|
type WriteCallback = (error: Error | null | undefined) => void;
|
||||||
type ServerHandlerCallback = (reply: "reply" | "noreply", ...extraArgs: any[]) => any;
|
type ServerHandlerCallback = (reply: "reply" | "noreply", ...extraArgs: any[]) => any;
|
||||||
type ServerHandler = (term: any, from: any, state: any, callback: ServerHandlerCallback) => void;
|
type ServerHandler = (term: any, from: any, state: any, callback: ServerHandlerCallback) => void;
|
||||||
|
/**
|
||||||
|
* Only handles Buffers.
|
||||||
|
*/
|
||||||
|
export declare class DumbPort extends Duplex {
|
||||||
|
private static readonly LEN_LEN;
|
||||||
|
private buf;
|
||||||
|
constructor();
|
||||||
|
_read(): Buffer | null;
|
||||||
|
_write(obj: any, encodingOrCallback?: BufferEncoding | WriteCallback, callback?: WriteCallback | undefined): void;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Handles full Erlang/Elixir terms.
|
||||||
|
*/
|
||||||
export declare class Port extends Duplex {
|
export declare class Port extends Duplex {
|
||||||
readonly bert: Bert;
|
readonly bert: Bert;
|
||||||
private lenBuffer;
|
private lenBuffer;
|
||||||
|
|
|
@ -1,6 +1,48 @@
|
||||||
import { Bert } from "./bert.js";
|
import { Bert } from "./bert.js";
|
||||||
import { Duplex } from "node:stream";
|
import { Duplex } from "node:stream";
|
||||||
const log = (msg) => process.stderr.write(`${msg}\r\n`);
|
const log = (msg) => process.stderr.write(`${msg}\r\n`);
|
||||||
|
/**
|
||||||
|
* Only handles Buffers.
|
||||||
|
*/
|
||||||
|
export class DumbPort extends Duplex {
|
||||||
|
static LEN_LEN = 2;
|
||||||
|
buf;
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.buf = Buffer.alloc(65_535 + DumbPort.LEN_LEN);
|
||||||
|
process.stdin.on("readable", () => {
|
||||||
|
while (this._read())
|
||||||
|
;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
_read() {
|
||||||
|
const lenBuf = process.stdin.read(DumbPort.LEN_LEN);
|
||||||
|
if (lenBuf) {
|
||||||
|
// Update this if you update LEN_LEN
|
||||||
|
const len = lenBuf.readUInt16BE(0);
|
||||||
|
const buf = process.stdin.read(len);
|
||||||
|
this.push(buf);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.push(null);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_write(obj, encodingOrCallback, callback) {
|
||||||
|
const actualCallback = callback || typeof encodingOrCallback === "function" ? encodingOrCallback : undefined;
|
||||||
|
if (Buffer.isBuffer(obj)) {
|
||||||
|
this.buf.writeUInt32BE(obj.byteLength);
|
||||||
|
obj.copy(this.buf, DumbPort.LEN_LEN);
|
||||||
|
process.stdout.write(this.buf.subarray(0, obj.byteLength + DumbPort.LEN_LEN), actualCallback);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new Error("write was passed non-Buffer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Handles full Erlang/Elixir terms.
|
||||||
|
*/
|
||||||
export class Port extends Duplex {
|
export class Port extends Duplex {
|
||||||
bert;
|
bert;
|
||||||
lenBuffer = Buffer.alloc(4);
|
lenBuffer = Buffer.alloc(4);
|
||||||
|
|
48
src/main.ts
48
src/main.ts
|
@ -8,6 +8,54 @@ type ServerHandler = (term: any, from: any, state: any, callback: ServerHandlerC
|
||||||
|
|
||||||
const log = (msg: string) => process.stderr.write(`${msg}\r\n`);
|
const log = (msg: string) => process.stderr.write(`${msg}\r\n`);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only handles Buffers.
|
||||||
|
*/
|
||||||
|
export class DumbPort extends Duplex {
|
||||||
|
private static readonly LEN_LEN = 2;
|
||||||
|
private buf;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.buf = Buffer.alloc(65_535 + DumbPort.LEN_LEN);
|
||||||
|
process.stdin.on("readable", () => {
|
||||||
|
while (this._read());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_read() {
|
||||||
|
const lenBuf: Buffer | null = process.stdin.read(DumbPort.LEN_LEN);
|
||||||
|
if (lenBuf) {
|
||||||
|
// Update this if you update LEN_LEN
|
||||||
|
const len = lenBuf.readUInt16BE(0);
|
||||||
|
const buf: Buffer | null = process.stdin.read(len);
|
||||||
|
this.push(buf);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.push(null);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override _write(obj: any, encodingOrCallback?: BufferEncoding | WriteCallback, callback?: WriteCallback | undefined) {
|
||||||
|
const actualCallback: any = callback || typeof encodingOrCallback === "function" ? encodingOrCallback : undefined;
|
||||||
|
|
||||||
|
if (Buffer.isBuffer(obj)) {
|
||||||
|
this.buf.writeUInt32BE(obj.byteLength);
|
||||||
|
obj.copy(this.buf, DumbPort.LEN_LEN);
|
||||||
|
process.stdout.write(
|
||||||
|
this.buf.subarray(0, obj.byteLength + DumbPort.LEN_LEN),
|
||||||
|
actualCallback
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else throw new Error("write was passed non-Buffer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles full Erlang/Elixir terms.
|
||||||
|
*/
|
||||||
export class Port extends Duplex {
|
export class Port extends Duplex {
|
||||||
public readonly bert: Bert;
|
public readonly bert: Bert;
|
||||||
private lenBuffer = Buffer.alloc(4);
|
private lenBuffer = Buffer.alloc(4);
|
||||||
|
|
Loading…
Reference in New Issue