summaryrefslogtreecommitdiff
path: root/fpcsrc/packages/palmunits/src/filestream.pp
blob: 91622d804aded8903c69638075e776378caee3b5 (plain)
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
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
{$MACRO ON}

(******************************************************************************
 *
 * Copyright (c) 1994-2000 Palm, Inc. or its subsidiaries.
 * All rights reserved.
 *
 * File: FileStream.h
 *
 * Release: Palm OS SDK 4.0 (63220)
 *
 * Description:
 *    Pilot File Stream equates -- File Streams were initially implemented
 *    in PalmOS v3.0 (not available in earlier versions)
 *
 * History:
 *    11/24/97 vmk      - Created by Vitaly Kruglikov
 *
 *****************************************************************************)

unit filestream;

interface

uses palmos, coretraps, errorbase;

(************************************************************
 * File Stream error codes
 * the constant dmErrorClass is defined in ErrorBase.h
 *************************************************************)

const
  fileErrMemError            = fileErrorClass or 1;  // out of memory error
  fileErrInvalidParam        = fileErrorClass or 2;  // invalid parameter value passed
  fileErrCorruptFile         = fileErrorClass or 3;  // the file is corrupted/invalid/not a stream file
  fileErrNotFound            = fileErrorClass or 4;  // couldn't find the file
  fileErrTypeCreatorMismatch = fileErrorClass or 5;  // file's type and creator didn't match those expected
  fileErrReplaceError        = fileErrorClass or 6;  // couldn't replace an existing file
  fileErrCreateError         = fileErrorClass or 7;  // couldn't create a new file
  fileErrOpenError           = fileErrorClass or 8;  // generic open error
  fileErrInUse               = fileErrorClass or 9;  // file couldn't be opened or deleted because it is in use
  fileErrReadOnly            = fileErrorClass or 10; // couldn't open in write mode because db is read-only
  fileErrInvalidDescriptor   = fileErrorClass or 11; // invalid file descriptor (FileHandle)
  fileErrCloseError          = fileErrorClass or 12; // error closing the database
  fileErrOutOfBounds         = fileErrorClass or 13; // attempted operation went out of bounds of the file
  fileErrPermissionDenied    = fileErrorClass or 14; // couldn't write to a file open for read-only access
  fileErrIOError             = fileErrorClass or 15; // general I/O error
  fileErrEOF                 = fileErrorClass or 16; // end-of-file error
  fileErrNotStream           = fileErrorClass or 17; // attempted to open a file that is not a stream

(************************************************************
 * File Stream handle type
 *************************************************************)

type
  FileHand = MemHandle;

const
  fileNullHandle = FileHand(0);

(************************************************************
 * Mode flags passed to FileOpen
 *************************************************************)

// fileModeReadOnly, fileModeReadWrite, fileModeUpdate, and fileModeAppend are mutually exclusive - only
// pass one of them to FileOpen!
const
  fileModeReadOnly       = $80000000; // open for read access
  fileModeReadWrite      = $40000000; // create for read/write access, discarding previous if any */
  fileModeUpdate         = $20000000; // open/create for read/write, preserving previous if any
  fileModeAppend         = $10000000; // open/create for read/write, always writing at the end

  fileModeLeaveOpen      = $08000000; // leave open when app quits
  fileModeExclusive      = $04000000; // don't let anyone else open it
  fileModeAnyTypeCreator = $02000000; // if set, skip type/creator validation when
                                      // opening or replacing an existing file

  fileModeTemporary      = $01000000; // will automatically delete the file when it is closed;
                                      // if this bit is set and the file type passed to FileOpen is zero,
                                      // FileOpen will use sysFileTTemp (defined in SystemResources.h for the file
                                      // type (recommended) - this will enable automatic cleanup of undeleted
                                      // temp files following a system crash in future PalmOS versions
                                      // (post-crash cleanup will likely come after 3.0)

  fileModeDontOverwrite  = $00800000; // if set, will prevent fileModeReadWrite from discarding an existing file
                                      // with the same name; may only be specified together with fileModeReadWrite

// For debugging/validation
const
  fileModeAllFlags = fileModeReadOnly or fileModeReadWrite or fileModeUpdate or
                     fileModeAppend or fileModeLeaveOpen or fileModeExclusive or
                     fileModeAnyTypeCreator or fileModeTemporary or fileModeDontOverwrite;

(************************************************************
 * Origin passed to FileSetPos
 *************************************************************)

type
  FileOriginEnum = Enum;

const
  fileOriginBeginning  = 1;                      // from the beginning (first data byte of file)
  fileOriginCurrent = Succ(fileOriginBeginning); // from the current position
  fileOriginEnd = Succ(fileOriginCurrent);       // from the end of file (one position beyond last data byte)

(************************************************************
 * Operation passed to FileControl
 *************************************************************)

type
  FileOpEnum = Enum;

