/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



/** @HTML */

#ifndef _OSL_FILE_HXX_
#define _OSL_FILE_HXX_

#ifdef __cplusplus

#include <osl/time.h>
#	include <rtl/memory.h>
#	include <rtl/ustring.hxx>

#include <osl/file.h>
#	include <rtl/byteseq.hxx>

#include <stdio.h>

namespace osl
{     


// -----------------------------------------------------------------------------
/** Base class for all File System specific objects.

    @see Directory
    @see DirectoryItem
    @see File
 */

class FileBase
{
public:

	enum RC {
        E_None         = osl_File_E_None,
        E_PERM         = osl_File_E_PERM,
		E_NOENT        = osl_File_E_NOENT,
		E_SRCH         = osl_File_E_SRCH,
		E_INTR         = osl_File_E_INTR,
		E_IO           = osl_File_E_IO,
		E_NXIO         = osl_File_E_NXIO,
		E_2BIG         = osl_File_E_2BIG,
		E_NOEXEC       = osl_File_E_NOEXEC,
		E_BADF         = osl_File_E_BADF,
		E_CHILD        = osl_File_E_CHILD,
		E_AGAIN        = osl_File_E_AGAIN,
		E_NOMEM        = osl_File_E_NOMEM,
		E_ACCES        = osl_File_E_ACCES,
		E_FAULT        = osl_File_E_FAULT,
		E_BUSY         = osl_File_E_BUSY,
		E_EXIST        = osl_File_E_EXIST,
		E_XDEV         = osl_File_E_XDEV,
		E_NODEV        = osl_File_E_NODEV,
		E_NOTDIR       = osl_File_E_NOTDIR,
		E_ISDIR        = osl_File_E_ISDIR,
		E_INVAL        = osl_File_E_INVAL,
		E_NFILE        = osl_File_E_NFILE,
		E_MFILE        = osl_File_E_MFILE,
		E_NOTTY        = osl_File_E_NOTTY,
		E_FBIG         = osl_File_E_FBIG,
		E_NOSPC        = osl_File_E_NOSPC,
		E_SPIPE        = osl_File_E_SPIPE,
		E_ROFS         = osl_File_E_ROFS,
		E_MLINK        = osl_File_E_MLINK,
		E_PIPE         = osl_File_E_PIPE,
		E_DOM          = osl_File_E_DOM,
		E_RANGE        = osl_File_E_RANGE,
		E_DEADLK       = osl_File_E_DEADLK,
		E_NAMETOOLONG  = osl_File_E_NAMETOOLONG,
		E_NOLCK        = osl_File_E_NOLCK,
		E_NOSYS        = osl_File_E_NOSYS,
		E_NOTEMPTY     = osl_File_E_NOTEMPTY,
		E_LOOP         = osl_File_E_LOOP,
		E_ILSEQ        = osl_File_E_ILSEQ,
		E_NOLINK       = osl_File_E_NOLINK,
		E_MULTIHOP     = osl_File_E_MULTIHOP,
		E_USERS        = osl_File_E_USERS,
		E_OVERFLOW     = osl_File_E_OVERFLOW,
		E_NOTREADY     = osl_File_E_NOTREADY,
		E_invalidError = osl_File_E_invalidError,	/* unmapped error: always last entry in enum! */
        E_TIMEDOUT     = osl_File_E_TIMEDOUT,
		E_NETWORK      = osl_File_E_NETWORK
	};


public:

	/**	Determine a valid unused canonical name for a requested name. 

        Determines a valid unused canonical name for a requested name. 
        Depending on the Operating System and the File System the illegal characters are replaced by valid ones. 
        If a file or directory with the requested name already exists a new name is generated following 
        the common rules on the actual Operating System and File System.

	    @param ustrRequestedURL [in]
	    Requested name of a file or directory.
    	
	    @param pustrValidURL [out]
	    On success receives a name which is unused and valid on the actual Operating System and
	    File System.

	    @return
	    E_None on success
	    E_INVAL the format of the parameters was not valid

	    @see DirectoryItem::getFileStatus()
	*/
	
	static inline RC getCanonicalName( const ::rtl::OUString& ustrRequestedURL, ::rtl::OUString& ustrValidURL )
	{
		return (RC) osl_getCanonicalName( ustrRequestedURL.pData, &ustrValidURL.pData );
	}

	/**	Convert a path relative to a given directory into an full qualified file URL.
	
	    Convert a path relative to a given directory into an full qualified file URL.
	    The function resolves symbolic links if possible and path ellipses, so on success
	    the resulting absolute path is fully resolved.
    	
	    @param ustrBaseDirectoryURL [in]
	    Base directory URL to which the relative path is related to.
    	
	    @param ustrRelativeFileURL [in]
	    An URL of a file or directory relative to the directory path specified by ustrBaseDirectoryURL
	    or an absolute path.
	    If ustrRelativeFileURL denotes an absolute path ustrBaseDirectoryURL will be ignored.
    	
	    @param ustrAbsoluteFileURL [out]
	    On success it receives the full qualified absoulte file URL.

	    @return 
	    E_None on success 
	    E_INVAL the format of the parameters was not valid
	    E_NOMEM not enough memory for allocating structures 
	    E_NOTDIR not a directory
	    E_ACCES permission denied
	    E_NOENT no such file or directory
	    E_NAMETOOLONG file name too long
	    E_OVERFLOW value too large for defined data type
	    E_FAULT bad address
	    E_INTR function call was interrupted
	    E_LOOP too many symbolic links encountered
	    E_MULTIHOP multihop attempted
	    E_NOLINK link has been severed

	    @see DirectoryItem::getFileStatus()
	*/

	static inline RC getAbsoluteFileURL( const ::rtl::OUString& ustrBaseDirectoryURL, const ::rtl::OUString& ustrRelativeFileURL, ::rtl::OUString& ustrAbsoluteFileURL )
	{
		return (RC) osl_getAbsoluteFileURL( ustrBaseDirectoryURL.pData, ustrRelativeFileURL.pData, &ustrAbsoluteFileURL.pData );
	}

    /**	Convert a file URL into a system dependend path.

	    @param ustrFileURL [in]
	    A File URL.
    	
	    @param ustrSystemPath [out]
	    On success it receives the system path.

	    @return 
	    E_None on success 
	    E_INVAL the format of the parameters was not valid

	    @see getFileURLFromSystemPath()
	*/

	static inline RC getSystemPathFromFileURL( const ::rtl::OUString& ustrFileURL, ::rtl::OUString& ustrSystemPath )
	{
		return (RC) osl_getSystemPathFromFileURL( ustrFileURL.pData, &ustrSystemPath.pData );
	}

    /**	Convert a system dependend path into a file URL.

	    @param ustrSystemPath [in]
	    A System dependent path of a file or directory.
    	
	    @param ustrFileURL [out]
	    On success it receives the file URL.

	    @return 
	    E_None on success
	    E_INVAL the format of the parameters was not valid

	    @see getSystemPathFromFileURL()
	*/

