summaryrefslogtreecommitdiff
path: root/qmake/tools/qfile.cpp
Unidiff
Diffstat (limited to 'qmake/tools/qfile.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--qmake/tools/qfile.cpp614
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
53extern 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
138QFile::QFile()
139{
140 init();
141}
142
143/*!
144 Constructs a QFile with a file name \a name.
145
146 \sa setName()
147*/
148
149QFile::QFile( const QString &name )
150 : fn(name)
151{
152 init();
153}
154
155
156/*!
157 Destroys a QFile. Calls close().
158*/
159
160QFile::~QFile()
161{
162 close();
163}
164
165
166/*!
167 \internal
168 Initialize internal data.
169*/
170
171void 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
216void 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
235bool 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
245bool 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
258bool 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
281void 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
297bool 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
327Q_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
379Q_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
400int 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
443int 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
483int 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
523static QCString locale_encoder( const QString &fileName )
524{
525 return fileName.local8Bit();
526}
527
528
529static 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
553QCString 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*/
572void QFile::setEncodingFunction( EncoderFn f )
573{
574 encoder = f;
575}
576
577static
578QString locale_decoder( const QCString &localFileName )
579{
580 return QString::fromLocal8Bit(localFileName);
581}
582
583static QFile::DecoderFn decoder = locale_decoder;
584
585/*!
586 This does the reverse of QFile::encodeName() using \a localFileName.
587
588 \sa setDecodingFunction()
589*/
590QString 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
610void QFile::setDecodingFunction( DecoderFn f )
611{
612 decoder = f;
613}
614