cfad47cfa3/t3compiler/tads3/include/file.h

4b825dc642cb6eb9a060e54bf8d69288fbee4904cfad47cfa334b206c65f22086bcc5d63e6f70944
1
#charset "us-ascii"
2
3
/*
4
 *   Copyright (c) 2001, 2006 Michael J. Roberts
5
 *   
6
 *   This file is part of TADS 3.
7
 *   
8
 *   This header defines the File intrinsic class.  
9
 */
10
11
#ifndef _FILE_H_
12
#define _FILE_H_
13
14
/* include our base class definition */
15
#include "systype.h"
16
17
/*
18
 *   File methods use the CharacterSet and ByteArray intrinsic
19
 *   classes, so include their headers to make sure they're available to
20
 *   File users.  
21
 */
22
#include "charset.h"
23
#include "bytearr.h"
24
25
26
/* ------------------------------------------------------------------------ */
27
/*
28
 *   File access modes.  These are used when calling the file open methods
29
 *   to specify how the file is to be accessed.
30
 */
31
32
/* 
33
 *   Read mode - the file is opened for reading (writing is not allowed).
34
 *   When opened in this mode, the file must exist, or a
35
 *   FileNotFoundException is thrown from the open method. 
36
 */
37
#define FileAccessRead            0x0001
38
39
/*
40
 *   Write mode - the file is opened for writing (reading is not allowed).
41
 *   When opened in this mode, if the file doesn't already exist, a new file
42
 *   is created; if the file does already exist, the existing data in the
43
 *   file are discarded (i.e., the file is truncated to zero length) on
44
 *   open. 
45
 */
46
#define FileAccessWrite           0x0002
47
48
/*
49
 *   Read/write mode, keeping existing contents - the file is opened for
50
 *   both reading and writing.  If the file does not exist, a new file is
51
 *   created.  If the file does already exist, the existing contents of the
52
 *   file are kept intact on open.  
53
 */
54
#define FileAccessReadWriteKeep   0x0003
55
56
/*
57
 *   Read/write mode, truncating existing contents - the file is opened for
58
 *   both reading and writing.  If the file does not exist, a new file is
59
 *   created.  If the file does already exist, the existing contents of the
60
 *   file are discarded (i.e., the file is truncated to zero length) on
61
 *   open.  
62
 */
63
#define FileAccessReadWriteTrunc  0x0004
64
65
66
/* ------------------------------------------------------------------------ */
67
/*
68
 *   Special file identifiers.  These identifiers can be passed to the 'open'
69
 *   routines in place of the filename string argument.
70
 *   
71
 *   The actual name and location of a special file is determined by the
72
 *   interpreter.  Since games use these internal identifiers rather than the
73
 *   actual system filenames when accessing special files, different
74
 *   interpreters can adapt to different local conventions without bothering
75
 *   the game code with the details.  The game code simply refers to the file
76
 *   it wants using the virtual identifier, and the interpreter takes care of
77
 *   the rest.
78
 *   
79
 *   Note that special files generally bypass the interpreter "file safety"
80
 *   settings.  This is important because it allows the library and games a
81
 *   degree of controlled access to the file system, even when the file
82
 *   safety settings wouldn't normally allow similar access for arbitrary
83
 *   file operations.  Even though this special file access can bypass the
84
 *   file safety level, it doesn't compromise security, because the
85
 *   interpreter has exclusive control over the names and locations of the
86
 *   special files - thus a game can only access the particular files that
87
 *   the interpreter designates as special, and can't use special files to
88
 *   access arbitrary file system entities.  
89
 */
90
91
/*
92
 *   The library defaults file.  This is the special file where the library
93
 *   stores user-controlled start-up default settings.  
94
 */
95
#define LibraryDefaultsFile    0x0001
96
97
98
/* ------------------------------------------------------------------------ */
99
/*
100
 *   The File intrinsic class provides access to files in the external file
101
 *   system.  This lets you create, read, and write files.  The class
102
 *   supports text files (with translations to and from local character
103
 *   sets), "data" files (using the special TADS 2 binary file format), and
104
 *   "raw" files (this mode lets you manipulate files in arbitrary text or
105
 *   binary formats by giving you direct access to the raw bytes in the
106
 *   file).  
107
 */