    static inline RC getFileURLFromSystemPath( const ::rtl::OUString& ustrSystemPath, ::rtl::OUString& ustrFileURL )
	{
		return (RC) osl_getFileURLFromSystemPath( ustrSystemPath.pData, &ustrFileURL.pData );
	}

    /**	Searche a full qualified system path or a file URL.

        @param ustrFileName [in] 
        A system dependent path, a file URL, a file or relative directory 
        
        @param ustrSearchPath [in]
        A list of system paths, in which a given file has to be searched. The Notation of a path list is 
        system dependend, e.g. on UNIX system "/usr/bin:/bin" and on Windows "C:\BIN;C:\BATCH".
        These paths are only for the search of a file or a relative path, otherwise it will be ignored. 
        If ustrSearchPath is NULL or while using the search path the search failed, the function searches for 
        a matching file in all system directories and in the directories listed in the PATH environment 
        variable. 
        The value of an environment variable should be used (e.g. LD_LIBRARY_PATH) if the caller is not 
        aware of the Operating System and so doesn't know which path list delimiter to use.
    						   
	    @param ustrFileURL [out]
	    On success it receives the full qualified file URL.

	    @return 
	    E_None on success
	    E_INVAL the format of the parameters was not valid
	    E_NOTDIR not a directory
	    E_NOENT no such file or directory not found
    	
	    @see getFileURLFromSystemPath()
	    @see getSystemPathFromFileURL()
	*/

    static inline RC searchFileURL( const ::rtl::OUString& ustrFileName, const ::rtl::OUString& ustrSearchPath, ::rtl::OUString& ustrFileURL )
	{
		return (RC) osl_searchFileURL( ustrFileName.pData, ustrSearchPath.pData, &ustrFileURL.pData );
	}

	/**	Retrieves the file URL of the system's temporary directory path.

		@param ustrTempDirURL[out] 
		On success receives the URL of system's	temporary directory path.

		@return 
		E_None on success
		E_NOENT	no such file or directory not found
	*/

	static inline RC getTempDirURL( ::rtl::OUString& ustrTempDirURL )
	{
		return (RC) osl_getTempDirURL( &ustrTempDirURL.pData );
	}
	
	/** Creates a temporary file in the directory provided by the caller or the
        directory returned by getTempDirURL. 
        Under UNIX Operating Systems the file will be created with read and write 
        access for the user exclusively. 
        If the caller requests only a handle to the open file but not the name of 
        it, the file will be automatically removed on close else the caller is 
        responsible for removing the file on success.<br><br>

        @param  pustrDirectoryURL [in] 
		Specifies the full qualified URL where the temporary file should be created. 
        If pustrDirectoryURL is 0 the path returned by osl_getTempDirURL will be used.
            
        @param  pHandle [out] 
		On success receives a handle to the open file.
        If pHandle is 0 the file will be closed on return, in this case
        pustrTempFileURL must not be 0.
            
        @param  pustrTempFileURL [out] 
		On success receives the full qualified URL of the temporary file.
        If pustrTempFileURL is 0 the file will be automatically removed
        on close, in this case pHandle must not be 0.
        If pustrTempFileURL is not 0 the caller receives the name of the
        created file and is responsible for removing the file.              

        @descr  
		Description of the different pHandle, ppustrTempFileURL parameter combinations.
        pHandle is 0 and pustrTempDirURL is 0 - this combination is invalid<br>
        pHandle is not 0 and pustrTempDirURL is 0 - a handle to the open file 
        will be returned on success and the file will be automatically removed on close<br>
        pHandle is 0 and pustrTempDirURL is not 0 - the name of the file will be
        returned, the caller is responsible for opening, closing and removing the file.<br>
        pHandle is not 0 and pustrTempDirURL is not 0 - a handle to the open file as well as
        the file name will be returned, the caller is responsible for closing and removing 
        the file.<br>
                                    
        @return 
		E_None   on success
        E_INVAL  the format of the parameter is invalid           
        E_NOMEM  not enough memory for allocating structures
	    E_ACCES  Permission denied	        
	    E_NOENT  No such file or directory
	    E_NOTDIR Not a directory
	    E_ROFS   Read-only file system
	    E_NOSPC  No space left on device
	    E_DQUOT  Quota exceeded
    	    
	    @see getTempDirURL()
    */
    
	static inline RC createTempFile(
	    ::rtl::OUString* pustrDirectoryURL, 
	    oslFileHandle*   pHandle, 
	    ::rtl::OUString* pustrTempFileURL)
	{	    	            
        rtl_uString*  pustr_dir_url       = pustrDirectoryURL ? pustrDirectoryURL->pData : 0;
        rtl_uString** ppustr_tmp_file_url = pustrTempFileURL  ? &pustrTempFileURL->pData : 0;
        
        return (RC) osl_createTempFile(pustr_dir_url, pHandle, ppustr_tmp_file_url);            
	}
};


// -----------------------------------------------------------------------------
/** The VolumeDevice class.

    @see VolumeInfo
*/
#ifdef OS2
class VolumeInfo;
#endif

class VolumeDevice : public FileBase
{
#ifdef OS2
public:
#endif
	oslVolumeDeviceHandle	_aHandle;

public:

    /** Constructor.
    */
    
	VolumeDevice() : _aHandle( NULL )
	{
	}

    /** Copy constructor.
    
        @param rDevice
        The other volume device.
    */
    
	VolumeDevice( const VolumeDevice & rDevice )
	{
		_aHandle = rDevice._aHandle;
		if ( _aHandle )
			osl_acquireVolumeDeviceHandle( _aHandle );
	}
    
    /** Destructor.
    */
    
	~VolumeDevice()
	{
		if ( _aHandle )
			osl_releaseVolumeDeviceHandle( _aHandle );
	}

    /** Assignment operator.
    
        @param rDevice
        The other volume device.
    */
    
	inline VolumeDevice & operator =( const VolumeDevice & rDevice )
	{
		oslVolumeDeviceHandle	newHandle = rDevice._aHandle;

		if ( newHandle )
			osl_acquireVolumeDeviceHandle( newHandle );

		if ( _aHandle )
			osl_releaseVolumeDeviceHandle( _aHandle );

		_aHandle = newHandle;

		return *this;
	}

    /** Automount a volume device.
                        
        @return
        E_None on success
        
        @todo 
        specify all error codes that may be returned                
    */
    
	inline RC automount()
	{
		return (RC)osl_automountVolumeDevice( _aHandle );
	}

    /** Unmount a volume device.
        
        @return
        E_None on success
        
        @todo 
        specify all error codes that may be returned                
    */
    
	inline RC unmount()
	{
		return (RC)osl_unmountVolumeDevice( _aHandle );
	}

    /** Get the full qualified URL where a device is mounted to.
	   	
	   	@return	    
	    The full qualified URL where the device is mounted to.    	
    */
	inline rtl::OUString getMountPath()
	{
		rtl::OUString	aPath;
		osl_getVolumeDeviceMountPath( _aHandle, &aPath.pData );
		return aPath;
	}

