[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdelibs
From:       Allan Sandfeld Jensen <kde () carewolf ! com>
Date:       2006-08-18 17:57:03
Message-ID: 1155923823.618872.20433.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 574326 by carewolf:

Merging the first parts of random-access KIO


 M  +1 -1      kdoctools/kio_help.cpp  
 M  +1 -0      kio/kio/CMakeLists.txt  
 A             kio/kio/filejob.cpp   [License: LGPL (v2)]
 A             kio/kio/filejob.h   [License: LGPL (v2)]
 M  +2 -0      kio/kio/global.cpp  
 M  +14 -2     kio/kio/global.h  
 M  +9 -0      kio/kio/job.cpp  
 M  +11 -0     kio/kio/job.h  
 M  +28 -0     kio/kio/slavebase.cpp  
 M  +18 -0     kio/kio/slavebase.h  
 M  +18 -2     kio/kio/slaveinterface.cpp  
 M  +8 -2      kio/kio/slaveinterface.h  
 M  +135 -0    kioslave/file/file.cc  
 M  +1 -0      kioslave/file/file.h  
 M  +1 -0      kioslave/file/file.protocol  


--- trunk/KDE/kdelibs/kdoctools/kio_help.cpp #574325:574326
@@ -359,7 +359,7 @@
 	return;
     }
 
-    int fd = open( _path.data(), O_RDONLY);
+    int fd = ::open( _path.data(), O_RDONLY);
     if ( fd < 0 ) {
 	error( KIO::ERR_CANNOT_OPEN_FOR_READING, url.path() );
 	return;
--- trunk/KDE/kdelibs/kio/kio/CMakeLists.txt #574325:574326
@@ -22,6 +22,7 @@
   jobuidelegate.h
   paste.h
   slavebase.h
+  filejob.h
   progressbase.h
   defaultprogress.h
   statusbarprogress.h
--- trunk/KDE/kdelibs/kio/kio/global.cpp #574325:574326
@@ -419,6 +419,8 @@
       return i18n("Using sub-URLs with %1 is not supported.", protocol);
     case CMD_MULTI_GET:
       return i18n("Multiple get is not supported with protocol %1.", protocol);
+    case CMD_OPEN:
+      return i18n("Opening files is not supported with protocol %1.", protocol);
     default:
       return i18n("Protocol %1 does not support action %2.", protocol, cmd);
   }/*end switch*/
--- trunk/KDE/kdelibs/kio/kio/global.h #574325:574326
@@ -166,12 +166,23 @@
     CMD_RESUMEANSWER = 'T', // 84
     CMD_CONFIG = 'U', // 85
     CMD_MULTI_GET = 'V', // 86
-    CMD_SETLINKDEST = 'W' // 87
+    CMD_SETLINKDEST = 'W', // 87
+    CMD_OPEN = 'X' // 88
     // Add new ones here once a release is done, to avoid breaking binary \
                compatibility.
     // Note that protocol-specific commands shouldn't be added here, but should use \
