;; 
;;=====================================================================================----- 
;; 
;;FUNCTION       FileIO() 
;; 
;;ACTION         Read or write file data using an array 
;; 
;;AUTHOR         Glenn Barnas 
;; 
;;VERSION        1.2  - 2013/04/15 
;; 
;;HISTORY        1.0  - 2009/09/09 - Initial Release 
;;               1.1  - 2011/08/03 - added read progress indicator option 
;;               1.2  - 2013/04/15 - Modified the array build process for read to use a 
;;                                   "stepped-dynamic" method.  This offers significant 
;;                                   (nearly 250 times faster) performance improvement 
;;                                   on read, with a slight improvement on write. 
;; 
;;SYNTAX         FileIO(File, Mode [, Data] [, OPTS]) 
;; 
;;PARAMETERS     File - REQUIRED - String 
;;               - The complete path to the file to read/write 
;; 
;;               Mode - REQUIRED - String 
;;               - One of R(ead), W(rite), or (A)ppend. 
;;                Write will delete/create a new file. 
;; 
;;               Data - OPTIONAL - Array 
;;               - An array of data to be written 
;; 
;;               OPTS - OPTIONAL - Integer 
;;               - A binary coded options value. Most are valid only when writing. 
;;                1 - set the line termination sequence to LF for unix style output. 
;;                2 - Suppress null line output (slightly slower write) 
;;                4 - Suppress final line termination 
;;                8 - Show progress indicators every 500 lines 
;; 
;;REMARKS        Will allow direct read/write replacement of a file - read to array, 
;;               modify array, write array to file 
;;               Read will return an error if the specified file is not present 
;;               Write will delete any current file & create a new file 
;;               Append will add the data to a file if it exists, or create a new file 
;;               Any write mode will return an error if a data array is not present 
;; 
;;               This UDF is most appropriate for configuration or data files sized 
;;               500K or smaller. 
;;               Larger files will work but will take a fair amount of time to load. 
;; 
;;RETURNS        Read: array of file data. Write: Integer 1=success, 0=failure 
;; 
;;DEPENDENCIES   none 
;; 
;;TESTED WITH    W2K, WXP, W2K3 
;; 
;;EXAMPLES       ; trim a log file to 100 lines - requires that the application be 
;;               stopped in most cases before trimming the log 
;;		 $aData = FileIO('.\app.log', 'R') 
;;               ; point to 100 lines before the end of the log data 
;;               $Start = UBound($aData) - 100 
;;               ; is log longer than 100 lines? Then trim it! 
;;		 If $Start > $UBound($aData) 
;;		   Dim $aOutData[100] 
;;                 ; loop through the last 100 lines of old array 
;;		   For $I = 0 to 99 
;;                   ; copying data to first 100 lines of new array 
;;		     $aOutData[$I] = $aData[$Start + $I] 
;;		   Next 
;;                 ; write the data back to the file 
;;		   If FileIO('.\app.log', 'W', $aOutData) 
;;		     'Log was successfully trimmed!' ? 
;;		   EndIf 
;;		 EndIf 
;; 
; 
Function FileIO($_File, $_Mode, OPTIONAL $_aData, OPTIONAL $_Opts)
 
  Dim $_				; temp var 
  Dim $_I				; index pointer 
  Dim $_Fp				; file pointer 
  Dim $_Fm				; file I/O mode 
  Dim $_Term				; line terminator 
  Dim $_NoNul				; Null line suppression flag 
  Dim $_FTerm				; final line term 
  Dim $_Prog				; Progress indicator flag 
 
  $FileIO = 0				; return fail by default 
 
 
  ; set the process options 
  $_Term  = IIf($_Opts & 1, Chr(10), @CRLF)
  $_NoNul = IIf($_Opts & 2, 1, 0)
  $_FTerm = IIf($_Opts & 4, '', $_Term)
  $_Prog  = IIf($_Opts & 8, 1, 0)
 
 
  ; validate the mode & set the I/O mode 
  $_Mode = Left($_Mode, 1)
  Select
   Case $_Mode = 'R'			; read 
    $_Fm = 2
   Case $_Mode = 'W'			; write/create 
    If VarType($_aData) < 8192
      Exit 87				; exit with error if Write/Create mode and no data 
    EndIf
    $_Fm = 5
    If Exist($_File)			; remove any existing file if not in Append mode 
      Del $_File
    EndIf
   Case $_Mode = 'A'			; append 
    If VarType($_aData) < 8192
      Exit 87				; exit with error if Write/Append mode and no data 
    EndIf
    $_Fm = 5
   Case 1				; invalid mode 
    Exit 87
  EndSelect
 
  ; locate an available file handle 
  $_Fp = FreeFileHandle
  If Not $_Fp
    Exit 1
  EndIf
 
  ; Open the file in the defined input or output mode - exit if the open fails 
  $_ = Open($_Fp, $_File, $_Fm)
  If @ERROR Exit @ERROR EndIf
 
  If $_Fm = 2				; read file 
    ReDim $_aData[499]			; start w/ 500 lines 
    $_I = -1
    $_ = ReadLine($_Fp)
    While Not @ERROR
      $_I = $_I + 1
      $_aData[$_I] = $_
      If $_I > 1 And $_I Mod 499 = 0
        ReDim Preserve $_aData[$_I + 500]
        If $_Prog '.' EndIf		; progress marker 
      EndIf
      $_ = ReadLine($_Fp)
    Loop
    $_ = Close($_Fp)
    If $_I < 0				; no data 
      Exit 2
    EndIf
    ReDim Preserve $_aData[$_I]
    If $_Prog '. ' EndIf
    $FileIO = $_aData
    Exit 0
  Else					; write file 
    For $_I = 0 to UBound($_aData) - 1
      If $_NoNul
        If $_aData[$_I]			; write if not null 
          $_ = WriteLine($_FP, $_aData[$_I] + $_Term)
        EndIf
      Else				; write always 
        $_ = WriteLine($_FP, $_aData[$_I] + $_Term)
      EndIf
      If $_I > 1 And $_I Mod 499 = 0 And $_Prog '.' EndIf
    Next
 
    ; write last line 
    If $_NoNul
      If $_aData[$_I]			; write if not null 
        $_ = WriteLine($_FP, $_aData[$_I] + $_FTerm)
      EndIf
    Else				; write always 
      $_ = WriteLine($_FP, $_aData[$_I] + $_FTerm)
    EndIf
 
    $_ = Close($_Fp)
    $FileIO = 1				; show a completed write 
    If $_Prog '. ' EndIf
    Exit 0
  EndIf
 
EndFunction