source: vendor/trolltech/current/src/kernel/qlocalfs.cpp

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

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 10.8 KB
Line 
1/****************************************************************************
2** $Id: qlocalfs.cpp 2 2005-11-16 15:49:26Z 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 }
158 emit newChildren( infos, op );
159 op->setState( StDone );
160 emit finished( op );
161}
162
163/*!
164 \reimp
165*/
166
167void QLocalFs::operationMkDir( QNetworkOperation *op )
168{
169#ifdef QLOCALFS_DEBUG
170 qDebug( "QLocalFs: operationMkDir" );
171#endif
172 op->setState( StInProgress );
173 QString dirname = op->arg( 0 );
174
175 dir = QDir( url()->path() );
176 if ( dir.mkdir( dirname ) ) {
177 QFileInfo fi( dir, dirname );
178 QUrlInfo inf( fi.fileName(), convertPermissions(&fi), fi.owner(), fi.group(),
179 fi.size(), fi.lastModified(), fi.lastRead(), fi.isDir(), fi.isFile(),
180 fi.isSymLink(), fi.isWritable(), fi.isReadable(), fi.isExecutable() );
181 emit newChild( inf, op );
182 op->setState( StDone );
183 emit createdDirectory( inf, op );
184 emit finished( op );
185 } else {
186 QString msg = tr( "Could not create directory\n%1" ).arg( dirname );
187 op->setState( StFailed );
188 op->setProtocolDetail( msg );
189 op->setErrorCode( (int)ErrMkDir );
190 emit finished( op );
191 }
192}
193
194/*!
195 \reimp
196*/
197
198void QLocalFs::operationRemove( QNetworkOperation *op )
199{
200#ifdef QLOCALFS_DEBUG
201 qDebug( "QLocalFs: operationRemove" );
202#endif
203 op->setState( StInProgress );
204 QString name = QUrl( op->arg( 0 ) ).path();
205 bool deleted = FALSE;
206
207 dir = QDir( url()->path() );
208
209 QFileInfo fi( dir, name );
210 if ( fi.isDir() ) {
211 if ( dir.rmdir( name ) )
212 deleted = TRUE;
213 }
214
215 if ( deleted || dir.remove( name ) ) {
216 op->setState( StDone );
217 emit removed( op );
218 emit finished( op );
219 } else {
220 QString msg = tr( "Could not remove file or directory\n%1" ).arg( name );
221 op->setState( StFailed );
222 op->setProtocolDetail( msg );
223 op->setErrorCode( (int)ErrRemove );
224 emit finished( op );
225 }
226}
227
228/*!
229 \reimp
230*/
231
232void QLocalFs::operationRename( QNetworkOperation *op )
233{
234#ifdef QLOCALFS_DEBUG
235 qDebug( "QLocalFs: operationRename" );
236#endif
237 op->setState( StInProgress );
238 QString oldname = op->arg( 0 );
239 QString newname = op->arg( 1 );
240
241 dir = QDir( url()->path() );
242 if ( dir.rename( oldname, newname ) ) {
243 op->setState( StDone );
244 emit itemChanged( op );
245 emit finished( op );
246 } else {
247 QString msg = tr( "Could not rename\n%1\nto\n%2" ).arg( oldname ).arg( newname );
248 op->setState( StFailed );
249 op->setProtocolDetail( msg );
250 op->setErrorCode( (int)ErrRename );
251 emit finished( op );
252 }
253}
254
255/*!
256 \reimp
257*/
258
259void QLocalFs::operationGet( QNetworkOperation *op )
260{
261#ifdef QLOCALFS_DEBUG
262 qDebug( "QLocalFs: operationGet" );
263#endif
264 op->setState( StInProgress );
265 QString from = QUrl( op->arg( 0 ) ).path();
266
267 QFile f( from );
268 if ( !f.open( IO_ReadOnly ) ) {
269#ifdef QLOCALFS_DEBUG
270 qDebug( "QLocalFs: could not open %s", from.latin1() );
271#endif
272 QString msg = tr( "Could not open\n%1" ).arg( from );
273 op->setState( StFailed );
274 op->setProtocolDetail( msg );
275 op->setErrorCode( (int)ErrGet );
276 emit finished( op );
277 return;
278 }
279
280 QByteArray s;
281 emit dataTransferProgress( 0, f.size(), op );
282 if ( f.size() != 0 ) {
283 int blockSize = calcBlockSize( f.size() );
284 if ( (int)f.size() < blockSize ) {
285 s.resize( f.size() );
286 f.readBlock( s.data(), f.size() );
287 emit data( s, op );
288 emit dataTransferProgress( f.size(), f.size(), op );
289#ifdef QLOCALFS_DEBUG
290 qDebug( "QLocalFs: got all %d bytes at once", f.size() );
291#endif
292 } else {
293 s.resize( blockSize );
294 int remaining = f.size();
295 while ( remaining > 0 ) {
296 if ( operationInProgress() != op )
297 return;
298 if ( remaining >= blockSize ) {
299 f.readBlock( s.data(), blockSize );
300 emit data( s, op );
301 emit dataTransferProgress( f.size() - remaining, f.size(), op );
302 remaining -= blockSize;
303 } else {
304 s.resize( remaining );
305 f.readBlock( s.data(), remaining );
306 emit data( s, op );
307 emit dataTransferProgress( f.size() - remaining, f.size(), op );
308 remaining -= remaining;
309 }
310 qApp->processEvents();
311 }
312#ifdef QLOCALFS_DEBUG
313 qDebug( "QLocalFs: got all %d bytes step by step", f.size() );
314#endif
315 emit dataTransferProgress( f.size(), f.size(), op );
316 }
317 }
318 op->setState( StDone );
319 f.close();
320 emit finished( op );
321}
322
323/*!
324 \reimp
325*/
326
327void QLocalFs::operationPut( QNetworkOperation *op )
328{
329#ifdef QLOCALFS_DEBUG
330 qDebug( "QLocalFs: operationPut" );
331#endif
332 op->setState( StInProgress );
333 QString to = QUrl( op->arg( 0 ) ).path();
334
335 QFile f( to );
336 if ( !f.open( IO_WriteOnly ) ) {
337 QString msg = tr( "Could not write\n%1" ).arg( to );
338 op->setState( StFailed );
339 op->setProtocolDetail( msg );
340 op->setErrorCode( (int)ErrPut );
341 emit finished( op );
342 return;
343 }
344
345 QByteArray ba( op->rawArg( 1 ) );
346 emit dataTransferProgress( 0, ba.size(), op );
347 int blockSize = calcBlockSize( ba.size() );
348 if ( (int)ba.size() < blockSize ) {
349 f.writeBlock( ba.data(), ba.size() );
350 emit dataTransferProgress( ba.size(), ba.size(), op );
351 } else {
352 int i = 0;
353 while ( i + blockSize < (int)ba.size() - 1 ) {
354 if ( operationInProgress() != op )
355 return;
356 f.writeBlock( &ba.data()[ i ], blockSize );
357 f.flush();
358 emit dataTransferProgress( i + blockSize, ba.size(), op );
359 i += blockSize;
360 qApp->processEvents();
361 }
362 if ( i < (int)ba.size() - 1 )
363 f.writeBlock( &ba.data()[ i ], ba.size() - i );
364 emit dataTransferProgress( ba.size(), ba.size(), op );
365 }
366 op->setState( StDone );
367 f.close();
368 emit finished( op );
369}
370
371/*!
372 \reimp
373*/
374
375int QLocalFs::supportedOperations() const
376{
377 return OpListChildren | OpMkDir | OpRemove | OpRename | OpGet | OpPut;
378}
379
380/*!
381 \internal
382*/
383
384int QLocalFs::calcBlockSize( int totalSize ) const
385{
386 if ( totalSize == 0 )
387 return 1024;
388 int s = totalSize / 100;
389 // we want a block size between 1KB and 1MB
390 if ( s < 1024 )
391 s = 1024;
392 if ( s > 1048576 )
393 s = 1048576;
394 return s;
395}
396
397#endif // QT_NO_NETWORKPROTOCOL
Note: See TracBrowser for help on using the repository browser.