import { isPlatformSupported } from '../helper' ; import { supportedError } from '../errors' ; import windows from './windows' ; import mac from './mac' ; import linux from './linux' ; import { extendedPingOptions , pingResponse } from '../types' ; import { ERROR_MESSAGES } from '../messages' ; import parser from "./parser.interface" ; function parserFactory ( platform , output ? , options ? ) { let parser ; let isWindows = false ; if ( ! isPlatformSupported ( platform ) ) { throw new supportedError ( ERROR_MESSAGES . PLATFORM_NOT_SUPPORTED . replace ( 'platform' , platform ) ) ; } if ( platform === 'win32' ) { parser = new windows ( defaultResponse , options ) ; isWindows = true ; } else if ( platform === 'darwin' ) { parser = new mac ( defaultResponse , options ) ; } else { parser = new linux ( defaultResponse , options ) ; } let result = parseOutput ( parser , isWindows , output ) ; return result ; } function parseOutput ( parser , isWindows , output ? ) { let lines = output ?. join ( '' ) . split ( '\n' ) ; let state = 0 ; let parsedOutput = defaultResponse ; lines ?. forEach ( ( line ) => { line = line . replace ( stripRegex , '' ) ; if ( line . length === 0 ) { } else if ( state === states . HEADER ) { parser . processHeader ( line ) ; state = states . BODY ; } else if ( state === states . BODY ) { ( ! checkIfBodyEnded ( line , isWindows ) ) ? parser . processBody ( line ) : state = states . FOOTER ; } else if ( state === states . FOOTER ) { parsedOutput = parser . processFooter ( line ) ; } } ) ; let result = createResult ( parsedOutput , lines ) ; return result ; } function checkIfBodyEnded ( line , windows ) { if ( windows ) { let isPingSummaryLineShown = line . slice ( - 1 ) === ':' ; if ( isPingSummaryLineShown ) { return true ; } } else { if ( line . indexOf ( '---' ) >= 0 ) { return true ; } } return false ; } function createResult ( result , lines ? ) { result . output = lines ?. join ( '\n' ) ; result . alive = result ?. times ?. length > 0 ; if ( result . alive ) { result . time = result . times [ 0 ] ; } if ( result . stddev === undefined && result . alive ) { let N = result . times . length ; const mean = result . times . reduce ( ( a , b ) => a + b ) / N ; const stddev = Math . sqrt ( result . times . map ( x => Math . pow ( x - mean , 2 ) ) . reduce ( ( a , b ) => a + b ) / N ) ; result . stddev = stddev ; } [ 'min' , 'avg' , 'max' , 'stddev' , 'packetLoss' ] . forEach ( ( key ) => { let v = ( result as any ) [ key ] ; if ( typeof v === 'number' ) { ( result as any ) [ key ] = v . toFixed ( 3 ) ; } } ) ; return result ; } const defaultResponse = { host : undefined , numericHost : undefined , alive : false , output : undefined , time : undefined , times : [ ] , min : undefined , max : undefined , avg : undefined , stddev : undefined , packetLoss : undefined , bufferSize : undefined } ; const stripRegex = /[ ]*\r?\n?$/g ; const states = { HEADER : 0 , BODY : 1 , FOOTER : 2 } ; export default parserFactory ;