special.  };
 
   /**
+   * Commands that can be invoked on a slave-file.
+   */
+  enum FileCommand {
+    CMD_READ  = 90,
+    CMD_WRITE = 91,
+    CMD_SEEK  = 92,
+    CMD_CLOSE = 93
+  };
+
+  /**
    * Error codes that can be emitted by KIO.
    */
   enum Error {
@@ -247,8 +258,9 @@
     ERR_UPGRADE_REQUIRED = KJob::UserDefinedError + 64, // A transport upgrade is \
                required to access this
                                                         // object.  For instance, \
                TLS is demanded by
                                                         // the server in order to \
                continue.
-    ERR_POST_DENIED = KJob::UserDefinedError + 65 // Issued when trying to POST data \
to a certain Ports +    ERR_POST_DENIED = KJob::UserDefinedError + 65, // Issued when \
trying to POST data to a certain Ports  // see job.cpp
+    ERR_COULD_NOT_SEEK = KJob::UserDefinedError + 66
   };
 
   /**
--- trunk/KDE/kdelibs/kio/kio/job.cpp #574325:574326
@@ -61,6 +61,7 @@
 #include "kmimemagic.h"
 #include "kprotocolinfo.h"
 #include "kprotocolmanager.h"
+#include "filejob.h"
 
 #include "kio/observer.h"
 
@@ -1091,6 +1092,14 @@
     return job;
 }
 
+FileJob *KIO::open( const KUrl& url, int access )
+{
+    // Send decoded path and encoded query
+    KIO_ARGS << url << access;
+    FileJob * job = new FileJob( url, packedArgs );
+    return job;
+}
+
 class PostErrorJob : public TransferJob
 {
 public:
--- trunk/KDE/kdelibs/kio/kio/job.h #574325:574326
@@ -26,6 +26,7 @@
 
 namespace KIO {
 
+    class FileJob;
 
     /**
      * Creates a single directory.
@@ -188,6 +189,16 @@
     KIO_EXPORT TransferJob *get( const KUrl& url, bool reload=false, bool \
showProgressInfo = true );  
     /**
+     * Open ( random access I/O )
+     *
+     * The file-job emits open() when opened
+     * @param url the URL of the file
+     * @param access the access priveleges (1 - ReadOnly, 2 - WriteOnly, 3 - \
Read/Write) +     * @return the file-handling job
+     */
+    KIO_EXPORT FileJob *open( const KUrl& url, int access );
+
+    /**
      * Put (a.k.a. write)
      *
      * @param url Where to write data.
--- trunk/KDE/kdelibs/kio/kio/slavebase.cpp #574325:574326
@@ -396,6 +396,15 @@
    m_pConnection->send( MSG_DATA_REQ );
 }
 
+void SlaveBase::opened()
+{
+   if (!mOutgoingMetaData.isEmpty())
+      sendMetaData();
+   slaveWriteError = false;
+   m_pConnection->send( MSG_OPENED );
+   if (slaveWriteError) exit();
+}
+
 void SlaveBase::error( int _errid, const QString &_text )
 {
     mIncomingMetaData.clear(); // Clear meta data
@@ -501,6 +510,18 @@
 //    d->processed_size = _bytes;
 }
 
+void SlaveBase::written( KIO::filesize_t _bytes )
+{
+    KIO_DATA << KIO_FILESIZE_T(_bytes);
+    m_pConnection->send( MSG_WRITTEN, data );
+}
+
+void SlaveBase::position( KIO::filesize_t _pos )
+{
+    KIO_DATA << KIO_FILESIZE_T(_pos);
+    m_pConnection->send( INF_POSITION, data );
+}
+
 void SlaveBase::processedPercent( float /* percent */ )
 {
   kDebug(7019) << "SlaveBase::processedPercent: STUB" << endl;
@@ -732,6 +753,8 @@
 { error(  ERR_UNSUPPORTED_ACTION, unsupportedActionErrorString(mProtocol, \
CMD_LISTDIR)); }  void SlaveBase::get(KUrl const & )
 { error(  ERR_UNSUPPORTED_ACTION, unsupportedActionErrorString(mProtocol, CMD_GET)); \
} +void SlaveBase::open(KUrl const &, int access )
+{ error(  ERR_UNSUPPORTED_ACTION, unsupportedActionErrorString(mProtocol, \
CMD_OPEN)); }  void SlaveBase::mimetype(KUrl const &url)
 { get(url); }
 void SlaveBase::rename(KUrl const &, KUrl const &, bool)
@@ -979,6 +1002,11 @@
         stream >> url;
         get( url );
     } break;
