code:
  
; Development notes:
;
; UDFs: oFile Collection
; Author: W.M. Hinsch (New Mexico Mark)
; Created: 1/11/02
; Last Mod: 1/19/02
; Dependencies: None
;
; Note 1
; I considered adding a level of abstraction by writing an oGetFile() function,
; then passing the file object to the oFileOpen function.
; However, the problem with this is that the file must exist first. It does
; not allow for file creation with the ForWriting option.
;
; Note 2
; Why the weird "** EOF **" and "** ERR **" error codes in the oFileReadLine
; and oFileRead functions?
; The bottom line is that a read or readline could return anything, including
; numbers reserved for error codes. This helps circumvent that problem.
; It is possible but very unlikely for this to happen under normal
; circumstances.
;
; Note 3
; In the write test, I find that NUL (ASCII 0) is not written to the test
; file. This may be due to internal KiXtart handling of Nulls.
;
; Note 4
; I chose the "oFile"FunctionName names to designate that we are working with
; objects. This is a combination of FileSystemObject and File objects, so
; I really wasn't comfortable with FSo/oFS or just "obj"FunctionName.
; "oFile" was a compromise. It shows that we are working with objects and
; files without making the names terribly long.
;
; Note 5
; This is definitely a "first blush" presentation. Suggestions are welcome.
; Please beat on these and let me know any more limitations and/or program
; errors you find. The contents of this message may be copied and pasted
; in totality for your own testing and modifications.
;
; Note 6
; Caution: If a file is opened for writing, its contents *will* be deleted.
; This is intended behavior, but use oFileOpen mode 2 with caution.
;
; Note 7
; Although I'm including all of these, after some real-world testing, I
; recommend mainly using oFileOpen() to make it easier to instantiate (with
; error testing) a file object. Of course, the bytewise read and write
; functions will be handy for those applications. However, in testing
; with a very large file, I found that
; $Line = oFileReadLine($oFile1)
; oFileWriteLine($oFile1, $Line)
; versus
; $Line = $oFile1.ReadLine
; $oFile2.WriteLine($Line)
;
; Showed a 3-to-1 performance gain by eliminating the function overhead and
; passing of string data from and to the functions.
;
; Note 8
; Not returning a number from, say, a fileopen function is deliberate. The
; error level is set, and that may be tested, if desired. However, I like
; the reduced overhead of not having to assign the function output to a
; variable.
;
;
; The console output from the following tests is:
;FileSpec = C:\DOCUME~1\whinsch\LOCALS~1\Temp\test.txt
;
;
;TEST_FWL
;Writing: "This is line 1."
;Writing: "This is line 2."
;Writing: "This is line 3."
;Writing: "This is line 4."
;Writing: "This is line 5."
;Writing: "This is line 6."
;Writing: "This is line 7."
;Writing: "This is line 8."
;Writing: "This is line 9."
;Writing: "This is line 10."
;
;TEST_FRL
;Reading line 1: "This is line 1."
;Reading line 2: "This is line 2."
;Reading line 3: "This is line 3."
;Reading line 4: "This is line 4."
;Reading line 5: "This is line 5."
;Reading line 6: "This is line 6."
;Reading line 7: "This is line 7."
;Reading line 8: "This is line 8."
;Reading line 9: "This is line 9."
;Reading line 10: "This is line 10."
;Reading line 11: "** EOF **"
;Reading line 12: "** EOF **"
;
;TEST_FRA
;Reading entire file contents.
;This is line 1.
;This is line 2.
;This is line 3.
;This is line 4.
;This is line 5.
;This is line 6.
;This is line 7.
;This is line 8.
;This is line 9.
;This is line 10.
;
;TEST_FW
;0
;1 2 3 4 5 6 7 8 9
;10 11 12 13 14 15 16 17 18
;19 20 21 22 23 24 25 26 27
;28 29 30 31 32 33 34 35 36
;37 38 39 40 41 42 43 44 45
;46 47 48 49 50 51 52 53 54
;55 56 57 58 59 60 61 62 63
;64 65 66 67 68 69 70 71 72
;73 74 75 76 77 78 79 80 81
;82 83 84 85 86 87 88 89 90
;91 92 93 94 95 96 97 98 99
;100 101 102 103 104 105 106 107 108
;109 110 111 112 113 114 115 116 117
;118 119 120 121 122 123 124 125 126
;127 128 129 130 131 132 133 134 135
;136 137 138 139 140 141 142 143 144
;145 146 147 148 149 150 151 152 153
;154 155 156 157 158 159 160 161 162
;163 164 165 166 167 168 169 170 171
;172 173 174 175 176 177 178 179 180
;181 182 183 184 185 186 187 188 189
;190 191 192 193 194 195 196 197 198
;199 200 201 202 203 204 205 206 207
;208 209 210 211 212 213 214 215 216
;217 218 219 220 221 222 223 224 225
;226 227 228 229 230 231 232 233 234
;235 236 237 238 239 240 241 242 243
;244 245 246 247 248 249 250 251 252
;253 254 255
;
;TEST_FR
;001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020
;021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040
;041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060
;061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 080
;081 082 083 084 085 086 087 088 089 090 091 092 093 094 095 096 097 098 099 100
;101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
;121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
;141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
;161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
;181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
;201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
;221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
;241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
;
;:TEST_CODE
;$FS = "%temp%\test.txt"
;"FileSpec = " + $FS ? ?
;GOSUB TEST_FWL
;GOSUB TEST_FRL
;GOSUB TEST_FRA
;GOSUB TEST_FW
;GOSUB TEST_FR
;$oFile = 0
;EXIT
;
;:TEST_FWL
;$oFile = oFileOpen($FS, 2) ; Open for write
;IF VarType($oFile) = 9
; ? "TEST_FWL" ?
; FOR $i = 1 TO 10
; $Line = "This is line " + $i + "."
; "Writing: " + Chr(34) + $Line + Chr(34) ?
; oFileWriteLine($oFile,$Line)
; NEXT
; oFileClose($oFile) ; Use UDF to close
;ELSE
; "oFile = " + $oFile ?
;ENDIF
;RETURN
;
;:TEST_FRL
;$oFile = oFileOpen($FS) ; Open for read
;IF VarType($oFile) = 9
; ? "TEST_FRL" ?
; FOR $i = 1 TO 12 ; Attempt to read two more lines than exist
; $Line = oFileReadLine($oFile)
; "Reading line " + $i + ": " + Chr(34) + $Line + Chr(34) ?
; NEXT
; $oFile.Close ; Native close method
;ELSE
; "oFile = " + $oFile ?
;ENDIF
;RETURN
;
;:TEST_FRA
;$oFile = oFileOpen($FS) ; Open for read
;IF VarType($oFile) = 9
; ? "TEST_FRA" ?
; "Reading entire file contents. " ?
; $aryContents = Split(oFileReadAll($oFile),@CRLF) ; Get file into array
; FOR EACH $Element IN $aryContents
; $Element ?
; NEXT
; oFileClose($oFile)
;ELSE
; "oFile = " + $oFile ?
;ENDIF
;RETURN
;
;:TEST_FW
;$oFile = oFileOpen($FS, 2) ; Open for write (delete prev. contents)
;IF VarType($oFile) = 9
; ? "TEST_FW" ?
; FOR $i = 0 TO 255
; "" + $i + Chr(9)
; IF $i - (($i / 9) * 9) = 0 ? ENDIF
; oFileWrite($oFile,Chr($i))
; NEXT
; $oFile.Close
; ?
;ELSE
; "oFile = " + $oFile ?
;ENDIF
;RETURN
;
;:TEST_FR
;$oFile = oFileOpen($FS) ; Open for read
;IF VarType($oFile) = 9
; ? "TEST_FR" ?
; $Ctr = 0
; $Byte = oFileRead($oFile)
; WHILE @ERROR=0
; $Byte = "" + Asc($Byte)
; $Byte = "" + SubStr("000",1,3-Len($Byte)) + $Byte + " "
; $Byte
; $Ctr = $Ctr + 1
; IF $Ctr - (($Ctr / 20) * 20) = 0 ? ENDIF
; $Byte = oFileRead($oFile)
; LOOP
; ?
; $oFile.Close
;ELSE
; "oFile = " + $oFile ?
;ENDIF
;RETURN
;
FUNCTION oFileOpen($iFile, OPTIONAL $iMode, OPTIONAL $iType)
; Returns open File Object. Error level set as follows
; 0 Success
; -1 Input parameter error
; -2 Could not find file
; -4 Could not instantiate File System Object
; -8 Could not open as text stream
; $iMode: 1=Read, 2=Write/Overwrite Existing File, 3=Append
; $iType: 0=ASCII, -1=Unicode, -2=System Default
$iFile = "" + $iFile
$iMode = 0 + $iMode
$iType = 0 + $iType
IF $iMode = 0 $iMode = 1 ENDIF
IF $iMode <> 1 AND $iMode <> 2 AND $iMode <> 8 EXIT -1 ENDIF
IF $iType < -2 OR $iType > 0 EXIT -1 ENDIF
DIM $oFS, $bCreate
$bCreate = $iMode & 2
IF NOT Exist($iFile) AND (NOT $bCreate) EXIT -2 ENDIF
$oFS = CreateObject("Scripting.FileSystemObject")
IF @ERROR EXIT -2 ENDIF
$oFileOpen = $oFS.OpenTextFile($iFile,$iMode,$bCreate,$iType)
IF @ERROR EXIT -8 RETURN ENDIF
ENDFUNCTION
;
FUNCTION oFileClose($oFile)
; $oFile is an open file object. It would probably be easier to just do the
; close in the script, but this is included for consistency.
; Returns nothing
IF VarType($oFile) <> 9 RETURN ENDIF
$oFile.Close
EXIT @ERROR
ENDFUNCTION
;
FUNCTION oFileRead($oFile, OPTIONAL $iBytes)
; $oFile is a file object opened for reading as a text stream.
; $iBytes is how many bytes to read from the file.
; Returns the specified number of bytes from a file (1 byte default)
; or sets an error level
$oFileRead = ""
$iBytes = 0 + $iBytes
IF VarType($oFile) <> 9 EXIT -1 ENDIF
IF $iBytes < 1 $iBytes = 1 ENDIF
IF NOT $oFile.AtEndOfStream
$oFileRead = $oFile.Read($iBytes)
ELSE
EXIT -1
ENDIF
EXIT @ERROR
ENDFUNCTION
;
FUNCTION oFileReadLine($oFile)
; $oFile is a file object opened for reading as a text stream.
; Returns the line (less the final EOL character) or sets error
IF VarType($oFile) <> 9 RETURN ENDIF
$oFileReadLine = ""
IF NOT $oFile.AtEndOfStream
$oFileReadLine = $oFile.ReadLine
ELSE
EXIT -1
ENDIF
EXIT @ERROR
ENDFUNCTION
;
FUNCTION oFileReadAll($oFile)
; $oFile is a file object opened for reading as a text stream.
; Returns the entire contents of a file as a string or sets an error level.
; Again, a simple $oFile.ReadAll would suffice in the main script. However,
; this function is here for consistency.
IF VarType($oFile) <> 9 RETURN ENDIF
$oFileReadAll = ""
$oFileReadAll = $oFile.ReadAll
EXIT @ERROR
ENDFUNCTION
;
FUNCTION oFileWrite($oFile, $String)
; $oFile is a file object opened for writing or appending as a text stream.
; $String contains the characters to write or append. CR/LFs are not
; automatically added.
; No return value, but sets error level
$String = "" + $String
IF VarType($oFile) <> 9 RETURN ENDIF
$oFile.Write($String)
EXIT @ERROR
ENDFUNCTION
;
FUNCTION oFileWriteLine($oFile, $String)
; $oFile is a file object opened for writing or appending as a text stream.
; $String contains the string to write or append. EOL is added.
; No return value, but sets error level
IF VarType($oFile) <> 9 RETURN ENDIF
$String = "" + $String
$oFile.WriteLine($String)
EXIT @ERROR
ENDFUNCTION
;

[ 19 January 2002: Message edited by: New Mexico Mark ]