	friend class VolumeInfo;
};

// -----------------------------------------------------------------------------

#define VolumeInfoMask_Attributes             osl_VolumeInfo_Mask_Attributes
#define VolumeInfoMask_TotalSpace             osl_VolumeInfo_Mask_TotalSpace
#define VolumeInfoMask_UsedSpace              osl_VolumeInfo_Mask_UsedSpace
#define VolumeInfoMask_FreeSpace              osl_VolumeInfo_Mask_FreeSpace
#define VolumeInfoMask_MaxNameLength          osl_VolumeInfo_Mask_MaxNameLength
#define VolumeInfoMask_MaxPathLength          osl_VolumeInfo_Mask_MaxPathLength
#define VolumeInfoMask_FileSystemName         osl_VolumeInfo_Mask_FileSystemName
#define VolumeInfoMask_FileSystemCaseHandling osl_VolumeInfo_Mask_FileSystemCaseHandling

class Directory;

/** The VolumeInfo class.

    Neither copy nor assignment is allowed for this class.

    @see Directory::getVolumeInfo
*/


class VolumeInfo
{
	oslVolumeInfo	_aInfo;
    sal_uInt32		_nMask;
	VolumeDevice	_aDevice;

    /** Copy constructor.
    */

	VolumeInfo( VolumeInfo& );
	
	/** Assginment operator.
	*/
	
	VolumeInfo& operator = ( VolumeInfo& );

public:

    /** Constructor.

        @param nMask 
        Set of flaggs decribing the demanded information.
    */

	VolumeInfo( sal_uInt32 nMask ): _nMask( nMask )
	{
        _aInfo.uStructSize = sizeof( oslVolumeInfo );
        rtl_fillMemory( &_aInfo.uValidFields, sizeof( oslVolumeInfo ) - sizeof( sal_uInt32 ), 0 );
		_aInfo.pDeviceHandle = &_aDevice._aHandle;
	}

    /** Destructor.
    */

    ~VolumeInfo()
	{
        if( _aInfo.ustrFileSystemName )
            rtl_uString_release( _aInfo.ustrFileSystemName );
	}

    /** Check if specified fields are valid.

        @param nMask
        Set of flags for the fields to check.
        
        @return sal_True if all fields are valid else sal_False.
    */

    inline sal_Bool isValid( sal_uInt32 nMask ) const
	{
        return ( nMask & _aInfo.uValidFields ) == nMask;
	}

    /** Check the remote flag.
    
        @return 
        sal_True if Attributes are valid and the volume is remote else sal_False.
    */

    inline sal_Bool getRemoteFlag() const
	{
        return 0 != (_aInfo.uAttributes & osl_Volume_Attribute_Remote);
	}

    /** Check the removeable flag.
    
        @return 
        sal_True if attributes are valid and the volume is removable else sal_False.
    */

    inline sal_Bool getRemoveableFlag() const
	{
        return 0 != (_aInfo.uAttributes & osl_Volume_Attribute_Removeable);
	}

    /** Check the compact disc flag.
    
        @return 
        sal_True if attributes are valid and the volume is a CDROM else sal_False.
    */

    inline sal_Bool getCompactDiscFlag() const
	{
        return 0 != (_aInfo.uAttributes & osl_Volume_Attribute_CompactDisc);
	}

    /** Check the floppy disc flag.
        
        @return 
        sal_True if attributes are valid and the volume is a floppy disk else sal_False.
    */

    inline sal_Bool getFloppyDiskFlag() const
	{
        return 0 != (_aInfo.uAttributes & osl_Volume_Attribute_FloppyDisk);
	}

    /** Check the fixed disk flag.
    
        @return 
        sal_True if attributes are valid and the volume is a fixed disk else sal_False.
    */

    inline sal_Bool getFixedDiskFlag() const
	{
        return 0 != (_aInfo.uAttributes & osl_Volume_Attribute_FixedDisk);
	}

    /** Check the RAM disk flag.
    
        @return 
        sal_True if attributes are valid and the volume is a RAM disk else sal_False.
    */

    inline sal_Bool getRAMDiskFlag() const
	{
        return 0 != (_aInfo.uAttributes & osl_Volume_Attribute_RAMDisk);
	}

    /** Determine the total space of a volume device.
    
        @return 
        The total diskspace of this volume if this information is valid,
	    0 otherwise.
    */

    inline sal_uInt64 getTotalSpace() const
	{
        return _aInfo.uTotalSpace;
	}

    /** Determine the free space of a volume device.
    
        @return 
        The free diskspace of this volume if this information is valid,
	    0 otherwise.
    */

    inline sal_uInt64 getFreeSpace() const
	{
        return _aInfo.uFreeSpace;
	}

    /** Determine the used space of a volume device.
    
        @return 
        The used diskspace of this volume if this information is valid,
	    0 otherwise.
    */

    inline sal_uInt64 getUsedSpace() const
	{
        return _aInfo.uUsedSpace;
	}

    /** Determine the maximal length of a file name.
    
        @return
        The maximal length of a file name if this information is valid,
        0 otherwise.
    */

    inline sal_uInt32 getMaxNameLength() const
	{
        return _aInfo.uMaxNameLength;
	}

    /** Determine the maximal length of a path name.
    
        @return 
        The maximal length of a path if this information is valid,
	    0 otherwise.
    */

    inline sal_uInt32 getMaxPathLength() const
	{
        return _aInfo.uMaxPathLength;
	}

    /** Determine the name of the volume device's File System.
    
        @return 
        The name of the volume's fielsystem if this information is valid,
	    otherwise an empty string.
    */

	inline ::rtl::OUString getFileSystemName() const
	{
        return _aInfo.ustrFileSystemName ? ::rtl::OUString( _aInfo.ustrFileSystemName ) : ::rtl::OUString();
	}


    /** Get the volume device handle.
    
        @return 
        The device handle of the volume if this information is valid,
	    otherwise returns NULL;
    */

	inline VolumeDevice getDeviceHandle() const
	{
        return _aDevice;
	}

    /** Return whether the file system is case sensitive or 
        case insensitive 
        
        @return
        true if the file system is case sensitive false otherwise
    */
    bool isCaseSensitiveFileSystem() const
    {
        return (_aInfo.uAttributes & osl_Volume_Attribute_Case_Sensitive);
    }
    
    /** Return whether the file system preserves the case of 
        file and directory names or not
        
        @return
        true if the file system preserves the case of file and
        directory names false otherwise
    */
    bool isCasePreservingFileSystem() const
    {
        return (_aInfo.uAttributes & osl_Volume_Attribute_Case_Is_Preserved);
    }
    
    friend class Directory;
};

// -----------------------------------------------------------------------------

#define	FileStatusMask_Type				osl_FileStatus_Mask_Type
#define FileStatusMask_Attributes		osl_FileStatus_Mask_Attributes
#define FileStatusMask_CreationTime		osl_FileStatus_Mask_CreationTime
#define FileStatusMask_AccessTime		osl_FileStatus_Mask_AccessTime
#define FileStatusMask_ModifyTime		osl_FileStatus_Mask_ModifyTime
#define FileStatusMask_FileSize			osl_FileStatus_Mask_FileSize
#define FileStatusMask_FileName			osl_FileStatus_Mask_FileName
#define FileStatusMask_FileURL			osl_FileStatus_Mask_FileURL
#define FileStatusMask_LinkTargetURL	osl_FileStatus_Mask_LinkTargetURL
#define FileStatusMask_All				osl_FileStatus_Mask_All
#define FileStatusMask_Validate			osl_FileStatus_Mask_Validate

#define Attribute_ReadOnly     osl_File_Attribute_ReadOnly
#define Attribute_Hidden       osl_File_Attribute_Hidden
#define Attribute_Executable   osl_File_Attribute_Executable
#define Attribute_GrpWrite     osl_File_Attribute_GrpWrite
#define Attribute_GrpRead      osl_File_Attribute_GrpRead
#define Attribute_GrpExe       osl_File_Attribute_GrpExe
#define Attribute_OwnWrite     osl_File_Attribute_OwnWrite
#define Attribute_OwnRead      osl_File_Attribute_OwnRead
#define Attribute_OwnExe       osl_File_Attribute_OwnExe
#define Attribute_OthWrite     osl_File_Attribute_OthWrite
#define Attribute_OthRead      osl_File_Attribute_OthRead
#define Attribute_OthExe       osl_File_Attribute_OthExe

class DirectoryItem;

/** The FileStatus class.

    @see DirectoryItem::getFileStatus
*/

class FileStatus
{
    oslFileStatus	_aStatus;
    sal_uInt32		_nMask;

    /** Copy constructor.
    */

	FileStatus( FileStatus& );
	
	/** Assignment operator.
	*/
	
	FileStatus& operator = ( FileStatus& );

public:

	enum Type {
        Directory =	osl_File_Type_Directory,
		Volume    = osl_File_Type_Volume,
		Regular   = osl_File_Type_Regular,
		Fifo      = osl_File_Type_Fifo,
		Socket    = osl_File_Type_Socket,
		Link      = osl_File_Type_Link,
		Special   = osl_File_Type_Special,
		Unknown   = osl_File_Type_Unknown
	};

    /** Constructor.

        @param nMask
        Set of flaggs decribing the demanded information.
    */

	FileStatus( sal_uInt32 nMask ): _nMask( nMask ) 
	{
        _aStatus.uStructSize = sizeof( oslFileStatus );
        rtl_fillMemory( &_aStatus.uValidFields, sizeof( oslFileStatus ) - sizeof( sal_uInt32 ), 0 );
	}

    /** Destructor.
    */

    ~FileStatus()
	{
		if ( _aStatus.ustrFileURL )
			rtl_uString_release( _aStatus.ustrFileURL );
		if ( _aStatus.ustrLinkTargetURL )
			rtl_uString_release( _aStatus.ustrLinkTargetURL );
		if ( _aStatus.ustrFileName )
			rtl_uString_release( _aStatus.ustrFileName );
	}

    /** Check if specified fields are valid.

        @param nMask
        Set of flags for the fields to check.
        
        @return 
        sal_True if all fields are valid else sal_False.
    */
    
    inline sal_Bool isValid( sal_uInt32 nMask ) const
	{
        return ( nMask & _aStatus.uValidFields ) == nMask;
	}

    /** Get the file type.
    
        @return 
        The file type if this information is valid, Unknown otherwise.
    */
    inline Type getFileType() const
	{
		return (_aStatus.uValidFields & FileStatusMask_Type) ?  (Type) _aStatus.eType : Unknown;
	}

    /** Get the file attributes.
    
        @return 
        The set of attribute flags of this file.
    */

    inline sal_uInt64 getAttributes() const
	{
        return _aStatus.uAttributes;
	}

    /** Get the creation time of this file.
    
        @return 
        The creation time if this information is valid,
	    an uninitialized TimeValue otherwise.
    */

    inline TimeValue getCreationTime() const
	{
        return _aStatus.aCreationTime;
	}

    /** Get the file access time.
    
        @return 
        The last access time if this information is valid,
	    an uninitialized TimeValue otherwise.
    */

    inline TimeValue getAccessTime() const
	{
        return _aStatus.aAccessTime;
	}

    /** Get the file modification time.
    
        @return 
        The last modified time if this information is valid,
	    an uninitialized TimeValue otherwise.
    */

    inline TimeValue getModifyTime() const
	{
        return _aStatus.aModifyTime;
	}

    /** Get the size of the file.
    
        @return 
        The actual file size if this information is valid, 0 otherwise.
    */

    inline sal_uInt64 getFileSize() const
	{
        return _aStatus.uFileSize;
	}

    /** Get the file name.
    
        @return 
        The file name if this information is valid, an empty string otherwise.
    */

    inline ::rtl::OUString getFileName() const
	{
        return _aStatus.ustrFileName ? ::rtl::OUString(_aStatus.ustrFileName) : ::rtl::OUString();
	}


    /** Get the URL of the file.
    
        @return 
        The full qualified URL of the file if this information is valid, an empty string otherwise.
    */

    inline ::rtl::OUString getFileURL() const
	{
        return _aStatus.ustrFileURL ? ::rtl::OUString(_aStatus.ustrFileURL) : ::rtl::OUString();
	}

    /** Get the link target URL.
    
        @return 
        The link target URL if this information is valid, an empty string otherwise.
    */

    inline ::rtl::OUString getLinkTargetURL() const
	{
		return _aStatus.ustrLinkTargetURL ? ::rtl::OUString(_aStatus.ustrLinkTargetURL) : ::rtl::OUString();
	}

    friend class DirectoryItem;
};


// -----------------------------------------------------------------------------
/** The file class object provides access to file contents and attributes.

    @see Directory
    @see DirectoryItem
 */

class File: public FileBase
{        
    oslFileHandle   _pData;
	::rtl::OUString _aPath;

    /** Copy constructor. 
    */

	File( File& );
	
	/** Assginment operator.
	*/
	
	File& operator = ( File& );

public:

    /** Constructor.

	    @param  ustrFileURL [in] 
	    The full qualified URL of the file. Relative paths are not allowed.
    */

    File( const ::rtl::OUString& ustrFileURL ): _pData( 0 ), _aPath( ustrFileURL ) {}

    /** Destructor
    */

	inline ~File()
	{
		close();
	}

    #define OpenFlag_Read   osl_File_OpenFlag_Read
    #define OpenFlag_Write  osl_File_OpenFlag_Write
    #define OpenFlag_Create osl_File_OpenFlag_Create
    #define OpenFlag_NoLock osl_File_OpenFlag_NoLock