+    case CMD_OPEN:
+    {
+        stream >> url >> i;
+        open( url, i );
+    } break;
     case CMD_PUT:
     {
         int permissions;
--- trunk/KDE/kdelibs/kio/kio/slavebase.h #574325:574326
@@ -91,6 +91,12 @@
     void dataReq( );
 
     /**
+     * open succedes
+     * @see open
+     */
+    void opened();
+
+    /**
      * Call to signal an error.
      * This also finishes the job, no need to call finished.
      *
@@ -180,6 +186,10 @@
      */
     void processedSize( KIO::filesize_t _bytes );
 
+    void position( KIO::filesize_t _pos );
+
+    void written( KIO::filesize_t _bytes );
+
     /**
      * Only use this if you can't know in advance the size of the
      * copied data. For example, if you're doing variable bitrate
@@ -364,6 +374,14 @@
     virtual void get( const KUrl& url );
 
     /**
+     * open.
+     * @param url the full url for this request. Host, port and user of the URL
+     *        can be assumed to be the same as in the last setHost() call.
+     * @param access 1 - rdonly, 2 - wronly or 3 - rdwr
+     */
+    virtual void open( const KUrl& url, int access );
+
+    /**
      * put, i.e. write data into a file.
      *
      * @param url where to write the file
--- trunk/KDE/kdelibs/kio/kio/slaveinterface.cpp #574325:574326
@@ -203,6 +203,10 @@
     case MSG_DATA_REQ:
         emit dataReq();
 	break;
+    case MSG_OPENED: {
+	emit open();
+	break;
+    }
     case MSG_FINISHED:
 	//kDebug(7007) << "Finished [this = " << this << "]" << endl;
         d->offset = 0;
@@ -255,9 +259,15 @@
         }
         break;
     case MSG_CONNECTED:
-	emit connected();
-	break;
+        emit connected();
+        break;
 
+    case MSG_WRITTEN:
+    {
+        KIO::filesize_t size = readFilesize_t(stream);
+        emit written( size );
+    }
+    break;
     case INF_TOTAL_SIZE:
 	{
 	    KIO::filesize_t size = readFilesize_t(stream);
@@ -279,6 +289,12 @@
 	    d->filesize = size;
 	}
 	break;
+    case INF_POSITION:
+	{
+	    KIO::filesize_t pos = readFilesize_t(stream);
+	    emit position( pos );
+	}
+	break;
     case INF_SPEED:
 	stream >> ul;
 	d->slave_calcs_speed = true;
--- trunk/KDE/kdelibs/kio/kio/slaveinterface.h #574325:574326
@@ -54,7 +54,8 @@
    INF_INFOMESSAGE,
    INF_META_DATA,
    INF_NETWORK_STATUS,
-   INF_MESSAGEBOX
+   INF_MESSAGEBOX,
+   INF_POSITION
    // add new ones here once a release is done, to avoid breaking binary \
compatibility  };
 
@@ -79,7 +80,8 @@
    MSG_CANRESUME,
    MSG_AUTH_KEY, // deprecated.
    MSG_DEL_AUTH_KEY, // deprecated.
-   MSG_CANSEEK
+   MSG_OPENED,
+   MSG_WRITTEN
    // add new ones here once a release is done, to avoid breaking binary \
compatibility  };
 
@@ -129,6 +131,9 @@
 
     void canResume( KIO::filesize_t );
 
+    void open();
+    void written( KIO::filesize_t );
+
     ///////////
     // Info sent by the slave
     //////////
@@ -136,6 +141,7 @@
     void totalSize( KIO::filesize_t );
     void processedSize( KIO::filesize_t );
     void redirection( const KUrl& );
+    void position( KIO::filesize_t );
 
     void speed( unsigned long );
     void errorPage();
--- trunk/KDE/kdelibs/kioslave/file/file.cc #574325:574326
@@ -2,6 +2,7 @@
    Copyright (C) 2000-2002 Stephan Kulow <coolo@kde.org>
    Copyright (C) 2000-2002 David Faure <faure@kde.org>
    Copyright (C) 2000-2002 Waldo Bastian <bastian@kde.org>
+   Copyright (C) 2006 Allan Sandfeld Jensen <sandfeld@kde.org>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
@@ -62,6 +63,7 @@
 #include <string.h>
 #endif
 
+#include <QByteArray>
 #include <qdatetime.h>
 #include <qregexp.h>
 
@@ -84,6 +86,7 @@
 #endif
 
 #include <kstandarddirs.h>
+#include <kio/connection.h>
 #include <kio/ioslave_defaults.h>
 #include <kde_file.h>
 #include <kglobal.h>
@@ -242,6 +245,7 @@
 
 void FileProtocol::get( const KUrl& url )
 {
+    kDebug( 7101 ) << "File::get" << endl;
     if (!url.isLocalFile()) {
         KUrl redir(url);
 	redir.setProtocol(config()->readEntry("DefaultRemoteProtocol", "smb"));
@@ -357,6 +361,137 @@
    return 0;
 }
 
+
+void FileProtocol::open( const KUrl& url, int access )
+{
+    kDebug(7101) << "FileProtocol::open " << url.url() << endl;
+
+    QByteArray _path( QFile::encodeName(url.path()));
+    KDE_struct_stat buff;
+    if ( KDE_stat( _path.data(), &buff ) == -1 ) {
+        if ( errno == EACCES )
+           error( KIO::ERR_ACCESS_DENIED, url.path() );
+        else
+           error( KIO::ERR_DOES_NOT_EXIST, url.path() );
+        return;
+    }
+
+    if ( S_ISDIR( buff.st_mode ) ) {
+        error( KIO::ERR_IS_DIRECTORY, url.path() );
+        return;
+    }
+    if ( !S_ISREG( buff.st_mode ) ) {
+        error( KIO::ERR_CANNOT_OPEN_FOR_READING, url.path() );
+        return;
+    }
+
+    int flags = 0;
+    if (access == 1) flags = O_RDONLY;
+    else
+    if (access == 2) flags = O_WRONLY;
+    else
+    if (access == 3) flags = O_RDWR;
+
+    int fd = KDE_open( _path.data(), flags);
+    if ( fd < 0 ) {
+        error( KIO::ERR_CANNOT_OPEN_FOR_READING, url.path() );
+        return;
+    }
+    // Determine the mimetype of the file to be retrieved, and emit it.
+    // This is mandatory in all slaves (for KRun/BrowserRun to work).
+    KMimeType::Ptr mt = KMimeType::findByURL( url, buff.st_mode, true /* local URL \
*/ ); +    emit mimeType( mt->name() );
+
+    totalSize( buff.st_size );
+    position( 0 );
+
+    emit opened();
+
+    QByteArray array;
+
+    // Command-loop:
+    int cmd = CMD_NONE;
+    while (true) {
+        kDebug( 7101 ) << "File::open -- loop" << endl;
+        QByteArray args;
+        int stat = appconn->read(&cmd, args);
+        if ( stat == -1 )
+        {   // error
+            kDebug( 7101 ) << "File::open -- connection error" << endl;
+            break;
+        }
+        QDataStream stream( args );
+        switch( cmd ) {
+        case CMD_READ: {
+            kDebug( 7101 ) << "File::open -- read" << endl;
+            int bytes;
+            stream >> bytes;
+            char buffer[ bytes ];
+        read_retry:
+            int res = ::read(fd, buffer, bytes);
+            if (res >= 0) {
+                array = array.fromRawData(buffer, bytes);
+                data( array );
+                array.clear();
+            } else {
+                if (errno == EINTR) goto read_retry;
+                error( KIO::ERR_COULD_NOT_READ, url.path());
+                break;
+            }
+            continue;
+        }
+        case CMD_WRITE: {
+            kDebug( 7101 ) << "File::open -- write" << endl;
+            QByteArray &buffer = args;
+
+            if (write_all( fd, buffer.data(), buffer.size()))
+            {
+                if ( errno == ENOSPC ) // disk full
+                {
+                    error( KIO::ERR_DISK_FULL, url.path());
+                    break;
+                }
+                else
+                {
+                    kWarning(7101) << "Couldn't write. Error:" << strerror(errno) << \
endl; +                    error( KIO::ERR_COULD_NOT_WRITE, url.path());
+                    break;
+                }
+            } else {
+                written(buffer.size());
+            }
+            continue;
+        }
+        case CMD_SEEK: {
+            kDebug( 7101 ) << "File::open -- seek" << endl;
+            int offset;
+            stream >> offset;
+            int res = KDE_lseek(fd, offset, SEEK_SET);
+            if (res != -1) {
+                position( offset );
+            } else {
+                error(KIO::ERR_COULD_NOT_SEEK, url.path());
+                break;
+            }
+            continue;
+        }
+        case CMD_NONE:
+            kDebug( 7101 ) << "File::open -- none " << endl;
+            continue;
+        case CMD_CLOSE:
+            kDebug( 7101 ) << "File::open -- close " << endl;
+            break;
+        default:
+            kDebug( 7101 ) << "File::open -- invalid command: " << cmd << endl;
+            cmd = CMD_CLOSE;
+            break;
+        }
+        break;
+    }
+    ::close( fd );
+    finished();
+}
+
 static bool
 same_inode(const KDE_struct_stat &src, const KDE_struct_stat &dest)
 {
--- trunk/KDE/kdelibs/kioslave/file/file.h #574325:574326
@@ -61,6 +61,7 @@
   virtual void mkdir( const KUrl& url, int permissions );
   virtual void chmod( const KUrl& url, int permissions );
   virtual void del( const KUrl& url, bool isfile);
+  virtual void open( const KUrl& url, int access );
 
   /**
    * Special commands supported by this slave:
--- trunk/KDE/kdelibs/kioslave/file/file.protocol #574325:574326
@@ -10,6 +10,7 @@
 deleting=true
 linking=true
 moving=true
+opening=true
 maxInstances=4
 DocPath=kioslave/file.html
 Class=:local


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic