1/** 2 * Copyright 2018 Google Inc. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16import { 17 helper, 18 debugError, 19 PuppeteerEventListener, 20} from '../common/helper.js'; 21import { ConnectionTransport } from '../common/ConnectionTransport.js'; 22 23export class PipeTransport implements ConnectionTransport { 24 _pipeWrite: NodeJS.WritableStream; 25 _pendingMessage: string; 26 _eventListeners: PuppeteerEventListener[]; 27 28 onclose?: () => void; 29 onmessage?: () => void; 30 31 constructor( 32 pipeWrite: NodeJS.WritableStream, 33 pipeRead: NodeJS.ReadableStream 34 ) { 35 this._pipeWrite = pipeWrite; 36 this._pendingMessage = ''; 37 this._eventListeners = [ 38 helper.addEventListener(pipeRead, 'data', (buffer) => 39 this._dispatch(buffer) 40 ), 41 helper.addEventListener(pipeRead, 'close', () => { 42 if (this.onclose) this.onclose.call(null); 43 }), 44 helper.addEventListener(pipeRead, 'error', debugError), 45 helper.addEventListener(pipeWrite, 'error', debugError), 46 ]; 47 this.onmessage = null; 48 this.onclose = null; 49 } 50 51 send(message: string): void { 52 this._pipeWrite.write(message); 53 this._pipeWrite.write('\0'); 54 } 55 56 _dispatch(buffer: Buffer): void { 57 let end = buffer.indexOf('\0'); 58 if (end === -1) { 59 this._pendingMessage += buffer.toString(); 60 return; 61 } 62 const message = this._pendingMessage + buffer.toString(undefined, 0, end); 63 if (this.onmessage) this.onmessage.call(null, message); 64 65 let start = end + 1; 66 end = buffer.indexOf('\0', start); 67 while (end !== -1) { 68 if (this.onmessage) 69 this.onmessage.call(null, buffer.toString(undefined, start, end)); 70 start = end + 1; 71 end = buffer.indexOf('\0', start); 72 } 73 this._pendingMessage = buffer.toString(undefined, start); 74 } 75 76 close(): void { 77 this._pipeWrite = null; 78 helper.removeEventListeners(this._eventListeners); 79 } 80} 81