const
  fileOpNone = 0;                                        // no-op

  fileOpDestructiveReadMode = Succ(fileOpNone);          // switch to destructive read mode (there is no turning back);
                                                         // implicitly rewinds the file to the beginning;
                                                         // destructive read mode deletes file stream data blocks as
                                                         // data is being read, thus freeing up storage automatically;
                                                         // once in destructive read mode, FileWrite, FileSeek and FileTruncate
                                                         // are not allowed; stream's contents after closing (or crash)
                                                         // are undefined.
                                                         // ARGUMENTS:
                                                         //    stream = open stream handle
                                                         //    valueP = NULL
                                                         //    valueLenP = NULL
                                                         // RETURNS:
                                                         //    zero on success; fileErr... on error

  fileOpGetEOFStatus = Succ(fileOpDestructiveReadMode);  // get end-of-file status (err = fileErrEOF indicates end of file condition);
                                                         // use FileClearerr to clear this error status
                                                         // ARGUMENTS:
                                                         //    stream = open stream handle
                                                         //    valueP = NULL
                                                         //    valueLenP = NULL
                                                         // RETURNS:
                                                         //    zero if _not_ end of file; non-zero if end of file

  fileOpGetLastError = Succ(fileOpGetEOFStatus);         // get error code from last operation on file stream, and
                                                         // clear the last error code value (will not change end of file
                                                         // or I/O error status -- use FileClearerr to reset all error codes)
                                                         // ARGUMENTS:
                                                         //    stream = open stream handle
                                                         //    valueP = NULL
                                                         //    valueLenP = NULL
                                                         // RETURNS:
                                                         //    Error code from last file stream operation

  fileOpClearError = Succ(fileOpGetLastError);           // clear I/O and end of file error status, and last error
                                                         // ARGUMENTS:
                                                         //    stream = open stream handle
                                                         //    valueP = NULL
                                                         //    valueLenP = NULL
                                                         // RETURNS:
                                                         //    zero on success; fileErr... on error

  fileOpGetIOErrorStatus = Succ(fileOpClearError);       // get I/O error status (like C runtime's ferror); use FileClearerr
                                                         // to clear this error status
                                                         // ARGUMENTS:
                                                         //    stream = open stream handle
                                                         //    valueP = NULL
                                                         //    valueLenP = NULL
                                                         // RETURNS:
                                                         //    zero if _not_ I/O error; non-zero if I/O error is pending

  fileOpGetCreatedStatus = Succ(fileOpGetIOErrorStatus); // find out whether the FileOpen call caused the file to
                                                         // be created
                                                         // ARGUMENTS:
                                                         //    stream = open stream handle
                                                         //    valueP = ptr to Boolean type variable
                                                         //    valueLenP = ptr to Int32 variable set to sizeof(Boolean)
                                                         // RETURNS:
                                                         //    zero on success; fileErr... on error;
                                                         //    the Boolean variable will be set to non zero if the file was created.

  fileOpGetOpenDbRef = Succ(fileOpGetCreatedStatus);     // get the open database reference (handle) of the underlying
                                                         // database that implements the stream (NULL if none);
                                                         // this is needed for performing PalmOS-specific operations on
                                                         // the underlying database, such as changing or getting creator/type,
                                                         // version, backup/reset bits, etc.
                                                         // ARGUMENTS:
                                                         //    stream = open stream handle
                                                         //    valueP = ptr to DmOpenRef type variable
                                                         //    valueLenP = ptr to Int32 variable set to sizeof(DmOpenRef)
                                                         // RETURNS:
                                                         //    zero on success; fileErr... on error;
                                                         //    the DmOpenRef variable will be set to the file's open db reference
                                                         //    that may be passed to Data Manager calls;
                                                         // WARNING:
                                                         //    Do not make any changes to the data of the underlying database --
                                                         //    this will cause the file stream to become corrupted.

  fileOpFlush = Succ(fileOpGetOpenDbRef);                // flush any cached data to storage
                                                         // ARGUMENTS:
                                                         //    stream = open stream handle
                                                         //    valueP = NULL
                                                         //    valueLenP = NULL
                                                         // RETURNS:
                                                         //    zero on success; fileErr... on error;

  fileOpLAST = Succ(fileOpFlush);                        // ***ADD NEW OPERATIONS BEFORE THIS ENTRY***
                                                         // ***  AND ALWAYS AFTER EXISTING ENTRIES ***
                                                         // ***     FOR BACKWARD COMPATIBILITY     ***

(************************************************************
 * File Stream procedures
 *************************************************************)

// Open/create a file stream (name must all be valid -- non-null, non-empty)
// (errP is optional - set to NULL to ignore)
function FileOpen(cardNo: UInt16; const nameP: PChar; type_, creator, openMode: UInt32; var errP: Err): FileHand; syscall sysTrapFileOpen;

// Close the file stream
function FileClose(stream: FileHand): Err; syscall sysTrapFileClose;

// Delete a file
function FileDelete(cardNo: UInt16; const nameP: PChar): Err; syscall sysTrapFileDelete;

