source: trunk/tools/common/kFile.cpp@ 3613

Last change on this file since 3613 was 3613, checked in by bird, 25 years ago

Corrected some bugs...

File size: 8.6 KB
Line 
1/* $Id: kFile.cpp,v 1.2 2000-05-27 02:14:20 bird Exp $
2 *
3 * kFile - Simple (for the time being) file class.
4 *
5 * Copyright (c) 2000 knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
6 *
7 * Project Odin Software License can be found in LICENSE.TXT
8 *
9 */
10
11/*******************************************************************************
12* Defined Constants And Macros *
13*******************************************************************************/
14#define INCL_DOSFILEMGR
15#define INCL_DOSERRORS
16
17
18/*******************************************************************************
19* Header Files *
20*******************************************************************************/
21#include <os2.h>
22#include <string.h>
23
24#include <kFile.h>
25
26
27/**
28 * Updates the internal filestatus struct.
29 * @returns Success indicator.
30 * On success filestatus is refreshed.
31 * @remark
32 */
33BOOL kFile::refreshFileStatus()
34{
35 if (!fStatusClean)
36 {
37 rc = (int)DosQueryFileInfo(hFile, FIL_QUERYEASIZE, &filestatus, sizeof(filestatus));
38 fStatusClean = (rc == NO_ERROR);
39 if (!fStatusClean && fThrowErrors)
40 throw (rc);
41 }
42 else
43 rc = NO_ERROR;
44
45 return fStatusClean;
46}
47
48
49/**
50 * Changes the real file position to match the virtual file position.
51 * @returns Success indicator.
52 */
53BOOL kFile::position()
54{
55 /*
56 * If virtual file offset is different from the real,
57 * issue a set file pointer call.
58 */
59 if (offVirtual != offReal)
60 {
61 ULONG off;
62 rc = (int)DosSetFilePtr(hFile, offVirtual, FILE_BEGIN, &off);
63 if (rc != NO_ERROR || off != offVirtual)
64 {
65 if (fThrowErrors)
66 throw (rc);
67 return FALSE;
68 }
69 offReal = offVirtual;
70 }
71
72 return TRUE;
73}
74
75
76/**
77 * Opens a file for binary reading or readwrite.
78 * @returns <object> with state updated.
79 * Throws OS/2 error on error.
80 * @param pszFilename Filename.
81 * @param fReadOnly TRUE: Open the file readonly. (default)
82 * FALSE: Open the file readwrite appending
83 * existing files.
84 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
85 */
86kFile::kFile(const char *pszFilename, BOOL fReadOnly/*=TRUE*/)
87: fReadOnly(fReadOnly),
88 fStatusClean(FALSE),
89 fThrowErrors(FALSE),
90 offVirtual(0),
91 offReal(0)
92{
93 ULONG fulOpenFlags;
94 ULONG fulOpenMode;
95 ULONG ulAction;
96
97 /*
98 * Determin open flags according to fReadOnly.
99 */
100 if (fReadOnly)
101 {
102 fulOpenFlags = OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
103 fulOpenMode = OPEN_SHARE_DENYWRITE | OPEN_ACCESS_READONLY;
104 }
105 else
106 {
107 fulOpenFlags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
108 fulOpenMode = OPEN_SHARE_DENYWRITE | OPEN_ACCESS_READWRITE;
109 }
110
111 rc = (int)DosOpen((PCSZ)pszFilename, &hFile, &ulAction, 0, FILE_NORMAL,
112 fulOpenFlags, fulOpenMode, NULL);
113 if (rc != NO_ERROR)
114 throw (rc);
115
116 if (!refreshFileStatus())
117 throw (rc);
118}
119
120
121/**
122 * Closes the file.
123 */
124kFile::~kFile()
125{
126 DosClose(hFile);
127}
128
129
130/**
131 * Reads <cbBuffer> bytes from the current file posistion into the buffer.
132 * @returns success indicator. (TRUE/FALSE)
133 * @param pvBuffer Output buffer.
134 * @param cbBuffer Amount of bytes to read.
135 */
136BOOL kFile::read(void *pvBuffer, long cbBuffer)
137{
138 if (position())
139 {
140 ULONG cbRead;
141 rc = (int)DosRead(hFile, pvBuffer, cbBuffer, &cbRead);
142 if (rc == NO_ERROR)
143 {
144 offVirtual = offReal += cbRead;
145 return TRUE;
146 }
147 }
148
149 if (fThrowErrors)
150 throw (rc);
151 return FALSE;
152}
153
154
155/**
156 * Reads <cbBuffer> bytes at file offset <off>.
157 * @returns success indicator. (TRUE/FALSE)
158 * @param pvBuffer Output buffer.
159 * @param cbBuffer Amount of bytes to read.
160 * @param off Absolute file offset.
161 */
162BOOL kFile::readAt(void *pvBuffer, long cbBuffer, long off)
163{
164 return set(off) && read(pvBuffer, cbBuffer);
165}
166
167
168/**
169 * Writes <cbBuffer> bytes to the file at the current file position.
170 * @returns success indicator. (TRUE/FALSE)
171 * @param pvBuffer Output buffer.
172 * @param cbBuffer Amount of bytes to write.
173 */
174BOOL kFile::write(void *pvBuffer, long cbBuffer)
175{
176 if (fReadOnly)
177 rc = ERROR_ACCESS_DENIED;
178 else
179 {
180 if (position())
181 {
182 ULONG cbWrote;
183
184 rc = (int)DosWrite(hFile, pvBuffer, cbBuffer, &cbWrote);
185 if (rc == NO_ERROR)
186 {
187 fStatusClean = FALSE;
188 offVirtual = offReal += cbWrote;
189 return TRUE;
190 }
191 }
192 }
193
194 if (fThrowErrors)
195 throw(rc);
196 return FALSE;
197}
198
199
200/**
201 * Write <cbBuffer> bytes at file offset <off> from <pvBuffer>.
202 * @returns success indicator. (TRUE/FALSE)
203 * @param pvBuffer Output buffer.
204 * @param cbBuffer Amount of bytes to write.
205 * @param off Absolute file offset.
206 */
207BOOL kFile::writeAt(void *pvBuffer, long cbBuffer, long off)
208{
209 return set(off) && write(pvBuffer, cbBuffer);
210}
211
212
213/**
214 * Seek relative to the current position.
215 * @returns Success indicator.
216 * @param off Relative reposition.
217 */
218BOOL kFile::move(long off)
219{
220 if ((off + offVirtual) & 0x80000000UL) /* above 2GB or negative */
221 rc = ERROR_NEGATIVE_SEEK;
222 else
223 {
224 if (off + offVirtual > filestatus.cbFile && fReadOnly) /* can't expand readonly file. */
225 rc = ERROR_HANDLE_EOF;
226 else
227 {
228 offVirtual += off;
229 return TRUE;
230 }
231 }
232
233 if (fThrowErrors)
234 throw(rc);
235 return FALSE;
236}
237
238
239/**
240 * Seek to an absolute position in the file (off).
241 * @returns Success indicator.
242 * @param off New file position.
243 */
244BOOL kFile::set(long off)
245{
246 if (off < 0)
247 rc = ERROR_NEGATIVE_SEEK;
248 else
249 {
250 if ((unsigned long)off > filestatus.cbFile && fReadOnly)
251 rc = ERROR_HANDLE_EOF;
252 else
253 {
254 offVirtual = off;
255 rc = NO_ERROR;
256 return TRUE;
257 }
258 }
259 if (fThrowErrors)
260 throw(rc);
261 return FALSE;
262}
263
264
265/**
266 * Seek to the end of the file.
267 * @returns Success indicator. TRUE / FALSE.
268 * @remark Will only throw error if refreshFileStatus failes.
269 */
270BOOL kFile::end()
271{
272 if (!refreshFileStatus())
273 return FALSE;
274 offVirtual = filestatus.cbFile; //?? or +1
275 rc = NO_ERROR;
276 return TRUE;
277}
278
279
280/**
281 * Seek to the start of the file.
282 * @returns TRUE.
283 * @remark Will never throw errors.
284 */
285BOOL kFile::start()
286{
287 offVirtual = 0;
288 rc = NO_ERROR;
289 return TRUE;
290}
291
292
293/**
294 * Get the size of the file.
295 * @returns Returns file size on success.
296 * -1 on error.
297 * @remark Will only throw error if refreshFileStatus failes.
298 */
299long kFile::getSize()
300{
301 if (!refreshFileStatus())
302 return -1;
303
304 return filestatus.cbFile;
305}
306
307
308/**
309 * Get current position.
310 * @returns The current file position.
311 * @remark Will only throw error if refreshFileStatus failes.
312 */
313long kFile::getPos() const
314{
315 return offVirtual;
316}
317
318
319/**
320 * Checks if we have reached the file end.
321 * @returns TRUE if end-of-file is reached.
322 * FALSE is not end-of-file.
323 * @remark Will only throw error if refreshFileStatus failes.
324 */
325BOOL kFile::isEOF()
326{
327 #if 0
328 throw(ERROR_NOT_SUPPORTED); //this method don't currently work! Need to use flag!
329 #else
330 if (!refreshFileStatus())
331 return (BOOL)-1;
332
333 return filestatus.cbFile >= offReal; //???
334 #endif
335}
336
337
338/**
339 * Set error behaviour to fail by throwing the OS/2 return code when an
340 * error occures.
341 * @returns TRUE;
342 * @remark Will never throw errors.
343 */
344BOOL kFile::setThrowOnErrors()
345{
346 fThrowErrors = TRUE;
347 rc = NO_ERROR;
348 return TRUE;
349}
350
351
352/**
353 * Set error behaviour to fail by return FALSE when an error has occures.
354 * @returns TRUE;
355 * @remark Will never throw errors.
356 */
357BOOL kFile::setFailOnErrors()
358{
359 fThrowErrors = FALSE;
360 rc = NO_ERROR;
361 return TRUE;
362}
363
364
365/**
366 * Gets the last error code.
367 * @returns OS/2 error code for the last operation.
368 * @remark Will never throw errors.
369 */
370int kFile::getLastError() const
371{
372 return rc;
373}
374
Note: See TracBrowser for help on using the repository browser.