source: trunk/src/kernel/qlocalfs.cpp@ 8

Last change on this file since 8 was 8, checked in by dmik, 20 years ago

Transferred Qt for OS/2 version 3.3.1-rc5 sources from the CVS

  • Property svn:keywords set to Id
File size: 11.1 KB
Line 
1/****************************************************************************
2** $Id: qlocalfs.cpp 8 2005-11-16 19:36:46Z dmik $
3**
4** Implementation of QLocalFs class
5**
6** Created : 950429
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the kernel 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 "qlocalfs.h"
39
40#ifndef QT_NO_NETWORKPROTOCOL
41
42#include "qfileinfo.h"
43#include "qfile.h"
44#include "qurlinfo.h"
45#include "qapplication.h"
46#include "qurloperator.h"
47
48//#define QLOCALFS_DEBUG
49
50
51/*!
52 \class QLocalFs qlocalfs.h
53 \brief The QLocalFs class is an implementation of a
54 QNetworkProtocol that works on the local file system.
55\if defined(commercial)
56 It is part of the <a href="commercialeditions.html">Qt Enterprise Edition</a>.
57\endif
58
59 \module network
60
61 \ingroup io
62
63 This class is derived from QNetworkProtocol. QLocalFs is not
64 normally used directly, but rather through a QUrlOperator, for
65 example:
66 \code
67 QUrlOperator op( "file:///tmp" );
68 op.listChildren(); // Asks the server to provide a directory listing
69 \endcode
70
71 This code will only work if the QLocalFs class is registered; to
72 register the class, you must call qInitNetworkProtocols() before
73 using a QUrlOperator with QLocalFs.
74
75 If you really need to use QLocalFs directly, don't forget
76 to set its QUrlOperator with setUrl().
77
78 \sa \link network.html Qt Network Documentation \endlink QNetworkProtocol, QUrlOperator
79*/
80
81/*!
82 Constructor.
83*/
84
85QLocalFs::QLocalFs()
86 : QNetworkProtocol()
87{
88}
89
90static int convertPermissions(QFileInfo *fi)
91{
92 int p = 0;
93 if ( fi->permission( QFileInfo::ReadOwner ) )
94 p |= QUrlInfo::ReadOwner;
95 if ( fi->permission( QFileInfo::WriteOwner ) )
96 p |= QUrlInfo::WriteOwner;
97 if ( fi->permission( QFileInfo::ExeOwner ) )
98 p |= QUrlInfo::ExeOwner;
99 if ( fi->permission( QFileInfo::ReadGroup ) )
100 p |= QUrlInfo::ReadGroup;
101 if ( fi->permission( QFileInfo::WriteGroup ) )
102 p |= QUrlInfo::WriteGroup;
103 if ( fi->permission( QFileInfo::ExeGroup ) )
104 p |= QUrlInfo::ExeGroup;
105 if ( fi->permission( QFileInfo::ReadOther ) )
106 p |= QUrlInfo::ReadOther;
107 if ( fi->permission( QFileInfo::WriteOther ) )
108 p |= QUrlInfo::WriteOther;
109 if ( fi->permission( QFileInfo::ExeOther ) )
110 p |= QUrlInfo::ExeOther;
111 return p;
112}
113
114/*!
115 \reimp
116*/
117
118void QLocalFs::operationListChildren( QNetworkOperation *op )
119{
120#ifdef QLOCALFS_DEBUG
121 qDebug( "QLocalFs: operationListChildren" );
122#endif
123 op->setState( StInProgress );
124
125 dir = QDir( url()->path() );
126 dir.setNameFilter( url()->nameFilter() );
127 dir.setMatchAllDirs( TRUE );
128 if ( !dir.isReadable() ) {
129 QString msg = tr( "Could not read directory\n%1" ).arg( url()->path() );
130 op->setState( StFailed );
131 op->setProtocolDetail( msg );
132 op->setErrorCode( (int)ErrListChildren );
133 emit finished( op );
134 return;
135 }
136
137 const QFileInfoList *filist = dir.entryInfoList( QDir::All | QDir::Hidden | QDir::System );
138 if ( !filist ) {
139 QString msg = tr( "Could not read directory\n%1" ).arg( url()->path() );
140 op->setState( StFailed );
141 op->setProtocolDetail( msg );
142 op->setErrorCode( (int)ErrListChildren );
143 emit finished( op );
144 return;
145 }
146
147 emit start( op );
148
149 QFileInfoListIterator it( *filist );
150 QFileInfo *fi;
151 QValueList<QUrlInfo> infos;
152 while ( ( fi = it.current() ) != 0 ) {
153 ++it;
154 infos << QUrlInfo( fi->fileName(), convertPermissions(fi), fi->owner(), fi->group(),
155 fi->size(), fi->lastModified(), fi->lastRead(), fi->isDir(), fi->isFile(),
156 fi->isSymLink(), fi->isWritable(), fi->isReadable(), fi->isExecutable() );
157 // ### Block signals to initiate a hack in QNetworkOperation that will
158 // prevent the op from being deleted during the qApp->processEvents() call
159 op->blockSignals( TRUE );
160 qApp->processEvents();
161 op->blockSignals( FALSE );
162 if ( op->state() == StStopped ) {
163 op->free();
164 return;
165 }
166 }
167 emit newChildren( infos, op );
168 op->setState( StDone );
169 emit finished( op );
170}
171
172/*!
173 \reimp
174*/
175
176void QLocalFs::operationMkDir( QNetworkOperation *op )
177{
178#ifdef QLOCALFS_DEBUG
179 qDebug( "QLocalFs: operationMkDir" );
180#endif
181 op->setState( StInProgress );
182 QString dirname = op->arg( 0 );
183
184 dir = QDir( url()->path() );
185 if ( dir.mkdir( dirname ) ) {
186 QFileInfo fi( dir, dirname );
187 QUrlInfo inf( fi.fileName(), convertPermissions(&fi), fi.owner(), fi.group(),
188 fi.size(), fi.lastModified(), fi.lastRead(), fi.isDir(), fi.isFile(),
189 fi.isSymLink(), fi.isWritable(), fi.isReadable(), fi.isExecutable() );
190 emit newChild( inf, op );
191 op->setState( StDone );
192 emit createdDirectory( inf, op );
193 emit finished( op );
194 } else {
195 QString msg = tr( "Could not create directory\n%1" ).arg( dirname );
196 op->setState( StFailed );
197 op->setProtocolDetail( msg );
198 op->setErrorCode( (int)ErrMkDir );
199 emit finished( op );
200 }
201}
202
203/*!
204 \reimp
205*/
206
207void QLocalFs::operationRemove( QNetworkOperation *op )
208{
209#ifdef QLOCALFS_DEBUG
210 qDebug( "QLocalFs: operationRemove" );
211#endif
212 op->setState( StInProgress );
213 QString name = QUrl( op->arg( 0 ) ).path();
214 bool deleted = FALSE;
215
216 dir = QDir( url()->path() );
217
218 QFileInfo fi( dir, name );
219 if ( fi.isDir() ) {
220 if ( dir.rmdir( name ) )
221 deleted = TRUE;
222 }
223
224 if ( deleted || dir.remove( name ) ) {
225 op->setState( StDone );
226 emit removed( op );
227 emit finished( op );
228 } else {
229 QString msg = tr( "Could not remove file or directory\n%1" ).arg( name );
230 op->setState( StFailed );
231 op->setProtocolDetail( msg );
232 op->setErrorCode( (int)ErrRemove );
233 emit finished( op );
234 }
235}
236
237/*!
238 \reimp
239*/
240
241void QLocalFs::operationRename( QNetworkOperation *op )
242{
243#ifdef QLOCALFS_DEBUG
244 qDebug( "QLocalFs: operationRename" );
245#endif
246 op->setState( StInProgress );
247 QString oldname = op->arg( 0 );
248 QString newname = op->arg( 1 );
249
250 dir = QDir( url()->path() );
251 if ( dir.rename( oldname, newname ) ) {
252 op->setState( StDone );
253 emit itemChanged( op );
254 emit finished( op );
255 } else {
256 QString msg = tr( "Could not rename\n%1\nto\n%2" ).arg( oldname ).arg( newname );
257 op->setState( StFailed );
258 op->setProtocolDetail( msg );
259 op->setErrorCode( (int)ErrRename );
260 emit finished( op );
261 }
262}
263
264/*!
265 \reimp
266*/
267
268void QLocalFs::operationGet( QNetworkOperation *op )
269{
270#ifdef QLOCALFS_DEBUG
271 qDebug( "QLocalFs: operationGet" );
272#endif
273 op->setState( StInProgress );
274 QString from = QUrl( op->arg( 0 ) ).path();
275
276 QFile f( from );
277 if ( !f.open( IO_ReadOnly ) ) {
278#ifdef QLOCALFS_DEBUG
279 qDebug( "QLocalFs: could not open %s", from.latin1() );
280#endif
281 QString msg = tr( "Could not open\n%1" ).arg( from );
282 op->setState( StFailed );
283 op->setProtocolDetail( msg );
284 op->setErrorCode( (int)ErrGet );
285 emit finished( op );
286 return;
287 }
288
289 QByteArray s;
290 emit dataTransferProgress( 0, f.size(), op );
291 if ( f.size() != 0 ) {
292 int blockSize = calcBlockSize( f.size() );
293 if ( (int)f.size() < blockSize ) {
294 s.resize( f.size() );
295 f.readBlock( s.data(), f.size() );
296 emit data( s, op );
297 emit dataTransferProgress( f.size(), f.size(), op );
298#ifdef QLOCALFS_DEBUG
299 qDebug( "QLocalFs: got all %d bytes at once", f.size() );
300#endif
301 } else {
302 s.resize( blockSize );
303 int remaining = f.size();
304 while ( remaining > 0 ) {
305 if ( operationInProgress() != op )
306 return;
307 if ( remaining >= blockSize ) {
308 f.readBlock( s.data(), blockSize );
309 emit data( s, op );
310 emit dataTransferProgress( f.size() - remaining, f.size(), op );
311 remaining -= blockSize;
312 } else {
313 s.resize( remaining );
314 f.readBlock( s.data(), remaining );
315 emit data( s, op );
316 emit dataTransferProgress( f.size() - remaining, f.size(), op );
317 remaining -= remaining;
318 }
319 qApp->processEvents();
320 }
321#ifdef QLOCALFS_DEBUG
322 qDebug( "QLocalFs: got all %d bytes step by step", f.size() );
323#endif
324 emit dataTransferProgress( f.size(), f.size(), op );
325 }
326 }
327 op->setState( StDone );
328 f.close();
329 emit finished( op );
330}
331
332/*!
333 \reimp
334*/
335
336void QLocalFs::operationPut( QNetworkOperation *op )
337{
338#ifdef QLOCALFS_DEBUG
339 qDebug( "QLocalFs: operationPut" );
340#endif
341 op->setState( StInProgress );
342 QString to = QUrl( op->arg( 0 ) ).path();
343
344 QFile f( to );
345 if ( !f.open( IO_WriteOnly ) ) {
346 QString msg = tr( "Could not write\n%1" ).arg( to );
347 op->setState( StFailed );
348 op->setProtocolDetail( msg );
349 op->setErrorCode( (int)ErrPut );
350 emit finished( op );
351 return;
352 }
353
354 QByteArray ba( op->rawArg( 1 ) );
355 emit dataTransferProgress( 0, ba.size(), op );
356 int blockSize = calcBlockSize( ba.size() );
357 if ( (int)ba.size() < blockSize ) {
358 f.writeBlock( ba.data(), ba.size() );
359 emit dataTransferProgress( ba.size(), ba.size(), op );
360 } else {
361 int i = 0;
362 while ( i + blockSize < (int)ba.size() - 1 ) {
363 if ( operationInProgress() != op )
364 return;
365 f.writeBlock( &ba.data()[ i ], blockSize );
366 f.flush();
367 emit dataTransferProgress( i + blockSize, ba.size(), op );
368 i += blockSize;
369 qApp->processEvents();
370 }
371 if ( i < (int)ba.size() - 1 )
372 f.writeBlock( &ba.data()[ i ], ba.size() - i );
373 emit dataTransferProgress( ba.size(), ba.size(), op );
374 }
375 op->setState( StDone );
376 f.close();
377 emit finished( op );
378}
379
380/*!
381 \reimp
382*/
383
384int QLocalFs::supportedOperations() const
385{
386 return OpListChildren | OpMkDir | OpRemove | OpRename | OpGet | OpPut;
387}
388
389/*!
390 \internal
391*/
392
393int QLocalFs::calcBlockSize( int totalSize ) const
394{
395 if ( totalSize == 0 )
396 return 1024;
397 int s = totalSize / 100;
398 // we want a block size between 1KB and 1MB
399 if ( s < 1024 )
400 s = 1024;
401 if ( s > 1048576 )
402 s = 1048576;
403 return s;
404}
405
406#endif // QT_NO_NETWORKPROTOCOL
Note: See TracBrowser for help on using the repository browser.