(***********************************************************************
 *
 * MACRO:      FileRead
 *
 * DESCRIPTION:   Read data from a file into a buffer.  If you need to read into a data storage
 *                heap-based chunk, record or resource, you _must_ use FileDmRead instead.
 *
 * PROTOTYPE:  Int32 FileRead(FileHand stream, void *bufP, Int32 objSize, Int32 numObj, Err *errP)
 *
 * PARAMETERS: stream      -- handle of open file
 *             bufP        -- buffer for reading data
 *             objSize     -- size of each object to read
 *             numObj      -- number of objects to read
 *             errP        -- ptr to variable for returning the error code (fileErr...)
 *                            (OPTIONAL -- pass NULL to ignore)
 *
 * RETURNED:   the number of objects that were read - this may be less than
 *             the number of objects requested
 *
 ***********************************************************************)

function FileRead(stream: FileHand; bufP: Pointer; objSize, numObj: Int32; var errP: Err): Int32;

(***********************************************************************
 *
 * MACRO:      FileDmRead
 *
 * DESCRIPTION:   Read data from a file into a data storage heap-based chunk, record
 *                or resource.
 *
 * PROTOTYPE:  Int32 FileDmRead(FileHand stream, void *startOfDmChunkP, Int32 destOffset,
 *                   Int32 objSize, Int32 numObj, Err *errP)
 *
 * PARAMETERS: stream      -- handle of open file
 *             startOfDmChunkP
 *                         -- ptr to beginning of data storage heap-based chunk, record or resource
 *             destOffset  -- offset from base ptr to the destination area (must be >= 0)
 *             objSize     -- size of each object to read
 *             numObj      -- number of objects to read
 *             errP        -- ptr to variable for returning the error code (fileErr...)
 *                            (OPTIONAL -- pass NULL to ignore)
 *
 * RETURNED:   the number of objects that were read - this may be less than
 *             the number of objects requested
 *
 ***********************************************************************)

function FileDmRead(stream: FileHand; startOfDmChunkP: Pointer; destOffset: Int32; objSize, numObj: Int32; var errP: Err): Int32;

// Low-level routine for reading data from a file stream -- use helper macros FileRead and FileDmRead
// instead of calling this function directly;
// (errP is optional - set to NULL to ignore)
function FileReadLow(stream: FileHand; baseP: Pointer; offset: Int32; dataStoreBased: Boolean;
                     objSize, numObj: Int32; var errP: Err): Int32; syscall sysTrapFileReadLow;

// Write data to a file stream
// (errP is optional - set to NULL to ignore)
function FileWrite(stream: FileHand; const dataP: Pointer; objSize, numObj: Int32; var errP: Err): Int32; syscall sysTrapFileWrite;

// Set position within a file stream
function FileSeek(stream: FileHand; offset: Int32; origin: FileOriginEnum): Err; syscall sysTrapFileSeek;

function FileRewind(stream: FileHand): Err;

// Get current position and filesize
// (fileSizeP and errP are optional - set to NULL to ignore)
function FileTell(stream: FileHand; var fileSizeP: Int32; var errP: Err): Int32; syscall sysTrapFileTell;

// Truncate a file
function FileTruncate(stream: FileHand; newSize: Int32): Err; syscall sysTrapFileTruncate;

// Returns the error code from the last operation on this file stream;
// if resetLastError is non-zero, resets the error status
// function FileControl(op: FileOpEnum; stream: FileHand; valueP: Pointer; var valueLenP: Int32): Err; syscall sysTrapFileControl;
function FileControl(op: FileOpEnum; stream: FileHand; valueP: Pointer; valueLenP: Pointer): Err; syscall sysTrapFileControl;

function FileEOF(stream: FileHand): Boolean;

function FileError(stream: FileHand): Err;

function FileClearerr(stream: FileHand): Err;

function FileGetLastError(stream: FileHand): Err;

function FileFlush(stream: FileHand): Err;

implementation

function FileRead(stream: FileHand; bufP: Pointer; objSize, numObj: Int32; var errP: Err): Int32;
begin
  FileRead := FileReadLow(stream, bufP, 0{offset}, False{dataStoreBased}, objSize, numObj, errP);
end;

function FileDmRead(stream: FileHand; startOfDmChunkP: Pointer; destOffset: Int32; objSize, numObj: Int32; var errP: Err): Int32;
begin
  FileDmRead := FileReadLow(stream, startOfDmChunkP, destOffset, True{dataStoreBased}, objSize, numObj, errP);
end;

function FileRewind(stream: FileHand): Err;
begin
  FileClearerr(stream);
  FileRewind := FileSeek(stream, 0, fileOriginBeginning);
end;

function FileEOF(stream: FileHand): Boolean;
begin
  FileEOF := FileControl(fileOpGetEOFStatus, stream, nil, Longint(nil)) = fileErrEOF;
end;

function FileError(stream: FileHand): Err;
begin
  FileError := FileControl(fileOpGetIOErrorStatus, stream, nil, Longint(nil));
end;

function FileClearerr(stream: FileHand): Err;
begin
  FileClearerr := FileControl(fileOpClearError, stream, nil, Longint(nil));
end;

function FileGetLastError(stream: FileHand): Err;
begin
  FileGetLastError := FileControl(fileOpGetLastError, stream, nil, Longint(nil));
end;

function FileFlush(stream: FileHand): Err;
begin
  FileFlush := FileControl(fileOpFlush, stream, nil, Longint(nil));
end;

end.