tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / wizards / source / scriptforge / SF_TextStream.xba
blob3860bebd1b0aa4188ef032fef7dfa150153a9b0a
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
3 <script:module xmlns:script="http://openoffice.org/2000/script" script:name="SF_TextStream" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
4 REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
5 REM === Full documentation is available on https://help.libreoffice.org/ ===
6 REM =======================================================================================================================
8 Option Compatible
9 Option ClassModule
11 Option Explicit
13 &apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;
14 &apos;&apos;&apos; SF_TextStream
15 &apos;&apos;&apos; =============
16 &apos;&apos;&apos; Class instantiated by the
17 &apos;&apos;&apos; SF_FileSystem.CreateTextFile
18 &apos;&apos;&apos; SF_FileSystem.OpenTextFile
19 &apos;&apos;&apos; methods to facilitate the sequential processing of text files
20 &apos;&apos;&apos; All open/read/write/close operations are presumed to happen during the same macro run
21 &apos;&apos;&apos; The encoding to be used may be chosen by the user
22 &apos;&apos;&apos; The list is in the Name column of https://www.iana.org/assignments/character-sets/character-sets.xhtml
23 &apos;&apos;&apos; Note that probably not all values are available
24 &apos;&apos;&apos; Line delimiters may be chosen by the user
25 &apos;&apos;&apos; In input, CR, LF or CR+LF are supported
26 &apos;&apos;&apos; In output, the default value is the usual newline on the actual operating system (see SF_FileSystem.sfNEWLINE)
27 &apos;&apos;&apos;
28 &apos;&apos;&apos; The design choices are largely inspired by
29 &apos;&apos;&apos; https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/textstream-object
30 &apos;&apos;&apos; The implementation is mainly based on the XTextInputStream and XTextOutputStream UNO interfaces
31 &apos;&apos;&apos; https://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1io_1_1XTextInputStream.html
32 &apos;&apos;&apos; https://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1io_1_1XTextOutputStream.html
33 &apos;&apos;&apos;
34 &apos;&apos;&apos; Disk file systems and document&apos;s internal file systems
35 &apos;&apos;&apos; All methods and properties are applicable without restrictions on both file systems.
36 &apos;&apos;&apos; However, when updates are operated on text files embedded in a document, (with the WriteXXX() methods),
37 &apos;&apos;&apos; the updates are first done on a copy of the original file. When the file is closed, the copy
38 &apos;&apos;&apos; will overwrite the original file. The whole process is transparent for the user script.
39 &apos;&apos;&apos;
40 &apos;&apos;&apos; Instantiation example:
41 &apos;&apos;&apos; Dim FSO As Object, myFile As Object
42 &apos;&apos;&apos; Set FSO = CreateScriptService(&quot;FileSystem&quot;)
43 &apos;&apos;&apos; Set myFile = FSO.OpenTextFile(&quot;C:\Temp\ThisFile.txt&quot;, FSO.ForReading) &apos; Once per file
44 &apos;&apos;&apos;
45 &apos;&apos;&apos; Detailed user documentation:
46 &apos;&apos;&apos; https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03/sf_textstream.html?DbPAR=BASIC
47 &apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;
49 REM ================================================================== EXCEPTIONS
51 Const FILENOTOPENERROR = &quot;FILENOTOPENERROR&quot; &apos; The file is already closed
52 Const FILEOPENMODEERROR = &quot;FILEOPENMODEERROR&quot; &apos; The file is open in incompatible mode
53 Const ENDOFFILEERROR = &quot;ENDOFFILEERROR&quot; &apos; When file was read, an end-of-file was encountered
55 REM ============================================================= PRIVATE MEMBERS
57 Private [Me] As Object
58 Private [_Parent] As Object
59 Private ObjectType As String &apos; Must be TEXTSTREAM
60 Private ServiceName As String
61 Private _FileName As String &apos; File where it is about in URL format
62 Private _IOMode As Integer &apos; ForReading, ForWriting or ForAppending
63 Private _Encoding As String &apos; https://www.iana.org/assignments/character-sets/character-sets.xhtml
64 Private _NewLine As String &apos; Line break in write mode
65 Private _FileExists As Boolean &apos; True if file exists before open
66 Private _LineNumber As Long &apos; Number of lines read or written
67 Private _FileHandler As Object &apos; com.sun.star.io.XInputStream or
68 &apos; com.sun.star.io.XOutputStream or
69 &apos; com.sun.star.io.XStream
70 Private _InputStream As Object &apos; com.sun.star.io.TextInputStream
71 Private _OutputStream As Object &apos; com.sun.star.io.TextOutputStream
72 Private _ForceBlankLine As Boolean &apos; Workaround: XTextInputStream misses last line if file ends with newline
74 &apos; Document&apos;s file system only
75 Private _IsEmbeddedFile As Boolean &apos; True when concerned file is embedded in a document
76 Private _EmbeddedFileName As String &apos; When not blank and in update mode, the full embedded file name
77 &apos; This file is initially copied in a temporary storage, modified by the actual class,
78 &apos; and rewritten in the document when the textstream.CloseFile() method is run
80 REM ============================================================ MODULE CONSTANTS
82 REM ===================================================== CONSTRUCTOR/DESTRUCTOR
84 REM -----------------------------------------------------------------------------
85 Private Sub Class_Initialize()
86 Set [Me] = Nothing
87 Set [_Parent] = Nothing
88 ObjectType = &quot;TEXTSTREAM&quot;
89 ServiceName = &quot;ScriptForge.TextStream&quot;
90 _FileName = &quot;&quot;
91 _IOMode = -1
92 _Encoding = &quot;&quot;
93 _NewLine = &quot;&quot;
94 _FileExists = False
95 _LineNumber = 0
96 Set _FileHandler = Nothing
97 Set _InputStream = Nothing
98 Set _OutputStream = Nothing
99 _ForceBlankLine = False
100 _IsEmbeddedFile = False
101 _EmbeddedFileName = &quot;&quot;
102 End Sub &apos; ScriptForge.SF_TextStream Constructor
104 REM -----------------------------------------------------------------------------
105 Private Sub Class_Terminate()
106 Call Class_Initialize()
107 End Sub &apos; ScriptForge.SF_TextStream Destructor
109 REM -----------------------------------------------------------------------------
110 Public Function Dispose() As Variant
111 Call Class_Terminate()
112 Set Dispose = Nothing
113 End Function &apos; ScriptForge.SF_TextStream Explicit Destructor
115 REM ================================================================== PROPERTIES
117 REM -----------------------------------------------------------------------------
118 Property Get AtEndOfStream() As Boolean
119 &apos;&apos;&apos; In reading mode, True indicates that the end of the file has been reached
120 &apos;&apos;&apos; In write and append modes, or if the file is not ready =&gt; always True
121 &apos;&apos;&apos; The property should be invoked BEFORE each ReadLine() method:
122 &apos;&apos;&apos; A ReadLine() executed while AtEndOfStream is True will raise an error
123 &apos;&apos;&apos; Example:
124 &apos;&apos;&apos; Dim sLine As String
125 &apos;&apos;&apos; Do While Not myFile.AtEndOfStream
126 &apos;&apos;&apos; sLine = myFile.ReadLine()
127 &apos;&apos;&apos; &apos; ...
128 &apos;&apos;&apos; Loop
130 AtEndOfStream = _PropertyGet(&quot;AtEndOfStream&quot;)
132 End Property &apos; ScriptForge.SF_TextStream.AtEndOfStream
134 REM -----------------------------------------------------------------------------
135 Property Get Encoding() As String
136 &apos;&apos;&apos; Returns the name of the text file either in url or in native operating system format
137 &apos;&apos;&apos; Example:
138 &apos;&apos;&apos; Dim myFile As Object
139 &apos;&apos;&apos; FSO.FileNaming = &quot;SYS&quot;
140 &apos;&apos;&apos; Set myFile = FSO.OpenTextFile(&quot;C:\Temp\myFile.txt&quot;)
141 &apos;&apos;&apos; MsgBox myFile.Encoding &apos; UTF-8
143 Encoding = _PropertyGet(&quot;Encoding&quot;)
145 End Property &apos; ScriptForge.SF_TextStream.Encoding
147 REM -----------------------------------------------------------------------------
148 Property Get FileName() As String
149 &apos;&apos;&apos; Returns the name of the text file either in url or in native operating system format
150 &apos;&apos;&apos; Example:
151 &apos;&apos;&apos; Dim myFile As Object
152 &apos;&apos;&apos; FSO.FileNaming = &quot;SYS&quot;
153 &apos;&apos;&apos; Set myFile = FSO.OpenTextFile(&quot;C:\Temp\myFile.txt&quot;)
154 &apos;&apos;&apos; MsgBox myFile.FileName &apos; C:\Temp\myFile.txt
156 FileName = _PropertyGet(&quot;FileName&quot;)
158 End Property &apos; ScriptForge.SF_TextStream.FileName
160 REM -----------------------------------------------------------------------------
161 Property Get IOMode() As String
162 &apos;&apos;&apos; Returns either &quot;READ&quot;, &quot;WRITE&quot; or &quot;APPEND&quot;
163 &apos;&apos;&apos; Example:
164 &apos;&apos;&apos; Dim myFile As Object
165 &apos;&apos;&apos; FSO.FileNaming = &quot;SYS&quot;
166 &apos;&apos;&apos; Set myFile = FSO.OpenTextFile(&quot;C:\Temp\myFile.txt&quot;)
167 &apos;&apos;&apos; MsgBox myFile.IOMode &apos; READ
169 IOMode = _PropertyGet(&quot;IOMode&quot;)
171 End Property &apos; ScriptForge.SF_TextStream.IOMode
173 REM -----------------------------------------------------------------------------
174 Property Get Line() As Long
175 &apos;&apos;&apos; Returns the number of lines read or written so far
176 &apos;&apos;&apos; Example:
177 &apos;&apos;&apos; Dim myFile As Object
178 &apos;&apos;&apos; FSO.FileNaming = &quot;SYS&quot;
179 &apos;&apos;&apos; Set myFile = FSO.OpenTextFile(&quot;C:\Temp\myFile.txt&quot;, FSO.ForAppending)
180 &apos;&apos;&apos; MsgBox myFile.Line &apos; The number of lines already present in myFile
182 Line = _PropertyGet(&quot;Line&quot;)
184 End Property &apos; ScriptForge.SF_TextStream.Line
186 REM -----------------------------------------------------------------------------
187 Property Get NewLine() As Variant
188 &apos;&apos;&apos; Returns the current character string to be inserted between 2 successive written lines
189 &apos;&apos;&apos; The default value is the native line separator in the current operating system
190 &apos;&apos;&apos; Example:
191 &apos;&apos;&apos; MsgBox myFile.NewLine
193 NewLine = _PropertyGet(&quot;NewLine&quot;)
195 End Property &apos; ScriptForge.SF_TextStream.NewLine (get)
197 REM -----------------------------------------------------------------------------
198 Property Let NewLine(ByVal pvLineBreak As Variant)
199 &apos;&apos;&apos; Sets the current character string to be inserted between 2 successive written lines
200 &apos;&apos;&apos; Example:
201 &apos;&apos;&apos; myFile.NewLine = Chr(13) &amp; Chr(10)
203 Const cstThisSub = &quot;TextStream.setNewLine&quot;
205 SF_Utils._EnterFunction(cstThisSub)
206 If VarType(pvLineBreak) = V_STRING Then _NewLine = pvLineBreak
207 SF_Utils._ExitFunction(cstThisSub)
209 End Property &apos; ScriptForge.SF_TextStream.NewLine (let)
211 REM ===================================================================== METHODS
213 REM -----------------------------------------------------------------------------
214 Public Function CloseFile() As Boolean
215 &apos;&apos;&apos; Empties the output buffer if relevant. Closes the actual input or output stream
216 &apos;&apos;&apos; Args:
217 &apos;&apos;&apos; Returns:
218 &apos;&apos;&apos; True if the closure was successful
219 &apos;&apos;&apos; Exceptions:
220 &apos;&apos;&apos; FILENOTOPENERROR Nothing found to close
221 &apos;&apos;&apos; Examples:
222 &apos;&apos;&apos; myFile.CloseFile()
224 Dim bClose As Boolean &apos; Return value
225 Dim oSfa As Object &apos; com.sun.star.ucb.SimpleFileAccess
226 Const cstThisSub = &quot;TextStream.CloseFile&quot;
227 Const cstSubArgs = &quot;&quot;
229 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
230 bClose = False
232 Check:
233 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
234 If Not _IsFileOpen() Then GoTo Finally
236 Try:
237 If Not IsNull(_InputStream) Then _InputStream.closeInput()
238 If Not IsNull(_OutputStream) Then
239 _OutputStream.flush()
240 _OutputStream.closeOutput()
241 End If
242 Set _InputStream = Nothing
243 Set _OutputStream = Nothing
244 Set _FileHandler = Nothing
246 &apos; Manage embedded file closure: copy temporary file to document internal storage
247 If _IsEmbeddedFile Then
248 Set oSfa = SF_Utils._GetUnoService(&quot;FileAccess&quot;)
249 oSfa.copy(_FileName, _EmbeddedFileName)
250 End If
252 bClose = True
254 Finally:
255 CloseFile = bClose
256 SF_Utils._ExitFunction(cstThisSub)
257 Exit Function
258 Catch:
259 GoTo Finally
260 End Function &apos; ScriptForge.SF_TextStream.CloseFile
262 REM -----------------------------------------------------------------------------
263 Public Function GetProperty(Optional ByVal PropertyName As Variant) As Variant
264 &apos;&apos;&apos; Return the actual value of the given property
265 &apos;&apos;&apos; Args:
266 &apos;&apos;&apos; PropertyName: the name of the property as a string
267 &apos;&apos;&apos; Returns:
268 &apos;&apos;&apos; The actual value of the property
269 &apos;&apos;&apos; If the property does not exist, returns Null
270 &apos;&apos;&apos; Exceptions:
271 &apos;&apos;&apos; see the exceptions of the individual properties
272 &apos;&apos;&apos; Examples:
273 &apos;&apos;&apos; myModel.GetProperty(&quot;MyProperty&quot;)
275 Const cstThisSub = &quot;TextStream.GetProperty&quot;
276 Const cstSubArgs = &quot;&quot;
278 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
279 GetProperty = Null
281 Check:
282 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
283 If Not SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
284 End If
286 Try:
287 GetProperty = _PropertyGet(PropertyName)
289 Finally:
290 SF_Utils._ExitFunction(cstThisSub)
291 Exit Function
292 Catch:
293 GoTo Finally
294 End Function &apos; ScriptForge.SF_TextStream.GetProperty
296 REM -----------------------------------------------------------------------------
297 Public Function Methods() As Variant
298 &apos;&apos;&apos; Return the list of public methods of the Model service as an array
300 Methods = Array( _
301 &quot;CloseFile&quot; _
302 , &quot;ReadAll&quot; _
303 , &quot;readLine&quot; _
304 , &quot;SkipLine&quot; _
305 , &quot;WriteBlankLines&quot; _
306 , &quot;WriteLine&quot; _
309 End Function &apos; ScriptForge.SF_TextStream.Methods
311 REM -----------------------------------------------------------------------------
312 Public Function Properties() As Variant
313 &apos;&apos;&apos; Return the list or properties of the Timer class as an array
315 Properties = Array( _
316 &quot;AtEndOfStream&quot; _
317 , &quot;Encoding&quot; _
318 , &quot;FileName&quot; _
319 , &quot;IOMode&quot; _
320 , &quot;Line&quot; _
321 , &quot;NewLine&quot; _
324 End Function &apos; ScriptForge.SF_TextStream.Properties
326 REM -----------------------------------------------------------------------------
327 Public Function ReadAll() As String
328 &apos;&apos;&apos; Returns all the remaining lines in the text stream as one string. Line breaks are NOT removed
329 &apos;&apos;&apos; The resulting string can be split in lines
330 &apos;&apos;&apos; either by using the usual Split Basic builtin function if the line delimiter is known
331 &apos;&apos;&apos; or with the SF_String.SplitLines method
332 &apos;&apos;&apos; For large files, using the ReadAll method wastes memory resources.
333 &apos;&apos;&apos; Other techniques should be used to input a file, such as reading a file line-by-line
334 &apos;&apos;&apos; Args:
335 &apos;&apos;&apos; Returns:
336 &apos;&apos;&apos; The read lines. The string may be empty.
337 &apos;&apos;&apos; Note that the Line property in incremented only by 1
338 &apos;&apos;&apos; Exceptions:
339 &apos;&apos;&apos; FILENOTOPENERROR File not open or already closed
340 &apos;&apos;&apos; FILEOPENMODEERROR File opened in write or append modes
341 &apos;&apos;&apos; ENDOFFILEERROR Previous reads already reached the end of the file
342 &apos;&apos;&apos; Examples:
343 &apos;&apos;&apos; Dim a As String
344 &apos;&apos;&apos; a = myFile.ReadAll()
346 Dim sRead As String &apos; Return value
347 Const cstThisSub = &quot;TextStream.ReadAll&quot;
348 Const cstSubArgs = &quot;&quot;
350 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
351 sRead = &quot;&quot;
353 Check:
354 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
355 If Not _IsFileOpen(&quot;READ&quot;) Then GoTo Finally
356 If _InputStream.isEOF() Then GoTo CatchEOF
357 End If
359 Try:
360 sRead = _InputStream.readString(Array(), False)
361 _LineNumber = _LineNumber + 1
363 Finally:
364 ReadAll = sRead
365 SF_Utils._ExitFunction(cstThisSub)
366 Exit Function
367 Catch:
368 GoTo Finally
369 CatchEOF:
370 SF_Exception.RaiseFatal(ENDOFFILEERROR, FileName)
371 GoTo Finally
372 End Function &apos; ScriptForge.SF_TextStream.ReadAll
374 REM -----------------------------------------------------------------------------
375 Public Function ReadLine() As String
376 &apos;&apos;&apos; Returns the next line in the text stream as a string. Line breaks are removed.
377 &apos;&apos;&apos; Args:
378 &apos;&apos;&apos; Returns:
379 &apos;&apos;&apos; The read line. The string may be empty.
380 &apos;&apos;&apos; Exceptions:
381 &apos;&apos;&apos; FILENOTOPENERROR File not open or already closed
382 &apos;&apos;&apos; FILEOPENMODEERROR File opened in write or append modes
383 &apos;&apos;&apos; ENDOFFILEERROR Previous reads already reached the end of the file
384 &apos;&apos;&apos; Examples:
385 &apos;&apos;&apos; Dim a As String
386 &apos;&apos;&apos; a = myFile.ReadLine()
388 Dim sRead As String &apos; Return value
389 Dim iRead As Integer &apos; Length of line break
390 Const cstThisSub = &quot;TextStream.ReadLine&quot;
391 Const cstSubArgs = &quot;&quot;
393 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
394 sRead = &quot;&quot;
396 Check:
397 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
398 If Not _IsFileOpen(&quot;READ&quot;) Then GoTo Finally
399 If AtEndOfStream Then GoTo CatchEOF
400 End If
402 Try:
403 &apos; When the text file ends with a line break,
404 &apos; XTextInputStream.readLine() returns the line break together with the last line
405 &apos; Hence the workaround to force a blank line at the end
406 If _ForceBlankLine Then
407 sRead = &quot;&quot;
408 _ForceBlankLine = False
409 Else
410 sRead = _InputStream.readLine()
411 &apos; The isEOF() is set immediately after having read the last line
412 If _InputStream.isEOF() And Len(sRead) &gt; 0 Then
413 iRead = 0
414 If SF_String.EndsWith(sRead, SF_String.sfCRLF) Then
415 iRead = 2
416 ElseIf SF_String.EndsWith(sRead, SF_String.sfLF) Or SF_String.EndsWith(sRead, SF_String.sfCR) Then
417 iRead = 1
418 End If
419 If iRead &gt; 0 Then
420 sRead = Left(sRead, Len(sRead) - iRead)
421 _ForceBlankLine = True &apos; Provision for a last empty line at the next read loop
422 End If
423 End If
424 End If
425 _LineNumber = _LineNumber + 1
427 Finally:
428 ReadLine = sRead
429 SF_Utils._ExitFunction(cstThisSub)
430 Exit Function
431 Catch:
432 GoTo Finally
433 CatchEOF:
434 SF_Exception.RaiseFatal(ENDOFFILEERROR, FileName)
435 GoTo Finally
436 End Function &apos; ScriptForge.SF_TextStream.ReadLine
438 REM -----------------------------------------------------------------------------
439 Public Function SetProperty(Optional ByVal PropertyName As Variant _
440 , Optional ByRef Value As Variant _
441 ) As Boolean
442 &apos;&apos;&apos; Set a new value to the given property
443 &apos;&apos;&apos; Args:
444 &apos;&apos;&apos; PropertyName: the name of the property as a string
445 &apos;&apos;&apos; Value: its new value
446 &apos;&apos;&apos; Exceptions
447 &apos;&apos;&apos; ARGUMENTERROR The property does not exist
449 Dim bSet As Boolean &apos; Return value
450 Const cstThisSub = &quot;TextStream.SetProperty&quot;
451 Const cstSubArgs = &quot;PropertyName, Value&quot;
453 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
454 bSet = False
456 Check:
457 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
458 If Not SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
459 End If
461 Try:
462 bSet = True
463 Select Case UCase(PropertyName)
464 Case &quot;NEWLINE&quot;
465 If Not SF_Utils._Validate(Value, &quot;Value&quot;, V_STRING) Then GoTo Catch
466 NewLine = Value
467 Case Else
468 bSet = False
469 End Select
471 Finally:
472 SetProperty = bSet
473 SF_Utils._ExitFunction(cstThisSub)
474 Exit Function
475 Catch:
476 GoTo Finally
477 End Function &apos; ScriptForge.SF_TextStream.SetProperty
479 REM -----------------------------------------------------------------------------
480 Public Sub SkipLine()
481 &apos;&apos;&apos; Skips the next line when reading a TextStream file.
482 &apos;&apos;&apos; Args:
483 &apos;&apos;&apos; Exceptions:
484 &apos;&apos;&apos; FILENOTOPENERROR File not open or already closed
485 &apos;&apos;&apos; FILEOPENMODEERROR File opened in write or append modes
486 &apos;&apos;&apos; ENDOFFILEERROR Previous reads already reached the end of the file
487 &apos;&apos;&apos; Examples:
488 &apos;&apos;&apos; myFile.SkipLine()
490 Dim sRead As String &apos; Read buffer
491 Const cstThisSub = &quot;TextStream.SkipLine&quot;
492 Const cstSubArgs = &quot;&quot;
494 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
496 Check:
497 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
498 If Not _IsFileOpen(&quot;READ&quot;) Then GoTo Finally
499 If Not _ForceBlankLine Then &apos; The file ends with a newline =&gt; return one empty line more
500 If _InputStream.isEOF() Then GoTo CatchEOF
501 End If
502 End If
504 Try:
505 sRead = ReadLine()
507 Finally:
508 SF_Utils._ExitFunction(cstThisSub)
509 Exit Sub
510 Catch:
511 GoTo Finally
512 CatchEOF:
513 SF_Exception.RaiseFatal(ENDOFFILEERROR, FileName)
514 GoTo Finally
515 End Sub &apos; ScriptForge.SF_TextStream.SkipLine
517 REM -----------------------------------------------------------------------------
518 Public Sub WriteBlankLines(Optional ByVal Lines As Variant)
519 &apos;&apos;&apos; Writes a number of empty lines in the output stream
520 &apos;&apos;&apos; Args:
521 &apos;&apos;&apos; Lines: the number of lines to write
522 &apos;&apos;&apos; Returns:
523 &apos;&apos;&apos; Exceptions:
524 &apos;&apos;&apos; FILENOTOPENERROR File not open or already closed
525 &apos;&apos;&apos; FILEOPENMODEERROR File opened in read mode
526 &apos;&apos;&apos; Examples:
527 &apos;&apos;&apos; myFile.WriteBlankLines(10)
528 Dim i As Long
529 Const cstThisSub = &quot;TextStream.WriteBlankLines&quot;
530 Const cstSubArgs = &quot;Lines&quot;
532 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
534 Check:
535 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
536 If Not _IsFileOpen(&quot;WRITE&quot;) Then GoTo Finally
537 If Not SF_Utils._Validate(Lines, &quot;Lines&quot;, V_NUMERIC) Then GoTo Finally
538 End If
540 Try:
541 For i = 1 To Lines
542 _OutputStream.writeString(_NewLine)
543 Next i
544 _LineNumber = _LineNumber + Lines
546 Finally:
547 SF_Utils._ExitFunction(cstThisSub)
548 Exit Sub
549 Catch:
550 GoTo Finally
551 End Sub &apos; ScriptForge.SF_TextStream.WriteBlankLines
553 REM -----------------------------------------------------------------------------
554 Public Sub WriteLine(Optional ByVal Line As Variant)
555 &apos;&apos;&apos; Writes the given line to the output stream. A newline is inserted if relevant
556 &apos;&apos;&apos; Args:
557 &apos;&apos;&apos; Line: the line to write, may be empty
558 &apos;&apos;&apos; Returns:
559 &apos;&apos;&apos; Exceptions:
560 &apos;&apos;&apos; FILENOTOPENERROR File not open or already closed
561 &apos;&apos;&apos; FILEOPENMODEERROR File opened in in read mode
562 &apos;&apos;&apos; Examples:
563 &apos;&apos;&apos; myFile.WriteLine(&quot;Next line&quot;)
564 Dim i As Long
565 Const cstThisSub = &quot;TextStream.WriteLine&quot;
566 Const cstSubArgs = &quot;Line&quot;
568 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
570 Check:
571 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
572 If Not _IsFileOpen(&quot;WRITE&quot;) Then GoTo Finally
573 If Not SF_Utils._Validate(Line, &quot;Line&quot;, V_STRING) Then GoTo Finally
574 End If
576 Try:
577 _OutputStream.writeString(Iif(_LineNumber &gt; 0, _NewLine, &quot;&quot;) &amp; Line)
578 _LineNumber = _LineNumber + 1
580 Finally:
581 SF_Utils._ExitFunction(cstThisSub)
582 Exit Sub
583 Catch:
584 GoTo Finally
585 End Sub &apos; ScriptForge.SF_TextStream.WriteLine
587 REM =========================================================== PRIVATE FUNCTIONS
589 REM -----------------------------------------------------------------------------
590 Public Sub _Initialize()
591 &apos;&apos;&apos; Opens file and setup input and/or output streams (ForAppending requires both)
593 Dim oSfa As Object &apos; com.sun.star.ucb.SimpleFileAccess
595 &apos; Default newline related to current operating system
596 _NewLine = SF_String.sfNEWLINE
598 Set oSfa = SF_Utils._GetUNOService(&quot;FileAccess&quot;)
600 &apos; Setup input and/or output streams based on READ/WRITE/APPEND IO modes
601 Select Case _IOMode
602 Case SF_FileSystem.ForReading
603 Set _FileHandler = oSfa.openFileRead(_FileName)
604 Set _InputStream = CreateUnoService(&quot;com.sun.star.io.TextInputStream&quot;)
605 _InputStream.setInputStream(_FileHandler)
606 Case SF_FileSystem.ForWriting
607 &apos; Output file is deleted beforehand
608 If _FileExists Then oSfa.kill(_FileName)
609 Set _FileHandler = oSfa.openFileWrite(_FileName)
610 Set _OutputStream = CreateUnoService(&quot;com.sun.star.io.TextOutputStream&quot;)
611 _OutputStream.setOutputStream(_FileHandler)
612 Case SF_FileSystem.ForAppending
613 Set _FileHandler = oSfa.openFileReadWrite(_FileName)
614 Set _InputStream = CreateUnoService(&quot;com.sun.star.io.TextInputStream&quot;)
615 Set _OutputStream = CreateUnoService(&quot;com.sun.star.io.TextOutputStream&quot;)
616 _InputStream.setInputStream(_FileHandler)
617 &apos; Position at end of file: Skip and count existing lines
618 _LineNumber = 0
619 Do While Not _InputStream.isEOF()
620 _InputStream.readLine()
621 _LineNumber = _LineNumber + 1
622 Loop
623 _OutputStream.setOutputStream(_FileHandler)
624 End Select
626 If _Encoding = &quot;&quot; Then _Encoding = &quot;UTF-8&quot;
627 If Not IsNull(_InputStream) Then _InputStream.setEncoding(_Encoding)
628 If Not IsNull(_OutputStream) Then _OutputStream.setEncoding(_Encoding)
630 End Sub &apos; ScriptForge.SF_TextStream._Initialize
632 REM -----------------------------------------------------------------------------
633 Private Function _IsFileOpen(Optional ByVal psMode As String) As Boolean
634 &apos;&apos;&apos; Checks if file is open with the right mode (READ or WRITE)
635 &apos;&apos;&apos; Raises an exception if the file is not open at all or not in the right mode
636 &apos;&apos;&apos; Args:
637 &apos;&apos;&apos; psMode: READ or WRITE or zero-length string
638 &apos;&apos;&apos; Exceptions:
639 &apos;&apos;&apos; FILENOTOPENERROR File not open or already closed
640 &apos;&apos;&apos; FILEOPENMODEERROR File opened in incompatible mode
642 _IsFileOpen = False
643 If IsMissing(psMode) Then psMode = &quot;&quot;
644 If IsNull(_InputStream) And IsNull(_OutputStream) Then GoTo CatchNotOpen
645 Select Case psMode
646 Case &quot;READ&quot;
647 If IsNull(_InputStream) Then GoTo CatchOpenMode
648 If _IOMode &lt;&gt; SF_FileSystem.ForReading Then GoTo CatchOpenMode
649 Case &quot;WRITE&quot;
650 If IsNull(_OutputStream) Then GoTo CatchOpenMode
651 If _IOMode = SF_FileSystem.ForReading Then GoTo CatchOpenMode
652 Case Else
653 End Select
654 _IsFileOpen = True
656 Finally:
657 Exit Function
658 CatchNotOpen:
659 SF_Exception.RaiseFatal(FILENOTOPENERROR, FileName)
660 GoTo Finally
661 CatchOpenMode:
662 SF_Exception.RaiseFatal(FILEOPENMODEERROR, FileName, IOMode)
663 GoTo Finally
664 End Function &apos; ScriptForge.SF_TextStream._IsFileOpen
666 REM -----------------------------------------------------------------------------
667 Private Function _PropertyGet(Optional ByVal psProperty As String)
668 &apos;&apos;&apos; Return the value of the named property
669 &apos;&apos;&apos; Args:
670 &apos;&apos;&apos; psProperty: the name of the property
672 Dim cstThisSub As String
673 Dim cstSubArgs As String
675 cstThisSub = &quot;TextStream.get&quot; &amp; psProperty
676 cstSubArgs = &quot;&quot;
677 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
679 Select Case UCase(psProperty)
680 Case UCase(&quot;AtEndOfStream&quot;)
681 Select Case _IOMode
682 Case SF_FileSystem.ForReading
683 If IsNull(_InputStream) Then _PropertyGet = True Else _PropertyGet = CBool(_InputStream.isEOF() And Not _ForceBlankLine)
684 Case Else : _PropertyGet = True
685 End Select
686 Case UCase(&quot;Encoding&quot;)
687 _PropertyGet = _Encoding
688 Case UCase(&quot;FileName&quot;)
689 &apos; Requested is the user visible file name in FileNaming notation
690 _PropertyGet = SF_FileSystem._ConvertFromUrl(Iif(_IsEmbeddedFile, _EmbeddedFileName, _FileName))
691 Case UCase(&quot;IOMode&quot;)
692 With SF_FileSystem
693 Select Case _IOMode
694 Case .ForReading : _PropertyGet = &quot;READ&quot;
695 Case .ForWriting : _PropertyGet = &quot;WRITE&quot;
696 Case .ForAppending : _PropertyGet = &quot;APPEND&quot;
697 Case Else : _PropertyGet = &quot;&quot;
698 End Select
699 End With
700 Case UCase(&quot;Line&quot;)
701 _PropertyGet = _LineNumber
702 Case UCase(&quot;NewLine&quot;)
703 _PropertyGet = _NewLine
704 Case Else
705 _PropertyGet = Null
706 End Select
708 Finally:
709 SF_Utils._ExitFunction(cstThisSub)
710 Exit Function
711 End Function &apos; ScriptForge.SF_TextStream._PropertyGet
713 REM -----------------------------------------------------------------------------
714 Private Function _Repr() As String
715 &apos;&apos;&apos; Convert the TextStream instance to a readable string, typically for debugging purposes (DebugPrint ...)
716 &apos;&apos;&apos; Args:
717 &apos;&apos;&apos; Return:
718 &apos;&apos;&apos; &quot;[TextStream]: File name, IOMode, LineNumber&quot;
720 _Repr = &quot;[TextStream]: &quot; &amp; FileName &amp; &quot;,&quot; &amp; IOMode &amp; &quot;,&quot; &amp; CStr(Line)
722 End Function &apos; ScriptForge.SF_TextStream._Repr
724 REM ============================================ END OF SCRIPTFORGE.SF_TextStream
725 </script:module>