nstdlib-nightly
Version:
Node.js standard library converted to runtime-agnostic ES modules.
151 lines (127 loc) • 3.48 kB
JavaScript
// Source: https://github.com/nodejs/node/blob/65eff1eb/lib/internal/socketaddress.js
import {
SocketAddress as _SocketAddress,
AF_INET,
AF_INET6,
} from "nstdlib/stub/binding/block_list";
import {
validateObject,
validateString,
validatePort,
validateUint32,
} from "nstdlib/lib/internal/validators";
import { codes as __codes__ } from "nstdlib/lib/internal/errors";
import {
customInspectSymbol as kInspect,
kEmptyObject,
} from "nstdlib/lib/internal/util";
import { inspect } from "nstdlib/lib/internal/util/inspect";
import {
markTransferMode,
kClone,
kDeserialize,
} from "nstdlib/lib/internal/worker/js_transferable";
const { ERR_INVALID_ARG_VALUE } = __codes__;
const kHandle = Symbol("kHandle");
const kDetail = Symbol("kDetail");
class SocketAddress {
static isSocketAddress(value) {
return value?.[kHandle] !== undefined;
}
constructor(options = kEmptyObject) {
markTransferMode(this, true, false);
validateObject(options, "options");
let { family = "ipv4" } = options;
const {
address = family === "ipv4" ? "127.0.0.1" : "::",
port = 0,
flowlabel = 0,
} = options;
let type;
if (typeof family?.toLowerCase === "function")
family = family.toLowerCase();
switch (family) {
case "ipv4":
type = AF_INET;
break;
case "ipv6":
type = AF_INET6;
break;
default:
throw new ERR_INVALID_ARG_VALUE("options.family", options.family);
}
validateString(address, "options.address");
validatePort(port, "options.port");
validateUint32(flowlabel, "options.flowlabel", false);
this[kHandle] = new _SocketAddress(address, port, type, flowlabel);
this[kDetail] = this[kHandle].detail({
address: undefined,
port: undefined,
family: undefined,
flowlabel: undefined,
});
}
get address() {
return this[kDetail].address;
}
get port() {
return this[kDetail].port;
}
get family() {
return this[kDetail].family === AF_INET ? "ipv4" : "ipv6";
}
get flowlabel() {
// The flow label can be changed internally.
return this[kHandle].flowlabel();
}
[kInspect](depth, options) {
if (depth < 0) return this;
const opts = {
...options,
depth: options.depth == null ? null : options.depth - 1,
};
return `SocketAddress ${inspect(this.toJSON(), opts)}`;
}
[kClone]() {
const handle = this[kHandle];
return {
data: { handle },
deserializeInfo: "internal/socketaddress:InternalSocketAddress",
};
}
[kDeserialize]({ handle }) {
this[kHandle] = handle;
this[kDetail] = handle.detail({
address: undefined,
port: undefined,
family: undefined,
flowlabel: undefined,
});
}
toJSON() {
return {
address: this.address,
port: this.port,
family: this.family,
flowlabel: this.flowlabel,
};
}
}
class InternalSocketAddress {
constructor(handle) {
markTransferMode(this, true, false);
this[kHandle] = handle;
this[kDetail] = this[kHandle]?.detail({
address: undefined,
port: undefined,
family: undefined,
flowlabel: undefined,
});
}
}
InternalSocketAddress.prototype.constructor =
SocketAddress.prototype.constructor;
Object.setPrototypeOf(InternalSocketAddress.prototype, SocketAddress.prototype);
export { SocketAddress };
export { InternalSocketAddress };
export { kHandle };