	/** Open a regular file.

        Open a file. Only regular files	can be openend.
        	        	
	    @param uFlags [in]
	    Specifies the open mode.
    	
	    @return 
	    E_None on success 
	    E_NOMEM not enough memory for allocating structures 
	    E_INVAL the format of the parameters was not valid
	    E_NAMETOOLONG pathname was too long
	    E_NOENT no such file or directory
	    E_ACCES permission denied
	    E_AGAIN a write lock could not be established
	    E_NOTDIR not a directory
	    E_NXIO no such device or address
	    E_NODEV no such device
	    E_ROFS read-only file system
	    E_TXTBSY text file busy
	    E_FAULT bad address
	    E_LOOP too many symbolic links encountered
	    E_NOSPC no space left on device
	    E_ISDIR is a directory
	    E_MFILE too many open files used by the process
	    E_NFILE too many open files in the system
	    E_DQUOT quota exceeded
	    E_EXIST file exists
	    E_INTR function call was interrupted
	    E_IO on I/O errors
	    E_MULTIHOP multihop attempted
	    E_NOLINK link has been severed
	    E_EOVERFLOW value too large for defined data type

	    @see close()
	    @see setPos()
	    @see getPos()
	    @see read()
	    @see write()
	    @see getSize()
	    @see setSize()
    */

    inline RC open( sal_uInt32 uFlags )
	{
        return (RC) osl_openFile( _aPath.pData, &_pData, uFlags );
	}

	/**	Close an open file.
	    
	    @return 
	    E_None on success 
	    E_INVAL the format of the parameters was not valid	
	    E_BADF Bad file
	    E_INTR function call was interrupted
	    E_NOLINK link has been severed
	    E_NOSPC no space left on device
	    E_IO on I/O errors
    	
	    @see open()
    */

    inline RC close()
	{
        oslFileError Error = osl_File_E_BADF;

        if( _pData )
		{
			Error=osl_closeFile( _pData );
            _pData = NULL;
		}

		return (RC) Error;
    }


    #define Pos_Absolut osl_Pos_Absolut
    #define Pos_Current osl_Pos_Current
    #define Pos_End     osl_Pos_End

    /** Set the internal position pointer of an open file.
	    
	    @param uHow [in] 
	    Distance to move the internal position pointer (from uPos).
    	
	    @param uPos [in]
	    Absolute position from the beginning of the file.
    	
	    @return 
	    E_None on success 
	    E_INVAL the format of the parameters was not valid
	    E_OVERFLOW the resulting file offset would be a value which cannot be represented correctly for regular files

	    @see open()
	    @see getPos()
    */

    inline RC setPos( sal_uInt32 uHow, sal_Int64 uPos )
	{
        return (RC) osl_setFilePos( _pData, uHow, uPos );
	}

	/**	Retrieve the current position of the internal pointer of an open file.
	    
	    @param uPos [out] 
	    On success receives the current position of the file pointer.
    	
	    @return 
	    E_None on success 
	    E_INVAL the format of the parameters was not valid
	    E_OVERFLOW the resulting file offset would be a value which cannot be represented correctly for regular files

	    @see open()
	    @see setPos()
	    @see read()
	    @see write()
    */

    inline RC getPos( sal_uInt64& uPos )
	{
        return (RC) osl_getFilePos( _pData, &uPos );
	}

    /**	Test if the end of a file is reached.
	    
	    @param pIsEOF [out]
	    Points to a variable that receives the end-of-file status.
    	
	    @return
	    E_None on success  
	    E_INVAL the format of the parameters was not valid
	    E_INTR function call was interrupted
	    E_IO on I/O errors
	    E_ISDIR is a directory
	    E_BADF bad file
	    E_FAULT bad address
	    E_AGAIN operation would block
	    E_NOLINK link has been severed

	    @see open()
	    @see read()
        @see readLine()
	    @see setPos()
    */

    inline RC isEndOfFile( sal_Bool *pIsEOF )
    {
        return (RC) osl_isEndOfFile( _pData, pIsEOF );
    }

	/**	Set the file size of an open file. 

        Sets the file size of an open file. The file can be truncated or enlarged by the function.
	    The position of the file pointer is not affeced by this function.
    		    
	    @param uSize [in] 
	    New size in bytes.
    	
	    @return 
	    E_None on success 
	    E_INVAL the format of the parameters was not valid
	    E_OVERFLOW the resulting file offset would be a value which cannot	be represented correctly for regular files

	    @see open()
	    @see setPos()
	    @see getStatus()
    */

    inline RC setSize( sal_uInt64 uSize )
	{
        return (RC) osl_setFileSize( _pData, uSize );
	}

	/**	Get the file size of an open file. 

        Gets the file size of an open file. 
	    The position of the file pointer is not affeced by this function.
    		    
	    @param rSize [out] 
	    Current size in bytes.
    	
	    @return 
	    E_None on success 
	    E_INVAL the format of the parameters was not valid
	    E_OVERFLOW the resulting file offset would be a value which cannot	be represented correctly for regular files

	    @see open()
	    @see setPos()
	    @see getSize()
	    @see setSize()
	    @see getStatus()
    */

    inline RC getSize( sal_uInt64 &rSize )
	{
        return (RC) osl_getFileSize( _pData, &rSize );
	}

	/**	Read a number of bytes from a file. 

        Reads a number of bytes from a file. The internal file pointer is 
        increased by the number of bytes read.
        	    
	    @param pBuffer [out]
	    Points to a buffer which receives data. The buffer must be large enough	
	    to hold uBytesRequested bytes.
    	
	    @param uBytesRequested [in]
	    Number of bytes which should be retrieved.
    	
	    @param rBytesRead [out]
	    On success the number of bytes which have actually been retrieved.
    	
	    @return 
	    E_None on success
	    E_INVAL the format of the parameters was not valid
	    E_INTR function call was interrupted
	    E_IO on I/O errors
	    E_ISDIR is a directory
	    E_BADF bad file
	    E_FAULT bad address
	    E_AGAIN operation would block
	    E_NOLINK link has been severed

	    @see open()
	    @see write()
        @see readLine()
	    @see setPos()
    */

    inline RC read( void *pBuffer, sal_uInt64 uBytesRequested, sal_uInt64& rBytesRead )
	{
        return (RC) osl_readFile( _pData, pBuffer, uBytesRequested, &rBytesRead );
	}

	/** Write a number of bytes to a file. 
	
	    Writes a number of bytes to a file. 
	    The internal file pointer is increased by the number of bytes read.
    		    
	    @param pBuffer [in]
	    Points to a buffer which contains the data.
    	
	    @param uBytesToWrite [in]
	    Number of bytes which should be written.
    	
	    @param rBytesWritten [out]
	    On success the number of bytes which have actually been written.

	    @return 
	    E_None on success 
	    E_INVAL the format of the parameters was not valid
	    E_FBIG file too large
	    E_DQUOT quota exceeded
	    E_AGAIN operation would block
	    E_BADF bad file
	    E_FAULT bad address
	    E_INTR function call was interrupted
	    E_IO on I/O errosr
	    E_NOLCK no record locks available
	    E_NOLINK link has been severed
	    E_NOSPC no space left on device
	    E_NXIO no such device or address

	    @see open()
	    @see read()
	    @see setPos()
    */

    inline RC write(const void *pBuffer, sal_uInt64 uBytesToWrite, sal_uInt64& rBytesWritten)
	{
        return (RC) osl_writeFile( _pData, pBuffer, uBytesToWrite, &rBytesWritten );
	}


