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