108
intrinsic class File 'file/030002': Object
109
{
110
    /*
111
     *   File has no constructors, so it is not possible to create a File
112
     *   with the 'new' operator.  To create a file, use one of the static
113
     *   creator methods instead:
114
     *   
115
     *   f = File.openTextFile()
116
     *   
117
     *   All of the open methods throw exceptions if the open fails:
118
     *   
119
     *   FileNotFoundException - indicates that the requested file doesn't
120
     *   exist.  This is thrown when the access mode requires an existing
121
     *   file but the named file does not exist.
122
     *   
123
     *   FileCreationException - indicates that the requested file could not
124
     *   be created.  This is thrown when the access mode requires creating
125
     *   a new file but the named file cannot be created.
126
     *   
127
     *   FileOpenException - indicates that the requested file could not be
128
     *   opened.  This is thrown when the access mode allows either an
129
     *   existing file to be opened or a new file to be created, but neither
130
     *   could be accomplished.
131
     *   
132
     *   FileSafetyException - the requested access mode is not allowed for
133
     *   the given file due to the current file safety level set by the
134
     *   user.  Users can set the file safety level (through command-line
135
     *   switches or other preference mechanisms which vary by interpreter)
136
     *   to restrict the types of file operations that applications are
137
     *   allowed to perform, in order to protect their systems from
138
     *   malicious programs.  This exception indicates that the user has set
139
     *   a safety level that is too restrictive for the requested operation.
140
     */
141
142
    /*
143
     *   Static creator method: open a text file.  Returns a File object
144
     *   that can be used to read or write the file.  'access' is the
145
     *   read/write mode, and must be one of FileAccessRead or
146
     *   FileAccessWrite.  'charset' is a CharacterSet object, or can
147
     *   optionally be a string naming a character set, in which case a
148
     *   CharacterSet object for the named character set will automatically
149
     *   be created.  If 'charset' is omitted, a default "us-ascii"
150
     *   character set will be used.
151
     *   
152
     *   When a file is opened in text mode for reading, each call to
153
     *   readFile() reads and returns a line of text from the file.  When a
154
     *   file is opened in text mode for writing, any existing file is
155
     *   discarded and replaced with the new data.  Each read and write to a
156
     *   text file is mapped through the CharacterSet in effect at the time
157
     *   of the read or write.  
158
     */
159
    static openTextFile(filename, access, charset?);
160
161
    /*
162
     *   Static creator method: open a file in 'data' mode.  Returns a File
163
     *   object that can be used to read or write the file.  'access'
164
     *   indicates the desired read/write access and the disposition of any
165
     *   existing file; any of the FileAccessXxx modes can be used.
166
     *   
167
     *   When a file is opened in data mode, you can read and write
168
     *   integers, strings, and 'true' values to the file, and the values in
169
     *   the file are marked with their datatype in a private data format.
170
     *   Because the file uses a tads-specific format, this mode cannot be
171
     *   used to read files created by other applications or write files for
172
     *   use by other applications; however, this storage format is
173
     *   convenient for storing simple data values because the File object
174
     *   takes care of converting to and from a portable binary format.  
175
     */
176
    static openDataFile(filename, access);
177
178
    /*
179
     *   Static creator method: open a file in 'raw' mode.  Returns a File
180
     *   object that can be used to read or write the file.  'access'
181
     *   indicates the desired read/write access mode and the disposition of
182
     *   any existing file; any of the FileAccessXxx modes can be used.
183
     *   
184
     *   When a file is opened in raw mode, only ByteArray values can be
185
     *   read and written.  The File object performs no translations of the
186
     *   bytes read or written.  This mode requires the calling program
187
     *   itself to perform all data conversions to and from a raw byte
188
     *   format, but the benefit of this extra work is that this mode can be
189
     *   used to read and write files in arbitrary data formats, including
190
     *   formats defined by other applications.  
191
     */
192
    static openRawFile(filename, access);
193
194
    /* 
195
     *   get the CharacterSet object the File is currently using; returns
196
     *   nil for a non-text file 
197
     */
198
    getCharacterSet();
199
200
    /*
201
     *   Set the CharacterSet object the File is to use from now on.  This
202
     *   is not meaningful except for text files.  'charset' must be a
203
     *   CharacterSet object; in particular note that a character set name
204
     *   given as a string is not allowed here.  
205
     */
206
    setCharacterSet(charset);
207
208
    /*
209
     *   Close the file.  Flushes any buffered information to the underlying
210
     *   system file and releases any system resources (such as share locks
211
     *   or system buffers) associated with the file.  After this routine is
212
     *   called, no further operations on the file can be performed (a
213
     *   FileClosedException will be thrown if any subsequent operations are
214
     *   attempted).
215
     *   
216
     *   It's not strictly necessary to call closeFile() on a File, since the
217
     *   system will automatically do this work when the File object becomes
218
     *   unreachable and is discarded by the garbage collector.  However, it
219
     *   is good practice to close a file explicitly by calling this method
220
     *   as soon as the program reaches a point at which it knows it's done
221
     *   with the file, because garbage collection might not run for a
222
     *   significant amount of time after the program is actually done with
223
     *   the file, in which case the system resources associated with the
224
     *   file would be needlessly retained for this extended time.  
225
     */
226
    closeFile();
227
228
    /*
229
     *   Read from the file.  Returns a data value that depends on the file
230
     *   mode, as described below, or nil at end of file.
231
     *   
232
     *   If the file is open in text mode, this reads a line of text from the
233
     *   file and returns a string with the text of the line read.  A line of
234
     *   text is a sequence of characters terminated with a line-ending
235
     *   sequence, which is a carriage return, line feed, CR/LF pair, LF/CR
236
     *   pair, or a Unicode line terminator character (0x2028) if the file is
237
     *   being read with one of the Unicode encodings.  If the line read ends
238
     *   in a line-ending sequence, the returned text will end in a '\n'
239
     *   character, regardless of which of the possible line-ending sequences
240
     *   is actually in the file, so the caller need not worry about the
241
     *   details of the external file's format.  Every line read from the
242
     *   file will end in a '\n' except possibly the last line - if the file
243
     *   does not end with a line-ending sequence, then the last line read
244
     *   from the file will not end in a '\n' character.  All bytes read from
245
     *   the file will be mapped to characters through the CharacterSet
246
     *   object currently in effect in the file, so the returned string will
247
     *   always be a standard Unicode string, regardless of the byte encoding
248
     *   of the file.
249
     *   
250
     *   If the file is open in 'data' mode, this reads one data element
251
     *   using the private tads-specific data format.  The result is a value
252
     *   of one of the types writable with writeFile() in 'data' mode.  In
253
     *   order to read a 'data' file, the file must have been previously
254
     *   written in 'data' mode.  
255
     */
256
    readFile();
257
258
    /*
259
     *   Write to the file.  Writes the given value to the file in a format
260
     *   that depends on the file mode, as described below.  No return
261
     *   value; if an error occurs writing the data, this throws a
262
     *   FileIOException.
263
     *   
264
     *   If the file is open in text mode, this writes text to the file,
265
     *   converting the given value to a string if necessary (and throwing
266
     *   an error if such a conversion is not possible), and translating the
267
     *   string to be written to bytes by mapping the string through the
268
     *   CharacterSet object currently in effect for the file.  Note that no
269
     *   line-ending characters are automatically added to the output, so if
270
     *   the caller wishes to write line terminators, it should simply
271
     *   include a '\n' character at the end of each line.
272
     *   
273
     *   If the file is open in 'data' mode, this writes the value, which
274
     *   must be a string, integer, enum, or 'true' value, in a private
275
     *   tads-specific data format that can later be read using the same
276
     *   format.  The values are converted to the private binary format,
277
     *   which is portable across platforms: a file written in 'data' mode
278
     *   on one machine can be copied (byte-for-byte) to another machine,
279
     *   even one that uses different hardware and a different operating
280
     *   system, and read back in 'data' mode on the new machine to yield
281
     *   the original values written.  
282
     */
283
    writeFile(val);
284
285
    /*
286
     *   Read bytes from the file into the given ByteArray object.  This can
287
     *   only be used for a file opened in 'raw' mode.  If 'start' and 'cnt'
288
     *   are given, they give the starting index in the byte array at which
289
     *   the bytes read are to be stored, and the number of bytes to read,
290
     *   respectively; if these are omitted, one byte is read from the file
291
     *   for each byte in the byte array.
292
     *   
293
     *   Returns the number of bytes actually read into the byte array,
294
     *   which will be less than or equal to the number requested.  If the
295
     *   number read is less than the number requested, it means that the
296
     *   end of the file was encountered, and only the returned number of
297
     *   bytes were available.  
298
     */
299
    readBytes(byteArr, start?, cnt?);
300
301
    /*
302
     *   Write bytes from the ByteArray object into the file.  This can only
303
     *   be used for a file opened in 'raw' mode.  If 'start' and 'cnt' are
304
     *   given, they give the starting index in the byte array of the bytes
305
     *   to be written, and the number of bytes to write, respectively; if
306
     *   these are omitted, all of the bytes in the array are written.
307
     *   
308
     *   No return value; if an error occurs writing the data, a
309
     *   FileIOException is thrown.  
310
     */
311
    writeBytes(byteArr, start?, cnt?);
312
313
    /*
314
     *   Get the current read/write position in the file.  Returns the byte
315
     *   offset in the file of the next byte to be read or written.  Note
316
     *   that this value is an offset, so 0 is the offset of the first byte
317
     *   in the file.  
318
     */
319
    getPos();
320
321
    /*
322
     *   Set the current read/write position in the file.  'pos' is a byte
323
     *   offset in the file; 0 is the offset of the first byte.
324
     *   
325
     *   For files in 'text' and 'data' modes, a caller should NEVER set the
326
     *   file position to any value other than a value previously returned
327
     *   by getPos(), because other positions might violate the format
328
     *   constraints.  For example, if you move the file position to a byte
329
     *   in the middle of a line-ending sequence in a text file, subsequent
330
     *   reading from the file might misinterpret the sequence as something
331
     *   other than a line ending, or as an extra line ending.  If you move
332
     *   the position in a 'data' file to a byte in the middle of an integer
333
     *   value, reading from the file would misinterpret as a data type tag
334
     *   a byte that is part of the integer value instead.  So it is never
335
     *   meaningful or safe to set an arbitrary byte offset in these file
336
     *   formats; only values known to be valid by virtue of having been
337
     *   returned from getPos() can be used here in these modes.  
338
     */
339
    setPos(pos);
340
341
    /*
342
     *   Set the current read/write position to the end of the file.  This
343
     *   can be used, for example, to open a 'data' mode file for
344
     *   read/write/keep access (keeping the contents of an existing file)
345
     *   and then adding more data after all of the existing data in the
346
     *   file.  
347
     */
348
    setPosEnd();
349
350
    /*
351
     *   Static creator method: open a resource in 'text' mode.  This acts
352
     *   like openTextFile(), but rather than opening an ordinary file, this
353
     *   method opens a resource.  Resources differ from ordinary files in
354
     *   two important respects.  First, a resource is named with a
355
     *   URL-style path rather than a local file system name.  Second, a
356
     *   resource can be embedded in the program's executable (.t3) file, or
357
     *   can be embedded in an external resource bundle (.3r0, etc) file.
358
     *   
359
     *   Resources are read-only, so the access mode is implicitly
360
     *   FileAccessRead.  
361
     */
362
    static openTextResource(resname, charset?);
363
364
    /*
365
     *   Static creator method: open a resource in 'raw' mode.  This acts
366
     *   like openRawFile(), but opens a resource rather than an ordinary
367
     *   file.
368
     *   
369
     *   Resources are read-only, so the access mode is implicitly
370
     *   FileAccessRead.  
371
     */
372
    static openRawResource(resname);
373
374
    /* get the size in bytes of the file */
375
    getFileSize();
376
}
377
378
#endif /* _FILE_H_ */