    /** Read a line from a file. 

        Reads a line from a file. The new line delimiter is NOT returned!
    	
	    @param	aSeq [in/out] 
	    A reference to a ::rtl::ByteSequence that will hold the line read on success.
    	
	    @return
	    E_None on success
	    E_INVAL the format of the parameters was not valid
	    E_INTR function call was interrupted
	    E_IO on I/O errors
	    E_ISDIR is a directory
	    E_BADF bad file
	    E_FAULT bad address
	    E_AGAIN operation would block
	    E_NOLINK link has been severed

	    @see open()
	    @see read()
	    @see write()
	    @see setPos()
    */

    inline RC readLine( ::rtl::ByteSequence& aSeq )
    {
        return (RC) osl_readLine( _pData, reinterpret_cast<sal_Sequence**>(&aSeq) );
    }

    /** Synchronize the memory representation of a file with that on the physical medium.
                
    The function ensures that all modified data and attributes of the file associated with 
    the given file handle have been written to the physical medium. 
    In case the hard disk has a write cache enabled, the data may not really be on 
    permanent storage when osl_syncFile returns.

    @return 
    <dl>
    <dt>E_None</dt>
    <dd>On success</dd>
    <dt>E_INVAL</dt>
    <dd>The value of the input parameter is invalid</dd>
    </dl>
    <br><p><strong>In addition to these error codes others may occur as well, for instance:</strong></p><br>
    <dt>E_BADF</dt>
    <dd>The file is not open for writing</dd>
    <dt>E_IO</dt>
    <dd>An I/O error occurred</dd>
    <dt>E_NOSPC</dt>
    <dd>There is no enough space on the target device</dd>
    <dt>E_ROFS</dt>
    <dd>The file is located on a read only file system</dd>
    <dt>E_TIMEDOUT</dt>
    <dd>A remote connection timed out. This may happen when a file is on a remote location</dd>
    </dl>

    @see osl_syncFile()
    @see open()
    @see write()
    */
    inline RC sync() const
    {
        OSL_PRECOND(_pData, "File::sync(): File not open");
        return (RC)osl_syncFile(_pData);
    }
    
	/** Copy a file to a new destination. 

        Copies a file to a new destination. Copies only files not directories. 
        No assumptions should be made about preserving attributes or file time.
        
	    @param ustrSourceFileURL [in] 
	    Full qualified URL of the source file.
    	
	    @param ustrDestFileURL [in]
	    Full qualified URL of the destination file. A directory is NOT a valid destination file!
    	
	    @return 
	    E_None on success
	    E_INVAL the format of the parameters was not valid
	    E_NOMEM not enough memory for allocating structures 
	    E_ACCES permission denied
	    E_PERM operation not permitted
	    E_NAMETOOLONG file name too long
	    E_NOENT no such file or directory
	    E_ISDIR is a directory
	    E_ROFS read-only file system

	    @see move()
	    @see remove()
    */

	inline static RC copy( const ::rtl::OUString& ustrSourceFileURL, const ::rtl::OUString& ustrDestFileURL )
	{
        return (RC) osl_copyFile( ustrSourceFileURL.pData, ustrDestFileURL.pData );
	}

	/** Move a file or directory to a new destination or renames it. 

        Moves a file or directory to a new destination or renames it. 
        File time and attributes are preserved.
    	
	    @param ustrSourceFileURL [in]
	    Full qualified URL of the source file.
    	
	    @param ustrDestFileURL [in]
	    Full qualified URL of the destination file. An existing directory is NOT a valid destination !
    	
	    @return 
	    E_None on success 
	    E_INVAL the format of the parameters was not valid
	    E_NOMEM not enough memory for allocating structures 
	    E_ACCES permission denied
	    E_PERM operation not permitted
	    E_NAMETOOLONG file name too long
	    E_NOENT no such file or directory
	    E_ROFS read-only file system

	    @see copy()
    */

    inline static RC move( const ::rtl::OUString& ustrSourceFileURL, const ::rtl::OUString& ustrDestFileURL )
	{
        return (RC) osl_moveFile( ustrSourceFileURL.pData, ustrDestFileURL.pData );
	}

	/** Remove a regular file.

	    @param ustrFileURL [in]
	    Full qualified URL of the file to remove.
    	
	    @return 
	    E_None on success 
	    E_INVAL the format of the parameters was not valid
	    E_NOMEM not enough memory for allocating structures 
	    E_ACCES permission denied
	    E_PERM operation not permitted
	    E_NAMETOOLONG file name too long
	    E_NOENT no such file or directory
	    E_ISDIR is a directory
	    E_ROFS read-only file system
	    E_FAULT bad address
	    E_LOOP too many symbolic links encountered
	    E_IO on I/O errors
	    E_BUSY device or resource busy
	    E_INTR function call was interrupted
	    E_LOOP too many symbolic links encountered
	    E_MULTIHOP multihop attempted
	    E_NOLINK link has been severed
	    E_TXTBSY text file busy
    	
	    @see open()
    */

    inline static RC remove( const ::rtl::OUString& ustrFileURL )
	{
        return (RC) osl_removeFile( ustrFileURL.pData );
	}

	/**	Set file attributes.

	    @param ustrFileURL [in]
	    The full qualified file URL.
    	
	    @param uAttributes [in]
	    Attributes of the file to be set.

	    @return 
	    E_None on success 
	    E_INVAL the format of the parameters was not valid
    	
	    @see FileStatus
    */

    inline static RC setAttributes( const ::rtl::OUString& ustrFileURL, sal_uInt64 uAttributes )
	{
        return (RC) osl_setFileAttributes( ustrFileURL.pData, uAttributes );
	}

	/**	Set the file time.

	    @param ustrFileURL [in]
	    The full qualified URL of the file.
    	
	    @param rCreationTime [in]
	    Creation time of the given file.
    	
	    @param rLastAccessTime [in]
	    Time of the last access of the given file.
    	
	    @param rLastWriteTime [in]
	    Time of the last modifying of the given file.

	    @return
	    E_None on success
	    E_INVAL the format of the parameters was not valid
	    E_NOENT no such file or directory not found
    	
	    @see FileStatus
    */

    inline static RC setTime( 
		const ::rtl::OUString& ustrFileURL, 
		const TimeValue& rCreationTime,
		const TimeValue& rLastAccessTime,
		const TimeValue& rLastWriteTime )
	{
        return (RC)  osl_setFileTime(
			ustrFileURL.pData, 
			&rCreationTime,
			&rLastAccessTime,
			&rLastWriteTime );
	}

    friend class DirectoryItem;
};

// -----------------------------------------------------------------------------
/** The directory item class object provides access to file status information.

    @see FileStatus
 */

class DirectoryItem: public FileBase
{
    oslDirectoryItem _pData;

public:

    /** Constructor.
    */

	DirectoryItem(): _pData( NULL )
	{
	}

    /** Copy constructor.
    */

	DirectoryItem( const DirectoryItem& rItem ): _pData( rItem._pData)
	{
		if( _pData )
            osl_acquireDirectoryItem( _pData );
	}

	/** Destructor.
	*/

	~DirectoryItem()
	{
		if( _pData )
			osl_releaseDirectoryItem( _pData );
	}

    /** Assignment operator.
    */

