Coverage Report

Created: 2026-07-10 11:04

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