1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | /* |
3 | * This file is part of the LibreOffice project. |
4 | * |
5 | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | * |
9 | * This file incorporates work covered by the following license notice: |
10 | * |
11 | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | * contributor license agreements. See the NOTICE file distributed |
13 | * with this work for additional information regarding copyright |
14 | * ownership. The ASF licenses this file to you under the Apache |
15 | * License, Version 2.0 (the "License"); you may not use this file |
16 | * except in compliance with the License. You may obtain a copy of |
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | */ |
19 | |
20 | #ifndef INCLUDED_OSL_FILE_HXX |
21 | #define INCLUDED_OSL_FILE_HXX |
22 | |
23 | #include <sal/config.h> |
24 | |
25 | #include <string.h> |
26 | |
27 | #include <cassert> |
28 | |
29 | #include <osl/time.h> |
30 | #include <rtl/ustring.hxx> |
31 | |
32 | #include <osl/file.h> |
33 | #include <rtl/byteseq.hxx> |
34 | |
35 | #include <stdio.h> |
36 | |
37 | namespace osl |
38 | { |
39 | |
40 | |
41 | // ----------------------------------------------------------------------------- |
42 | /** Base class for all File System specific objects. |
43 | |
44 | @see Directory |
45 | @see DirectoryItem |
46 | @see File |
47 | */ |
48 | |
49 | class FileBase |
50 | { |
51 | public: |
52 | |
53 | enum RC { |
54 | E_None = osl_File_E_None, |
55 | E_PERM = osl_File_E_PERM, |
56 | E_NOENT = osl_File_E_NOENT, |
57 | E_SRCH = osl_File_E_SRCH, |
58 | E_INTR = osl_File_E_INTR, |
59 | E_IO = osl_File_E_IO, |
60 | E_NXIO = osl_File_E_NXIO, |
61 | E_2BIG = osl_File_E_2BIG, |
62 | E_NOEXEC = osl_File_E_NOEXEC, |
63 | E_BADF = osl_File_E_BADF, |
64 | E_CHILD = osl_File_E_CHILD, |
65 | E_AGAIN = osl_File_E_AGAIN, |
66 | E_NOMEM = osl_File_E_NOMEM, |
67 | E_ACCES = osl_File_E_ACCES, |
68 | E_FAULT = osl_File_E_FAULT, |
69 | E_BUSY = osl_File_E_BUSY, |
70 | E_EXIST = osl_File_E_EXIST, |
71 | E_XDEV = osl_File_E_XDEV, |
72 | E_NODEV = osl_File_E_NODEV, |
73 | E_NOTDIR = osl_File_E_NOTDIR, |
74 | E_ISDIR = osl_File_E_ISDIR, |
75 | E_INVAL = osl_File_E_INVAL, |
76 | E_NFILE = osl_File_E_NFILE, |
77 | E_MFILE = osl_File_E_MFILE, |
78 | E_NOTTY = osl_File_E_NOTTY, |
79 | E_FBIG = osl_File_E_FBIG, |
80 | E_NOSPC = osl_File_E_NOSPC, |
81 | E_SPIPE = osl_File_E_SPIPE, |
82 | E_ROFS = osl_File_E_ROFS, |
83 | E_MLINK = osl_File_E_MLINK, |
84 | E_PIPE = osl_File_E_PIPE, |
85 | E_DOM = osl_File_E_DOM, |
86 | E_RANGE = osl_File_E_RANGE, |
87 | E_DEADLK = osl_File_E_DEADLK, |
88 | E_NAMETOOLONG = osl_File_E_NAMETOOLONG, |
89 | E_NOLCK = osl_File_E_NOLCK, |
90 | E_NOSYS = osl_File_E_NOSYS, |
91 | E_NOTEMPTY = osl_File_E_NOTEMPTY, |
92 | E_LOOP = osl_File_E_LOOP, |
93 | E_ILSEQ = osl_File_E_ILSEQ, |
94 | E_NOLINK = osl_File_E_NOLINK, |
95 | E_MULTIHOP = osl_File_E_MULTIHOP, |
96 | E_USERS = osl_File_E_USERS, |
97 | E_OVERFLOW = osl_File_E_OVERFLOW, |
98 | E_NOTREADY = osl_File_E_NOTREADY, |
99 | E_invalidError = osl_File_E_invalidError, /* unmapped error: always last entry in enum! */ |
100 | E_TIMEDOUT = osl_File_E_TIMEDOUT, |
101 | E_NETWORK = osl_File_E_NETWORK |
102 | }; |
103 | |
104 | |
105 | public: |
106 | |
107 | /** Determine a valid unused canonical name for a requested name. |
108 | |
109 | Determines a valid unused canonical name for a requested name. |
110 | Depending on the Operating System and the File System the illegal characters are replaced by valid ones. |
111 | If a file or directory with the requested name already exists a new name is generated following |
112 | the common rules on the actual Operating System and File System. |
113 | |
114 | @param ustrRequestedURL [in] |
115 | Requested name of a file or directory. |
116 | |
117 | @param ustrValidURL [out] |
118 | On success receives a name which is unused and valid on the actual Operating System and |
119 | File System. |
120 | |
121 | @return |
122 | E_None on success |
123 | E_INVAL the format of the parameters was not valid |
124 | |
125 | @see DirectoryItem::getFileStatus() |
126 | */ |
127 | |
128 | static inline RC getCanonicalName( const ::rtl::OUString& ustrRequestedURL, ::rtl::OUString& ustrValidURL ) |
129 | { |
130 | return static_cast< RC >( osl_getCanonicalName( ustrRequestedURL.pData, &ustrValidURL.pData ) ); |
131 | } |
132 | |
133 | /** Convert a path relative to a given directory into an full qualified file URL. |
134 | |
135 | Convert a path relative to a given directory into an full qualified file URL. |
136 | The function resolves symbolic links if possible and path ellipses, so on success |
137 | the resulting absolute path is fully resolved. |
138 | |
139 | @param ustrBaseDirectoryURL [in] |
140 | Base directory URL to which the relative path is related to. |
141 | |
142 | @param ustrRelativeFileURL [in] |
143 | An URL of a file or directory relative to the directory path specified by ustrBaseDirectoryURL |
144 | or an absolute path. |
145 | If ustrRelativeFileURL denotes an absolute path ustrBaseDirectoryURL will be ignored. |
146 | |
147 | @param ustrAbsoluteFileURL [out] |
148 | On success it receives the full qualified absolute file URL. |
149 | |
150 | @return |
151 | E_None on success |
152 | E_INVAL the format of the parameters was not valid |
153 | E_NOMEM not enough memory for allocating structures |
154 | E_NOTDIR not a directory |
155 | E_ACCES permission denied |
156 | E_NOENT no such file or directory |
157 | E_NAMETOOLONG file name too long |
158 | E_OVERFLOW value too large for defined data type |
159 | E_FAULT bad address |
160 | E_INTR function call was interrupted |
161 | E_LOOP too many symbolic links encountered |
162 | E_MULTIHOP multihop attempted |
163 | E_NOLINK link has been severed |
164 | |
165 | @see DirectoryItem::getFileStatus() |
166 | */ |
167 | |
168 | static inline RC getAbsoluteFileURL( const ::rtl::OUString& ustrBaseDirectoryURL, const ::rtl::OUString& ustrRelativeFileURL, ::rtl::OUString& ustrAbsoluteFileURL ) |
169 | { |
170 | return static_cast< RC >( osl_getAbsoluteFileURL( ustrBaseDirectoryURL.pData, ustrRelativeFileURL.pData, &ustrAbsoluteFileURL.pData ) ); |
171 | } |
172 | |
173 | /** Convert a file URL into a system dependend path. |
174 | |
175 | @param ustrFileURL [in] |
176 | A File URL. |
177 | |
178 | @param ustrSystemPath [out] |
179 | On success it receives the system path. |
180 | |
181 | @return |
182 | E_None on success |
183 | E_INVAL the format of the parameters was not valid |
184 | |
185 | @see getFileURLFromSystemPath() |
186 | */ |
187 | |
188 | static inline RC getSystemPathFromFileURL( const ::rtl::OUString& ustrFileURL, ::rtl::OUString& ustrSystemPath ) |
189 | { |
190 | return static_cast< RC >( osl_getSystemPathFromFileURL( ustrFileURL.pData, &ustrSystemPath.pData ) ); |
191 | } |
192 | |
193 | /** Convert a system dependend path into a file URL. |
194 | |
195 | @param ustrSystemPath [in] |
196 | A System dependent path of a file or directory. |
197 | |
198 | @param ustrFileURL [out] |
199 | On success it receives the file URL. |
200 | |
201 | @return |
202 | E_None on success |
203 | E_INVAL the format of the parameters was not valid |
204 | |
205 | @see getSystemPathFromFileURL() |
206 | */ |
207 | |
208 | static inline RC getFileURLFromSystemPath( const ::rtl::OUString& ustrSystemPath, ::rtl::OUString& ustrFileURL ) |
209 | { |
210 | return static_cast< RC >( osl_getFileURLFromSystemPath( ustrSystemPath.pData, &ustrFileURL.pData ) ); |
211 | } |
212 | |
213 | /** Searche a full qualified system path or a file URL. |
214 | |
215 | @param ustrFileName [in] |
216 | A system dependent path, a file URL, a file or relative directory |
217 | |
218 | @param ustrSearchPath [in] |
219 | A list of system paths, in which a given file has to be searched. The Notation of a path list is |
220 | system dependend, e.g. on UNIX system "/usr/bin:/bin" and on Windows "C:\BIN;C:\BATCH". |
221 | These paths are only for the search of a file or a relative path, otherwise it will be ignored. |
222 | If ustrSearchPath is NULL or while using the search path the search failed, the function searches for |
223 | a matching file in all system directories and in the directories listed in the PATH environment |
224 | variable. |
225 | The value of an environment variable should be used (e.g. LD_LIBRARY_PATH) if the caller is not |
226 | aware of the Operating System and so doesn't know which path list delimiter to use. |
227 | |
228 | @param ustrFileURL [out] |
229 | On success it receives the full qualified file URL. |
230 | |
231 | @return |
232 | E_None on success |
233 | E_INVAL the format of the parameters was not valid |
234 | E_NOTDIR not a directory |
235 | E_NOENT no such file or directory not found |
236 | |
237 | @see getFileURLFromSystemPath() |
238 | @see getSystemPathFromFileURL() |
239 | */ |
240 | |
241 | static inline RC searchFileURL( const ::rtl::OUString& ustrFileName, const ::rtl::OUString& ustrSearchPath, ::rtl::OUString& ustrFileURL ) |
242 | { |
243 | return static_cast< RC >( osl_searchFileURL( ustrFileName.pData, ustrSearchPath.pData, &ustrFileURL.pData ) ); |
244 | } |
245 | |
246 | /** Retrieves the file URL of the system's temporary directory path. |
247 | |
248 | @param[out] ustrTempDirURL |
249 | On success receives the URL of system's temporary directory path. |
250 | |
251 | @return |
252 | E_None on success |
253 | E_NOENT no such file or directory not found |
254 | */ |
255 | |
256 | static inline RC getTempDirURL( ::rtl::OUString& ustrTempDirURL ) |
257 | { |
258 | return static_cast< RC >( osl_getTempDirURL( &ustrTempDirURL.pData ) ); |
259 | } |
260 | |
261 | /** Creates a temporary file in the directory provided by the caller or the |
262 | directory returned by getTempDirURL. |
263 | Under UNIX Operating Systems the file will be created with read and write |
264 | access for the user exclusively. |
265 | If the caller requests only a handle to the open file but not the name of |
266 | it, the file will be automatically removed on close else the caller is |
267 | responsible for removing the file on success.<br><br> |
268 | |
269 | @param pustrDirectoryURL [in] |
270 | Specifies the full qualified URL where the temporary file should be created. |
271 | If pustrDirectoryURL is 0 the path returned by osl_getTempDirURL will be used. |
272 | |
273 | @param pHandle [out] |
274 | On success receives a handle to the open file. |
275 | If pHandle is 0 the file will be closed on return, in this case |
276 | pustrTempFileURL must not be 0. |
277 | |
278 | @param pustrTempFileURL [out] |
279 | On success receives the full qualified URL of the temporary file. |
280 | If pustrTempFileURL is 0 the file will be automatically removed |
281 | on close, in this case pHandle must not be 0. |
282 | If pustrTempFileURL is not 0 the caller receives the name of the |
283 | created file and is responsible for removing the file. |
284 | |
285 | Description of the different pHandle, ppustrTempFileURL parameter combinations. |
286 | pHandle is 0 and pustrTempDirURL is 0 - this combination is invalid<br> |
287 | pHandle is not 0 and pustrTempDirURL is 0 - a handle to the open file |
288 | will be returned on success and the file will be automatically removed on close<br> |
289 | pHandle is 0 and pustrTempDirURL is not 0 - the name of the file will be |
290 | returned, the caller is responsible for opening, closing and removing the file.<br> |
291 | pHandle is not 0 and pustrTempDirURL is not 0 - a handle to the open file as well as |
292 | the file name will be returned, the caller is responsible for closing and removing |
293 | the file.<br> |
294 | |
295 | @return |
296 | E_None on success |
297 | E_INVAL the format of the parameter is invalid |
298 | E_NOMEM not enough memory for allocating structures |
299 | E_ACCES Permission denied |
300 | E_NOENT No such file or directory |
301 | E_NOTDIR Not a directory |
302 | E_ROFS Read-only file system |
303 | E_NOSPC No space left on device |
304 | E_DQUOT Quota exceeded |
305 | |
306 | @see getTempDirURL() |
307 | */ |
308 | |
309 | static inline RC createTempFile( |
310 | ::rtl::OUString* pustrDirectoryURL, |
311 | oslFileHandle* pHandle, |
312 | ::rtl::OUString* pustrTempFileURL) |
313 | { |
314 | rtl_uString* pustr_dir_url = pustrDirectoryURL ? pustrDirectoryURL->pData : 0; |
315 | rtl_uString** ppustr_tmp_file_url = pustrTempFileURL ? &pustrTempFileURL->pData : 0; |
316 | |
317 | return static_cast< RC >( osl_createTempFile(pustr_dir_url, pHandle, ppustr_tmp_file_url) ); |
318 | } |
319 | }; |
320 | |
321 | |
322 | // ----------------------------------------------------------------------------- |
323 | /** The VolumeDevice class. |
324 | |
325 | @see VolumeInfo |
326 | */ |
327 | |
328 | class VolumeDevice : public FileBase |
329 | { |
330 | oslVolumeDeviceHandle _aHandle; |
331 | |
332 | public: |
333 | |
334 | /** Constructor. |
335 | */ |
336 | |
337 | VolumeDevice() : _aHandle( NULL ) |
338 | { |
339 | } |
340 | |
341 | /** Copy constructor. |
342 | |
343 | @param rDevice |
344 | The other volume device. |
345 | */ |
346 | |
347 | VolumeDevice( const VolumeDevice & rDevice ) |
348 | { |
349 | _aHandle = rDevice._aHandle; |
350 | if ( _aHandle ) |
351 | osl_acquireVolumeDeviceHandle( _aHandle ); |
352 | } |
353 | |
354 | /** Destructor. |
355 | */ |
356 | |
357 | ~VolumeDevice() |
358 | { |
359 | if ( _aHandle ) |
360 | osl_releaseVolumeDeviceHandle( _aHandle ); |
361 | } |
362 | |
363 | /** Assignment operator. |
364 | |
365 | @param rDevice |
366 | The other volume device. |
367 | */ |
368 | |
369 | inline VolumeDevice & operator =( const VolumeDevice & rDevice ) |
370 | { |
371 | oslVolumeDeviceHandle newHandle = rDevice._aHandle; |
372 | |
373 | if ( newHandle ) |
374 | osl_acquireVolumeDeviceHandle( newHandle ); |
375 | |
376 | if ( _aHandle ) |
377 | osl_releaseVolumeDeviceHandle( _aHandle ); |
378 | |
379 | _aHandle = newHandle; |
380 | |
381 | return *this; |
382 | } |
383 | |
384 | /** Get the full qualified URL where a device is mounted to. |
385 | |
386 | @return |
387 | The full qualified URL where the device is mounted to. |
388 | */ |
389 | inline rtl::OUString getMountPath() |
390 | { |
391 | rtl::OUString aPath; |
392 | osl_getVolumeDeviceMountPath( _aHandle, &aPath.pData ); |
393 | return aPath; |
394 | } |
395 | |
396 | friend class VolumeInfo; |
397 | }; |
398 | |
399 | // ----------------------------------------------------------------------------- |
400 | |
401 | class Directory; |
402 | |
403 | /** The VolumeInfo class. |
404 | |
405 | Neither copy nor assignment is allowed for this class. |
406 | |
407 | @see Directory::getVolumeInfo |
408 | */ |
409 | |
410 | |
411 | class VolumeInfo |
412 | { |
413 | oslVolumeInfo _aInfo; |
414 | sal_uInt32 _nMask; |
415 | VolumeDevice _aDevice; |
416 | |
417 | /** Copy constructor. |
418 | */ |
419 | |
420 | VolumeInfo( VolumeInfo& ); |
421 | |
422 | /** Assginment operator. |
423 | */ |
424 | |
425 | VolumeInfo& operator = ( VolumeInfo& ); |
426 | |
427 | public: |
428 | |
429 | /** Constructor. |
430 | |
431 | @param nMask |
432 | Set of flags decribing the demanded information. |
433 | */ |
434 | |
435 | VolumeInfo( sal_uInt32 nMask ): _nMask( nMask ) |
436 | { |
437 | _aInfo.uStructSize = sizeof( oslVolumeInfo ); |
438 | memset( &_aInfo.uValidFields, 0, sizeof( oslVolumeInfo ) - sizeof( sal_uInt32 ) ); |
439 | _aInfo.pDeviceHandle = &_aDevice._aHandle; |
440 | } |
441 | |
442 | /** Destructor. |
443 | */ |
444 | |
445 | ~VolumeInfo() |
446 | { |
447 | if( _aInfo.ustrFileSystemName ) |
448 | rtl_uString_release( _aInfo.ustrFileSystemName ); |
449 | } |
450 | |
451 | /** Check if specified fields are valid. |
452 | |
453 | @param nMask |
454 | Set of flags for the fields to check. |
455 | |
456 | @return true if all fields are valid else false. |
457 | */ |
458 | |
459 | inline bool isValid( sal_uInt32 nMask ) const |
460 | { |
461 | return ( nMask & _aInfo.uValidFields ) == nMask; |
462 | } |
463 | |
464 | /** Check the remote flag. |
465 | |
466 | @return |
467 | true if Attributes are valid and the volume is remote else false. |
468 | */ |
469 | |
470 | inline bool getRemoteFlag() const |
471 | { |
472 | return 0 != (_aInfo.uAttributes & osl_Volume_Attribute_Remote); |
473 | } |
474 | |
475 | /** Check the removeable flag. |
476 | |
477 | @return |
478 | true if attributes are valid and the volume is removable else false. |
479 | */ |
480 | |
481 | inline bool getRemoveableFlag() const |
482 | { |
483 | return 0 != (_aInfo.uAttributes & osl_Volume_Attribute_Removeable); |
484 | } |
485 | |
486 | /** Check the compact disc flag. |
487 | |
488 | @return |
489 | true if attributes are valid and the volume is a CDROM else false. |
490 | */ |
491 | |
492 | inline bool getCompactDiscFlag() const |
493 | { |
494 | return 0 != (_aInfo.uAttributes & osl_Volume_Attribute_CompactDisc); |
495 | } |
496 | |
497 | /** Check the floppy disc flag. |
498 | |
499 | @return |
500 | true if attributes are valid and the volume is a floppy disk else false. |
501 | */ |
502 | |
503 | inline bool getFloppyDiskFlag() const |
504 | { |
505 | return 0 != (_aInfo.uAttributes & osl_Volume_Attribute_FloppyDisk); |
506 | } |
507 | |
508 | /** Check the fixed disk flag. |
509 | |
510 | @return |
511 | true if attributes are valid and the volume is a fixed disk else false. |
512 | */ |
513 | |
514 | inline bool getFixedDiskFlag() const |
515 | { |
516 | return 0 != (_aInfo.uAttributes & osl_Volume_Attribute_FixedDisk); |
517 | } |
518 | |
519 | /** Check the RAM disk flag. |
520 | |
521 | @return |
522 | true if attributes are valid and the volume is a RAM disk else false. |
523 | */ |
524 | |
525 | inline bool getRAMDiskFlag() const |
526 | { |
527 | return 0 != (_aInfo.uAttributes & osl_Volume_Attribute_RAMDisk); |
528 | } |
529 | |
530 | /** Determine the total space of a volume device. |
531 | |
532 | @return |
533 | The total diskspace of this volume if this information is valid, |
534 | 0 otherwise. |
535 | */ |
536 | |
537 | inline sal_uInt64 getTotalSpace() const |
538 | { |
539 | return _aInfo.uTotalSpace; |
540 | } |
541 | |
542 | /** Determine the free space of a volume device. |
543 | |
544 | @return |
545 | The free diskspace of this volume if this information is valid, |
546 | 0 otherwise. |
547 | */ |
548 | |
549 | inline sal_uInt64 getFreeSpace() const |
550 | { |
551 | return _aInfo.uFreeSpace; |
552 | } |
553 | |
554 | /** Determine the used space of a volume device. |
555 | |
556 | @return |
557 | The used diskspace of this volume if this information is valid, |
558 | 0 otherwise. |
559 | */ |
560 | |
561 | inline sal_uInt64 getUsedSpace() const |
562 | { |
563 | return _aInfo.uUsedSpace; |
564 | } |
565 | |
566 | /** Determine the maximal length of a file name. |
567 | |
568 | @return |
569 | The maximal length of a file name if this information is valid, |
570 | 0 otherwise. |
571 | */ |
572 | |
573 | inline sal_uInt32 getMaxNameLength() const |
574 | { |
575 | return _aInfo.uMaxNameLength; |
576 | } |
577 | |
578 | /** Determine the maximal length of a path name. |
579 | |
580 | @return |
581 | The maximal length of a path if this information is valid, |
582 | 0 otherwise. |
583 | */ |
584 | |
585 | inline sal_uInt32 getMaxPathLength() const |
586 | { |
587 | return _aInfo.uMaxPathLength; |
588 | } |
589 | |
590 | /** Determine the name of the volume device's File System. |
591 | |
592 | @return |
593 | The name of the volume's fielsystem if this information is valid, |
594 | otherwise an empty string. |
595 | */ |
596 | |
597 | inline ::rtl::OUString getFileSystemName() const |
598 | { |
599 | return _aInfo.ustrFileSystemName ? ::rtl::OUString( _aInfo.ustrFileSystemName ) : ::rtl::OUString(); |
600 | } |
601 | |
602 | |
603 | /** Get the volume device handle. |
604 | |
605 | @return |
606 | The device handle of the volume if this information is valid, |
607 | otherwise returns NULL; |
608 | */ |
609 | |
610 | inline VolumeDevice getDeviceHandle() const |
611 | { |
612 | return _aDevice; |
613 | } |
614 | |
615 | /** Return whether the file system is case sensitive or |
616 | case insensitive |
617 | |
618 | @return |
619 | true if the file system is case sensitive false otherwise |
620 | */ |
621 | bool isCaseSensitiveFileSystem() const |
622 | { |
623 | return (_aInfo.uAttributes & osl_Volume_Attribute_Case_Sensitive); |
624 | } |
625 | |
626 | /** Return whether the file system preserves the case of |
627 | file and directory names or not |
628 | |
629 | @return |
630 | true if the file system preserves the case of file and |
631 | directory names false otherwise |
632 | */ |
633 | bool isCasePreservingFileSystem() const |
634 | { |
635 | return (_aInfo.uAttributes & osl_Volume_Attribute_Case_Is_Preserved); |
636 | } |
637 | |
638 | friend class Directory; |
639 | }; |
640 | |
641 | // ----------------------------------------------------------------------------- |
642 | class DirectoryItem; |
643 | |
644 | /** The FileStatus class. |
645 | |
646 | @see DirectoryItem::getFileStatus |
647 | */ |
648 | |
649 | class FileStatus |
650 | { |
651 | oslFileStatus _aStatus; |
652 | sal_uInt32 _nMask; |
653 | |
654 | /** Copy constructor. |
655 | */ |
656 | |
657 | FileStatus( FileStatus& ); |
658 | |
659 | /** Assignment operator. |
660 | */ |
661 | |
662 | FileStatus& operator = ( FileStatus& ); |
663 | |
664 | public: |
665 | |
666 | enum Type { |
667 | Directory = osl_File_Type_Directory, |
668 | Volume = osl_File_Type_Volume, |
669 | Regular = osl_File_Type_Regular, |
670 | Fifo = osl_File_Type_Fifo, |
671 | Socket = osl_File_Type_Socket, |
672 | Link = osl_File_Type_Link, |
673 | Special = osl_File_Type_Special, |
674 | Unknown = osl_File_Type_Unknown |
675 | }; |
676 | |
677 | /** Constructor. |
678 | |
679 | @param nMask |
680 | Set of flags decribing the demanded information. |
681 | */ |
682 | |
683 | FileStatus( sal_uInt32 nMask ): _nMask( nMask ) |
684 | { |
685 | _aStatus.uStructSize = sizeof( oslFileStatus ); |
686 | memset( &_aStatus.uValidFields, 0, sizeof( oslFileStatus ) - sizeof( sal_uInt32 ) ); |
687 | } |
688 | |
689 | /** Destructor. |
690 | */ |
691 | |
692 | ~FileStatus() |
693 | { |
694 | if ( _aStatus.ustrFileURL ) |
695 | rtl_uString_release( _aStatus.ustrFileURL ); |
696 | if ( _aStatus.ustrLinkTargetURL ) |
697 | rtl_uString_release( _aStatus.ustrLinkTargetURL ); |
698 | if ( _aStatus.ustrFileName ) |
699 | rtl_uString_release( _aStatus.ustrFileName ); |
700 | } |
701 | |
702 | /** Check if specified fields are valid. |
703 | |
704 | @param nMask |
705 | Set of flags for the fields to check. |
706 | |
707 | @return |
708 | true if all fields are valid else false. |
709 | */ |
710 | |
711 | inline bool isValid( sal_uInt32 nMask ) const |
712 | { |
713 | return ( nMask & _aStatus.uValidFields ) == nMask; |
714 | } |
715 | |
716 | /** Get the file type. |
717 | |
718 | @return |
719 | The file type. |
720 | */ |
721 | inline Type getFileType() const |
722 | { |
723 | SAL_INFO_IF( |
724 | !isValid(osl_FileStatus_Mask_Type), "sal.osl" , |
725 | "no FileStatus Type determined" ); |
726 | return isValid(osl_FileStatus_Mask_Type) |
727 | ? static_cast< Type >(_aStatus.eType) : Unknown; |
728 | } |
729 | |
730 | /** Is it a directory? |
731 | This method returns True for both directories, and volumes. |
732 | |
733 | @return |
734 | True if it's a directory, False otherwise. |
735 | |
736 | @see getFileType |
737 | @since LibreOffice 3.6 |
738 | */ |
739 | inline bool isDirectory() const |
740 | { |
741 | return ( getFileType() == Directory || getFileType() == Volume ); |
742 | } |
743 | |
744 | /** Is it a regular file? |
745 | |
746 | @return |
747 | True if it's a regular file, False otherwise. |
748 | |
749 | @see getFileType |
750 | @see isFile |
751 | @see isLink |
752 | @since LibreOffice 3.6 |
753 | */ |
754 | inline bool isRegular() const |
755 | { |
756 | return ( getFileType() == Regular ); |
757 | } |
758 | |
759 | /** Is it a link? |
760 | |
761 | @return |
762 | True if it's a link, False otherwise. |
763 | |
764 | @see getFileType |
765 | @since LibreOffice 3.6 |
766 | */ |
767 | inline bool isLink() const |
768 | { |
769 | return ( getFileType() == Link ); |
770 | } |
771 | |
772 | /** Get the file attributes. |
773 | |
774 | @return |
775 | The set of attribute flags of this file. |
776 | */ |
777 | |
778 | inline sal_uInt64 getAttributes() const |
779 | { |
780 | SAL_INFO_IF( |
781 | !isValid(osl_FileStatus_Mask_Attributes), "sal.osl" , |
782 | "no FileStatus Attributes determined" ); |
783 | return _aStatus.uAttributes; |
784 | } |
785 | |
786 | /** Get the creation time of this file. |
787 | |
788 | @return |
789 | The creation time if this information is valid, an uninitialized |
790 | TimeValue otherwise. |
791 | */ |
792 | |
793 | inline TimeValue getCreationTime() const |
794 | { |
795 | SAL_INFO_IF( |
796 | !isValid(osl_FileStatus_Mask_CreationTime), "sal.osl" , |
797 | "no FileStatus CreationTime determined" ); |
798 | return _aStatus.aCreationTime; |
799 | } |
800 | |
801 | /** Get the file access time. |
802 | |
803 | @return |
804 | The last access time if this information is valid, an uninitialized |
805 | TimeValue otherwise. |
806 | */ |
807 | |
808 | inline TimeValue getAccessTime() const |
809 | { |
810 | SAL_INFO_IF( |
811 | !isValid(osl_FileStatus_Mask_AccessTime), "sal.osl" , |
812 | "no FileStatus AccessTime determined" ); |
813 | return _aStatus.aAccessTime; |
814 | } |
815 | |
816 | /** Get the file modification time. |
817 | |
818 | @return |
819 | The last modified time if this information is valid, an uninitialized |
820 | TimeValue otherwise. |
821 | */ |
822 | |
823 | inline TimeValue getModifyTime() const |
824 | { |
825 | SAL_INFO_IF( |
826 | !isValid(osl_FileStatus_Mask_ModifyTime), "sal.osl" , |
827 | "no FileStatus ModifyTime determined" ); |
828 | return _aStatus.aModifyTime; |
829 | } |
830 | |
831 | /** Get the size of the file. |
832 | |
833 | @return |
834 | The actual file size if this information is valid, 0 otherwise. |
835 | */ |
836 | |
837 | inline sal_uInt64 getFileSize() const |
838 | { |
839 | SAL_INFO_IF( |
840 | !isValid(osl_FileStatus_Mask_FileSize), "sal.osl" , |
841 | "no FileStatus FileSize determined" ); |
842 | return _aStatus.uFileSize; |
843 | } |
844 | |
845 | /** Get the file name. |
846 | |
847 | @return |
848 | The file name if this information is valid, an empty string otherwise. |
849 | */ |
850 | |
851 | inline ::rtl::OUString getFileName() const |
852 | { |
853 | SAL_INFO_IF( |
854 | !isValid(osl_FileStatus_Mask_FileName), "sal.osl" , |
855 | "no FileStatus FileName determined" ); |
856 | return isValid(osl_FileStatus_Mask_FileName) |
857 | ? rtl::OUString(_aStatus.ustrFileName) : rtl::OUString(); |
858 | } |
859 | |
860 | |
861 | /** Get the URL of the file. |
862 | |
863 | @return |
864 | The full qualified URL of the file if this information is valid, an |
865 | empty string otherwise. |
866 | */ |
867 | |
868 | inline ::rtl::OUString getFileURL() const |
869 | { |
870 | SAL_INFO_IF( |
871 | !isValid(osl_FileStatus_Mask_FileURL), "sal.osl" , |
872 | "no FileStatus FileURL determined" ); |
873 | return isValid(osl_FileStatus_Mask_FileURL) |
874 | ? rtl::OUString(_aStatus.ustrFileURL) : rtl::OUString(); |
875 | } |
876 | |
877 | /** Get the link target URL. |
878 | |
879 | @return |
880 | The link target URL if this information is valid, an empty string |
881 | otherwise. |
882 | */ |
883 | |
884 | inline ::rtl::OUString getLinkTargetURL() const |
885 | { |
886 | SAL_INFO_IF( |
887 | !isValid(osl_FileStatus_Mask_LinkTargetURL), "sal.osl" , |
888 | "no FileStatus LinkTargetURL determined" ); |
889 | return isValid(osl_FileStatus_Mask_LinkTargetURL) |
890 | ? rtl::OUString(_aStatus.ustrLinkTargetURL) : rtl::OUString(); |
891 | } |
892 | |
893 | friend class DirectoryItem; |
894 | }; |
895 | |
896 | |
897 | // ----------------------------------------------------------------------------- |
898 | /** The file class object provides access to file contents and attributes. |
899 | |
900 | @see Directory |
901 | @see DirectoryItem |
902 | */ |
903 | |
904 | class File: public FileBase |
905 | { |
906 | oslFileHandle _pData; |
907 | ::rtl::OUString _aPath; |
908 | |
909 | /** Copy constructor. |
910 | */ |
911 | |
912 | File( File& ); |
913 | |
914 | /** Assginment operator. |
915 | */ |
916 | |
917 | File& operator = ( File& ); |
918 | |
919 | public: |
920 | |
921 | /** Constructor. |
922 | |
923 | @param ustrFileURL [in] |
924 | The full qualified URL of the file. Relative paths are not allowed. |
925 | */ |
926 | |
927 | File( const ::rtl::OUString& ustrFileURL ): _pData( 0 ), _aPath( ustrFileURL ) {} |
928 | |
929 | /** Destructor |
930 | */ |
931 | |
932 | inline ~File() |
933 | { |
934 | close(); |
935 | } |
936 | |
937 | /** Obtain the URL. |
938 | |
939 | @return |
940 | the URL with which this File instance was created. |
941 | |
942 | @since LibreOffice 4.1 |
943 | */ |
944 | inline rtl::OUString getURL() const { return _aPath; } |
945 | |
946 | /** Open a regular file. |
947 | |
948 | Open a file. Only regular files can be openend. |
949 | |
950 | @param uFlags [in] |
951 | Specifies the open mode. |
952 | |
953 | @return |
954 | E_None on success |
955 | E_NOMEM not enough memory for allocating structures |
956 | E_INVAL the format of the parameters was not valid |
957 | E_NAMETOOLONG pathname was too long |
958 | E_NOENT no such file or directory |
959 | E_ACCES permission denied |
960 | E_AGAIN a write lock could not be established |
961 | E_NOTDIR not a directory |
962 | E_NXIO no such device or address |
963 | E_NODEV no such device |
964 | E_ROFS read-only file system |
965 | E_TXTBSY text file busy |
966 | E_FAULT bad address |
967 | E_LOOP too many symbolic links encountered |
968 | E_NOSPC no space left on device |
969 | E_ISDIR is a directory |
970 | E_MFILE too many open files used by the process |
971 | E_NFILE too many open files in the system |
972 | E_DQUOT quota exceeded |
973 | E_EXIST file exists |
974 | E_INTR function call was interrupted |
975 | E_IO on I/O errors |
976 | E_MULTIHOP multihop attempted |
977 | E_NOLINK link has been severed |
978 | E_EOVERFLOW value too large for defined data type |
979 | |
980 | @see close() |
981 | @see setPos() |
982 | @see getPos() |
983 | @see read() |
984 | @see write() |
985 | @see getSize() |
986 | @see setSize() |
987 | */ |
988 | |
989 | inline RC open( sal_uInt32 uFlags ) |
990 | { |
991 | return static_cast< RC >( osl_openFile( _aPath.pData, &_pData, uFlags ) ); |
992 | } |
993 | |
994 | /** Close an open file. |
995 | |
996 | @return |
997 | E_None on success |
998 | E_INVAL the format of the parameters was not valid |
999 | E_BADF Bad file |
1000 | E_INTR function call was interrupted |
1001 | E_NOLINK link has been severed |
1002 | E_NOSPC no space left on device |
1003 | E_IO on I/O errors |
1004 | |
1005 | @see open() |
1006 | */ |
1007 | |
1008 | inline RC close() |
1009 | { |
1010 | oslFileError Error = osl_File_E_BADF; |
1011 | |
1012 | if( _pData ) |
1013 | { |
1014 | Error=osl_closeFile( _pData ); |
1015 | _pData = NULL; |
1016 | } |
1017 | |
1018 | return static_cast< RC >( Error ); |
1019 | } |
1020 | |
1021 | /** Set the internal position pointer of an open file. |
1022 | |
1023 | @param uHow [in] |
1024 | Distance to move the internal position pointer (from uPos). |
1025 | |
1026 | @param uPos [in] |
1027 | Absolute position from the beginning of the file. |
1028 | |
1029 | @return |
1030 | E_None on success |
1031 | E_INVAL the format of the parameters was not valid |
1032 | E_OVERFLOW the resulting file offset would be a value which cannot be represented correctly for regular files |
1033 | |
1034 | @see open() |
1035 | @see getPos() |
1036 | */ |
1037 | |
1038 | inline RC setPos( sal_uInt32 uHow, sal_Int64 uPos ) SAL_WARN_UNUSED_RESULT |
1039 | { |
1040 | return static_cast< RC >( osl_setFilePos( _pData, uHow, uPos ) ); |
1041 | } |
1042 | |
1043 | /** Retrieve the current position of the internal pointer of an open file. |
1044 | |
1045 | @param uPos [out] |
1046 | On success receives the current position of the file pointer. |
1047 | |
1048 | @return |
1049 | E_None on success |
1050 | E_INVAL the format of the parameters was not valid |
1051 | E_OVERFLOW the resulting file offset would be a value which cannot be represented correctly for regular files |
1052 | |
1053 | @see open() |
1054 | @see setPos() |
1055 | @see read() |
1056 | @see write() |
1057 | */ |
1058 | |
1059 | inline RC getPos( sal_uInt64& uPos ) |
1060 | { |
1061 | return static_cast< RC >( osl_getFilePos( _pData, &uPos ) ); |
1062 | } |
1063 | |
1064 | /** Test if the end of a file is reached. |
1065 | |
1066 | @param pIsEOF [out] |
1067 | Points to a variable that receives the end-of-file status. |
1068 | |
1069 | @return |
1070 | E_None on success |
1071 | E_INVAL the format of the parameters was not valid |
1072 | E_INTR function call was interrupted |
1073 | E_IO on I/O errors |
1074 | E_ISDIR is a directory |
1075 | E_BADF bad file |
1076 | E_FAULT bad address |
1077 | E_AGAIN operation would block |
1078 | E_NOLINK link has been severed |
1079 | |
1080 | @see open() |
1081 | @see read() |
1082 | @see readLine() |
1083 | @see setPos() |
1084 | */ |
1085 | |
1086 | inline RC isEndOfFile( sal_Bool *pIsEOF ) |
1087 | { |
1088 | return static_cast< RC >( osl_isEndOfFile( _pData, pIsEOF ) ); |
1089 | } |
1090 | |
1091 | /** Set the file size of an open file. |
1092 | |
1093 | Sets the file size of an open file. The file can be truncated or enlarged by the function. |
1094 | The position of the file pointer is not affeced by this function. |
1095 | |
1096 | @param uSize [in] |
1097 | New size in bytes. |
1098 | |
1099 | @return |
1100 | E_None on success |
1101 | E_INVAL the format of the parameters was not valid |
1102 | E_OVERFLOW the resulting file offset would be a value which cannot be represented correctly for regular files |
1103 | |
1104 | @see open() |
1105 | @see setPos() |
1106 | @see getStatus() |
1107 | */ |
1108 | |
1109 | inline RC setSize( sal_uInt64 uSize ) |
1110 | { |
1111 | return static_cast< RC >( osl_setFileSize( _pData, uSize ) ); |
1112 | } |
1113 | |
1114 | /** Get the file size of an open file. |
1115 | |
1116 | Gets the file size of an open file. |
1117 | The position of the file pointer is not affeced by this function. |
1118 | |
1119 | @param rSize [out] |
1120 | Current size in bytes. |
1121 | |
1122 | @return |
1123 | E_None on success |
1124 | E_INVAL the format of the parameters was not valid |
1125 | E_OVERFLOW the resulting file offset would be a value which cannot be represented correctly for regular files |
1126 | |
1127 | @see open() |
1128 | @see setPos() |
1129 | @see getSize() |
1130 | @see setSize() |
1131 | @see getStatus() |
1132 | */ |
1133 | |
1134 | inline RC getSize( sal_uInt64 &rSize ) |
1135 | { |
1136 | return static_cast< RC >( osl_getFileSize( _pData, &rSize ) ); |
1137 | } |
1138 | |
1139 | /** Read a number of bytes from a file. |
1140 | |
1141 | Reads a number of bytes from a file. The internal file pointer is |
1142 | increased by the number of bytes read. |
1143 | |
1144 | @param pBuffer [out] |
1145 | Points to a buffer which receives data. The buffer must be large enough |
1146 | to hold uBytesRequested bytes. |
1147 | |
1148 | @param uBytesRequested [in] |
1149 | Number of bytes which should be retrieved. |
1150 | |
1151 | @param rBytesRead [out] |
1152 | On success the number of bytes which have actually been retrieved. |
1153 | |
1154 | @return |
1155 | E_None on success |
1156 | E_INVAL the format of the parameters was not valid |
1157 | E_INTR function call was interrupted |
1158 | E_IO on I/O errors |
1159 | E_ISDIR is a directory |
1160 | E_BADF bad file |
1161 | E_FAULT bad address |
1162 | E_AGAIN operation would block |
1163 | E_NOLINK link has been severed |
1164 | |
1165 | @see open() |
1166 | @see write() |
1167 | @see readLine() |
1168 | @see setPos() |
1169 | */ |
1170 | |
1171 | inline RC read( void *pBuffer, sal_uInt64 uBytesRequested, sal_uInt64& rBytesRead ) |
1172 | { |
1173 | return static_cast< RC >( osl_readFile( _pData, pBuffer, uBytesRequested, &rBytesRead ) ); |
1174 | } |
1175 | |
1176 | /** Write a number of bytes to a file. |
1177 | |
1178 | Writes a number of bytes to a file. |
1179 | The internal file pointer is increased by the number of bytes read. |
1180 | |
1181 | @param pBuffer [in] |
1182 | Points to a buffer which contains the data. |
1183 | |
1184 | @param uBytesToWrite [in] |
1185 | Number of bytes which should be written. |
1186 | |
1187 | @param rBytesWritten [out] |
1188 | On success the number of bytes which have actually been written. |
1189 | |
1190 | @return |
1191 | E_None on success |
1192 | E_INVAL the format of the parameters was not valid |
1193 | E_FBIG file too large |
1194 | E_DQUOT quota exceeded |
1195 | E_AGAIN operation would block |
1196 | E_BADF bad file |
1197 | E_FAULT bad address |
1198 | E_INTR function call was interrupted |
1199 | E_IO on I/O errosr |
1200 | E_NOLCK no record locks available |
1201 | E_NOLINK link has been severed |
1202 | E_NOSPC no space left on device |
1203 | E_NXIO no such device or address |
1204 | |
1205 | @see open() |
1206 | @see read() |
1207 | @see setPos() |
1208 | */ |
1209 | |
1210 | inline RC write(const void *pBuffer, sal_uInt64 uBytesToWrite, sal_uInt64& rBytesWritten) |
1211 | { |
1212 | return static_cast< RC >( osl_writeFile( _pData, pBuffer, uBytesToWrite, &rBytesWritten ) ); |
1213 | } |
1214 | |
1215 | |
1216 | /** Read a line from a file. |
1217 | |
1218 | Reads a line from a file. The new line delimiter is NOT returned! |
1219 | |
1220 | @param aSeq [in/out] |
1221 | A reference to a ::rtl::ByteSequence that will hold the line read on success. |
1222 | |
1223 | @return |
1224 | E_None on success |
1225 | E_INVAL the format of the parameters was not valid |
1226 | E_INTR function call was interrupted |
1227 | E_IO on I/O errors |
1228 | E_ISDIR is a directory |
1229 | E_BADF bad file |
1230 | E_FAULT bad address |
1231 | E_AGAIN operation would block |
1232 | E_NOLINK link has been severed |
1233 | |
1234 | @see open() |
1235 | @see read() |
1236 | @see write() |
1237 | @see setPos() |
1238 | */ |
1239 | |
1240 | inline RC readLine( ::rtl::ByteSequence& aSeq ) |
1241 | { |
1242 | return static_cast< RC >( osl_readLine( _pData, reinterpret_cast<sal_Sequence**>(&aSeq) ) ); |
1243 | } |
1244 | |
1245 | /** Synchronize the memory representation of a file with that on the physical medium. |
1246 | |
1247 | The function ensures that all modified data and attributes of the file associated with |
1248 | the given file handle have been written to the physical medium. |
1249 | In case the hard disk has a write cache enabled, the data may not really be on |
1250 | permanent storage when osl_syncFile returns. |
1251 | |
1252 | @return |
1253 | <dl> |
1254 | <dt>E_None</dt> |
1255 | <dd>On success</dd> |
1256 | <dt>E_INVAL</dt> |
1257 | <dd>The value of the input parameter is invalid</dd> |
1258 | <br><p><strong>In addition to these error codes others may occur as well, for instance:</strong></p><br> |
1259 | <dt>E_BADF</dt> |
1260 | <dd>The file is not open for writing</dd> |
1261 | <dt>E_IO</dt> |
1262 | <dd>An I/O error occurred</dd> |
1263 | <dt>E_NOSPC</dt> |
1264 | <dd>There is no enough space on the target device</dd> |
1265 | <dt>E_ROFS</dt> |
1266 | <dd>The file is located on a read only file system</dd> |
1267 | <dt>E_TIMEDOUT</dt> |
1268 | <dd>A remote connection timed out. This may happen when a file is on a remote location</dd> |
1269 | </dl> |
1270 | |
1271 | @see osl_syncFile() |
1272 | @see open() |
1273 | @see write() |
1274 | */ |
1275 | inline RC sync() const |
1276 | { |
1277 | OSL_PRECOND(_pData, "File::sync(): File not open" ); |
1278 | return static_cast< RC >(osl_syncFile(_pData)); |
1279 | } |
1280 | |
1281 | /** Copy a file to a new destination. |
1282 | |
1283 | Copies a file to a new destination. Copies only files not directories. |
1284 | No assumptions should be made about preserving attributes or file time. |
1285 | |
1286 | @param ustrSourceFileURL [in] |
1287 | Full qualified URL of the source file. |
1288 | |
1289 | @param ustrDestFileURL [in] |
1290 | Full qualified URL of the destination file. A directory is NOT a valid destination file! |
1291 | |
1292 | @return |
1293 | E_None on success |
1294 | E_INVAL the format of the parameters was not valid |
1295 | E_NOMEM not enough memory for allocating structures |
1296 | E_ACCES permission denied |
1297 | E_PERM operation not permitted |
1298 | E_NAMETOOLONG file name too long |
1299 | E_NOENT no such file or directory |
1300 | E_ISDIR is a directory |
1301 | E_ROFS read-only file system |
1302 | |
1303 | @see move() |
1304 | @see remove() |
1305 | */ |
1306 | |
1307 | inline static RC copy( const ::rtl::OUString& ustrSourceFileURL, const ::rtl::OUString& ustrDestFileURL ) |
1308 | { |
1309 | return static_cast< RC >( osl_copyFile( ustrSourceFileURL.pData, ustrDestFileURL.pData ) ); |
1310 | } |
1311 | |
1312 | /** Move a file or directory to a new destination or renames it. |
1313 | |
1314 | Moves a file or directory to a new destination or renames it. |
1315 | File time and attributes are preserved. |
1316 | |
1317 | @param ustrSourceFileURL [in] |
1318 | Full qualified URL of the source file. |
1319 | |
1320 | @param ustrDestFileURL [in] |
1321 | Full qualified URL of the destination file. An existing directory is NOT a valid destination ! |
1322 | |
1323 | @return |
1324 | E_None on success |
1325 | E_INVAL the format of the parameters was not valid |
1326 | E_NOMEM not enough memory for allocating structures |
1327 | E_ACCES permission denied |
1328 | E_PERM operation not permitted |
1329 | E_NAMETOOLONG file name too long |
1330 | E_NOENT no such file or directory |
1331 | E_ROFS read-only file system |
1332 | |
1333 | @see copy() |
1334 | */ |
1335 | |
1336 | inline static RC move( const ::rtl::OUString& ustrSourceFileURL, const ::rtl::OUString& ustrDestFileURL ) |
1337 | { |
1338 | return static_cast< RC >( osl_moveFile( ustrSourceFileURL.pData, ustrDestFileURL.pData ) ); |
1339 | } |
1340 | |
1341 | /** Remove a regular file. |
1342 | |
1343 | @param ustrFileURL [in] |
1344 | Full qualified URL of the file to remove. |
1345 | |
1346 | @return |
1347 | E_None on success |
1348 | E_INVAL the format of the parameters was not valid |
1349 | E_NOMEM not enough memory for allocating structures |
1350 | E_ACCES permission denied |
1351 | E_PERM operation not permitted |
1352 | E_NAMETOOLONG file name too long |
1353 | E_NOENT no such file or directory |
1354 | E_ISDIR is a directory |
1355 | E_ROFS read-only file system |
1356 | E_FAULT bad address |
1357 | E_LOOP too many symbolic links encountered |
1358 | E_IO on I/O errors |
1359 | E_BUSY device or resource busy |
1360 | E_INTR function call was interrupted |
1361 | E_LOOP too many symbolic links encountered |
1362 | E_MULTIHOP multihop attempted |
1363 | E_NOLINK link has been severed |
1364 | E_TXTBSY text file busy |
1365 | |
1366 | @see open() |
1367 | */ |
1368 | |
1369 | inline static RC remove( const ::rtl::OUString& ustrFileURL ) |
1370 | { |
1371 | return static_cast< RC >( osl_removeFile( ustrFileURL.pData ) ); |
1372 | } |
1373 | |
1374 | /** Set file attributes. |
1375 | |
1376 | @param ustrFileURL [in] |
1377 | The full qualified file URL. |
1378 | |
1379 | @param uAttributes [in] |
1380 | Attributes of the file to be set. |
1381 | |
1382 | @return |
1383 | E_None on success |
1384 | E_INVAL the format of the parameters was not valid |
1385 | |
1386 | @see FileStatus |
1387 | */ |
1388 | |
1389 | inline static RC setAttributes( const ::rtl::OUString& ustrFileURL, sal_uInt64 uAttributes ) |
1390 | { |
1391 | return static_cast< RC >( osl_setFileAttributes( ustrFileURL.pData, uAttributes ) ); |
1392 | } |
1393 | |
1394 | /** Set the file time. |
1395 | |
1396 | @param ustrFileURL [in] |
1397 | The full qualified URL of the file. |
1398 | |
1399 | @param rCreationTime [in] |
1400 | Creation time of the given file. |
1401 | |
1402 | @param rLastAccessTime [in] |
1403 | Time of the last access of the given file. |
1404 | |
1405 | @param rLastWriteTime [in] |
1406 | Time of the last modifying of the given file. |
1407 | |
1408 | @return |
1409 | E_None on success |
1410 | E_INVAL the format of the parameters was not valid |
1411 | E_NOENT no such file or directory not found |
1412 | |
1413 | @see FileStatus |
1414 | */ |
1415 | |
1416 | inline static RC setTime( |
1417 | const ::rtl::OUString& ustrFileURL, |
1418 | const TimeValue& rCreationTime, |
1419 | const TimeValue& rLastAccessTime, |
1420 | const TimeValue& rLastWriteTime ) |
1421 | { |
1422 | return static_cast< RC >( osl_setFileTime( |
1423 | ustrFileURL.pData, |
1424 | &rCreationTime, |
1425 | &rLastAccessTime, |
1426 | &rLastWriteTime ) ); |
1427 | } |
1428 | |
1429 | friend class DirectoryItem; |
1430 | }; |
1431 | |
1432 | // ----------------------------------------------------------------------------- |
1433 | /** The directory item class object provides access to file status information. |
1434 | |
1435 | @see FileStatus |
1436 | */ |
1437 | |
1438 | class DirectoryItem: public FileBase |
1439 | { |
1440 | oslDirectoryItem _pData; |
1441 | |
1442 | public: |
1443 | |
1444 | /** Constructor. |
1445 | */ |
1446 | |
1447 | DirectoryItem(): _pData( NULL ) |
1448 | { |
1449 | } |
1450 | |
1451 | /** Copy constructor. |
1452 | */ |
1453 | |
1454 | DirectoryItem( const DirectoryItem& rItem ): _pData( rItem._pData) |
1455 | { |
1456 | if( _pData ) |
1457 | osl_acquireDirectoryItem( _pData ); |
1458 | } |
1459 | |
1460 | /** Destructor. |
1461 | */ |
1462 | |
1463 | ~DirectoryItem() |
1464 | { |
1465 | if( _pData ) |
1466 | osl_releaseDirectoryItem( _pData ); |
1467 | } |
1468 | |
1469 | /** Assignment operator. |
1470 | */ |
1471 | |
1472 | DirectoryItem& operator=(const DirectoryItem& rItem ) |
1473 | { |
1474 | if (&rItem != this) |
1475 | { |
1476 | if( _pData ) |
1477 | osl_releaseDirectoryItem( _pData ); |
1478 | |
1479 | _pData = rItem._pData; |
1480 | |
1481 | if( _pData ) |
1482 | osl_acquireDirectoryItem( _pData ); |
1483 | } |
1484 | return *this; |
1485 | } |
1486 | |
1487 | /** Check for validity of this instance. |
1488 | |
1489 | @return |
1490 | true if object is valid directory item else false. |
1491 | */ |
1492 | |
1493 | inline bool is() |
1494 | { |
1495 | return _pData != NULL; |
1496 | } |
1497 | |
1498 | /** Retrieve a single directory item. |
1499 | |
1500 | Retrieves a single directory item. The returned handle has an initial refcount of 1. |
1501 | Due to performance issues it is not recommended to use this function while |
1502 | enumerating the contents of a directory. In this case use osl_getNextDirectoryItem() instead. |
1503 | |
1504 | @param ustrFileURL [in] |
1505 | An absolute file URL. |
1506 | |
1507 | @param rItem [out] |
1508 | On success it receives a handle which can be used for subsequent calls to osl_getFileStatus(). |
1509 | The handle has to be released by a call to osl_releaseDirectoryItem(). |
1510 | |
1511 | @return |
1512 | E_None on success |
1513 | E_INVAL the format of the parameters was not valid |
1514 | E_NOMEM not enough memory for allocating structures |
1515 | E_ACCES permission denied |
1516 | E_MFILE too many open files used by the process |
1517 | E_NFILE too many open files in the system |
1518 | E_NOENT no such file or directory |
1519 | E_LOOP too many symbolic links encountered |
1520 | E_NAMETOOLONG the file name is too long |
1521 | E_NOTDIR a component of the path prefix of path is not a directory |
1522 | E_IO on I/O errors |
1523 | E_MULTIHOP multihop attempted |
1524 | E_NOLINK link has been severed |
1525 | E_FAULT bad address |
1526 | E_INTR the function call was interrupted |
1527 | |
1528 | @see FileStatus |
1529 | @see Directory::getNextItem() |
1530 | */ |
1531 | |
1532 | static inline RC get( const ::rtl::OUString& ustrFileURL, DirectoryItem& rItem ) |
1533 | { |
1534 | if( rItem._pData) |
1535 | { |
1536 | osl_releaseDirectoryItem( rItem._pData ); |
1537 | rItem._pData = NULL; |
1538 | } |
1539 | |
1540 | return static_cast< RC >( osl_getDirectoryItem( ustrFileURL.pData, &rItem._pData ) ); |
1541 | } |
1542 | |
1543 | /** Retrieve information about a single file or directory. |
1544 | |
1545 | @param rStatus [in|out] |
1546 | Reference to a class which receives the information of the file or directory |
1547 | represented by this directory item. |
1548 | |
1549 | @return |
1550 | E_None on success |
1551 | E_NOMEM not enough memory for allocating structures |
1552 | E_INVAL the format of the parameters was not valid |
1553 | E_LOOP too many symbolic links encountered |
1554 | E_ACCES permission denied |
1555 | E_NOENT no such file or directory |
1556 | E_NAMETOOLONG file name too long |
1557 | E_BADF invalid oslDirectoryItem parameter |
1558 | E_FAULT bad address |
1559 | E_OVERFLOW value too large for defined data type |
1560 | E_INTR function call was interrupted |
1561 | E_NOLINK link has been severed |
1562 | E_MULTIHOP components of path require hopping to multiple remote machines and the file system does not allow it |
1563 | E_MFILE too many open files used by the process |
1564 | E_NFILE too many open files in the system |
1565 | E_NOSPC no space left on device |
1566 | E_NXIO no such device or address |
1567 | E_IO on I/O errors |
1568 | E_NOSYS function not implemented |
1569 | |
1570 | @see get() |
1571 | @see Directory::getNextItem() |
1572 | @see FileStatus |
1573 | */ |
1574 | |
1575 | inline RC getFileStatus( FileStatus& rStatus ) |
1576 | { |
1577 | return static_cast< RC >( osl_getFileStatus( _pData, &rStatus._aStatus, rStatus._nMask ) ); |
1578 | } |
1579 | |
1580 | /** Determine if a directory item point the same underlying file |
1581 | |
1582 | The comparison is done first by URL, and then by resolving links to |
1583 | find the target, and finally by comparing inodes on unix. |
1584 | |
1585 | @param[in] pOther |
1586 | A directory handle to compare with the underlying object's item |
1587 | |
1588 | @return |
1589 | true: if the items point to an identical resource<br> |
1590 | false: if the items point to a different resource, or a fatal error occured<br> |
1591 | |
1592 | @see osl_getDirectoryItem() |
1593 | |
1594 | @since LibreOffice 3.6 |
1595 | */ |
1596 | inline bool isIdenticalTo( const DirectoryItem &pOther ) |
1597 | { |
1598 | return osl_identicalDirectoryItem( _pData, pOther._pData ); |
1599 | } |
1600 | |
1601 | friend class Directory; |
1602 | }; |
1603 | |
1604 | //########################################### |
1605 | |
1606 | /** Base class for observers of directory creation notifications. |
1607 | |
1608 | Clients which uses the method createDirectoryPath of the class |
1609 | Directory may want to be informed about the directories that |
1610 | have been created. This may be accomplished by deriving from |
1611 | this base class and overwriting the virtual function |
1612 | DirectoryCreated. |
1613 | |
1614 | @see Directory::createPath |
1615 | */ |
1616 | class DirectoryCreationObserver |
1617 | { |
1618 | public: |
1619 | virtual ~DirectoryCreationObserver() {} |
1620 | |
1621 | /** This method will be called when a new directory has been |
1622 | created and needs to be overwritten by derived classes. |
1623 | You must not delete the directory that was just created |
1624 | otherwise you will run into an endless loop. |
1625 | |
1626 | @param aDirectoryUrl |
1627 | [in]The absolute file URL of the directory that was just created by |
1628 | ::osl::Directory::createPath. |
1629 | */ |
1630 | virtual void DirectoryCreated(const rtl::OUString& aDirectoryUrl) = 0; |
1631 | }; |
1632 | |
1633 | //########################################### |
1634 | // This just an internal helper function for |
1635 | // private use. |
1636 | extern "C" inline void SAL_CALL onDirectoryCreated(void* pData, rtl_uString* aDirectoryUrl) |
1637 | { |
1638 | (static_cast<DirectoryCreationObserver*>(pData))->DirectoryCreated(aDirectoryUrl); |
1639 | } |
1640 | |
1641 | /** The directory class object provides a enumeration of DirectoryItems. |
1642 | |
1643 | @see DirectoryItem |
1644 | @see File |
1645 | */ |
1646 | |
1647 | class Directory: public FileBase |
1648 | { |
1649 | oslDirectory _pData; |
1650 | ::rtl::OUString _aPath; |
1651 | |
1652 | /** Copy constructor. |
1653 | */ |
1654 | |
1655 | Directory( Directory& ); |
1656 | |
1657 | /** Assignment operator. |
1658 | */ |
1659 | |
1660 | Directory& operator = ( Directory& ); |
1661 | |
1662 | public: |
1663 | |
1664 | /** Constructor. |
1665 | |
1666 | @param strPath [in] |
1667 | The full qualified URL of the directory. |
1668 | Relative URLs are not allowed. |
1669 | */ |
1670 | |
1671 | Directory( const ::rtl::OUString& strPath ): _pData( 0 ), _aPath( strPath ) |
1672 | { |
1673 | } |
1674 | |
1675 | /** Destructor. |
1676 | */ |
1677 | |
1678 | ~Directory() |
1679 | { |
1680 | close(); |
1681 | } |
1682 | |
1683 | /** Obtain the URL. |
1684 | |
1685 | @return |
1686 | the URL with which this Directory instance was created. |
1687 | |
1688 | @since LibreOffice 4.1 |
1689 | */ |
1690 | inline rtl::OUString getURL() const { return _aPath; } |
1691 | |
1692 | /** Open a directory for enumerating its contents. |
1693 | |
1694 | @return |
1695 | E_None on success |
1696 | E_INVAL the format of the parameters was not valid |
1697 | E_NOENT the specified path doesn't exist |
1698 | E_NOTDIR the specified path is not an directory |
1699 | E_NOMEM not enough memory for allocating structures |
1700 | E_ACCES permission denied |
1701 | E_MFILE too many open files used by the process |
1702 | E_NFILE too many open files in the system |
1703 | E_NAMETOOLONG File name too long |
1704 | E_LOOP Too many symbolic links encountered |
1705 | |
1706 | @see getNextItem() |
1707 | @see close() |
1708 | */ |
1709 | |
1710 | inline RC open() |
1711 | { |
1712 | return static_cast< RC >( osl_openDirectory( _aPath.pData, &_pData ) ); |
1713 | } |
1714 | |
1715 | /** Query if directory is open. |
1716 | |
1717 | Query if directory is open and so item enumeration is valid. |
1718 | |
1719 | @return |
1720 | true if the directory is open else false. |
1721 | |
1722 | @see open() |
1723 | @see close() |
1724 | */ |
1725 | |
1726 | inline bool isOpen() { return _pData != NULL; } |
1727 | |
1728 | /** Close a directory. |
1729 | |
1730 | @return |
1731 | E_None on success |
1732 | E_INVAL the format of the parameters was not valid |
1733 | E_NOMEM not enough memory for allocating structures |
1734 | E_BADF invalid oslDirectory parameter |
1735 | E_INTR the function call was interrupted |
1736 | |
1737 | @see open() |
1738 | */ |
1739 | |
1740 | inline RC close() |
1741 | { |
1742 | oslFileError Error = osl_File_E_BADF; |
1743 | |
1744 | if( _pData ) |
1745 | { |
1746 | Error=osl_closeDirectory( _pData ); |
1747 | _pData = NULL; |
1748 | } |
1749 | |
1750 | return static_cast< RC >( Error ); |
1751 | } |
1752 | |
1753 | |
1754 | /** Resets the directory item enumeration to the beginning. |
1755 | |
1756 | @return |
1757 | E_None on success |
1758 | E_INVAL the format of the parameters was not valid |
1759 | E_NOENT the specified path doesn't exist |
1760 | E_NOTDIR the specified path is not an directory |
1761 | E_NOMEM not enough memory for allocating structures |
1762 | E_ACCES permission denied |
1763 | E_MFILE too many open files used by the process |
1764 | E_NFILE too many open files in the system |
1765 | E_NAMETOOLONG File name too long |
1766 | E_LOOP Too many symbolic links encountered |
1767 | |
1768 | @see open() |
1769 | */ |
1770 | |
1771 | inline RC reset() |
1772 | { |
1773 | close(); |
1774 | return open(); |
1775 | } |
1776 | |
1777 | /** Retrieve the next item of a previously opened directory. |
1778 | |
1779 | Retrieves the next item of a previously opened directory. |
1780 | |
1781 | @param rItem [out] |
1782 | On success a valid DirectoryItem. |
1783 | |
1784 | @param nHint [in] |
1785 | With this parameter the caller can tell the implementation that (s)he |
1786 | is going to call this function uHint times afterwards. This enables the implementation to |
1787 | get the information for more than one file and cache it until the next calls. |
1788 | |
1789 | @return |
1790 | E_None on success |
1791 | E_INVAL the format of the parameters was not valid |
1792 | E_NOMEM not enough memory for allocating structures |
1793 | E_NOENT no more entries in this directory |
1794 | E_BADF invalid oslDirectory parameter |
1795 | E_OVERFLOW the value too large for defined data type |
1796 | |
1797 | @see DirectoryItem |
1798 | */ |
1799 | |
1800 | inline RC getNextItem( DirectoryItem& rItem, sal_uInt32 nHint = 0 ) |
1801 | { |
1802 | if( rItem._pData ) |
1803 | { |
1804 | osl_releaseDirectoryItem( rItem._pData ); |
1805 | rItem._pData = 0; |
1806 | } |
1807 | return ( RC) osl_getNextDirectoryItem( _pData, &rItem._pData, nHint ); |
1808 | } |
1809 | |
1810 | |
1811 | /** Retrieve information about a volume. |
1812 | |
1813 | Retrieves information about a volume. A volume can either be a mount point, a network |
1814 | resource or a drive depending on Operating System and File System. |
1815 | |
1816 | @param ustrDirectoryURL [in] |
1817 | Full qualified URL of the volume |
1818 | |
1819 | @param rInfo [out] |
1820 | On success it receives information about the volume. |
1821 | |
1822 | @return |
1823 | E_None on success |
1824 | E_NOMEM not enough memory for allocating structures |
1825 | E_INVAL the format of the parameters was not valid |
1826 | E_NOTDIR not a directory |
1827 | E_NAMETOOLONG file name too long |
1828 | E_NOENT no such file or directory |
1829 | E_ACCES permission denied |
1830 | E_LOOP too many symbolic links encountered |
1831 | E_FAULT Bad address |
1832 | E_IO on I/O errors |
1833 | E_NOSYS function not implemented |
1834 | E_MULTIHOP multihop attempted |
1835 | E_NOLINK link has been severed |
1836 | E_INTR function call was interrupted |
1837 | |
1838 | @see FileStatus |
1839 | @see VolumeInfo |
1840 | */ |
1841 | |
1842 | inline static RC getVolumeInfo( const ::rtl::OUString& ustrDirectoryURL, VolumeInfo& rInfo ) |
1843 | { |
1844 | return static_cast< RC >( osl_getVolumeInformation( ustrDirectoryURL.pData, &rInfo._aInfo, rInfo._nMask ) ); |
1845 | } |
1846 | |
1847 | /** Create a directory. |
1848 | |
1849 | @param ustrDirectoryURL [in] |
1850 | Full qualified URL of the directory to create. |
1851 | |
1852 | @return |
1853 | E_None on success |
1854 | E_INVAL the format of the parameters was not valid |
1855 | E_NOMEM not enough memory for allocating structures |
1856 | E_EXIST file exists |
1857 | E_ACCES permission denied |
1858 | E_NAMETOOLONG file name too long |
1859 | E_NOENT no such file or directory |
1860 | E_NOTDIR not a directory |
1861 | E_ROFS read-only file system |
1862 | E_NOSPC no space left on device |
1863 | E_DQUOT quota exceeded |
1864 | E_LOOP too many symbolic links encountered |
1865 | E_FAULT bad address |
1866 | E_IO on I/O errors |
1867 | E_MLINK too many links |
1868 | E_MULTIHOP multihop attempted |
1869 | E_NOLINK link has been severed |
1870 | |
1871 | @see remove() |
1872 | */ |
1873 | |
1874 | inline static RC create( const ::rtl::OUString& ustrDirectoryURL ) |
1875 | { |
1876 | return static_cast< RC >( osl_createDirectory( ustrDirectoryURL.pData ) ); |
1877 | } |
1878 | |
1879 | /** Remove an empty directory. |
1880 | |
1881 | @param ustrDirectoryURL [in] |
1882 | Full qualified URL of the directory. |
1883 | |
1884 | @return |
1885 | E_None on success |
1886 | E_INVAL the format of the parameters was not valid |
1887 | E_NOMEM not enough memory for allocating structures |
1888 | E_PERM operation not permitted |
1889 | E_ACCES permission denied |
1890 | E_NOENT no such file or directory |
1891 | E_NOTDIR not a directory |
1892 | E_NOTEMPTY directory not empty |
1893 | E_FAULT bad address |
1894 | E_NAMETOOLONG file name too long |
1895 | E_BUSY device or resource busy |
1896 | E_ROFS read-only file system |
1897 | E_LOOP too many symbolic links encountered |
1898 | E_BUSY device or resource busy |
1899 | E_EXIST file exists |
1900 | E_IO on I/O errors |
1901 | E_MULTIHOP multihop attempted |
1902 | E_NOLINK link has been severed |
1903 | |
1904 | @see create() |
1905 | */ |
1906 | |
1907 | inline static RC remove( const ::rtl::OUString& ustrDirectoryURL ) |
1908 | { |
1909 | return static_cast< RC >( osl_removeDirectory( ustrDirectoryURL.pData ) ); |
1910 | } |
1911 | |
1912 | /** Create a directory path. |
1913 | |
1914 | The osl_createDirectoryPath function creates a specified directory path. |
1915 | All nonexisting sub directories will be created. |
1916 | <p><strong>PLEASE NOTE:</strong> You cannot rely on getting the error code |
1917 | E_EXIST for existing directories. Programming against this error code is |
1918 | in general a strong indication of a wrong usage of osl_createDirectoryPath.</p> |
1919 | |
1920 | @param aDirectoryUrl |
1921 | [in] The absolute file URL of the directory path to create. |
1922 | A relative file URL will not be accepted. |
1923 | |
1924 | @param aDirectoryCreationObserver |
1925 | [in] Pointer to an instance of type DirectoryCreationObserver that will |
1926 | be informed about the creation of a directory. The value of this |
1927 | parameter may be NULL, in this case notifications will not be sent. |
1928 | |
1929 | @return |
1930 | <dl> |
1931 | <dt>E_None</dt> |
1932 | <dd>On success</dd> |
1933 | <dt>E_INVAL</dt> |
1934 | <dd>The format of the parameters was not valid</dd> |
1935 | <dt>E_ACCES</dt> |
1936 | <dd>Permission denied</dd> |
1937 | <dt>E_EXIST</dt> |
1938 | <dd>The final node of the specified directory path already exist</dd> |
1939 | <dt>E_NAMETOOLONG</dt> |
1940 | <dd>The name of the specified directory path exceeds the maximum allowed length</dd> |
1941 | <dt>E_NOTDIR</dt> |
1942 | <dd>A component of the specified directory path already exist as file in any part of the directory path</dd> |
1943 | <dt>E_ROFS</dt> |
1944 | <dd>Read-only file system</dd> |
1945 | <dt>E_NOSPC</dt> |
1946 | <dd>No space left on device</dd> |
1947 | <dt>E_DQUOT</dt> |
1948 | <dd>Quota exceeded</dd> |
1949 | <dt>E_FAULT</dt> |
1950 | <dd>Bad address</dd> |
1951 | <dt>E_IO</dt> |
1952 | <dd>I/O error</dd> |
1953 | <dt>E_LOOP</dt> |
1954 | <dd>Too many symbolic links encountered</dd> |
1955 | <dt>E_NOLINK</dt> |
1956 | <dd>Link has been severed</dd> |
1957 | <dt>E_invalidError</dt> |
1958 | <dd>An unknown error occurred</dd> |
1959 | </dl> |
1960 | |
1961 | @see DirectoryCreationObserver |
1962 | @see create |
1963 | */ |
1964 | static RC createPath( |
1965 | const ::rtl::OUString& aDirectoryUrl, |
1966 | DirectoryCreationObserver* aDirectoryCreationObserver = NULL) |
1967 | { |
1968 | return static_cast< RC >(osl_createDirectoryPath( |
1969 | aDirectoryUrl.pData, |
1970 | (aDirectoryCreationObserver) ? onDirectoryCreated : NULL, |
1971 | aDirectoryCreationObserver)); |
1972 | } |
1973 | }; |
1974 | |
1975 | } /* namespace osl */ |
1976 | |
1977 | #endif // INCLUDED_OSL_FILE_HXX |
1978 | |
1979 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
1980 | |