	DirectoryItem& operator=(const DirectoryItem& rItem )
	{
	    if (&rItem != this)
	    {
            if( _pData )
                osl_releaseDirectoryItem( _pData );

            _pData = rItem._pData;
        
            if( _pData )
                osl_acquireDirectoryItem( _pData );
        }
		return *this;
    }

    /** Check for validity of this instance.
    
        @return 
        sal_True if object is valid directory item else sal_False.
     */

    inline sal_Bool is()
	{
        return _pData != NULL;
	}

    /**	Retrieve a single directory item. 

        Retrieves a single directory item. The returned handle has an initial refcount of 1.
        Due to performance issues it is not recommended to use this function while 
        enumerating the contents of a directory. In this case use osl_getNextDirectoryItem() instead.
    	
	    @param ustrFileURL [in] 
	    An absolute file URL. 
    	
	    @param rItem [out] 
	    On success it receives a handle which can be used for subsequent calls to osl_getFileStatus().
	    The handle has to be released by a call to osl_releaseDirectoryItem().
    	
	    @return 
	    E_None on success 
	    E_INVAL the format of the parameters was not valid
	    E_NOMEM not enough memory for allocating structures 
	    E_ACCES permission denied
	    E_MFILE too many open files used by the process
	    E_NFILE too many open files in the system
	    E_NOENT no such file or directory
	    E_LOOP	too many symbolic links encountered
	    E_NAMETOOLONG the file name is too long
	    E_NOTDIR a component of the path prefix of path is not a directory	
	    E_IO on I/O errors
	    E_MULTIHOP multihop attempted
	    E_NOLINK link has been severed
	    E_FAULT bad address
	    E_INTR the function call was interrupted
	    
	    @see FileStatus
	    @see Directory::getNextItem()
    */

    static inline RC get( const ::rtl::OUString& ustrFileURL, DirectoryItem& rItem )
	{
        if( rItem._pData)
        {
			osl_releaseDirectoryItem( rItem._pData );
            rItem._pData = NULL;
        }

		return (RC) osl_getDirectoryItem( ustrFileURL.pData, &rItem._pData );
	}

	/**	Retrieve information about a single file or directory.
	    
	    @param	rStatus [in|out] 
	    Reference to a class which receives the information of the file or directory
	    represented by this directory item. 
    		    
	    @return 
	    E_None on success
	    E_NOMEM not enough memory for allocating structures 
	    E_INVAL the format of the parameters was not valid
	    E_LOOP too many symbolic links encountered
	    E_ACCES permission denied
	    E_NOENT no such file or directory
	    E_NAMETOOLONG file name too long
	    E_BADF invalid oslDirectoryItem parameter
	    E_FAULT bad address
	    E_OVERFLOW value too large for defined data type
	    E_INTR function call was interrupted
	    E_NOLINK link has been severed
	    E_MULTIHOP components of path require hopping to multiple remote machines and the file system does not allow it
	    E_MFILE too many open files used by the process
	    E_NFILE too many open files in the system
	    E_NOSPC no space left on device
	    E_NXIO no such device or address
	    E_IO on I/O errors
	    E_NOSYS function not implemented

	    @see get()
	    @see Directory::getNextItem()	   
	    @see FileStatus 
    */

    inline RC getFileStatus( FileStatus& rStatus )
	{
		return (RC) osl_getFileStatus( _pData, &rStatus._aStatus, rStatus._nMask );
	}

    friend class Directory;
};

//###########################################

/** Base class for observers of directory creation notifications.

    Clients which uses the method createDirectoryPath of the class
    Directory may want to be informed about the directories that 
    have been created. This may be accomplished by deriving from 
    this base class and overwriting the virtual function 
    DirectoryCreated.
    
    @see Directory::createPath
*/
class DirectoryCreationObserver
{          
public:    
    virtual ~DirectoryCreationObserver() {}
    
    /** This method will be called when a new directory has been
        created and needs to be overwritten by derived classes.
        You must not delete the directory that was just created 
        otherwise you will run into an endless loop.
        
        @param aDirectoryUrl
        [in]The absolute file URL of the directory that was just created by
        ::osl::Directory::createPath.
    */
    virtual void DirectoryCreated(const rtl::OUString& aDirectoryUrl) = 0;    
};

//###########################################
// This just an internal helper function for
// private use. 
extern "C" inline void SAL_CALL onDirectoryCreated(void* pData, rtl_uString* aDirectoryUrl)
{
    (static_cast<DirectoryCreationObserver*>(pData))->DirectoryCreated(aDirectoryUrl);
}

/** The directory class object provides a enumeration of DirectoryItems.

    @see DirectoryItem
    @see File
 */

class Directory: public FileBase
{
    oslDirectory    _pData;
	::rtl::OUString _aPath;

    /** Copy constructor.
    */
    
	Directory( Directory& );
	
	/**  Assignment operator.
	*/
	
	Directory& operator = ( Directory& );

public:

    /** Constructor.

	    @param strPath [in] 
	    The full qualified URL of the directory.
	    Relative URLs are not allowed.
     */

	Directory( const ::rtl::OUString& strPath ): _pData( 0 ), _aPath( strPath )
	{
	}

    /** Destructor.
    */

    ~Directory()
	{
		close();
	}

    /** Open a directory for enumerating its contents.	 
	   
	    @return 
	    E_None on success
	    E_INVAL the format of the parameters was not valid
	    E_NOENT the specified path doesn't exist
	    E_NOTDIR the specified path is not an directory 
	    E_NOMEM not enough memory for allocating structures 
	    E_ACCES permission denied
	    E_MFILE too many open files used by the process
	    E_NFILE too many open files in the system
	    E_NAMETOOLONG File name too long
	    E_LOOP Too many symbolic links encountered

	    @see getNextItem()
	    @see close()
    */

    inline RC open()
	{
        return (RC) osl_openDirectory( _aPath.pData, &_pData );
	}

    /** Query if directory is open.
    
        Query if directory is open and so item enumeration is valid.

        @return 
        sal_True if the directory is open else sal_False.

        @see open()
        @see close()
    */

	inline sal_Bool isOpen() { return _pData != NULL; }

	/**	Close a directory.
	
 	    @return 
	    E_None on success 
	    E_INVAL the format of the parameters was not valid
	    E_NOMEM not enough memory for allocating structures
	    E_BADF invalid oslDirectory parameter
	    E_INTR the function call was interrupted

	    @see open()
	*/

    inline RC close()
	{
        oslFileError Error = osl_File_E_BADF;

        if( _pData )
		{
			Error=osl_closeDirectory( _pData );
            _pData = NULL;
		}

		return (RC) Error;
	}


    /** Resets the directory item enumeration to the beginning.

        @return 
        E_None on success
	    E_INVAL the format of the parameters was not valid
	    E_NOENT the specified path doesn't exist
	    E_NOTDIR the specified path is not an directory 
	    E_NOMEM not enough memory for allocating structures 
	    E_ACCES permission denied
	    E_MFILE too many open files used by the process
	    E_NFILE too many open files in the system
	    E_NAMETOOLONG File name too long
	    E_LOOP Too many symbolic links encountered
	    
        @see open()
    */

