[2] | 1 | /****************************************************************************
|
---|
| 2 | ** $Id: qfile.cpp 8 2005-11-16 19:36:46Z dmik $
|
---|
| 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 | #ifndef NO_ERRNO_H
|
---|
| 52 | #include <errno.h>
|
---|
| 53 | #endif
|
---|
| 54 |
|
---|
| 55 |
|
---|
| 56 | // Duplicated from qobject.h, but we cannot include qobject.h here since
|
---|
| 57 | // it causes qmake to not build on irix g++
|
---|
| 58 | #define QT_TRANSLATE_NOOP(scope,x) (x)
|
---|
| 59 |
|
---|
| 60 | const char* qt_fileerr_unknown = QT_TRANSLATE_NOOP( "QFile", "Unknown error" );
|
---|
| 61 | const char* qt_fileerr_read = QT_TRANSLATE_NOOP( "QFile", "Could not read from the file" );
|
---|
| 62 | const char* qt_fileerr_write = QT_TRANSLATE_NOOP( "QFile", "Could not write to the file" );
|
---|
| 63 |
|
---|
| 64 | #define QFILEERR_EACCES QT_TRANSLATE_NOOP( "QFile", "Permission denied" )
|
---|
| 65 | #define QFILEERR_EMFILE QT_TRANSLATE_NOOP( "QFile", "Too many open files" )
|
---|
| 66 | #define QFILEERR_ENOENT QT_TRANSLATE_NOOP( "QFile", "No such file or directory" )
|
---|
| 67 | #define QFILEERR_ENOSPC QT_TRANSLATE_NOOP( "QFile", "No space left on device" )
|
---|
| 68 |
|
---|
| 69 | class QFilePrivate
|
---|
| 70 | {
|
---|
| 71 | public:
|
---|
| 72 | QString errorString;
|
---|
| 73 | };
|
---|
| 74 |
|
---|
| 75 | extern bool qt_file_access( const QString& fn, int t );
|
---|
| 76 |
|
---|
| 77 | /*!
|
---|
| 78 | \class QFile qfile.h
|
---|
| 79 | \reentrant
|
---|
| 80 | \brief The QFile class is an I/O device that operates on files.
|
---|
| 81 |
|
---|
| 82 | \ingroup io
|
---|
| 83 | \mainclass
|
---|
| 84 |
|
---|
| 85 | QFile is an I/O device for reading and writing binary and text
|
---|
| 86 | files. A QFile may be used by itself or more conveniently with a
|
---|
| 87 | QDataStream or QTextStream.
|
---|
| 88 |
|
---|
| 89 | The file name is usually passed in the constructor but can be
|
---|
| 90 | changed with setName(). You can check for a file's existence with
|
---|
| 91 | exists() and remove a file with remove().
|
---|
| 92 |
|
---|
| 93 | The file is opened with open(), closed with close() and flushed
|
---|
| 94 | with flush(). Data is usually read and written using QDataStream
|
---|
| 95 | or QTextStream, but you can read with readBlock() and readLine()
|
---|
| 96 | and write with writeBlock(). QFile also supports getch(),
|
---|
| 97 | ungetch() and putch().
|
---|
| 98 |
|
---|
| 99 | The size of the file is returned by size(). You can get the
|
---|
| 100 | current file position or move to a new file position using the
|
---|
| 101 | at() functions. If you've reached the end of the file, atEnd()
|
---|
| 102 | returns TRUE. The file handle is returned by handle().
|
---|
| 103 |
|
---|
| 104 | Here is a code fragment that uses QTextStream to read a text file
|
---|
| 105 | line by line. It prints each line with a line number.
|
---|
| 106 | \code
|
---|
| 107 | QStringList lines;
|
---|
| 108 | QFile file( "file.txt" );
|
---|
| 109 | if ( file.open( IO_ReadOnly ) ) {
|
---|
| 110 | QTextStream stream( &file );
|
---|
| 111 | QString line;
|
---|
| 112 | int i = 1;
|
---|
| 113 | while ( !stream.atEnd() ) {
|
---|
| 114 | line = stream.readLine(); // line of text excluding '\n'
|
---|
| 115 | printf( "%3d: %s\n", i++, line.latin1() );
|
---|
| 116 | lines += line;
|
---|
| 117 | }
|
---|
| 118 | file.close();
|
---|
| 119 | }
|
---|
| 120 | \endcode
|
---|
| 121 |
|
---|
| 122 | Writing text is just as easy. The following example shows how to
|
---|
| 123 | write the data we read into the string list from the previous
|
---|
| 124 | example:
|
---|
| 125 | \code
|
---|
| 126 | QFile file( "file.txt" );
|
---|
| 127 | if ( file.open( IO_WriteOnly ) ) {
|
---|
| 128 | QTextStream stream( &file );
|
---|
| 129 | for ( QStringList::Iterator it = lines.begin(); it != lines.end(); ++it )
|
---|
| 130 | stream << *it << "\n";
|
---|
| 131 | file.close();
|
---|
| 132 | }
|
---|
| 133 | \endcode
|
---|
| 134 |
|
---|
| 135 | The QFileInfo class holds detailed information about a file, such
|
---|
| 136 | as access permissions, file dates and file types.
|
---|
| 137 |
|
---|
| 138 | The QDir class manages directories and lists of file names.
|
---|
| 139 |
|
---|
| 140 | Qt uses Unicode file names. If you want to do your own I/O on Unix
|
---|
[8] | 141 | and OS/2 systems you may want to use encodeName() (and decodeName()) to
|
---|
[2] | 142 | convert the file name into the local encoding.
|
---|
| 143 |
|
---|
| 144 | \important readAll() at()
|
---|
| 145 |
|
---|
| 146 | \sa QDataStream, QTextStream
|
---|
| 147 | */
|
---|
| 148 |
|
---|
| 149 | /*!
|
---|
| 150 | \fn Q_LONG QFile::writeBlock( const QByteArray& data )
|
---|
| 151 |
|
---|
| 152 | \overload
|
---|
| 153 | */
|
---|
| 154 |
|
---|
| 155 |
|
---|
| 156 | /*!
|
---|
| 157 | Constructs a QFile with no name.
|
---|
| 158 | */
|
---|
| 159 |
|
---|
| 160 | QFile::QFile()
|
---|
| 161 | : d(0)
|
---|
| 162 | {
|
---|
| 163 | init();
|
---|
| 164 | }
|
---|
| 165 |
|
---|
| 166 | /*!
|
---|
| 167 | Constructs a QFile with a file name \a name.
|
---|
| 168 |
|
---|
| 169 | \sa setName()
|
---|
| 170 | */
|
---|
| 171 |
|
---|
| 172 | QFile::QFile( const QString &name )
|
---|
| 173 | : fn(name), d(0)
|
---|
| 174 | {
|
---|
| 175 | init();
|
---|
| 176 | }
|
---|
| 177 |
|
---|
| 178 |
|
---|
| 179 | /*!
|
---|
| 180 | Destroys a QFile. Calls close().
|
---|
| 181 | */
|
---|
| 182 |
|
---|
| 183 | QFile::~QFile()
|
---|
| 184 | {
|
---|
| 185 | close();
|
---|
| 186 | delete d;
|
---|
| 187 | }
|
---|
| 188 |
|
---|
| 189 |
|
---|
| 190 | /*!
|
---|
| 191 | \internal
|
---|
| 192 | Initialize internal data.
|
---|
| 193 | */
|
---|
| 194 |
|
---|
| 195 | void QFile::init()
|
---|
| 196 | {
|
---|
| 197 | delete d;
|
---|
| 198 | d = new QFilePrivate;
|
---|
| 199 | setFlags( IO_Direct );
|
---|
| 200 | setStatus( IO_Ok );
|
---|
| 201 | setErrorString( qt_fileerr_unknown );
|
---|
| 202 | fh = 0;
|
---|
| 203 | fd = 0;
|
---|
| 204 | length = 0;
|
---|
| 205 | ioIndex = 0;
|
---|
| 206 | ext_f = FALSE; // not an external file handle
|
---|
| 207 | }
|
---|
| 208 |
|
---|
| 209 |
|
---|
| 210 | /*!
|
---|
| 211 | \fn QString QFile::name() const
|
---|
| 212 |
|
---|
| 213 | Returns the name set by setName().
|
---|
| 214 |
|
---|
| 215 | \sa setName(), QFileInfo::fileName()
|
---|
| 216 | */
|
---|
| 217 |
|
---|
| 218 | /*!
|
---|
| 219 | Sets the name of the file to \a name. The name can have no path, a
|
---|
| 220 | relative path or an absolute absolute path.
|
---|
| 221 |
|
---|
| 222 | Do not call this function if the file has already been opened.
|
---|
| 223 |
|
---|
| 224 | If the file name has no path or a relative path, the path used
|
---|
| 225 | will be whatever the application's current directory path is
|
---|
| 226 | \e{at the time of the open()} call.
|
---|
| 227 |
|
---|
| 228 | Example:
|
---|
| 229 | \code
|
---|
| 230 | QFile file;
|
---|
| 231 | QDir::setCurrent( "/tmp" );
|
---|
| 232 | file.setName( "readme.txt" );
|
---|
| 233 | QDir::setCurrent( "/home" );
|
---|
| 234 | file.open( IO_ReadOnly ); // opens "/home/readme.txt" under Unix
|
---|
| 235 | \endcode
|
---|
| 236 |
|
---|
| 237 | Note that the directory separator "/" works for all operating
|
---|
| 238 | systems supported by Qt.
|
---|
| 239 |
|
---|
| 240 | \sa name(), QFileInfo, QDir
|
---|
| 241 | */
|
---|
| 242 |
|
---|
| 243 | void QFile::setName( const QString &name )
|
---|
| 244 | {
|
---|
| 245 | if ( isOpen() ) {
|
---|
| 246 | #if defined(QT_CHECK_STATE)
|
---|
| 247 | qWarning( "QFile::setName: File is open" );
|
---|
| 248 | #endif
|
---|
| 249 | close();
|
---|
| 250 | }
|
---|
| 251 | fn = name;
|
---|
| 252 | }
|
---|
| 253 |
|
---|
| 254 | /*!
|
---|
| 255 | \overload
|
---|
| 256 |
|
---|
| 257 | Returns TRUE if this file exists; otherwise returns FALSE.
|
---|
| 258 |
|
---|
| 259 | \sa name()
|
---|
| 260 | */
|
---|
| 261 |
|
---|
| 262 | bool QFile::exists() const
|
---|
| 263 | {
|
---|
| 264 | return qt_file_access( fn, F_OK );
|
---|
| 265 | }
|
---|
| 266 |
|
---|
| 267 | /*!
|
---|
| 268 | Returns TRUE if the file given by \a fileName exists; otherwise
|
---|
| 269 | returns FALSE.
|
---|
| 270 | */
|
---|
| 271 |
|
---|
| 272 | bool QFile::exists( const QString &fileName )
|
---|
| 273 | {
|
---|
| 274 | return qt_file_access( fileName, F_OK );
|
---|
| 275 | }
|
---|
| 276 |
|
---|
| 277 |
|
---|
| 278 | /*!
|
---|
| 279 | Removes the file specified by the file name currently set. Returns
|
---|
| 280 | TRUE if successful; otherwise returns FALSE.
|
---|
| 281 |
|
---|
| 282 | The file is closed before it is removed.
|
---|
| 283 | */
|
---|
| 284 |
|
---|
| 285 | bool QFile::remove()
|
---|
| 286 | {
|
---|
| 287 | close();
|
---|
| 288 | return remove( fn );
|
---|
| 289 | }
|
---|
| 290 |
|
---|
| 291 | #if defined(Q_OS_MAC) || defined(Q_OS_MSDOS) || defined(Q_OS_WIN32) || defined(Q_OS_OS2)
|
---|
| 292 | # define HAS_TEXT_FILEMODE // has translate/text filemode
|
---|
| 293 | #endif
|
---|
| 294 | #if defined(O_NONBLOCK)
|
---|
| 295 | # define HAS_ASYNC_FILEMODE
|
---|
| 296 | # define OPEN_ASYNC O_NONBLOCK
|
---|
| 297 | #elif defined(O_NDELAY)
|
---|
| 298 | # define HAS_ASYNC_FILEMODE
|
---|
| 299 | # define OPEN_ASYNC O_NDELAY
|
---|
| 300 | #endif
|
---|
| 301 |
|
---|
| 302 | /*!
|
---|
| 303 | Flushes the file buffer to the disk.
|
---|
| 304 |
|
---|
| 305 | close() also flushes the file buffer.
|
---|
| 306 | */
|
---|
| 307 |
|
---|
| 308 | void QFile::flush()
|
---|
| 309 | {
|
---|
| 310 | if ( isOpen() && fh ) // can only flush open/buffered
|
---|
| 311 | fflush( fh ); // file
|
---|
| 312 | }
|
---|
| 313 |
|
---|
| 314 | /*! \reimp
|
---|
| 315 | \fn QIODevice::Offset QFile::at() const
|
---|
| 316 | */
|
---|
| 317 |
|
---|
| 318 | /*!
|
---|
| 319 | Returns TRUE if the end of file has been reached; otherwise returns FALSE.
|
---|
| 320 | If QFile has not been open()'d, then the behavior is undefined.
|
---|
| 321 |
|
---|
| 322 | \sa size()
|
---|
| 323 | */
|
---|
| 324 |
|
---|
| 325 | bool QFile::atEnd() const
|
---|
| 326 | {
|
---|
| 327 | if ( !isOpen() ) {
|
---|
| 328 | #if defined(QT_CHECK_STATE)
|
---|
| 329 | qWarning( "QFile::atEnd: File is not open" );
|
---|
| 330 | #endif
|
---|
| 331 | return FALSE;
|
---|
| 332 | }
|
---|
| 333 | if ( isDirectAccess() && !isTranslated() ) {
|
---|
| 334 | if ( at() < length )
|
---|
| 335 | return FALSE;
|
---|
| 336 | }
|
---|
| 337 | return QIODevice::atEnd();
|
---|
| 338 | }
|
---|
| 339 |
|
---|
| 340 | /*!
|
---|
| 341 | Reads a line of text.
|
---|
| 342 |
|
---|
| 343 | Reads bytes from the file into the char* \a p, until end-of-line
|
---|
| 344 | or \a maxlen bytes have been read, whichever occurs first. Returns
|
---|
| 345 | the number of bytes read, or -1 if there was an error. Any
|
---|
| 346 | terminating newline is not stripped.
|
---|
| 347 |
|
---|
| 348 | This function is only efficient for buffered files. Avoid
|
---|
| 349 | readLine() for files that have been opened with the \c IO_Raw
|
---|
| 350 | flag.
|
---|
| 351 |
|
---|
| 352 | \sa readBlock(), QTextStream::readLine()
|
---|
| 353 | */
|
---|
| 354 |
|
---|
| 355 | Q_LONG QFile::readLine( char *p, Q_ULONG maxlen )
|
---|
| 356 | {
|
---|
| 357 | if ( maxlen == 0 ) // application bug?
|
---|
| 358 | return 0;
|
---|
| 359 | #if defined(QT_CHECK_STATE)
|
---|
| 360 | Q_CHECK_PTR( p );
|
---|
| 361 | if ( !isOpen() ) { // file not open
|
---|
| 362 | qWarning( "QFile::readLine: File not open" );
|
---|
| 363 | return -1;
|
---|
| 364 | }
|
---|
| 365 | if ( !isReadable() ) { // reading not permitted
|
---|
| 366 | qWarning( "QFile::readLine: Read operation not permitted" );
|
---|
| 367 | return -1;
|
---|
| 368 | }
|
---|
| 369 | #endif
|
---|
| 370 | Q_LONG nread; // number of bytes read
|
---|
| 371 | if ( isRaw() ) { // raw file
|
---|
| 372 | nread = QIODevice::readLine( p, maxlen );
|
---|
| 373 | } else { // buffered file
|
---|
| 374 | p = fgets( p, maxlen, fh );
|
---|
| 375 | if ( p ) {
|
---|
| 376 | nread = qstrlen( p );
|
---|
| 377 | if ( !isSequentialAccess() )
|
---|
| 378 | ioIndex += nread;
|
---|
| 379 | } else {
|
---|
| 380 | nread = -1;
|
---|
| 381 | setStatus(IO_ReadError);
|
---|
| 382 | setErrorString( qt_fileerr_read );
|
---|
| 383 | }
|
---|
| 384 | }
|
---|
| 385 | return nread;
|
---|
| 386 | }
|
---|
| 387 |
|
---|
| 388 |
|
---|
| 389 | /*!
|
---|
| 390 | \overload
|
---|
| 391 |
|
---|
| 392 | Reads a line of text.
|
---|
| 393 |
|
---|
| 394 | Reads bytes from the file into string \a s, until end-of-line or
|
---|
| 395 | \a maxlen bytes have been read, whichever occurs first. Returns
|
---|
| 396 | the number of bytes read, or -1 if there was an error, e.g. end of
|
---|
| 397 | file. Any terminating newline is not stripped.
|
---|
| 398 |
|
---|
| 399 | This function is only efficient for buffered files. Avoid using
|
---|
| 400 | readLine() for files that have been opened with the \c IO_Raw
|
---|
| 401 | flag.
|
---|
| 402 |
|
---|
| 403 | Note that the string is read as plain Latin1 bytes, not Unicode.
|
---|
| 404 |
|
---|
| 405 | \sa readBlock(), QTextStream::readLine()
|
---|
| 406 | */
|
---|
| 407 |
|
---|
| 408 | Q_LONG QFile::readLine( QString& s, Q_ULONG maxlen )
|
---|
| 409 | {
|
---|
| 410 | QByteArray ba(maxlen);
|
---|
| 411 | Q_LONG l = readLine(ba.data(),maxlen);
|
---|
| 412 | if ( l >= 0 ) {
|
---|
| 413 | ba.truncate(l);
|
---|
| 414 | s = QString(ba);
|
---|
| 415 | }
|
---|
| 416 | return l;
|
---|
| 417 | }
|
---|
| 418 |
|
---|
| 419 |
|
---|
| 420 | /*!
|
---|
| 421 | Reads a single byte/character from the file.
|
---|
| 422 |
|
---|
| 423 | Returns the byte/character read, or -1 if the end of the file has
|
---|
| 424 | been reached.
|
---|
| 425 |
|
---|
| 426 | \sa putch(), ungetch()
|
---|
| 427 | */
|
---|
| 428 |
|
---|
| 429 | int QFile::getch()
|
---|
| 430 | {
|
---|
| 431 | #if defined(QT_CHECK_STATE)
|
---|
| 432 | if ( !isOpen() ) { // file not open
|
---|
| 433 | qWarning( "QFile::getch: File not open" );
|
---|
| 434 | return EOF;
|
---|
| 435 | }
|
---|
| 436 | if ( !isReadable() ) { // reading not permitted
|
---|
| 437 | qWarning( "QFile::getch: Read operation not permitted" );
|
---|
| 438 | return EOF;
|
---|
| 439 | }
|
---|
| 440 | #endif
|
---|
| 441 |
|
---|
| 442 | int ch;
|
---|
| 443 |
|
---|
| 444 | if ( !ungetchBuffer.isEmpty() ) {
|
---|
| 445 | int len = ungetchBuffer.length();
|
---|
| 446 | ch = ungetchBuffer[ len-1 ];
|
---|
| 447 | ungetchBuffer.truncate( len - 1 );
|
---|
| 448 | return ch;
|
---|
| 449 | }
|
---|
| 450 |
|
---|
| 451 | if ( isRaw() ) { // raw file (inefficient)
|
---|
| 452 | char buf[1];
|
---|
| 453 | ch = readBlock( buf, 1 ) == 1 ? buf[0] : EOF;
|
---|
| 454 | } else { // buffered file
|
---|
| 455 | if ( (ch = getc( fh )) != EOF ) {
|
---|
| 456 | if ( !isSequentialAccess() )
|
---|
| 457 | ioIndex++;
|
---|
| 458 | } else {
|
---|
| 459 | setStatus(IO_ReadError);
|
---|
| 460 | setErrorString( qt_fileerr_read );
|
---|
| 461 | }
|
---|
| 462 | }
|
---|
| 463 | return ch;
|
---|
| 464 | }
|
---|
| 465 |
|
---|
| 466 | /*!
|
---|
| 467 | Writes the character \a ch to the file.
|
---|
| 468 |
|
---|
| 469 | Returns \a ch, or -1 if some error occurred.
|
---|
| 470 |
|
---|
| 471 | \sa getch(), ungetch()
|
---|
| 472 | */
|
---|
| 473 |
|
---|
| 474 | int QFile::putch( int ch )
|
---|
| 475 | {
|
---|
| 476 | #if defined(QT_CHECK_STATE)
|
---|
| 477 | if ( !isOpen() ) { // file not open
|
---|
| 478 | qWarning( "QFile::putch: File not open" );
|
---|
| 479 | return EOF;
|
---|
| 480 | }
|
---|
| 481 | if ( !isWritable() ) { // writing not permitted
|
---|
| 482 | qWarning( "QFile::putch: Write operation not permitted" );
|
---|
| 483 | return EOF;
|
---|
| 484 | }
|
---|
| 485 | #endif
|
---|
| 486 | if ( isRaw() ) { // raw file (inefficient)
|
---|
| 487 | char buf[1];
|
---|
| 488 | buf[0] = ch;
|
---|
| 489 | ch = writeBlock( buf, 1 ) == 1 ? ch : EOF;
|
---|
| 490 | } else { // buffered file
|
---|
| 491 | if ( (ch = putc( ch, fh )) != EOF ) {
|
---|
| 492 | if ( !isSequentialAccess() )
|
---|
| 493 | ioIndex++;
|
---|
| 494 | if ( ioIndex > length ) // update file length
|
---|
| 495 | length = ioIndex;
|
---|
| 496 | } else {
|
---|
| 497 | setStatus(IO_WriteError);
|
---|
| 498 | setErrorString( qt_fileerr_write );
|
---|
| 499 | }
|
---|
| 500 | }
|
---|
| 501 | return ch;
|
---|
| 502 | }
|
---|
| 503 |
|
---|
| 504 | /*!
|
---|
| 505 | Puts the character \a ch back into the file and decrements the
|
---|
| 506 | index if it is not zero.
|
---|
| 507 |
|
---|
| 508 | This function is normally called to "undo" a getch() operation.
|
---|
| 509 |
|
---|
| 510 | Returns \a ch, or -1 if an error occurred.
|
---|
| 511 |
|
---|
| 512 | \sa getch(), putch()
|
---|
| 513 | */
|
---|
| 514 |
|
---|
| 515 | int QFile::ungetch( int ch )
|
---|
| 516 | {
|
---|
| 517 | #if defined(QT_CHECK_STATE)
|
---|
| 518 | if ( !isOpen() ) { // file not open
|
---|
| 519 | qWarning( "QFile::ungetch: File not open" );
|
---|
| 520 | return EOF;
|
---|
| 521 | }
|
---|
| 522 | if ( !isReadable() ) { // reading not permitted
|
---|
| 523 | qWarning( "QFile::ungetch: Read operation not permitted" );
|
---|
| 524 | return EOF;
|
---|
| 525 | }
|
---|
| 526 | #endif
|
---|
| 527 | if ( ch == EOF ) // cannot unget EOF
|
---|
| 528 | return ch;
|
---|
| 529 |
|
---|
| 530 | if ( isSequentialAccess() && !fh) {
|
---|
| 531 | // pipe or similar => we cannot ungetch, so do it manually
|
---|
| 532 | ungetchBuffer += QChar(ch);
|
---|
| 533 | return ch;
|
---|
| 534 | }
|
---|
| 535 |
|
---|
| 536 | if ( isRaw() ) { // raw file (very inefficient)
|
---|
| 537 | char buf[1];
|
---|
| 538 | at( ioIndex-1 );
|
---|
| 539 | buf[0] = ch;
|
---|
| 540 | if ( writeBlock(buf, 1) == 1 )
|
---|
| 541 | at ( ioIndex-1 );
|
---|
| 542 | else
|
---|
| 543 | ch = EOF;
|
---|
| 544 | } else { // buffered file
|
---|
| 545 | if ( (ch = ungetc(ch, fh)) != EOF ) {
|
---|
| 546 | if ( !isSequentialAccess() )
|
---|
| 547 | ioIndex--;
|
---|
| 548 | } else {
|
---|
| 549 | setStatus( IO_ReadError );
|
---|
| 550 | setErrorString( qt_fileerr_read );
|
---|
| 551 | }
|
---|
| 552 | }
|
---|
| 553 | return ch;
|
---|
| 554 | }
|
---|
| 555 |
|
---|
| 556 |
|
---|
| 557 | static QCString locale_encoder( const QString &fileName )
|
---|
| 558 | {
|
---|
| 559 | return fileName.local8Bit();
|
---|
| 560 | }
|
---|
| 561 |
|
---|
| 562 |
|
---|
| 563 | static QFile::EncoderFn encoder = locale_encoder;
|
---|
| 564 |
|
---|
| 565 | /*!
|
---|
| 566 | When you use QFile, QFileInfo, and QDir to access the file system
|
---|
[8] | 567 | with Qt, you can use Unicode file names. On Unix and OS/2, these file
|
---|
| 568 | names are converted to an 8-bit encoding. If you want to do your own
|
---|
| 569 | file I/O on Unix or OS/2, you should convert the file name using this
|
---|
[2] | 570 | function. On Windows NT/2000, Unicode file names are supported
|
---|
| 571 | directly in the file system and this function should be avoided.
|
---|
| 572 | On Windows 95, non-Latin1 locales are not supported.
|
---|
| 573 |
|
---|
| 574 | By default, this function converts \a fileName to the local 8-bit
|
---|
| 575 | encoding determined by the user's locale. This is sufficient for
|
---|
| 576 | file names that the user chooses. File names hard-coded into the
|
---|
| 577 | application should only use 7-bit ASCII filename characters.
|
---|
| 578 |
|
---|
| 579 | The conversion scheme can be changed using setEncodingFunction().
|
---|
| 580 | This might be useful if you wish to give the user an option to
|
---|
| 581 | store file names in UTF-8, etc., but be aware that such file names
|
---|
| 582 | would probably then be unrecognizable when seen by other programs.
|
---|
| 583 |
|
---|
| 584 | \sa decodeName()
|
---|
| 585 | */
|
---|
| 586 |
|
---|
| 587 | QCString QFile::encodeName( const QString &fileName )
|
---|
| 588 | {
|
---|
| 589 | return (*encoder)(fileName);
|
---|
| 590 | }
|
---|
| 591 |
|
---|
| 592 | /*!
|
---|
| 593 | \enum QFile::EncoderFn
|
---|
| 594 |
|
---|
| 595 | This is used by QFile::setEncodingFunction().
|
---|
| 596 | */
|
---|
| 597 |
|
---|
| 598 | /*!
|
---|
| 599 | \nonreentrant
|
---|
| 600 |
|
---|
| 601 | Sets the function for encoding Unicode file names to \a f. The
|
---|
| 602 | default encodes in the locale-specific 8-bit encoding.
|
---|
| 603 |
|
---|
| 604 | \sa encodeName()
|
---|
| 605 | */
|
---|
| 606 | void QFile::setEncodingFunction( EncoderFn f )
|
---|
| 607 | {
|
---|
| 608 | encoder = f;
|
---|
| 609 | }
|
---|
| 610 |
|
---|
| 611 | static
|
---|
| 612 | QString locale_decoder( const QCString &localFileName )
|
---|
| 613 | {
|
---|
| 614 | return QString::fromLocal8Bit(localFileName);
|
---|
| 615 | }
|
---|
| 616 |
|
---|
| 617 | static QFile::DecoderFn decoder = locale_decoder;
|
---|
| 618 |
|
---|
| 619 | /*!
|
---|
| 620 | This does the reverse of QFile::encodeName() using \a localFileName.
|
---|
| 621 |
|
---|
| 622 | \sa setDecodingFunction()
|
---|
| 623 | */
|
---|
| 624 | QString QFile::decodeName( const QCString &localFileName )
|
---|
| 625 | {
|
---|
| 626 | return (*decoder)(localFileName);
|
---|
| 627 | }
|
---|
| 628 |
|
---|
| 629 | /*!
|
---|
| 630 | \enum QFile::DecoderFn
|
---|
| 631 |
|
---|
| 632 | This is used by QFile::setDecodingFunction().
|
---|
| 633 | */
|
---|
| 634 |
|
---|
| 635 | /*!
|
---|
| 636 | \nonreentrant
|
---|
| 637 |
|
---|
| 638 | Sets the function for decoding 8-bit file names to \a f. The
|
---|
| 639 | default uses the locale-specific 8-bit encoding.
|
---|
| 640 |
|
---|
| 641 | \sa encodeName(), decodeName()
|
---|
| 642 | */
|
---|
| 643 |
|
---|
| 644 | void QFile::setDecodingFunction( DecoderFn f )
|
---|
| 645 | {
|
---|
| 646 | decoder = f;
|
---|
| 647 | }
|
---|
| 648 |
|
---|
| 649 | /*!
|
---|
| 650 | Returns a human-readable description of the reason of an error that occurred
|
---|
| 651 | on the device. The error described by the string corresponds to changes of
|
---|
| 652 | QIODevice::status(). If the status is reset, the error string is also reset.
|
---|
| 653 |
|
---|
| 654 | The returned strings are not translated with the QObject::tr() or
|
---|
| 655 | QApplication::translate() functions. They are marked as translatable
|
---|
| 656 | strings in the "QFile" context. Before you show the string to the user you
|
---|
| 657 | should translate it first, for example:
|
---|
| 658 |
|
---|
| 659 | \code
|
---|
| 660 | QFile f( "address.dat" );
|
---|
| 661 | if ( !f.open( IO_ReadOnly ) {
|
---|
| 662 | QMessageBox::critical(
|
---|
| 663 | this,
|
---|
| 664 | tr("Open failed"),
|
---|
| 665 | tr("Could not open file for reading: %1").arg( qApp->translate("QFile",f.errorString()) )
|
---|
| 666 | );
|
---|
| 667 | return;
|
---|
| 668 | }
|
---|
| 669 | \endcode
|
---|
| 670 |
|
---|
| 671 | \sa QIODevice::status(), QIODevice::resetStatus(), setErrorString()
|
---|
| 672 | */
|
---|
| 673 |
|
---|
| 674 | QString QFile::errorString() const
|
---|
| 675 | {
|
---|
| 676 | if ( status() == IO_Ok )
|
---|
| 677 | return qt_fileerr_unknown;
|
---|
| 678 | return d->errorString;
|
---|
| 679 | }
|
---|
| 680 |
|
---|
| 681 | /*!
|
---|
| 682 | \nonreentrant
|
---|
| 683 |
|
---|
| 684 | Sets the error string returned by the errorString() function to \a str.
|
---|
| 685 |
|
---|
| 686 | \sa errorString(), QIODevice::status()
|
---|
| 687 | */
|
---|
| 688 |
|
---|
| 689 | void QFile::setErrorString( const QString& str )
|
---|
| 690 | {
|
---|
| 691 | d->errorString = str;
|
---|
| 692 | }
|
---|
| 693 |
|
---|
| 694 | void QFile::setErrorStringErrno( int errnum )
|
---|
| 695 | {
|
---|
| 696 | switch ( errnum ) {
|
---|
| 697 | case EACCES:
|
---|
| 698 | d->errorString = QFILEERR_EACCES;
|
---|
| 699 | break;
|
---|
| 700 | case EMFILE:
|
---|
| 701 | d->errorString = QFILEERR_EMFILE;
|
---|
| 702 | break;
|
---|
| 703 | case ENOENT:
|
---|
| 704 | d->errorString = QFILEERR_ENOENT;
|
---|
| 705 | break;
|
---|
| 706 | case ENOSPC:
|
---|
| 707 | d->errorString = QFILEERR_ENOSPC;
|
---|
| 708 | break;
|
---|
| 709 | default:
|
---|
| 710 | #ifndef Q_OS_TEMP
|
---|
| 711 | d->errorString = QString::fromLocal8Bit( strerror( errnum ) );
|
---|
| 712 | #else
|
---|
| 713 | {
|
---|
| 714 | unsigned short *string;
|
---|
| 715 | FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
|
---|
| 716 | NULL,
|
---|
| 717 | errnum,
|
---|
| 718 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
---|
| 719 | (LPTSTR)&string,
|
---|
| 720 | 0,
|
---|
| 721 | NULL );
|
---|
| 722 | d->errorString = QString::fromUcs2( string );
|
---|
| 723 | LocalFree( (HLOCAL)string );
|
---|
| 724 | }
|
---|
| 725 | #endif
|
---|
| 726 | break;
|
---|
| 727 | }
|
---|
| 728 | }
|
---|