' EDX Data Parser ' Thursday, 2003-01-02 ' ' Crude EDX file parser (used by Alt4) ' given a file f containing the data of interest... f = "C:\data\rmr\Alt4\AEJ350.EDX" motordata = edxCookedData(f) thrust = edxThrustChart(motordata) for i = 0 to ubound(thrust) wscript.echo thrust(i)(0), thrust(i)(1) next function edxThrustChart(edxArray) ' given edxCookedData, this function extracts the thrust data points ' and returns it as an array containing ordered pairs of time/thrust ' data. dim aTmp(), i redim aTmp(-1) for i = 0 to ubound(edxArray) if edxArray(i)(0) = 20 then redim preserve aTmp( ubound(aTmp) + 1 ) aTmp(ubound(aTmp)) = Split( edxArray(i)(2), " ") end if next edxThrustChart = aTmp end function function edxCookedData(filepath) ' given the path to an EDX-format file, returns ' a nested array of trimmed and split data lines. ' This data is still "raw" in the sense that everything after column 20 ' is a blob in the final element of each subarray. ' Dependencies: ReadFile, LineNormalForm ' Argument(s): path to data ' Return(s): nested 0-based array of trimmed "raw" data. The top level ' elements correspond to non-blank lines in the original ' file - "blank" lines are lines containing nothing but ' whitespace, so lines such as the usually empty "Cost" ' line ARE returned, since they contain characters. ' Each of these elements in turn is an array of 3 elements: ' (0) - numeric designator for line ' (1) - Caption, with trailing "...:" removed ' (2) - string of the data which follows the caption. ' Example: Assume you called the function from script with a line ' of codelike this: ' motor = edxRawData("C:\tmp\dat.edx") ' and assume that dat.edx contains only the following two ' lines: ' ' 15 Favg Newtons.: 632.648 ' 20 Time /Thrust.: 2.30 200.877 ' ' motor would then be an array with elements motor(0) and ' motor(1); motor(0) and motor(1) in turn would be arrays, ' and the actual data contained would be ' motor(0)(0) = 15 ' motor(0)(1) = "Favg Newtons" ' motor(0)(2) = 632.648 ' motor(1)(0) = 20 ' motor(1)(1) = "Time /Thrust" ' motor(1)(2) = "2.30 200.877" Dim aData, aTmp(2), i ' using readfile, normalization, and VBScript's internal Split method, ' we can get the data into a semi-raw array in one step: aData = Split( LineNormalForm( ReadFile(filepath) ), vbCr) for i = 0 to ubound(aData) ' the intent of the EDX format seems to be actual column-based ' delimitation which is also readable. the following loop assumes ' the numeric designator is always in columns 1-2, the caption sans ' ":" is always in 5-17, and the data is everything in 20+. ' assuming alignment is generally correct, we will also trim the ' data again just in case there is excess white space. aTmp(0) = Trim(Left(aData(i), 2)) aTmp(1) = Mid(aData(i), 5, 13) Do While Right(aTmp(1), 1) = "." aTmp(1) = Left(aTmp(1), Len(aTmp(1)) - 1) Loop aTmp(1) = Trim(aTmp(1)) ' just in case WS is embedded... aTmp(2) = Trim(Mid(aData(i), 20)) ' now transfer cleaned data back into aData(i) aData(i) = aTmp next edxCookedData = aData end function ' ========================================= Function LineNormalForm(ByVal sData) ' takes arbitrary multiline string as an argument string ' returns with ' + lead/tail whitespace remove from all lines ' + empty lines removed ' + line endings changed to carriage returns to facilitate ' regular-expression based searches. ' Dependencies: Regular expression support (VBScript 5.5 ' preferred). ' Argument: multiline string to be massaged ' Return: multiline string, processed as outlined above. Dim rx set rx = new regexp rx.multiline=true rx.global=true rx.pattern = "(\s)*(\r|\n)+(\s)*" sData = rx.Replace(sData, vbCr) rx.global = false rx.multiline = false rx.pattern = "^\s+" sData = rx.Replace(sData, "") rx.pattern = "\s+$" LineNormalForm = rx.Replace(sData, "") end Function Function ReadFile(FilePath) 'Given the path to a file, will return entire contents ' works with either ANSI or Unicode Dim FSO, CurrentFile Const ForReading = 1, TristateUseDefault = -2, _ DoNotCreateFile = False Set FSO = createobject("Scripting.FileSystemObject") If FSO.FileExists(FilePath) Then If FSO.GetFile(FilePath).Size>0 Then Set CurrentFile = FSO.OpenTextFile(FilePath, ForReading, _ False, TristateUseDefault) If CurrentFile.AtEndOfStream <> True Then ReadFile = CurrentFile.ReadAll: CurrentFile.Close End If End If End If End Function