    inline RC reset()
	{
        close();
        return open();
	}

	/**	Retrieve the next item of a previously opened directory. 

        Retrieves the next item of a previously opened directory.
        	   	
	    @param	rItem [out] 
	    On success a valid DirectoryItem.
    	
	    @param	nHint [in] 
	    With this parameter the caller can tell the implementation that (s)he
        is going to call this function uHint times afterwards. This enables the implementation to
        get the information for more than one file and cache it until the next calls.

	    @return 
	    E_None on success 
	    E_INVAL the format of the parameters was not valid
	    E_NOMEM not enough memory for allocating structures 
	    E_NOENT no more entries in this directory
	    E_BADF invalid oslDirectory parameter
	    E_OVERFLOW the value too large for defined data type
	    	    
	    @see DirectoryItem
    */

    inline RC getNextItem( DirectoryItem& rItem, sal_uInt32 nHint = 0 )
	{
        if( rItem._pData )
        {
            osl_releaseDirectoryItem( rItem._pData );
            rItem._pData = 0;
        }
		return ( RC) osl_getNextDirectoryItem( _pData, &rItem._pData, nHint );
	}


	/** Retrieve information about a volume. 

        Retrieves information about a volume. A volume can either be a mount point, a network
	    resource or a drive depending on Operating System and File System. 

	    @param ustrDirectoryURL [in]
	    Full qualified URL of the volume
    	
	    @param rInfo [out]
	    On success it receives information about the volume.
    		    
	    @return 
	    E_None on success 
	    E_NOMEM not enough memory for allocating structures 
	    E_INVAL the format of the parameters was not valid
	    E_NOTDIR not a directory
	    E_NAMETOOLONG file name too long
	    E_NOENT no such file or directory
	    E_ACCES permission denied
	    E_LOOP too many symbolic links encountered
	    E_FAULT Bad address
	    E_IO on I/O errors
	    E_NOSYS function not implemented
	    E_MULTIHOP multihop attempted
	    E_NOLINK link has been severed
	    E_INTR function call was interrupted

	    @see FileStatus	 
	    @see VolumeInfo   
    */	

    inline static RC getVolumeInfo( const ::rtl::OUString& ustrDirectoryURL, VolumeInfo& rInfo )
	{
        return (RC) osl_getVolumeInformation( ustrDirectoryURL.pData, &rInfo._aInfo, rInfo._nMask );
	}

    /**	Create a directory.

	    @param ustrDirectoryURL [in] 
	    Full qualified URL of the directory to create.

	    @return 
	    E_None on success 
	    E_INVAL the format of the parameters was not valid
	    E_NOMEM not enough memory for allocating structures 
	    E_EXIST file exists
	    E_ACCES permission denied
	    E_NAMETOOLONG file name too long
	    E_NOENT no such file or directory
	    E_NOTDIR not a directory
	    E_ROFS read-only file system
	    E_NOSPC no space left on device
	    E_DQUOT quota exceeded
	    E_LOOP too many symbolic links encountered
	    E_FAULT bad address
	    E_IO on I/O errors
	    E_MLINK too many links
	    E_MULTIHOP multihop attempted
	    E_NOLINK link has been severed

	    @see remove()
    */

	inline static RC create( const ::rtl::OUString& ustrDirectoryURL )
	{
        return (RC) osl_createDirectory( ustrDirectoryURL.pData );
	}

	/**	Remove an empty directory.

	    @param ustrDirectoryURL [in]
	    Full qualified URL of the directory.
    	
	    @return 
	    E_None on success 
	    E_INVAL the format of the parameters was not valid
	    E_NOMEM not enough memory for allocating structures 
	    E_PERM operation not permitted
	    E_ACCES permission denied
	    E_NOENT no such file or directory
	    E_NOTDIR not a directory
	    E_NOTEMPTY directory not empty
	    E_FAULT bad address
	    E_NAMETOOLONG file name too long
	    E_BUSY device or resource busy
	    E_ROFS read-only file system
	    E_LOOP too many symbolic links encountered
	    E_BUSY device or resource busy
	    E_EXIST file exists
	    E_IO on I/O errors
	    E_MULTIHOP multihop attempted
	    E_NOLINK link has been severed

	    @see create()
    */

	inline static RC remove( const ::rtl::OUString& ustrDirectoryURL )
	{
        return (RC) osl_removeDirectory( ustrDirectoryURL.pData );
	}
    
    /** Create a directory path.

        The osl_createDirectoryPath function creates a specified directory path. 
        All nonexisting sub directories will be created.
        <p><strong>PLEASE NOTE:</strong> You cannot rely on getting the error code 
		E_EXIST for existing directories. Programming against this error code is 
		in general a strong indication of a wrong usage of osl_createDirectoryPath.</p>
		
        @param aDirectoryUrl 
        [in] The absolute file URL of the directory path to create.
        A relative file URL will not be accepted.
                
        @param aDirectoryCreationObserver
        [in] Pointer to an instance of type DirectoryCreationObserver that will
        be informed about the creation of a directory. The value of this 
        parameter may be NULL, in this case notifications will not be sent. 
                        
        @return 
        <dl>
        <dt>E_None</dt> 
        <dd>On success</dd> 
        <dt>E_INVAL</dt>
        <dd>The format of the parameters was not valid</dd>
        <dt>E_ACCES</dt>
        <dd>Permission denied</dd>
        <dt>E_EXIST</dt>
        <dd>The final node of the specified directory path already exist</dd>
        <dt>E_NAMETOOLONG</dt>
        <dd>The name of the specified directory path exceeds the maximum allowed length</dd>
        <dt>E_NOTDIR</dt>
        <dd>A component of the specified directory path already exist as file in any part of the directory path</dd>
        <dt>E_ROFS</dt>
        <dd>Read-only file system</dd>
	    <dt>E_NOSPC</dt>
	    <dd>No space left on device</dd>
	    <dt>E_DQUOT</dt>
	    <dd>Quota exceeded</dd>
	    <dt>E_FAULT</dt>
	    <dd>Bad address</dd>
	    <dt>E_IO</dt>
	    <dd>I/O error</dd>
	    <dt>E_LOOP</dt>
	    <dd>Too many symbolic links encountered</dd>
        <dt>E_NOLINK</dt>
        <dd>Link has been severed</dd>
        <dt>E_invalidError</dt>
        <dd>An unknown error occurred</dd>
	    </dl>
    	
	    @see DirectoryCreationObserver	    
	    @see create
	*/	
	static RC createPath(
	    const ::rtl::OUString& aDirectoryUrl, 
	    DirectoryCreationObserver* aDirectoryCreationObserver = NULL)
	{	 
	    return (RC)osl_createDirectoryPath(
	        aDirectoryUrl.pData, 
	        (aDirectoryCreationObserver) ? onDirectoryCreated : NULL, 
	        aDirectoryCreationObserver);	 
	}
};

} /* namespace osl */

#endif  /* __cplusplus */
#endif	/* _OSL_FILE_HXX_ */

