import { ChunkCombiner , createTextDecoderCombiner } from './chunkCombiner' ; import { CommunicationObserver } from './CommunicationObserver' ; import { Cancellable } from './Cancellable' ; param target param chunks returns export function chunksToLines ( target , chunkCombiner ? ) { const chunks = chunkCombiner ?? createTextDecoderCombiner ( ) ; let previous ; let finished = false ; let quoted = false ; function bufferReceived ( chunk ) { let index ; let start = 0 ; if ( previous ) { chunk = chunks . concat ( previous , chunk ) ; index = ( previous as Buffer ) . length ; } else { index = 0 ; } while ( index < chunk . length ) { const c = chunk [ index ] ; if ( c === 10 ) { if ( ! quoted ) { const end = index > 0 && chunk [ index - 1 ] === 13 ? index - 1 : index ; if ( finished ) { return ; } target . next ( chunks . toUtf8String ( chunk , start , end ) ) ; start = index + 1 ; } } else if ( c === 34 ) { quoted = ! quoted ; } index ++ ; } if ( start < index ) { previous = chunks . copy ( chunk , start , index ) ; } else { previous = undefined ; } } return { next ( chunk ) { if ( finished ) return ; try { bufferReceived ( chunk ) ; } catch ( e ) { this . error ( e as Error ) ; } } , error ( error ) { if ( ! finished ) { finished = true ; target . error ( error ) ; } } , complete ( ) { if ( ! finished ) { if ( previous ) { target . next ( chunks . toUtf8String ( previous , 0 , previous . length ) ) ; } finished = true ; target . complete ( ) ; } } , useCancellable ( cancellable ) { if ( target . useCancellable ) { const self = this ; target . useCancellable ( { cancel ( ) { cancellable . cancel ( ) ; previous = undefined ; self . complete ( ) ; } , isCancelled ( ) { return cancellable . isCancelled ( ) ; } , } ) ; } } , } ; }