( socket: Socket, options: UdsResponseReaderOptions, )
| 26 | } |
| 27 | |
| 28 | export function attachUdsResponseReader( |
| 29 | socket: Socket, |
| 30 | options: UdsResponseReaderOptions, |
| 31 | ): void { |
| 32 | let buffer = '' |
| 33 | let bufferBytes = 0 |
| 34 | let settled = false |
| 35 | const decoder = new StringDecoder('utf8') |
| 36 | |
| 37 | function cleanupListeners(): void { |
| 38 | socket.off('data', onData) |
| 39 | socket.off('error', onError) |
| 40 | socket.off('end', onEnd) |
| 41 | socket.off('close', onClose) |
| 42 | } |
| 43 | |
| 44 | function finish(error?: Error): void { |
| 45 | if (settled) return |
| 46 | settled = true |
| 47 | buffer = '' |
| 48 | bufferBytes = 0 |
| 49 | cleanupListeners() |
| 50 | if (error) { |
| 51 | socket.destroy() |
| 52 | } else { |
| 53 | socket.end() |
| 54 | } |
| 55 | options.onSettled(error) |
| 56 | } |
| 57 | |
| 58 | function onData(chunk: Buffer): void { |
| 59 | const decoded = decoder.write(chunk) |
| 60 | const decodedBytes = Buffer.byteLength(decoded, 'utf8') |
| 61 | if (bufferBytes + decodedBytes > options.maxFrameBytes) { |
| 62 | finish(new Error('UDS response frame exceeded size limit')) |
| 63 | return |
| 64 | } |
| 65 | |
| 66 | buffer += decoded |
| 67 | bufferBytes += decodedBytes |
| 68 | let newlineIndex = buffer.indexOf('\n') |
| 69 | while (newlineIndex !== -1) { |
| 70 | const line = buffer.slice(0, newlineIndex) |
| 71 | const consumed = buffer.slice(0, newlineIndex + 1) |
| 72 | buffer = buffer.slice(newlineIndex + 1) |
| 73 | bufferBytes -= Buffer.byteLength(consumed, 'utf8') |
| 74 | if (!line.trim()) { |
| 75 | newlineIndex = buffer.indexOf('\n') |
| 76 | continue |
| 77 | } |
| 78 | let response: UdsMessage |
| 79 | try { |
| 80 | response = parseResponseLine(line) |
| 81 | } catch (error) { |
| 82 | finish(error instanceof Error ? error : new Error(errorMessage(error))) |
| 83 | return |
| 84 | } |
| 85 | if ( |
no test coverage detected