src/vs/workbench/services/extensions/common/rpcProtocol.ts
968 LOC · 889 covered · 79 uncovered · 262 ranges · 110 concepts · 35 introducers · 55 tests
File neighbourhood
The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.
Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file
In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.
Graph controls are ready.
Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.
/*---------------------------------------------------------------------------------------------
rpcProtocol.ts ×73
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { RunOnceScheduler } from '../../../../base/common/async.js';
import { VSBuffer } from '../../../../base/common/buffer.js';
import { CancellationToken, CancellationTokenSource } from '../../../../base/common/cancellation.js';
import { CharCode } from '../../../../base/common/charCode.js';
import * as errors from '../../../../base/common/errors.js';
import { Emitter, Event } from '../../../../base/common/event.js';
import { Disposable, DisposableStore, IDisposable } from '../../../../base/common/lifecycle.js';
import { MarshalledObject } from '../../../../base/common/marshalling.js';
import { MarshalledId } from '../../../../base/common/marshallingIds.js';
import { IURITransformer, transformIncomingURIs } from '../../../../base/common/uriIpc.js';
import { IMessagePassingProtocol } from '../../../../base/parts/ipc/common/ipc.js';
import { CanceledLazyPromise, LazyPromise } from './lazyPromise.js';
import { getStringIdentifierForProxy, IRPCProtocol, Proxied, ProxyIdentifier, SerializableObjectWithBuffers } from './proxyIdentifier.js';
export interface JSONStringifyReplacer {
(key: string, value: any): any;
}
function safeStringify(obj: any, replacer: JSONStringifyReplacer | null): string {
rpcProtocol.ts ×2
try {
return JSON.stringify(obj, <(key: string, value: any) => any>replacer);
} catch (err) {
}
const refSymbolName = '$$ref$$';
const undefinedRef = { [refSymbolName]: -1 } as const;
class StringifiedJsonWithBufferRefs {
constructor(
public readonly jsonString: string,
public readonly referencedBuffers: readonly VSBuffer[],
) { }
export function stringifyJsonWithBufferRefs<T>(obj: T, replacer: JSONStringifyReplacer | null = null, useSafeStringify = false): StringifiedJsonWithBufferRefs {
const serialized = (useSafeStringify ? safeStringify : JSON.stringify)(obj, (key, value) => {
if (typeof value === 'undefined') {
return undefinedRef; // JSON.stringify normally converts 'undefined' to 'null'
if (value instanceof VSBuffer) {
const bufferIndex = foundBuffers.push(value) - 1;
return { [refSymbolName]: bufferIndex };
}
if (replacer) {
return replacer(key, value);
}
return value;
});
return {
jsonString: serialized,
referencedBuffers: foundBuffers
};
}
export function parseJsonAndRestoreBufferRefs(jsonString: string, buffers: readonly VSBuffer[], uriTransformer: IURITransformer | null): any {
if (value) {
const ref = value[refSymbolName];
if (typeof ref === 'number') {
return buffers[ref];
}
if (uriTransformer && (<MarshalledObject>value).$mid === MarshalledId.Uri) {
return uriTransformer.transformIncoming(value);
}
return value;
});
}
function stringify(obj: any, replacer: JSONStringifyReplacer | null): string {
rpcProtocol.ts ×1
return JSON.stringify(obj, <(key: string, value: any) => any>replacer);
}
function createURIReplacer(transformer: IURITransformer | null): JSONStringifyReplacer | null {
rpcProtocol.ts ×13
if (!transformer) {
return null;
}
return (key: string, value: any): any => {
if (value && value.$mid === MarshalledId.Uri) {
return transformer.transformOutgoing(value);
}
return value;
};
}
export const enum RequestInitiator {
LocalSide = 0,
OtherSide = 1
}
export const enum ResponsiveState {
Responsive = 0,
Unresponsive = 1
}
export interface IRPCProtocolLogger {
logIncoming(msgLength: number, req: number, initiator: RequestInitiator, str: string, data?: any): void;
logOutgoing(msgLength: number, req: number, initiator: RequestInitiator, str: string, data?: any): void;
}
const noop = () => { };
const _RPCProtocolSymbol = Symbol.for('rpcProtocol');
const _RPCProxySymbol = Symbol.for('rpcProxy');
export class RPCProtocol extends Disposable implements IRPCProtocol {
[_RPCProtocolSymbol] = true;
private static readonly UNRESPONSIVE_TIME = 3 * 1000; // 3s
private readonly _onDidChangeResponsiveState: Emitter<ResponsiveState> = this._register(new Emitter<ResponsiveState>());
public readonly onDidChangeResponsiveState: Event<ResponsiveState> = this._onDidChangeResponsiveState.event;
private readonly _protocol: IMessagePassingProtocol;
private readonly _logger: IRPCProtocolLogger | null;
private readonly _uriTransformer: IURITransformer | null;
private readonly _uriReplacer: JSONStringifyReplacer | null;
private _isDisposed: boolean;
private readonly _locals: any[];
private readonly _proxies: any[];
private _lastMessageId: number;
private readonly _cancelInvokedHandlers: { [req: string]: () => void };
private readonly _pendingRPCReplies: { [msgId: string]: PendingRPCReply };
private _responsiveState: ResponsiveState;
private _unacknowledgedCount: number;
private _unresponsiveTime: number;
private _asyncCheckUresponsive: RunOnceScheduler;
constructor(protocol: IMessagePassingProtocol, logger: IRPCProtocolLogger | null = null, transformer: IURITransformer | null = null) {
this._protocol = protocol;
this._logger = logger;
this._uriTransformer = transformer;
this._uriReplacer = createURIReplacer(this._uriTransformer);
this._isDisposed = false;
this._locals = [];
this._proxies = [];
for (let i = 0, len = ProxyIdentifier.count; i < len; i++) {
this._locals[i] = null;
this._proxies[i] = null;
}
this._cancelInvokedHandlers = Object.create(null);
this._pendingRPCReplies = {};
this._responsiveState = ResponsiveState.Responsive;
this._unacknowledgedCount = 0;
this._unresponsiveTime = 0;
this._asyncCheckUresponsive = this._register(new RunOnceScheduler(() => this._checkUnresponsive(), 1000));
this._register(this._protocol.onMessage((msg) => this._receiveOneMessage(msg)));
}
public override dispose(): void {
// Release all outstanding promises with a canceled error
Object.keys(this._pendingRPCReplies).forEach((msgId) => {
const pending = this._pendingRPCReplies[msgId];
delete this._pendingRPCReplies[msgId];
pending.resolveErr(errors.canceled());
super.dispose();
}
public drain(): Promise<void> {
if (typeof this._protocol.drain === 'function') {
return this._protocol.drain();
}
return Promise.resolve();
}
private _onWillSendRequest(req: number): void {
// Since this is the first request we are sending in a while,
// mark this moment as the start for the countdown to unresponsive time
this._unresponsiveTime = Date.now() + RPCProtocol.UNRESPONSIVE_TIME;
}
this._unacknowledgedCount++;
if (!this._asyncCheckUresponsive.isScheduled()) {
this._asyncCheckUresponsive.schedule();
}
}
private _onDidReceiveAcknowledge(req: number): void {
this._unresponsiveTime = Date.now() + RPCProtocol.UNRESPONSIVE_TIME;
this._unacknowledgedCount--;
if (this._unacknowledgedCount === 0) {
// No more need to check for unresponsive
this._asyncCheckUresponsive.cancel();
}
// The ext host is responsive!
this._setResponsiveState(ResponsiveState.Responsive);
}
private _checkUnresponsive(): void {
if (this._unacknowledgedCount === 0) {
// Not waiting for anything => cannot say if it is responsive or not
return;
}
if (Date.now() > this._unresponsiveTime) {
// Unresponsive!!
this._setResponsiveState(ResponsiveState.Unresponsive);
} else {
// Not (yet) unresponsive, be sure to check again soon
this._asyncCheckUresponsive.schedule();
}
}
private _setResponsiveState(newResponsiveState: ResponsiveState): void {
// no change
return;
}
this._responsiveState = newResponsiveState;
this._onDidChangeResponsiveState.fire(this._responsiveState);
public get responsiveState(): ResponsiveState {
return this._responsiveState;
}
public transformIncomingURIs<T>(obj: T): T {
if (!this._uriTransformer) {
return obj;
}
return transformIncomingURIs(obj, this._uriTransformer);
}
public getProxy<T>(identifier: ProxyIdentifier<T>): Proxied<T> {
if (!this._proxies[rpcId]) {
this._proxies[rpcId] = this._createProxy(rpcId, sid);
}
return this._proxies[rpcId];
}
private _createProxy<T>(rpcId: number, debugName: string): T {
get: (target: any, name: PropertyKey) => {
if (typeof name === 'string' && !target[name] && name.charCodeAt(0) === CharCode.DollarSign) {
target[name] = (...myArgs: any[]) => {
return this._remoteCall(rpcId, name, myArgs);
};
}
if (name === _RPCProxySymbol) {
return debugName;
}
}
};
return new Proxy(Object.create(null), handler);
}
public set<T, R extends T>(identifier: ProxyIdentifier<T>, value: R): R {
return value;
}
public assertRegistered(identifiers: ProxyIdentifier<any>[]): void {
for (let i = 0, len = identifiers.length; i < len; i++) {
const identifier = identifiers[i];
if (!this._locals[identifier.nid]) {
throw new Error(`Missing proxy instance ${identifier.sid}`);
}
}
}
private _receiveOneMessage(rawmsg: VSBuffer): void {
return;
}
const msgLength = rawmsg.byteLength;
const buff = MessageBuffer.read(rawmsg, 0);
const messageType = <MessageType>buff.readUInt8();
const req = buff.readUInt32();
switch (messageType) {
case MessageType.RequestJSONArgs:
case MessageType.RequestJSONArgsWithCancellation: {
if (this._uriTransformer) {
args = transformIncomingURIs(args, this._uriTransformer);
}
this._receiveRequest(msgLength, req, rpcId, method, args, (messageType === MessageType.RequestJSONArgsWithCancellation));
rpcProtocol.ts ×5
break;
}
case MessageType.RequestMixedArgsWithCancellation: {
if (this._uriTransformer) {
args = transformIncomingURIs(args, this._uriTransformer);
}
this._receiveRequest(msgLength, req, rpcId, method, args, (messageType === MessageType.RequestMixedArgsWithCancellation));
rpcProtocol.ts ×26
break;
}
this._logger?.logIncoming(msgLength, req, RequestInitiator.LocalSide, `ack`);
this._onDidReceiveAcknowledge(req);
break;
}
case MessageType.Cancel: {
break;
}
break;
}
if (this._uriTransformer) {
value = transformIncomingURIs(value, this._uriTransformer);
}
break;
}
const value = MessageIO.deserializeReplyOKJSONWithBuffers(buff, this._uriTransformer);
rpcProtocol.ts ×15
this._receiveReply(msgLength, req, value);
break;
}
this._receiveReply(msgLength, req, value);
break;
}
if (this._uriTransformer) {
err = transformIncomingURIs(err, this._uriTransformer);
}
break;
}
break;
}
console.error(`received unexpected message`);
console.error(rawmsg);
}
private _receiveRequest(msgLength: number, req: number, rpcId: number, method: string, args: any[], usesCancellationToken: boolean): void {
this._logger?.logIncoming(msgLength, req, RequestInitiator.OtherSide, `receiveRequest ${getStringIdentifierForProxy(rpcId)}.${method}(`, args);
rpcProtocol.ts ×47
const callId = String(req);
let promise: Promise<any>;
let cancel: () => void;
if (usesCancellationToken) {
args.push(cancellationTokenSource.token);
promise = this._invokeHandler(rpcId, method, args);
cancel = () => cancellationTokenSource.cancel();
promise = this._invokeHandler(rpcId, method, args);
cancel = noop;
}
this._cancelInvokedHandlers[callId] = cancel;
// Acknowledge the request
const msg = MessageIO.serializeAcknowledged(req);
this._logger?.logOutgoing(msg.byteLength, req, RequestInitiator.OtherSide, `ack`);
this._protocol.send(msg);
promise.then((r) => {
const msg = MessageIO.serializeReplyOK(req, r, this._uriReplacer);
this._logger?.logOutgoing(msg.byteLength, req, RequestInitiator.OtherSide, `reply:`, r);
this._protocol.send(msg);
const msg = MessageIO.serializeReplyErr(req, err);
this._logger?.logOutgoing(msg.byteLength, req, RequestInitiator.OtherSide, `replyErr:`, err);
this._protocol.send(msg);
}
private _receiveCancel(msgLength: number, req: number): void {
this._logger?.logIncoming(msgLength, req, RequestInitiator.OtherSide, `receiveCancel`);
rpcProtocol.ts ×4
const callId = String(req);
this._cancelInvokedHandlers[callId]?.();
}
private _receiveReply(msgLength: number, req: number, value: any): void {
this._logger?.logIncoming(msgLength, req, RequestInitiator.LocalSide, `receiveReply:`, value);
rpcProtocol.ts ×7
const callId = String(req);
if (!this._pendingRPCReplies.hasOwnProperty(callId)) {
return;
}
const pendingReply = this._pendingRPCReplies[callId];
delete this._pendingRPCReplies[callId];
pendingReply.resolveOk(value);
}
private _receiveReplyErr(msgLength: number, req: number, value: any): void {
this._logger?.logIncoming(msgLength, req, RequestInitiator.LocalSide, `receiveReplyErr:`, value);
rpcProtocol.ts ×7
const callId = String(req);
if (!this._pendingRPCReplies.hasOwnProperty(callId)) {
return;
}
const pendingReply = this._pendingRPCReplies[callId];
delete this._pendingRPCReplies[callId];
let err: any = undefined;
if (value) {
err.name = value.name;
err.message = value.message;
err.stack = value.stack;
}
}
private _invokeHandler(rpcId: number, methodName: string, args: any[]): Promise<any> {
return Promise.resolve(this._doInvokeHandler(rpcId, methodName, args));
} catch (err) {
}
private _doInvokeHandler(rpcId: number, methodName: string, args: any[]): any {
if (!actor) {
throw new Error('Unknown actor ' + getStringIdentifierForProxy(rpcId));
}
if (typeof method !== 'function') {
throw new Error('Unknown method ' + methodName + ' on actor ' + getStringIdentifierForProxy(rpcId));
}
}
private _remoteCall(rpcId: number, methodName: string, args: any[]): Promise<any> {
return new CanceledLazyPromise();
}
if (args.length > 0 && CancellationToken.isCancellationToken(args[args.length - 1])) {
}
if (cancellationToken && cancellationToken.isCancellationRequested) {
return Promise.reject<any>(errors.canceled());
}
const serializedRequestArguments = MessageIO.serializeRequestArguments(args, this._uriReplacer);
const req = ++this._lastMessageId;
const callId = String(req);
const result = new LazyPromise();
const disposable = new DisposableStore();
if (cancellationToken) {
this._logger?.logOutgoing(msg.byteLength, req, RequestInitiator.LocalSide, `cancel`);
this._protocol.send(msg);
}
this._pendingRPCReplies[callId] = new PendingRPCReply(result, disposable);
this._onWillSendRequest(req);
const msg = MessageIO.serializeRequest(req, rpcId, methodName, serializedRequestArguments, !!cancellationToken);
this._logger?.logOutgoing(msg.byteLength, req, RequestInitiator.LocalSide, `request: ${getStringIdentifierForProxy(rpcId)}.${methodName}(`, args);
rpcProtocol.ts ×13
this._protocol.send(msg);
return result;
}
class PendingRPCReply {
constructor(
private readonly _disposable: IDisposable
) { }
public resolveOk(value: any): void {
this._disposable.dispose();
}
public resolveErr(err: any): void {
this._disposable.dispose();
}
class MessageBuffer {
public static alloc(type: MessageType, req: number, messageSize: number): MessageBuffer {
const result = new MessageBuffer(VSBuffer.alloc(messageSize + 1 /* type */ + 4 /* req */), 0);
rpcProtocol.ts ×47
result.writeUInt8(type);
result.writeUInt32(req);
return result;
}
public static read(buff: VSBuffer, offset: number): MessageBuffer {
}
private _buff: VSBuffer;
private _offset: number;
public get buffer(): VSBuffer {
}
private constructor(buff: VSBuffer, offset: number) {
this._offset = offset;
}
public static sizeUInt8(): number {
}
public static readonly sizeUInt32 = 4;
public writeUInt8(n: number): void {
}
public readUInt8(): number {
return n;
}
public writeUInt32(n: number): void {
}
public readUInt32(): number {
return n;
}
public static sizeShortString(str: VSBuffer): number {
}
public writeShortString(str: VSBuffer): void {
this._buff.set(str, this._offset); this._offset += str.byteLength;
}
public readShortString(): string {
const strByteLength = this._buff.readUInt8(this._offset); this._offset += 1;
rpcProtocol.ts ×47
const strBuff = this._buff.slice(this._offset, this._offset + strByteLength);
const str = strBuff.toString(); this._offset += strByteLength;
return str;
}
public static sizeLongString(str: VSBuffer): number {
}
public writeLongString(str: VSBuffer): void {
this._buff.set(str, this._offset); this._offset += str.byteLength;
}
public readLongString(): string {
const strByteLength = this._buff.readUInt32BE(this._offset); this._offset += 4;
rpcProtocol.ts ×47
const strBuff = this._buff.slice(this._offset, this._offset + strByteLength);
const str = strBuff.toString(); this._offset += strByteLength;
return str;
}
public writeBuffer(buff: VSBuffer): void {
this._buff.writeUInt32BE(buff.byteLength, this._offset); this._offset += 4;
rpcProtocol.ts ×15
this._buff.set(buff, this._offset); this._offset += buff.byteLength;
}
public static sizeVSBuffer(buff: VSBuffer): number {
}
public writeVSBuffer(buff: VSBuffer): void {
this._buff.set(buff, this._offset); this._offset += buff.byteLength;
}
public readVSBuffer(): VSBuffer {
const buffLength = this._buff.readUInt32BE(this._offset); this._offset += 4;
rpcProtocol.ts ×2
const buff = this._buff.slice(this._offset, this._offset + buffLength); this._offset += buffLength;
return buff;
}
public static sizeMixedArray(arr: readonly MixedArg[]): number {
size += 1; // arr length
for (let i = 0, len = arr.length; i < len; i++) {
const el = arr[i];
size += 1; // arg type
switch (el.type) {
case ArgType.String:
break;
break;
size += this.sizeLongString(el.value);
for (let i = 0; i < el.buffers.length; ++i) {
size += this.sizeVSBuffer(el.buffers[i]);
}
break;
break;
}
return size;
}
public writeMixedArray(arr: readonly MixedArg[]): void {
for (let i = 0, len = arr.length; i < len; i++) {
const el = arr[i];
switch (el.type) {
case ArgType.String:
this.writeLongString(el.value);
break;
this.writeVSBuffer(el.value);
break;
this.writeUInt32(el.buffers.length);
this.writeLongString(el.value);
for (let i = 0; i < el.buffers.length; ++i) {
this.writeBuffer(el.buffers[i]);
}
break;
break;
}
}
public readMixedArray(): Array<string | VSBuffer | SerializableObjectWithBuffers<any> | undefined> {
const arr: Array<string | VSBuffer | SerializableObjectWithBuffers<any> | undefined> = new Array(arrLen);
for (let i = 0; i < arrLen; i++) {
const argType = <ArgType>this.readUInt8();
switch (argType) {
case ArgType.String:
break;
break;
const jsonString = this.readLongString();
const buffers: VSBuffer[] = [];
for (let i = 0; i < bufferCount; ++i) {
buffers.push(this.readVSBuffer());
}
arr[i] = new SerializableObjectWithBuffers(parseJsonAndRestoreBufferRefs(jsonString, buffers, null));
break;
}
break;
}
return arr;
}
const enum SerializedRequestArgumentType {
Simple,
Mixed,
}
type SerializedRequestArguments =
| { readonly type: SerializedRequestArgumentType.Simple; args: string }
| { readonly type: SerializedRequestArgumentType.Mixed; args: MixedArg[] };
class MessageIO {
private static _useMixedArgSerialization(arr: any[]): boolean {
if (arr[i] instanceof VSBuffer) {
}
}
}
public static serializeRequestArguments(args: any[], replacer: JSONStringifyReplacer | null): SerializedRequestArguments {
for (let i = 0, len = args.length; i < len; i++) {
const arg = args[i];
if (arg instanceof VSBuffer) {
const { jsonString, referencedBuffers } = stringifyJsonWithBufferRefs(arg.value, replacer);
rpcProtocol.ts ×15
massagedArgs[i] = { type: ArgType.SerializedObjectWithBuffers, value: VSBuffer.fromString(jsonString), buffers: referencedBuffers };
massagedArgs[i] = { type: ArgType.String, value: VSBuffer.fromString(stringify(arg, replacer)) };
rpcProtocol.ts ×5
}
return {
type: SerializedRequestArgumentType.Mixed,
args: massagedArgs,
};
}
type: SerializedRequestArgumentType.Simple,
args: stringify(args, replacer)
};
public static serializeRequest(req: number, rpcId: number, method: string, serializedArgs: SerializedRequestArguments, usesCancellationToken: boolean): VSBuffer {
case SerializedRequestArgumentType.Simple:
return this._requestJSONArgs(req, rpcId, method, serializedArgs.args, usesCancellationToken);
rpcProtocol.ts ×5
return this._requestMixedArgs(req, rpcId, method, serializedArgs.args, usesCancellationToken);
rpcProtocol.ts ×26
}
private static _requestJSONArgs(req: number, rpcId: number, method: string, args: string, usesCancellationToken: boolean): VSBuffer {
const argsBuff = VSBuffer.fromString(args);
let len = 0;
len += MessageBuffer.sizeUInt8();
len += MessageBuffer.sizeShortString(methodBuff);
len += MessageBuffer.sizeLongString(argsBuff);
const result = MessageBuffer.alloc(usesCancellationToken ? MessageType.RequestJSONArgsWithCancellation : MessageType.RequestJSONArgs, req, len);
result.writeUInt8(rpcId);
result.writeShortString(methodBuff);
result.writeLongString(argsBuff);
return result.buffer;
}
public static deserializeRequestJSONArgs(buff: MessageBuffer): { rpcId: number; method: string; args: any[] } {
const method = buff.readShortString();
const args = buff.readLongString();
return {
rpcId: rpcId,
method: method,
args: JSON.parse(args)
};
}
private static _requestMixedArgs(req: number, rpcId: number, method: string, args: readonly MixedArg[], usesCancellationToken: boolean): VSBuffer {
let len = 0;
len += MessageBuffer.sizeUInt8();
len += MessageBuffer.sizeShortString(methodBuff);
len += MessageBuffer.sizeMixedArray(args);
const result = MessageBuffer.alloc(usesCancellationToken ? MessageType.RequestMixedArgsWithCancellation : MessageType.RequestMixedArgs, req, len);
result.writeUInt8(rpcId);
result.writeShortString(methodBuff);
result.writeMixedArray(args);
return result.buffer;
}
public static deserializeRequestMixedArgs(buff: MessageBuffer): { rpcId: number; method: string; args: any[] } {
const method = buff.readShortString();
const rawargs = buff.readMixedArray();
const args: any[] = new Array(rawargs.length);
for (let i = 0, len = rawargs.length; i < len; i++) {
const rawarg = rawargs[i];
if (typeof rawarg === 'string') {
args[i] = rawarg;
}
}
return {
rpcId: rpcId,
method: method,
args: args
};
}
public static serializeAcknowledged(req: number): VSBuffer {
}
public static serializeCancel(req: number): VSBuffer {
}
public static serializeReplyOK(req: number, res: any, replacer: JSONStringifyReplacer | null): VSBuffer {
const { jsonString, referencedBuffers } = stringifyJsonWithBufferRefs(res.value, replacer, true);
rpcProtocol.ts ×15
return this._serializeReplyOKJSONWithBuffers(req, jsonString, referencedBuffers);
}
private static _serializeReplyOKEmpty(req: number): VSBuffer {
}
private static _serializeReplyOKVSBuffer(req: number, res: VSBuffer): VSBuffer {
len += MessageBuffer.sizeVSBuffer(res);
const result = MessageBuffer.alloc(MessageType.ReplyOKVSBuffer, req, len);
result.writeVSBuffer(res);
return result.buffer;
}
public static deserializeReplyOKVSBuffer(buff: MessageBuffer): VSBuffer {
}
private static _serializeReplyOKJSON(req: number, res: string): VSBuffer {
let len = 0;
len += MessageBuffer.sizeLongString(resBuff);
const result = MessageBuffer.alloc(MessageType.ReplyOKJSON, req, len);
result.writeLongString(resBuff);
return result.buffer;
}
private static _serializeReplyOKJSONWithBuffers(req: number, res: string, buffers: readonly VSBuffer[]): VSBuffer {
let len = 0;
len += MessageBuffer.sizeUInt32; // buffer count
len += MessageBuffer.sizeLongString(resBuff);
for (const buffer of buffers) {
len += MessageBuffer.sizeVSBuffer(buffer);
}
const result = MessageBuffer.alloc(MessageType.ReplyOKJSONWithBuffers, req, len);
result.writeUInt32(buffers.length);
result.writeLongString(resBuff);
for (const buffer of buffers) {
result.writeBuffer(buffer);
}
return result.buffer;
}
public static deserializeReplyOKJSON(buff: MessageBuffer): any {
return JSON.parse(res);
}
public static deserializeReplyOKJSONWithBuffers(buff: MessageBuffer, uriTransformer: IURITransformer | null): SerializableObjectWithBuffers<any> {
const res = buff.readLongString();
const buffers: VSBuffer[] = [];
for (let i = 0; i < bufferCount; ++i) {
buffers.push(buff.readVSBuffer());
}
return new SerializableObjectWithBuffers(parseJsonAndRestoreBufferRefs(res, buffers, uriTransformer));
}
public static serializeReplyErr(req: number, err: any): VSBuffer {
const errStr: string | undefined = (err ? safeStringify(errors.transformErrorForSerialization(err), null) : undefined);
rpcProtocol.ts ×7
if (typeof errStr !== 'string') {
}
let len = 0;
len += MessageBuffer.sizeLongString(errBuff);
const result = MessageBuffer.alloc(MessageType.ReplyErrError, req, len);
result.writeLongString(errBuff);
return result.buffer;
public static deserializeReplyErrError(buff: MessageBuffer): Error {
return JSON.parse(err);
}
private static _serializeReplyErrEmpty(req: number): VSBuffer {
}
const enum MessageType {
RequestJSONArgs = 1,
RequestJSONArgsWithCancellation = 2,
RequestMixedArgs = 3,
RequestMixedArgsWithCancellation = 4,
Acknowledged = 5,
Cancel = 6,
ReplyOKEmpty = 7,
ReplyOKVSBuffer = 8,
ReplyOKJSON = 9,
ReplyOKJSONWithBuffers = 10,
ReplyErrError = 11,
ReplyErrEmpty = 12,
}
const enum ArgType {
String = 1,
VSBuffer = 2,
SerializedObjectWithBuffers = 3,
Undefined = 4,
}
type MixedArg =
| { readonly type: ArgType.String; readonly value: VSBuffer }
| { readonly type: ArgType.VSBuffer; readonly value: VSBuffer }
| { readonly type: ArgType.SerializedObjectWithBuffers; readonly value: VSBuffer; readonly buffers: readonly VSBuffer[] }
| { readonly type: ArgType.Undefined }
;