Qtopia library API Documentation

filemanager.cpp

00001 /**********************************************************************
00002 ** Copyright (C) 2000 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of Qtopia Environment.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00015 **
00016 ** Contact info@trolltech.com if any conditions of this licensing are
00017 ** not clear to you.
00018 **
00019 **********************************************************************/
00020 #include "filemanager.h"
00021 #include "applnk.h"
00022 
00023 #include <qdir.h>
00024 #include <qfile.h>
00025 #include <qfileinfo.h>
00026 #include <qtextstream.h>
00027 #include <qtextcodec.h>
00028 
00029 #include <errno.h>
00030 #include <stdlib.h>
00031 #include <unistd.h>
00032 #include <sys/stat.h>
00033 #include <dirent.h>
00034 #ifdef Q_OS_MACX
00035 // MacOS X does not have sendfile.. :(
00036 // But maybe in the future.. !?
00037 #  ifdef SENDFILE
00038 #    include <sys/types.h>
00039 #    include <sys/socket.h>
00040 #  endif
00041 #else
00042 #  include <sys/sendfile.h>
00043 #endif /* Q_OS_MACX */
00044 #include <fcntl.h>
00045 
00054 FileManager::FileManager()
00055 {
00056 }
00057 
00061 FileManager::~FileManager()
00062 {
00063 
00064 }
00065 
00071 bool FileManager::saveFile( const DocLnk &f, const QByteArray &data )
00072 {
00073  QString fn = f.file() + ".new";
00074     ensurePathExists( fn );
00075     QFile fl( fn );
00076     if ( !fl.open( IO_WriteOnly|IO_Raw ) ) {
00077        qWarning("open failed");
00078        return FALSE;
00079     }
00080     int total_written = fl.writeBlock( data );
00081     fl.close();
00082     if ( total_written != int(data.size()) || !f.writeLink() ) {
00083   QFile::remove( fn );
00084   return FALSE;
00085     }
00086        qDebug("total written %d out of %d", total_written, data.size());
00087     // else rename the file...
00088     if ( !renameFile( fn.latin1(), f.file().latin1() ) ) {
00089   qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(),
00090       f.file().latin1(), errno );
00091   // remove the file...
00092     }
00093     return TRUE;
00094 }
00095 
00103 bool FileManager::saveFile( const DocLnk &f, const QString &text )
00104 {
00105  QString fn = f.file() + ".new";
00106     ensurePathExists( fn );
00107     QFile fl( fn );
00108     if ( !fl.open( IO_WriteOnly|IO_Raw ) ) {
00109        qWarning("open failed");
00110        return FALSE;
00111     }
00112 
00113     QCString cstr = text.utf8();
00114     int total_written;
00115     total_written = fl.writeBlock( cstr.data(), cstr.length() );
00116     fl.close();
00117     if ( total_written != int(cstr.length()) || !f.writeLink() ) {
00118        QFile::remove( fn );
00119        return FALSE;
00120     }
00121     // okay now rename the file..
00122     if ( !renameFile( fn.latin1(), f.file().latin1() ) ) {
00123        qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(),
00124                  f.file().latin1(), errno );
00125 
00126     }
00127     return TRUE;
00128 }
00129 
00130 
00138 bool FileManager::loadFile( const DocLnk &f, QString &text )
00139 {
00140     QString fn = f.file();
00141     QFile fl( fn );
00142     if ( !fl.open( IO_ReadOnly ) )
00143   return FALSE;
00144     QTextStream ts( &fl );
00145 #if QT_VERSION <= 230 && defined(QT_NO_CODECS)
00146     // The below should work, but doesn't in Qt 2.3.0
00147     ts.setCodec( QTextCodec::codecForMib( 106 ) );
00148 #else
00149     ts.setEncoding( QTextStream::UnicodeUTF8 );
00150 #endif
00151     text = ts.read();
00152     fl.close();
00153     return TRUE;
00154 }
00155 
00156 
00162 bool FileManager::loadFile( const DocLnk &f, QByteArray &ba )
00163 {
00164     QString fn = f.file();
00165     QFile fl( fn );
00166     if ( !fl.open( IO_ReadOnly ) )
00167   return FALSE;
00168     ba.resize( fl.size() );
00169     if ( fl.size() > 0 )
00170   fl.readBlock( ba.data(), fl.size() );
00171     fl.close();
00172     return TRUE;
00173 }
00174 
00181 bool FileManager::copyFile( const AppLnk &src, const AppLnk &dest )
00182 {
00183     QFile sf( src.file() );
00184     if ( !sf.open( IO_ReadOnly ) )
00185   return FALSE;
00186 
00187     QString fn = dest.file() + ".new";
00188     ensurePathExists( fn );
00189     QFile df( fn );
00190     if ( !df.open( IO_WriteOnly|IO_Raw ) )
00191   return FALSE;
00192 
00193     const int bufsize = 16384;
00194     char buffer[bufsize];
00195     bool ok = TRUE;
00196     int bytesRead = 0;
00197     while ( ok && !sf.atEnd() ) {
00198   bytesRead = sf.readBlock( buffer, bufsize );
00199   if ( bytesRead < 0 )
00200       ok = FALSE;
00201   while ( ok && bytesRead > 0 ) {
00202       int bytesWritten = df.writeBlock( buffer, bytesRead );
00203       if ( bytesWritten < 0 )
00204     ok = FALSE;
00205       else
00206     bytesRead -= bytesWritten;
00207   }
00208     }
00209 
00210     if ( ok )
00211   ok = dest.writeLink();
00212     
00213     if ( ok ) {
00214   // okay now rename the file...
00215   if ( !renameFile( fn.latin1(), dest.file().latin1() )  ) {
00216       qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(),
00217           dest.file().latin1(), errno );
00218       // remove the tmp file, otherwise, it will just lay around...
00219       QFile::remove( fn.latin1() );
00220   }
00221     } else {
00222   QFile::remove( fn.latin1() );
00223     }
00224 
00225     return ok;
00226 }
00227 
00228 bool FileManager::copyFile( const QString & src, const QString & dest ) {
00229    bool success = true;
00230    struct stat status;
00231    int read_fd=0;
00232    int write_fd=0;
00233    struct stat stat_buf;
00234    off_t offset = 0;
00235    QFile srcFile(src);
00236    QFile destFile(dest);
00237 
00238    if(!srcFile.open( IO_ReadOnly|IO_Raw)) {
00239          return success = false;
00240    }
00241    read_fd = srcFile.handle();
00242    if(read_fd != -1) {
00243       fstat (read_fd, &stat_buf);
00244       if( !destFile.open( IO_WriteOnly|IO_Raw ) )
00245             return success = false;
00246       write_fd = destFile.handle(); 
00247       if(write_fd != -1) {
00248          int err=0;
00249          QString msg;
00250 #ifdef Q_OS_MACX
00251 #ifdef SENDFILE
00252      /* FreeBSD does support a different kind of 
00253       * sendfile. (eilers)
00254       * I took this from Very Secure FTPd
00255       * Licence: GPL
00256       * Author: Chris Evans
00257       * sysdeputil.c
00258       */
00259           /* XXX - start_pos will truncate on 32-bit machines - can we
00260            * say "start from current pos"?
00261            */
00262           off_t written = 0;
00263       int retval = 0;
00264           retval = sendfile(read_fd, write_fd, offset, stat_buf.st_size, NULL,
00265                             &written, 0);
00266           /* Translate to Linux-like retval */
00267           if (written > 0)
00268           {
00269             err = (int) written;
00270           }
00271 #else /* SENDFILE */
00272       err == -1;
00273       msg = "FAILURE: Using unsupported function \"sendfile()\" Need Workaround !!";
00274       success = false;
00275 #         warning "Need workaround for sendfile!!(eilers)"
00276 #endif  /* SENDFILE */
00277 
00278 #else
00279       err = sendfile(write_fd, read_fd, &offset, stat_buf.st_size);
00280       if( err == -1) {
00281           switch(err) {
00282           case EBADF : msg = "The input file was not opened for reading or the output file was not opened for writing. ";
00283           case EINVAL: msg = "Descriptor is not valid or locked. ";
00284           case ENOMEM: msg = "Insufficient memory to read from in_fd.";
00285           case EIO: msg = "Unspecified error while reading from in_fd.";
00286           };
00287           success = false;
00288       }
00289 #endif /* Q_OS_MACX */
00290       if( !success )
00291           qWarning( msg );
00292      } else {
00293          qWarning("open write failed %s, %s",src.latin1(), dest.latin1());
00294          success = false;
00295       }
00296    } else {
00297       qWarning("open read failed %s, %s",src.latin1(), dest.latin1());
00298       success = false;
00299    }
00300    srcFile.close();
00301    destFile.close();
00302     // Set file permissions
00303   if( stat( (const char *) src, &status ) == 0 ) {
00304       chmod( (const char *) dest, status.st_mode );
00305     }
00306 
00307   return success;
00308 }
00309 
00310 
00311 bool FileManager::renameFile( const QString & src, const QString & dest ) {
00312    if(copyFile( src, dest )) {
00313       if(QFile::remove(src) ) {
00314        return true;
00315       }
00316    }
00317     return false;  
00318 }
00319 
00320 /*
00321 bool FileManager::copyFile( const QString & src, const QString & dest ) {
00322    bool success = true;
00323    struct stat status;
00324    int read_fd=0;
00325    int write_fd=0;
00326    struct stat stat_buf;
00327    off_t offset = 0;
00328    QFile srcFile(src);
00329    QFile destFile(dest);
00330 
00331    if(!srcFile.open( IO_ReadOnly|IO_Raw)) {
00332          return success = false;
00333    }
00334    read_fd = srcFile.handle();
00335    if(read_fd != -1) {
00336       fstat (read_fd, &stat_buf);
00337       if( !destFile.open( IO_WriteOnly|IO_Raw ) )
00338             return success = false;
00339       write_fd = destFile.handle();
00340       if(write_fd != -1) {
00341          int err=0;
00342          QString msg;
00343          err = sendfile(write_fd, read_fd, &offset, stat_buf.st_size);
00344          if( err == -1) {
00345             switch(err) {
00346             case EBADF : msg = "The input file was not opened for reading or the output file was not opened for writing. ";
00347             case EINVAL: msg = "Descriptor is not valid or locked. ";
00348             case ENOMEM: msg = "Insufficient memory to read from in_fd.";
00349             case EIO: msg = "Unspecified error while reading from in_fd.";
00350             };
00351             success = false;
00352          }
00353       } else {
00354          qWarning("open write failed %s, %s",src.latin1(), dest.latin1());
00355          success = false;
00356       }
00357    } else {
00358       qWarning("open read failed %s, %s",src.latin1(), dest.latin1());
00359       success = false;
00360    }
00361    srcFile.close();
00362    destFile.close();
00363     // Set file permissions
00364   if( stat( (const char *) src, &status ) == 0 ) {
00365       chmod( (const char *) dest, status.st_mode );
00366     }
00367 
00368   return success;
00369 }
00370 
00371 
00372 bool FileManager::renameFile( const QString & src, const QString & dest ) {
00373    if(copyFile( src, dest )) {
00374       if(QFile::remove(src) ) {
00375        return true;
00376       }
00377    }
00378     return false;
00379 }
00380 */
00381 
00388 QIODevice* FileManager::openFile( const DocLnk& f )
00389 {
00390     QString fn = f.file();
00391     QFile* fl = new QFile( fn );
00392     if ( !fl->open( IO_ReadOnly ) ) {
00393   delete fl;
00394         fl = 0;
00395     }
00396     return fl;
00397 }
00398 
00405 QIODevice* FileManager::saveFile( const DocLnk& f )
00406 {
00407     QString fn = f.file();
00408     ensurePathExists( fn );
00409     QFile* fl = new QFile( fn );
00410     if ( fl->open( IO_WriteOnly ) ) {
00411   f.writeLink();
00412     } else {
00413   delete fl;
00414         fl = 0;
00415     }
00416     return fl;
00417 }
00418 
00423 bool FileManager::exists( const DocLnk &f )
00424 {
00425     return QFile::exists(f.file());
00426 }
00427 
00428 
00433 bool FileManager::ensurePathExists( const QString &fn )
00434 {
00435     QFileInfo fi(fn);
00436     fi.setFile( fi.dirPath(TRUE) );
00437     if ( !fi.exists() ) {
00438   if ( system(("mkdir -p "+fi.filePath())) )
00439       return FALSE;
00440     }
00441 
00442     return TRUE;
00443 }
KDE Logo
This file is part of the documentation for OPIE Version 1.5.5.
Documentation copyright © 1997-2003 the KDE developers. 2003 OPIE developers
Generated on Tue Feb 10 20:24:04 2004 by doxygen 1.3.5 written by Dimitri van Heesch, © 1997-2001