#include-once ; #INDEX# ======================================================================================================================= ; Title .........: DifHandler v2 ; AutoIt Version : 3.3.8.1 ; Description ...: Reads and writes Data Interchange Format (.DIF) files ; Author(s) .....: David Williams (willichan) ; Dll ...........: ; =============================================================================================================================== ; #CURRENT# ===================================================================================================================== ;_DifHandler_ReadDifToArray ;_DifHandler_WriteArrayToDif ; =============================================================================================================================== ; #INTERNAL_USE_ONLY# =========================================================================================================== ;__DifHandler_CloseOut ;__DifHandler_ReadElement ;__DifHandler_ReadHeader ;__DifHandler_ReadTuple ; =============================================================================================================================== ; #VARIABLES# =================================================================================================================== ; =============================================================================================================================== ; #CONSTANTS# =================================================================================================================== ; =============================================================================================================================== ; #FUNCTION# ==================================================================================================================== ; Name...........: _DifHandler_ReadDifToArray ; Description ...: Reads the specified DIF file to an array ; Syntax.........: _DifHandler_ReadDifToArray($sDifFilePath) ; Parameters ....: $sDifFilePath - Path/filename of the DIF to be read ; Return values .: Success - returns array containing data read from DIF in the format $array[rows][columns] ; Failure - returns what data could be processed, and sets @error ; 1 - file does not exist ; 2 - file is a directory ; 3 - unable to open file for read access ; 4 - malformed file, invalid header ; 5 - malformed file, invalid data ; 6 - malformed file, premature end-of-file (might still return full table) ; 7 - malformed file, premature end-of-data (might still return full table) ; 8 - unknown file read error ; 9 - data beyond defined scope (depricated) ; Author ........: David Williams (willichan) ; Modified.......: ; Remarks .......: This function also takes Microsoft's mistake into account, and inverts tuple (row) and vector (column) header ; data when the DIF file contains a TABLE string of "EXCEL". Also takes into account that many systems do not ; fully follow the DIF spec. When an error 6 or 7 are returned, the data returned may still likely be valid, ; depending on the DIF provided. ; Related .......: ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _DifHandler_ReadDifToArray($sDifFilePath) Local $avParameters[6] = [-1, -1, -1, -1, 0, 0] ; 0 - Generator ; 1 - Vectors (columns) ; 2 - Tuples (rows) ; 3 - Current Block (-1 = start of file, 0 = header, 1 = data, 2 = end) ; 4 - Current Vector ; 5 - Current Tuple Local $iErr, $hFile Local $avReturn[1][2] = [[0, 0]] Local $avElement[1] If Not FileExists($sDifFilePath) Then Return SetError(1, 0, $avReturn) If StringInStr(FileGetAttrib($sDifFilePath), "D") Then Return SetError(2, 0, $avReturn) $hFile = FileOpen($sDifFilePath, 0) If $hFile = -1 Then Return SetError(3, 0, $avReturn) ;-----HEADER $iErr = __DifHandler_ReadHeader($hFile, $avParameters) If $iErr Then Return SetError($iErr, __DifHandler_CloseOut($hFile), $avReturn) ReDim $avReturn[1][$avParameters[1]] ;-----DATA While $avParameters[3] = 1 $iErr = __DifHandler_ReadTuple($hFile, $avParameters, $avReturn) If $iErr Then Return SetError($iErr, __DifHandler_CloseOut($hFile), $avReturn) WEnd ;-----END $iErr = __DifHandler_ReadElement($hFile, $avParameters, $avElement) If $iErr Then Return SetError($iErr, __DifHandler_CloseOut($hFile), $avReturn) If $avElement[1] = "EOD" Then $avParameters[3] = 2 ;-----Finish ;If $avParameters[3] = 1 Then Return SetError(9, __DifHandler_CloseOut($hFile), $avReturn) ;If $avParameters[5] > $avParameters[2] Then Return SetError(9, __DifHandler_CloseOut($hFile), $avReturn) __DifHandler_CloseOut($hFile) Return $avReturn EndFunc ;==>_DifHandler_ReadDifToArray ; #FUNCTION# ==================================================================================================================== ; Name ..........: _DifHandler_WriteArrayToDif ; Description ...: ; Syntax ........: _DifHandler_WriteArrayToDif(Byref $avArrayData, $sDifFilePath[, $bAssumeText = False]) ; Parameters ....: $avArrayData - Data to write to DIF file ; $sDifFilePath - Path to output file ; $bAssumeText - Assume all values are text? If false, will attempt to determine type ; Return values .: Success - returns 0 ; Failure - returns 1, sets @error ; 1 - $avArrayData is not a valid array ; 2 - $bAssumeText is not a boolean value ; 3 - Unable to open $sDifFilePath for Write ; Author ........: David Williams (willichan) ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _DifHandler_WriteArrayToDif(ByRef $avArrayData, $sDifFilePath, $bAssumeText = False) Local $iTuples, $iVectors, $hFile, $iT, $iV, $bIsText If Not IsArray($avArrayData) Then Return SetError(1, 0, 1) If UBound($avArrayData, 0) <> 2 Then Return SetError(1, 0, 1) If Not IsBool($bAssumeText) Then Return SetError(2, 0, 1) $hFile = FileOpen($sDifFilePath, 10) If $hFile = -1 Then Return SetError(3, 0, 1) $iTuples = UBound($avArrayData, 1) $iVectors = UBound($avArrayData, 2) ; Write Header FileWriteLine($hFile, 'TABLE') FileWriteLine($hFile, '0,1') FileWriteLine($hFile, '""') FileWriteLine($hFile, 'VECTORS') FileWriteLine($hFile, '0,' & $iVectors) FileWriteLine($hFile, '""') FileWriteLine($hFile, 'TUPLES') FileWriteLine($hFile, '0,' & $iTuples) FileWriteLine($hFile, '""') FileWriteLine($hFile, 'DATA') FileWriteLine($hFile, '0,0') FileWriteLine($hFile, '""') ; Write Data For $iT = 0 To $iTuples - 1 ; Beginning Of Tuple FileWriteLine($hFile, '-1,0') FileWriteLine($hFile, 'BOT') ; Write Vectors For $iV = 0 To $iVectors - 1 $bIsText = True If Not $bAssumeText Then If String(Number($avArrayData[$iT][$iV])) = String($avArrayData[$iT][$iV]) Then $bIsText = False EndIf If $bIsText Then FileWriteLine($hFile, '1,0') FileWriteLine($hFile, '"' & $avArrayData[$iT][$iV] & '"') Else FileWriteLine($hFile, '0,' & $avArrayData[$iT][$iV]) FileWriteLine($hFile, 'V') EndIf Next Next ; Write End FileWriteLine($hFile, '-1,0') FileWriteLine($hFile, "EOD") Return __DifHandler_CloseOut($hFile) EndFunc ;==>_DifHandler_WriteArrayToDif ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __DifHandler_CloseOut ; Description ...: Closes the file handle $hFile, and returns a 0 ; Syntax ........: __DifHandler_CloseOut(Byref $hFile) ; Parameters ....: $hFile - DIF file handle ; Return values .: Always returns 0 ; Author ........: David Williams (willichan) ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __DifHandler_CloseOut(ByRef $hFile) FileClose($hFile) Return 0 EndFunc ;==>__DifHandler_CloseOut ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __DifHandler_ReadElement ; Description ...: ; Syntax ........: __DifHandler_ReadElement(Byref $hFile, Byref $avParameters, Byref $avElement) ; Parameters ....: $hFile - DIF file handle ; $avParameters - Array of parameter variables to avoid using globals ; $avElement - An array containing element values ; Return values .: Success - returns 0 ; Failure - returns error number ; 5 - malformed file, invalid data ; 6 - malformed file, premature end-of-file ; 8 - unknown file read error ; Author ........: David Williams (willichan) ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __DifHandler_ReadElement(ByRef $hFile, ByRef $avParameters, ByRef $avElement) Local $sLine, $iErr, $vTemp $sLine = FileReadLine($hFile) $iErr = @error If $iErr = -1 Then Return 6 If $iErr = 1 Then Return 8 $sLine = StringStripWS($sLine, 2) Switch $sLine Case "EOD" ReDim $avElement[2] $avElement[0] = 1 $avElement[1] = $sLine Case "TABLE", "VECTORS", "TUPLES", "DATA" ;known header elements ReDim $avElement[4] $avElement[0] = 3 $avElement[1] = $sLine ;----- $sLine = FileReadLine($hFile) $iErr = @error If $iErr = -1 Then Return 6 If $iErr = 1 Then Return 8 $sLine = StringStripWS($sLine, 2) $vTemp = StringSplit($sLine, ",", 0) If $vTemp[0] <> 2 Then Return 5 If $vTemp[1] <> 0 Then Return 5 $avElement[2] = $vTemp[2] ;----- $sLine = FileReadLine($hFile) $iErr = @error If $iErr = -1 Then Return 6 If $iErr = 1 Then Return 8 $sLine = StringStripWS($sLine, 2) $avElement[3] = $sLine Case Else ;should be data here If $avParameters[3] <> 0 Then ; skip unknown header data $vTemp = StringSplit($sLine, ",", 0) If $vTemp[0] <> 2 Then Return 5 Switch $vTemp[1] Case -1 ;directive (BOT or EOD) ReDim $avElement[2] $avElement[0] = 1 ;----- $sLine = FileReadLine($hFile) $iErr = @error If $iErr = -1 Then Return 6 If $iErr = 1 Then Return 8 $avElement[1] = StringStripWS($sLine, 2) Case 0 ;numeric data ReDim $avElement[3] $avElement[0] = 2 $sLine = FileReadLine($hFile) $iErr = @error If $iErr = -1 Then Return 6 If $iErr = 1 Then Return 8 $avElement[1] = StringStripWS($vTemp[2], 2) $avElement[2] = StringStripWS($sLine, 2) Case 1 ;string data ReDim $avElement[3] $avElement[0] = 2 $avElement[2] = "STRING" ;----- $sLine = FileReadLine($hFile) $iErr = @error If $iErr = -1 Then Return 6 If $iErr = 1 Then Return 8 $avElement[1] = StringStripWS($sLine, 2) Case Else Return 5 EndSwitch EndIf EndSwitch Return 0 EndFunc ;==>__DifHandler_ReadElement ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __DifHandler_ReadHeader ; Description ...: Reads header block from $hFile file and populated $avParameters ; Syntax ........: __DifHandler_ReadHeader(Byref $hFile, Byref $avParameters) ; Parameters ....: $hFile - DIF file handle ; $avParameters - Array of parameter variables to avoid using globals ; Return values .: Success - returns 0, $avParameters contains header info ; Failure - returns error number ; 4 - malformed file, invalid header ; 5 - malformed file, invalid data ; 6 - malformed file, premature end-of-file ; 7 - malformed file, premature end-of-data ; 8 - unknown file read error ; Author ........: David Williams (willichan) ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __DifHandler_ReadHeader(ByRef $hFile, ByRef $avParameters) Local $iErr, $avElement[1], $bBackwards = False, $vTemp $iErr = __DifHandler_ReadElement($hFile, $avParameters, $avElement) If $iErr Then Return $iErr If $avElement[0] <> 3 Then Return 4 If $avElement[1] <> "TABLE" Then Return 4 $avParameters[3] = 0 $avParameters[0] = $avElement[3] If $avElement[3] = '"EXCEL"' Then $bBackwards = True While $avParameters[3] = 0 $iErr = __DifHandler_ReadElement($hFile, $avParameters, $avElement) If $iErr Then Return $iErr If $avElement[0] <> 3 Then Return 4 Switch $avElement[1] Case "TABLE" Return 4 Case "VECTORS" If $bBackwards Then If $avParameters[2] <> -1 Then Return 4 $avParameters[2] = $avElement[2] Else If $avParameters[1] <> -1 Then Return 4 $avParameters[1] = $avElement[2] EndIf Case "TUPLES" If $bBackwards Then If $avParameters[1] <> -1 Then Return 4 $avParameters[1] = $avElement[2] Else If $avParameters[2] <> -1 Then Return 4 $avParameters[2] = $avElement[2] EndIf Case "DATA" ; end of header $avParameters[3] = 1 EndSwitch WEnd For $vTemp = 0 To 3 If $avParameters[$vTemp] = -1 Then Return 4 Next Return 0 EndFunc ;==>__DifHandler_ReadHeader ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __DifHandler_ReadTuple ; Description ...: Reads a full tuple (row) of data ; Syntax ........: __DifHandler_ReadTuple(Byref $hFile, Byref $avParameters, Byref $avReturn) ; Parameters ....: $hFile - DIF file handle ; $avParameters - Array of parameter variables to avoid using globals ; $avReturn - Array containing data read from DIF file ; Return values .: Success - returns 0, $avReturn contains the new tuple ; Failure - returns error number ; 5 - malformed file, invalid data ; 6 - malformed file, premature end-of-file ; 7 - malformed file, premature end-of-data ; 8 - unknown file read error ; Author ........: David Williams (willichan) ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __DifHandler_ReadTuple(ByRef $hFile, ByRef $avParameters, ByRef $avReturn) Local $iErr, $avElement[1] $iErr = __DifHandler_ReadElement($hFile, $avParameters, $avElement) If $iErr Then Return $iErr If $avElement[1] <> "BOT" Then Return 5 $avParameters[5] += 1 ReDim $avReturn[$avParameters[5]][$avParameters[1]] $avParameters[4] = 0 While $avParameters[4] < $avParameters[1] $avParameters[4] += 1 $iErr = __DifHandler_ReadElement($hFile, $avParameters, $avElement) If $iErr Then Return $iErr If $avElement[1] = "BOT" Then Return 5 If $avElement[1] = "EOD" Then $avParameters[3] = 2 If $avParameters[4] = 1 Then Return 0 Else Return 7 EndIf EndIf If $avElement[0] <> 2 Then Return 5 If $avElement[2] = "STRING" Then $avElement[1] = StringMid($avElement[1], 2, StringLen($avElement[1]) - 2) $avReturn[$avParameters[5] - 1][$avParameters[4] - 1] = $avElement[1] WEnd Return 0 EndFunc ;==>__DifHandler_ReadTuple