Orb/Doxygen/qtools/qfile.cpp
changeset 0 42188c7ea2d9
equal deleted inserted replaced
-1:000000000000 0:42188c7ea2d9
       
     1 /****************************************************************************
       
     2 ** 
       
     3 **
       
     4 ** Implementation of QFile class
       
     5 **
       
     6 ** Created : 930812
       
     7 **
       
     8 ** Copyright (C) 1992-2000 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 "qglobal.h"
       
    39 #if defined(_OS_WIN32_)
       
    40 #ifdef UNICODE
       
    41 #ifndef _UNICODE
       
    42 #define _UNICODE
       
    43 #endif
       
    44 #endif
       
    45 #endif
       
    46 
       
    47 #include "qfile.h"
       
    48 #include "qfiledefs_p.h"
       
    49 
       
    50 extern bool qt_file_access( const QString& fn, int t );
       
    51 
       
    52 // NOT REVISED
       
    53 /*!
       
    54   \class QFile qfile.h
       
    55   \brief The QFile class is an I/O device that operates on files.
       
    56 
       
    57   \ingroup io
       
    58 
       
    59   QFile is an I/O device for reading and writing binary and text files.	A
       
    60   QFile may be used by itself (readBlock and writeBlock) or by more
       
    61   conveniently using QDataStream or QTextStream.
       
    62 
       
    63   Here is a code fragment that uses QTextStream to read a text
       
    64   file line by line. It prints each line with a line number.
       
    65   \code
       
    66     QFile f("file.txt");
       
    67     if ( f.open(IO_ReadOnly) ) {    // file opened successfully
       
    68 	QTextStream t( &f );	    // use a text stream
       
    69 	QString s;
       
    70 	int n = 1;
       
    71 	while ( !t.eof() ) {	    // until end of file...
       
    72 	    s = t.readLine();	    // line of text excluding '\n'
       
    73 	    printf( "%3d: %s\n", n++, (const char *)s );
       
    74 	}
       
    75 	f.close();
       
    76     }
       
    77   \endcode
       
    78 
       
    79   The QFileInfo class holds detailed information about a file, such as
       
    80   access permissions, file dates and file types.
       
    81 
       
    82   The QDir class manages directories and lists of file names.
       
    83 
       
    84   \sa QDataStream, QTextStream
       
    85 */
       
    86 
       
    87 
       
    88 /*!
       
    89   Constructs a QFile with no name.
       
    90 */
       
    91 
       
    92 QFile::QFile()
       
    93 {
       
    94     init();
       
    95 }
       
    96 
       
    97 /*!
       
    98   Constructs a QFile with a file name \e name.
       
    99   \sa setName()
       
   100 */
       
   101 
       
   102 QFile::QFile( const QString &name )
       
   103     : fn(name)
       
   104 {
       
   105     init();
       
   106 }
       
   107 
       
   108 
       
   109 /*!
       
   110   Destructs a QFile.  Calls close().
       
   111 */
       
   112 
       
   113 QFile::~QFile()
       
   114 {
       
   115     close();
       
   116 }
       
   117 
       
   118 
       
   119 /*!
       
   120   \internal
       
   121   Initialize internal data.
       
   122 */
       
   123 
       
   124 void QFile::init()
       
   125 {
       
   126     setFlags( IO_Direct );
       
   127     setStatus( IO_Ok );
       
   128     fh	   = 0;
       
   129     fd	   = 0;
       
   130     length = 0;
       
   131     ioIndex = 0;
       
   132     ext_f  = FALSE;				// not an external file handle
       
   133 }
       
   134 
       
   135 
       
   136 /*!
       
   137   \fn QString QFile::name() const
       
   138   Returns the name set by setName().
       
   139   \sa setName(), QFileInfo::fileName()
       
   140 */
       
   141 
       
   142 /*!
       
   143   Sets the name of the file. The name can include an absolute directory
       
   144   path or it can be a name or a path relative to the current directory.
       
   145 
       
   146   Do not call this function if the file has already been opened.
       
   147 
       
   148   Note that if the name is relative QFile does not associate it with the
       
   149   current directory.  If you change directory before calling open(), open
       
   150   uses the new current directory.
       
   151 
       
   152   Example:
       
   153   \code
       
   154      QFile f;
       
   155      QDir::setCurrent( "/tmp" );
       
   156      f.setName( "readme.txt" );
       
   157      QDir::setCurrent( "/home" );
       
   158      f.open( IO_ReadOnly );	   // opens "/home/readme.txt" under UNIX
       
   159   \endcode
       
   160 
       
   161   Also note that the directory separator '/' works for all operating
       
   162   systems supported by Qt.
       
   163 
       
   164   \sa name(), QFileInfo, QDir
       
   165 */
       
   166 
       
   167 void QFile::setName( const QString &name )
       
   168 {
       
   169     if ( isOpen() ) {
       
   170 #if defined(CHECK_STATE)
       
   171 	qWarning( "QFile::setName: File is open" );
       
   172 #endif
       
   173 	close();
       
   174     }
       
   175     fn = name;
       
   176 }
       
   177 
       
   178 /*!
       
   179   Returns TRUE if this file exists, otherwise FALSE.
       
   180   \sa name()
       
   181 */
       
   182 
       
   183 bool QFile::exists() const
       
   184 {
       
   185     return qt_file_access( fn, F_OK );
       
   186 }
       
   187 
       
   188 /*!
       
   189   Returns TRUE if the file given by \e fileName exists, otherwise FALSE.
       
   190 */
       
   191 
       
   192 bool QFile::exists( const QString &fileName )
       
   193 {
       
   194     return qt_file_access( fileName, F_OK );
       
   195 }
       
   196 
       
   197 
       
   198 /*!
       
   199   Removes the file specified by the file name currently set.
       
   200   Returns TRUE if successful, otherwise FALSE.
       
   201 
       
   202   The file is closed before it is removed.
       
   203 */
       
   204 
       
   205 bool QFile::remove()
       
   206 {
       
   207     close();
       
   208     return remove( fn );
       
   209 }
       
   210 
       
   211 #if defined(_OS_MAC_) || defined(_OS_MSDOS_) || defined(_OS_WIN32_) || defined(_OS_OS2_) || defined(_OS_CYGWIN_)
       
   212 # define HAS_TEXT_FILEMODE			// has translate/text filemode
       
   213 #endif
       
   214 #if defined(O_NONBLOCK)
       
   215 # define HAS_ASYNC_FILEMODE
       
   216 # define OPEN_ASYNC O_NONBLOCK
       
   217 #elif defined(O_NDELAY)
       
   218 # define HAS_ASYNC_FILEMODE
       
   219 # define OPEN_ASYNC O_NDELAY
       
   220 #endif
       
   221 
       
   222 /*!
       
   223   Flushes the file buffer to the disk.
       
   224 
       
   225   close() also flushes the file buffer.
       
   226 */
       
   227 
       
   228 void QFile::flush()
       
   229 {
       
   230     if ( isOpen() && fh )			// can only flush open/buffered
       
   231 	fflush( fh );				//   file
       
   232 }
       
   233 
       
   234 /*!
       
   235   Returns TRUE if the end of file has been reached, otherwise FALSE.
       
   236   \sa size()
       
   237 */
       
   238 
       
   239 bool QFile::atEnd() const
       
   240 {
       
   241     if ( !isOpen() ) {
       
   242 #if defined(CHECK_STATE)
       
   243 	qWarning( "QFile::atEnd: File is not open" );
       
   244 #endif
       
   245 	return FALSE;
       
   246     }
       
   247     if ( isDirectAccess() && !isTranslated() ) {
       
   248 	if ( at() < length )
       
   249 	    return FALSE;
       
   250     }
       
   251     return QIODevice::atEnd();
       
   252 }
       
   253 
       
   254 /*!
       
   255   Reads a line of text.
       
   256 
       
   257   Reads bytes from the file until end-of-line is reached, or up to \a
       
   258   maxlen bytes, and returns the number of bytes read, or -1 in case of
       
   259   error.  The terminating newline is not stripped.
       
   260 
       
   261   This function is efficient only for buffered files.  Avoid
       
   262   readLine() for files that have been opened with the \c IO_Raw
       
   263   flag.
       
   264 
       
   265   \sa readBlock(), QTextStream::readLine()
       
   266 */
       
   267 
       
   268 int QFile::readLine( char *p, uint maxlen )
       
   269 {
       
   270     if ( maxlen == 0 )				// application bug?
       
   271 	return 0;
       
   272 #if defined(CHECK_STATE)
       
   273     CHECK_PTR( p );
       
   274     if ( !isOpen() ) {				// file not open
       
   275 	qWarning( "QFile::readLine: File not open" );
       
   276 	return -1;
       
   277     }
       
   278     if ( !isReadable() ) {			// reading not permitted
       
   279 	qWarning( "QFile::readLine: Read operation not permitted" );
       
   280 	return -1;
       
   281     }
       
   282 #endif
       
   283     int nread;					// number of bytes read
       
   284     if ( isRaw() ) {				// raw file
       
   285 	nread = QIODevice::readLine( p, maxlen );
       
   286     } else {					// buffered file
       
   287 	p = fgets( p, maxlen, fh );
       
   288 	if ( p ) {
       
   289 	    nread = qstrlen( p );
       
   290 	    ioIndex += nread;
       
   291 	} else {
       
   292 	    nread = -1;
       
   293 	    setStatus(IO_ReadError);
       
   294 	}
       
   295     }
       
   296     return nread;
       
   297 }
       
   298 
       
   299 
       
   300 /*!
       
   301   Reads a line of text.
       
   302 
       
   303   Reads bytes from the file until end-of-line is reached, or up to \a
       
   304   maxlen bytes, and returns the number of bytes read, or -1 in case of
       
   305   error.  The terminating newline is not stripped.
       
   306 
       
   307   This function is efficient only for buffered files.  Avoid
       
   308   readLine() for files that have been opened with the \c IO_Raw
       
   309   flag.
       
   310 
       
   311   Note that the string is read as plain Latin1 bytes, not Unicode.
       
   312 
       
   313   \sa readBlock(), QTextStream::readLine()
       
   314 */
       
   315 
       
   316 int QFile::readLine( QString& s, uint maxlen )
       
   317 {
       
   318     QByteArray ba(maxlen);
       
   319     int l = readLine(ba.data(),maxlen);
       
   320     if ( l >= 0 ) {
       
   321 	ba.truncate(l);
       
   322 	s = QString(ba);
       
   323     }
       
   324     return l;
       
   325 }
       
   326 
       
   327 
       
   328 /*!
       
   329   Reads a single byte/character from the file.
       
   330 
       
   331   Returns the byte/character read, or -1 if the end of the file has been
       
   332   reached.
       
   333 
       
   334   \sa putch(), ungetch()
       
   335 */
       
   336 
       
   337 int QFile::getch()
       
   338 {
       
   339 #if defined(CHECK_STATE)
       
   340     if ( !isOpen() ) {				// file not open
       
   341 	qWarning( "QFile::getch: File not open" );
       
   342 	return EOF;
       
   343     }
       
   344     if ( !isReadable() ) {			// reading not permitted
       
   345 	qWarning( "QFile::getch: Read operation not permitted" );
       
   346 	return EOF;
       
   347     }
       
   348 #endif
       
   349 
       
   350     int ch;
       
   351 
       
   352     if ( !ungetchBuffer.isEmpty() ) {
       
   353 	int len = ungetchBuffer.length();
       
   354 	ch = ungetchBuffer[ len-1 ];
       
   355 	ungetchBuffer.truncate( len - 1 );
       
   356 	return ch;
       
   357     }
       
   358 
       
   359     if ( isRaw() ) {				// raw file (inefficient)
       
   360 	char buf[1];
       
   361 	ch = readBlock( buf, 1 ) == 1 ? buf[0] : EOF;
       
   362     } else {					// buffered file
       
   363 	if ( (ch = getc( fh )) != EOF )
       
   364 	    ioIndex++;
       
   365 	else
       
   366 	    setStatus(IO_ReadError);
       
   367     }
       
   368     return ch;
       
   369 }
       
   370 
       
   371 /*!
       
   372   \fn int QFile::writeBlock( const QByteArray& data )
       
   373   \reimp
       
   374   \internal
       
   375   Should be removed in 3.0
       
   376 */
       
   377 
       
   378 /*!
       
   379   Writes the character \e ch to the file.
       
   380 
       
   381   Returns \e ch, or -1 if some error occurred.
       
   382 
       
   383   \sa getch(), ungetch()
       
   384 */
       
   385 
       
   386 int QFile::putch( int ch )
       
   387 {
       
   388 #if defined(CHECK_STATE)
       
   389     if ( !isOpen() ) {				// file not open
       
   390 	qWarning( "QFile::putch: File not open" );
       
   391 	return EOF;
       
   392     }
       
   393     if ( !isWritable() ) {			// writing not permitted
       
   394 	qWarning( "QFile::putch: Write operation not permitted" );
       
   395 	return EOF;
       
   396     }
       
   397 #endif
       
   398     if ( isRaw() ) {				// raw file (inefficient)
       
   399 	char buf[1];
       
   400 	buf[0] = ch;
       
   401 	ch = writeBlock( buf, 1 ) == 1 ? ch : EOF;
       
   402     } else {					// buffered file
       
   403 	if ( (ch = putc( ch, fh )) != EOF ) {
       
   404 	    ioIndex++;
       
   405 	    if ( ioIndex > length )		// update file length
       
   406 		length = ioIndex;
       
   407 	} else {
       
   408 	    setStatus(IO_WriteError);
       
   409 	}
       
   410     }
       
   411     return ch;
       
   412 }
       
   413 
       
   414 /*!
       
   415   Puts the character \e ch back into the file and decrements the index if it
       
   416   is not zero.
       
   417 
       
   418   This function is normally called to "undo" a getch() operation.
       
   419 
       
   420   Returns \e ch, or -1 if some error occurred.
       
   421 
       
   422   \sa getch(), putch()
       
   423 */
       
   424 
       
   425 int QFile::ungetch( int ch )
       
   426 {
       
   427 #if defined(CHECK_STATE)
       
   428     if ( !isOpen() ) {				// file not open
       
   429 	qWarning( "QFile::ungetch: File not open" );
       
   430 	return EOF;
       
   431     }
       
   432     if ( !isReadable() ) {			// reading not permitted
       
   433 	qWarning( "QFile::ungetch: Read operation not permitted" );
       
   434 	return EOF;
       
   435     }
       
   436 #endif
       
   437     if ( ch == EOF )				// cannot unget EOF
       
   438 	return ch;
       
   439 
       
   440     if ( isSequentialAccess() && !fh) {
       
   441 	// pipe or similar => we cannot ungetch, so do it manually
       
   442 	ungetchBuffer +=ch;
       
   443 	return ch;
       
   444     }
       
   445 
       
   446     if ( isRaw() ) {				// raw file (very inefficient)
       
   447 	char buf[1];
       
   448 	at( ioIndex-1 );
       
   449 	buf[0] = ch;
       
   450 	if ( writeBlock(buf, 1) == 1 )
       
   451 	    at ( ioIndex-1 );
       
   452 	else
       
   453 	    ch = EOF;
       
   454     } else {					// buffered file
       
   455 	if ( (ch = ungetc(ch, fh)) != EOF )
       
   456 	    ioIndex--;
       
   457 	else
       
   458 	    setStatus( IO_ReadError );
       
   459     }
       
   460     return ch;
       
   461 }
       
   462 
       
   463 
       
   464 static QCString locale_encoder( const QString &fileName )
       
   465 {
       
   466     return fileName.local8Bit();
       
   467 }
       
   468 
       
   469 
       
   470 static QFile::EncoderFn encoder = locale_encoder;
       
   471 
       
   472 /*!
       
   473   When you use QFile, QFileInfo, and QDir to access the filesystem
       
   474   with Qt, you can use Unicode filenames.  On Unix, these filenames
       
   475   are converted to an 8-bit encoding.  If you want to do your own
       
   476   file I/O on Unix, you should convert the filename using this
       
   477   function.  On Windows NT, Unicode filenames are supported directly
       
   478   in the filesystem and this function should be avoided. On Windows 95,
       
   479   non-Latin1 locales are not supported at this time.
       
   480 
       
   481   By default, this function converts to the local 8-bit encoding
       
   482   determined by the user's locale.  This is sufficient for
       
   483   filenames that the user chooses.  Filenames hard-coded into the
       
   484   application should only use 7-bit ASCII filename characters.
       
   485 
       
   486   The conversion scheme can be changed using setEncodingFunction().
       
   487   This might be useful if you wish to give the user an option to
       
   488   store in filenames in UTF-8, etc., but beware that such filenames
       
   489   would probably then be unrecognizable when seen by other programs.
       
   490 
       
   491   \sa decodeName()
       
   492 */
       
   493 
       
   494 QCString QFile::encodeName( const QString &fileName )
       
   495 {
       
   496     return (*encoder)(fileName);
       
   497 }
       
   498 
       
   499 /*!
       
   500   \enum QFile::EncoderFn
       
   501 
       
   502   This is used by QFile::setEncodingFunction().
       
   503 */
       
   504 
       
   505 /*!
       
   506   Sets the function for encoding Unicode filenames.
       
   507   The default encodes in the locale-specific 8-bit encoding.
       
   508 
       
   509   \sa encodeName()
       
   510 */
       
   511 void QFile::setEncodingFunction( EncoderFn f )
       
   512 {
       
   513     encoder = f;
       
   514 }
       
   515 
       
   516 static
       
   517 QString locale_decoder( const QCString &localFileName )
       
   518 {
       
   519     return QString::fromLocal8Bit(localFileName);
       
   520 }
       
   521 
       
   522 static QFile::DecoderFn decoder = locale_decoder;
       
   523 
       
   524 /*!
       
   525   This does the reverse of QFile::encodeName().
       
   526 
       
   527   \sa setDecodingFunction()
       
   528 */
       
   529 QString QFile::decodeName( const QCString &localFileName )
       
   530 {
       
   531     return (*decoder)(localFileName);
       
   532 }
       
   533 
       
   534 /*!
       
   535   \enum QFile::DecoderFn
       
   536 
       
   537   This is used by QFile::setDecodingFunction().
       
   538 */
       
   539 
       
   540 /*!
       
   541   Sets the function for decoding 8-bit filenames.
       
   542   The default uses the locale-specific 8-bit encoding.
       
   543 
       
   544   \sa encodeName(), decodeName()
       
   545 */
       
   546 
       
   547 void QFile::setDecodingFunction( DecoderFn f )
       
   548 {
       
   549     decoder = f;
       
   550 }