author | kergoth <kergoth> | 2002-11-01 00:10:42 (UTC) |
---|---|---|
committer | kergoth <kergoth> | 2002-11-01 00:10:42 (UTC) |
commit | 5042e3cf0d3514552769e441f5aad590c8eaf967 (patch) (unidiff) | |
tree | 4a5ea45f3519d981a172ab5275bf38c6fa778dec /qmake/tools/qfile.cpp | |
parent | 108c1c753e74e989cc13923086996791428c9af4 (diff) | |
download | opie-5042e3cf0d3514552769e441f5aad590c8eaf967.zip opie-5042e3cf0d3514552769e441f5aad590c8eaf967.tar.gz opie-5042e3cf0d3514552769e441f5aad590c8eaf967.tar.bz2 |
Adding qmake in preperation for new build system
-rw-r--r-- | qmake/tools/qfile.cpp | 614 |
1 files changed, 614 insertions, 0 deletions
diff --git a/qmake/tools/qfile.cpp b/qmake/tools/qfile.cpp new file mode 100644 index 0000000..a578b49 --- a/dev/null +++ b/qmake/tools/qfile.cpp | |||
@@ -0,0 +1,614 @@ | |||
1 | /**************************************************************************** | ||
2 | ** $Id$ | ||
3 | ** | ||
4 | ** Implementation of QFile class | ||
5 | ** | ||
6 | ** Created : 930812 | ||
7 | ** | ||
8 | ** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. | ||
9 | ** | ||
10 | ** This file is part of the tools module of the Qt GUI Toolkit. | ||
11 | ** | ||
12 | ** This file may be distributed under the terms of the Q Public License | ||
13 | ** as defined by Trolltech AS of Norway and appearing in the file | ||
14 | ** LICENSE.QPL included in the packaging of this file. | ||
15 | ** | ||
16 | ** This file may be distributed and/or modified under the terms of the | ||
17 | ** GNU General Public License version 2 as published by the Free Software | ||
18 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
19 | ** packaging of this file. | ||
20 | ** | ||
21 | ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition | ||
22 | ** licenses may use this file in accordance with the Qt Commercial License | ||
23 | ** Agreement provided with the Software. | ||
24 | ** | ||
25 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
26 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
27 | ** | ||
28 | ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for | ||
29 | ** information about Qt Commercial License Agreements. | ||
30 | ** See http://www.trolltech.com/qpl/ for QPL licensing information. | ||
31 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
32 | ** | ||
33 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
34 | ** not clear to you. | ||
35 | ** | ||
36 | **********************************************************************/ | ||
37 | |||
38 | #include "qplatformdefs.h" | ||
39 | |||
40 | // POSIX Large File Support redefines open -> open64 | ||
41 | #if defined(open) | ||
42 | # undef open | ||
43 | #endif | ||
44 | |||
45 | // POSIX Large File Support redefines truncate -> truncate64 | ||
46 | #if defined(truncate) | ||
47 | # undef truncate | ||
48 | #endif | ||
49 | |||
50 | #include "qfile.h" | ||
51 | |||
52 | |||
53 | extern bool qt_file_access( const QString& fn, int t ); | ||
54 | |||
55 | /*! | ||
56 | \class QFile qfile.h | ||
57 | \reentrant | ||
58 | \brief The QFile class is an I/O device that operates on files. | ||
59 | |||
60 | \ingroup io | ||
61 | \mainclass | ||
62 | |||
63 | QFile is an I/O device for reading and writing binary and text | ||
64 | files. A QFile may be used by itself or more conveniently with a | ||
65 | QDataStream or QTextStream. | ||
66 | |||
67 | The file name is usually passed in the constructor but can be | ||
68 | changed with setName(). You can check for a file's existence with | ||
69 | exists() and remove a file with remove(). | ||
70 | |||
71 | The file is opened with open(), closed with close() and flushed | ||
72 | with flush(). Data is usually read and written using QDataStream | ||
73 | or QTextStream, but you can read with readBlock() and readLine() | ||
74 | and write with writeBlock(). QFile also supports getch(), | ||
75 | ungetch() and putch(). | ||
76 | |||
77 | The size of the file is returned by size(). You can get the | ||
78 | current file position or move to a new file position using the | ||
79 | at() functions. If you've reached the end of the file, atEnd() | ||
80 | returns TRUE. The file handle is returned by handle(). | ||
81 | |||
82 | Here is a code fragment that uses QTextStream to read a text file | ||
83 | line by line. It prints each line with a line number. | ||
84 | \code | ||
85 | QStringList lines; | ||
86 | QFile file( "file.txt" ); | ||
87 | if ( file.open( IO_ReadOnly ) ) { | ||
88 | QTextStream stream( &file ); | ||
89 | QString line; | ||
90 | int i = 1; | ||
91 | while ( !stream.eof() ) { | ||
92 | line = stream.readLine(); // line of text excluding '\n' | ||
93 | printf( "%3d: %s\n", i++, line.latin1() ); | ||
94 | lines += line; | ||
95 | } | ||
96 | file.close(); | ||
97 | } | ||
98 | \endcode | ||
99 | |||
100 | Writing text is just as easy. The following example shows how to | ||
101 | write the data we read into the string list from the previous | ||
102 | example: | ||
103 | \code | ||
104 | QFile file( "file.txt" ); | ||
105 | if ( file.open( IO_WriteOnly ) ) { | ||
106 | QTextStream stream( &file ); | ||
107 | for ( QStringList::Iterator it = lines.begin(); it != lines.end(); ++it ) | ||
108 | stream << *it << "\n"; | ||
109 | file.close(); | ||
110 | } | ||
111 | \endcode | ||
112 | |||
113 | The QFileInfo class holds detailed information about a file, such | ||
114 | as access permissions, file dates and file types. | ||
115 | |||
116 | The QDir class manages directories and lists of file names. | ||
117 | |||
118 | Qt uses Unicode file names. If you want to do your own I/O on Unix | ||
119 | systems you may want to use encodeName() (and decodeName()) to | ||
120 | convert the file name into the local encoding. | ||
121 | |||
122 | \important readAll() | ||
123 | |||
124 | \sa QDataStream, QTextStream | ||
125 | */ | ||
126 | |||
127 | /*! | ||
128 | \fn Q_LONG QFile::writeBlock( const QByteArray& data ) | ||
129 | |||
130 | \overload | ||
131 | */ | ||
132 | |||
133 | |||
134 | /*! | ||
135 | Constructs a QFile with no name. | ||
136 | */ | ||
137 | |||
138 | QFile::QFile() | ||
139 | { | ||
140 | init(); | ||
141 | } | ||
142 | |||
143 | /*! | ||
144 | Constructs a QFile with a file name \a name. | ||
145 | |||
146 | \sa setName() | ||
147 | */ | ||
148 | |||
149 | QFile::QFile( const QString &name ) | ||
150 | : fn(name) | ||
151 | { | ||
152 | init(); | ||
153 | } | ||
154 | |||
155 | |||
156 | /*! | ||
157 | Destroys a QFile. Calls close(). | ||
158 | */ | ||
159 | |||
160 | QFile::~QFile() | ||
161 | { | ||
162 | close(); | ||
163 | } | ||
164 | |||
165 | |||
166 | /*! | ||
167 | \internal | ||
168 | Initialize internal data. | ||
169 | */ | ||
170 | |||
171 | void QFile::init() | ||
172 | { | ||
173 | setFlags( IO_Direct ); | ||
174 | setStatus( IO_Ok ); | ||
175 | fh = 0; | ||
176 | fd = 0; | ||
177 | length = 0; | ||
178 | ioIndex = 0; | ||
179 | ext_f = FALSE; // not an external file handle | ||
180 | } | ||
181 | |||
182 | |||
183 | /*! | ||
184 | \fn QString QFile::name() const | ||
185 | |||
186 | Returns the name set by setName(). | ||
187 | |||
188 | \sa setName(), QFileInfo::fileName() | ||
189 | */ | ||
190 | |||
191 | /*! | ||
192 | Sets the name of the file to \a name. The name can have no path, a | ||
193 | relative path or an absolute absolute path. | ||
194 | |||
195 | Do not call this function if the file has already been opened. | ||
196 | |||
197 | If the file name has no path or a relative path, the path used | ||
198 | will be whatever the application's current directory path is | ||
199 | \e{at the time of the open()} call. | ||
200 | |||
201 | Example: | ||
202 | \code | ||
203 | QFile file; | ||
204 | QDir::setCurrent( "/tmp" ); | ||
205 | file.setName( "readme.txt" ); | ||
206 | QDir::setCurrent( "/home" ); | ||
207 | file.open( IO_ReadOnly ); // opens "/home/readme.txt" under Unix | ||
208 | \endcode | ||
209 | |||
210 | Note that the directory separator "/" works for all operating | ||
211 | systems supported by Qt. | ||
212 | |||
213 | \sa name(), QFileInfo, QDir | ||
214 | */ | ||
215 | |||
216 | void QFile::setName( const QString &name ) | ||
217 | { | ||
218 | if ( isOpen() ) { | ||
219 | #if defined(QT_CHECK_STATE) | ||
220 | qWarning( "QFile::setName: File is open" ); | ||
221 | #endif | ||
222 | close(); | ||
223 | } | ||
224 | fn = name; | ||
225 | } | ||
226 | |||
227 | /*! | ||
228 | \overload | ||
229 | |||
230 | Returns TRUE if this file exists; otherwise returns FALSE. | ||
231 | |||
232 | \sa name() | ||
233 | */ | ||
234 | |||
235 | bool QFile::exists() const | ||
236 | { | ||
237 | return qt_file_access( fn, F_OK ); | ||
238 | } | ||
239 | |||
240 | /*! | ||
241 | Returns TRUE if the file given by \a fileName exists; otherwise | ||
242 | returns FALSE. | ||
243 | */ | ||
244 | |||
245 | bool QFile::exists( const QString &fileName ) | ||
246 | { | ||
247 | return qt_file_access( fileName, F_OK ); | ||
248 | } | ||
249 | |||
250 | |||
251 | /*! | ||
252 | Removes the file specified by the file name currently set. Returns | ||
253 | TRUE if successful; otherwise returns FALSE. | ||
254 | |||
255 | The file is closed before it is removed. | ||
256 | */ | ||
257 | |||
258 | bool QFile::remove() | ||
259 | { | ||
260 | close(); | ||
261 | return remove( fn ); | ||
262 | } | ||
263 | |||
264 | #if defined(Q_OS_MAC) || defined(Q_OS_MSDOS) || defined(Q_OS_WIN32) || defined(Q_OS_OS2) | ||
265 | # define HAS_TEXT_FILEMODE // has translate/text filemode | ||
266 | #endif | ||
267 | #if defined(O_NONBLOCK) | ||
268 | # define HAS_ASYNC_FILEMODE | ||
269 | # define OPEN_ASYNC O_NONBLOCK | ||
270 | #elif defined(O_NDELAY) | ||
271 | # define HAS_ASYNC_FILEMODE | ||
272 | # define OPEN_ASYNC O_NDELAY | ||
273 | #endif | ||
274 | |||
275 | /*! | ||
276 | Flushes the file buffer to the disk. | ||
277 | |||
278 | close() also flushes the file buffer. | ||
279 | */ | ||
280 | |||
281 | void QFile::flush() | ||
282 | { | ||
283 | if ( isOpen() && fh ) // can only flush open/buffered | ||
284 | fflush( fh ); // file | ||
285 | } | ||
286 | |||
287 | /*! \reimp | ||
288 | \fn QIODevice::Offset QFile::at() const | ||
289 | */ | ||
290 | |||
291 | /*! | ||
292 | Returns TRUE if the end of file has been reached; otherwise returns FALSE. | ||
293 | |||
294 | \sa size() | ||
295 | */ | ||
296 | |||
297 | bool QFile::atEnd() const | ||
298 | { | ||
299 | if ( !isOpen() ) { | ||
300 | #if defined(QT_CHECK_STATE) | ||
301 | qWarning( "QFile::atEnd: File is not open" ); | ||
302 | #endif | ||
303 | return FALSE; | ||
304 | } | ||
305 | if ( isDirectAccess() && !isTranslated() ) { | ||
306 | if ( at() < length ) | ||
307 | return FALSE; | ||
308 | } | ||
309 | return QIODevice::atEnd(); | ||
310 | } | ||
311 | |||
312 | /*! | ||
313 | Reads a line of text. | ||
314 | |||
315 | Reads bytes from the file into the char* \a p, until end-of-line | ||
316 | or \a maxlen bytes have been read, whichever occurs first. Returns | ||
317 | the number of bytes read, or -1 if there was an error. Any | ||
318 | terminating newline is not stripped. | ||
319 | |||
320 | This function is only efficient for buffered files. Avoid | ||
321 | readLine() for files that have been opened with the \c IO_Raw | ||
322 | flag. | ||
323 | |||
324 | \sa readBlock(), QTextStream::readLine() | ||
325 | */ | ||
326 | |||
327 | Q_LONG QFile::readLine( char *p, Q_ULONG maxlen ) | ||
328 | { | ||
329 | if ( maxlen == 0 ) // application bug? | ||
330 | return 0; | ||
331 | #if defined(QT_CHECK_STATE) | ||
332 | Q_CHECK_PTR( p ); | ||
333 | if ( !isOpen() ) { // file not open | ||
334 | qWarning( "QFile::readLine: File not open" ); | ||
335 | return -1; | ||
336 | } | ||
337 | if ( !isReadable() ) { // reading not permitted | ||
338 | qWarning( "QFile::readLine: Read operation not permitted" ); | ||
339 | return -1; | ||
340 | } | ||
341 | #endif | ||
342 | Q_LONG nread; // number of bytes read | ||
343 | if ( isRaw() ) { // raw file | ||
344 | nread = QIODevice::readLine( p, maxlen ); | ||
345 | } else { // buffered file | ||
346 | p = fgets( p, maxlen, fh ); | ||
347 | if ( p ) { | ||
348 | nread = qstrlen( p ); | ||
349 | if ( !isSequentialAccess() ) | ||
350 | ioIndex += nread; | ||
351 | } else { | ||
352 | nread = -1; | ||
353 | setStatus(IO_ReadError); | ||
354 | } | ||
355 | } | ||
356 | return nread; | ||
357 | } | ||
358 | |||
359 | |||
360 | /*! | ||
361 | \overload | ||
362 | |||
363 | Reads a line of text. | ||
364 | |||
365 | Reads bytes from the file into string \a s, until end-of-line or | ||
366 | \a maxlen bytes have been read, whichever occurs first. Returns | ||
367 | the number of bytes read, or -1 if there was an error, e.g. end of | ||
368 | file. Any terminating newline is not stripped. | ||
369 | |||
370 | This function is only efficient for buffered files. Avoid using | ||
371 | readLine() for files that have been opened with the \c IO_Raw | ||
372 | flag. | ||
373 | |||
374 | Note that the string is read as plain Latin1 bytes, not Unicode. | ||
375 | |||
376 | \sa readBlock(), QTextStream::readLine() | ||
377 | */ | ||
378 | |||
379 | Q_LONG QFile::readLine( QString& s, Q_ULONG maxlen ) | ||
380 | { | ||
381 | QByteArray ba(maxlen); | ||
382 | Q_LONG l = readLine(ba.data(),maxlen); | ||
383 | if ( l >= 0 ) { | ||
384 | ba.truncate(l); | ||
385 | s = QString(ba); | ||
386 | } | ||
387 | return l; | ||
388 | } | ||
389 | |||
390 | |||
391 | /*! | ||
392 | Reads a single byte/character from the file. | ||
393 | |||
394 | Returns the byte/character read, or -1 if the end of the file has | ||
395 | been reached. | ||
396 | |||
397 | \sa putch(), ungetch() | ||
398 | */ | ||
399 | |||
400 | int QFile::getch() | ||
401 | { | ||
402 | #if defined(QT_CHECK_STATE) | ||
403 | if ( !isOpen() ) { // file not open | ||
404 | qWarning( "QFile::getch: File not open" ); | ||
405 | return EOF; | ||
406 | } | ||
407 | if ( !isReadable() ) { // reading not permitted | ||
408 | qWarning( "QFile::getch: Read operation not permitted" ); | ||
409 | return EOF; | ||
410 | } | ||
411 | #endif | ||
412 | |||
413 | int ch; | ||
414 | |||
415 | if ( !ungetchBuffer.isEmpty() ) { | ||
416 | int len = ungetchBuffer.length(); | ||
417 | ch = ungetchBuffer[ len-1 ]; | ||
418 | ungetchBuffer.truncate( len - 1 ); | ||
419 | return ch; | ||
420 | } | ||
421 | |||
422 | if ( isRaw() ) { // raw file (inefficient) | ||
423 | char buf[1]; | ||
424 | ch = readBlock( buf, 1 ) == 1 ? buf[0] : EOF; | ||
425 | } else { // buffered file | ||
426 | if ( (ch = getc( fh )) != EOF ) | ||
427 | if ( !isSequentialAccess() ) | ||
428 | ioIndex++; | ||
429 | else | ||
430 | setStatus(IO_ReadError); | ||
431 | } | ||
432 | return ch; | ||
433 | } | ||
434 | |||
435 | /*! | ||
436 | Writes the character \a ch to the file. | ||
437 | |||
438 | Returns \a ch, or -1 if some error occurred. | ||
439 | |||
440 | \sa getch(), ungetch() | ||
441 | */ | ||
442 | |||
443 | int QFile::putch( int ch ) | ||
444 | { | ||
445 | #if defined(QT_CHECK_STATE) | ||
446 | if ( !isOpen() ) { // file not open | ||
447 | qWarning( "QFile::putch: File not open" ); | ||
448 | return EOF; | ||
449 | } | ||
450 | if ( !isWritable() ) { // writing not permitted | ||
451 | qWarning( "QFile::putch: Write operation not permitted" ); | ||
452 | return EOF; | ||
453 | } | ||
454 | #endif | ||
455 | if ( isRaw() ) { // raw file (inefficient) | ||
456 | char buf[1]; | ||
457 | buf[0] = ch; | ||
458 | ch = writeBlock( buf, 1 ) == 1 ? ch : EOF; | ||
459 | } else { // buffered file | ||
460 | if ( (ch = putc( ch, fh )) != EOF ) { | ||
461 | if ( !isSequentialAccess() ) | ||
462 | ioIndex++; | ||
463 | if ( ioIndex > length ) // update file length | ||
464 | length = ioIndex; | ||
465 | } else { | ||
466 | setStatus(IO_WriteError); | ||
467 | } | ||
468 | } | ||
469 | return ch; | ||
470 | } | ||
471 | |||
472 | /*! | ||
473 | Puts the character \a ch back into the file and decrements the | ||
474 | index if it is not zero. | ||
475 | |||
476 | This function is normally called to "undo" a getch() operation. | ||
477 | |||
478 | Returns \a ch, or -1 if an error occurred. | ||
479 | |||
480 | \sa getch(), putch() | ||
481 | */ | ||
482 | |||
483 | int QFile::ungetch( int ch ) | ||
484 | { | ||
485 | #if defined(QT_CHECK_STATE) | ||
486 | if ( !isOpen() ) { // file not open | ||
487 | qWarning( "QFile::ungetch: File not open" ); | ||
488 | return EOF; | ||
489 | } | ||
490 | if ( !isReadable() ) { // reading not permitted | ||
491 | qWarning( "QFile::ungetch: Read operation not permitted" ); | ||
492 | return EOF; | ||
493 | } | ||
494 | #endif | ||
495 | if ( ch == EOF ) // cannot unget EOF | ||
496 | return ch; | ||
497 | |||
498 | if ( isSequentialAccess() && !fh) { | ||
499 | // pipe or similar => we cannot ungetch, so do it manually | ||
500 | ungetchBuffer +=ch; | ||
501 | return ch; | ||
502 | } | ||
503 | |||
504 | if ( isRaw() ) { // raw file (very inefficient) | ||
505 | char buf[1]; | ||
506 | at( ioIndex-1 ); | ||
507 | buf[0] = ch; | ||
508 | if ( writeBlock(buf, 1) == 1 ) | ||
509 | at ( ioIndex-1 ); | ||
510 | else | ||
511 | ch = EOF; | ||
512 | } else { // buffered file | ||
513 | if ( (ch = ungetc(ch, fh)) != EOF ) | ||
514 | if ( !isSequentialAccess() ) | ||
515 | ioIndex--; | ||
516 | else | ||
517 | setStatus( IO_ReadError ); | ||
518 | } | ||
519 | return ch; | ||
520 | } | ||
521 | |||
522 | |||
523 | static QCString locale_encoder( const QString &fileName ) | ||
524 | { | ||
525 | return fileName.local8Bit(); | ||
526 | } | ||
527 | |||
528 | |||
529 | static QFile::EncoderFn encoder = locale_encoder; | ||
530 | |||
531 | /*! | ||
532 | When you use QFile, QFileInfo, and QDir to access the file system | ||
533 | with Qt, you can use Unicode file names. On Unix, these file names | ||
534 | are converted to an 8-bit encoding. If you want to do your own | ||
535 | file I/O on Unix, you should convert the file name using this | ||
536 | function. On Windows NT/2000, Unicode file names are supported | ||
537 | directly in the file system and this function should be avoided. | ||
538 | On Windows 95, non-Latin1 locales are not supported. | ||
539 | |||
540 | By default, this function converts \a fileName to the local 8-bit | ||
541 | encoding determined by the user's locale. This is sufficient for | ||
542 | file names that the user chooses. File names hard-coded into the | ||
543 | application should only use 7-bit ASCII filename characters. | ||
544 | |||
545 | The conversion scheme can be changed using setEncodingFunction(). | ||
546 | This might be useful if you wish to give the user an option to | ||
547 | store file names in UTF-8, etc., but be aware that such file names | ||
548 | would probably then be unrecognizable when seen by other programs. | ||
549 | |||
550 | \sa decodeName() | ||
551 | */ | ||
552 | |||
553 | QCString QFile::encodeName( const QString &fileName ) | ||
554 | { | ||
555 | return (*encoder)(fileName); | ||
556 | } | ||
557 | |||
558 | /*! | ||
559 | \enum QFile::EncoderFn | ||
560 | |||
561 | This is used by QFile::setEncodingFunction(). | ||
562 | */ | ||
563 | |||
564 | /*! | ||
565 | \nonreentrant | ||
566 | |||
567 | Sets the function for encoding Unicode file names to \a f. The | ||
568 | default encodes in the locale-specific 8-bit encoding. | ||
569 | |||
570 | \sa encodeName() | ||
571 | */ | ||
572 | void QFile::setEncodingFunction( EncoderFn f ) | ||
573 | { | ||
574 | encoder = f; | ||
575 | } | ||
576 | |||
577 | static | ||
578 | QString locale_decoder( const QCString &localFileName ) | ||
579 | { | ||
580 | return QString::fromLocal8Bit(localFileName); | ||
581 | } | ||
582 | |||
583 | static QFile::DecoderFn decoder = locale_decoder; | ||
584 | |||
585 | /*! | ||
586 | This does the reverse of QFile::encodeName() using \a localFileName. | ||
587 | |||
588 | \sa setDecodingFunction() | ||
589 | */ | ||
590 | QString QFile::decodeName( const QCString &localFileName ) | ||
591 | { | ||
592 | return (*decoder)(localFileName); | ||
593 | } | ||
594 | |||
595 | /*! | ||
596 | \enum QFile::DecoderFn | ||
597 | |||
598 | This is used by QFile::setDecodingFunction(). | ||
599 | */ | ||
600 | |||
601 | /*! | ||
602 | \nonreentrant | ||
603 | |||
604 | Sets the function for decoding 8-bit file names to \a f. The | ||
605 | default uses the locale-specific 8-bit encoding. | ||
606 | |||
607 | \sa encodeName(), decodeName() | ||
608 | */ | ||
609 | |||
610 | void QFile::setDecodingFunction( DecoderFn f ) | ||
611 | { | ||
612 | decoder = f; | ||
613 | } | ||
614 | |||