1 #ifndef CORELIB___NCBIFILE__HPP
2 #define CORELIB___NCBIFILE__HPP
3
4 /* $Id: ncbifile.hpp 606787 2020-04-27 16:15:35Z lavr $
5 * ===========================================================================
6 *
7 * PUBLIC DOMAIN NOTICE
8 * National Center for Biotechnology Information
9 *
10 * This software/database is a "United States Government Work" under the
11 * terms of the United States Copyright Act. It was written as part of
12 * the author's official duties as a United States Government employee and
13 * thus cannot be copyrighted. This software/database is freely available
14 * to the public for use. The National Library of Medicine and the U.S.
15 * Government have not placed any restriction on its use or reproduction.
16 *
17 * Although all reasonable efforts have been taken to ensure the accuracy
18 * and reliability of the software and data, the NLM and the U.S.
19 * Government do not and cannot warrant the performance or results that
20 * may be obtained by using this software or data. The NLM and the U.S.
21 * Government disclaim all warranties, express or implied, including
22 * warranties of performance, merchantability or fitness for any particular
23 * purpose.
24 *
25 * Please cite the author in any work or product based on this material.
26 *
27 * ===========================================================================
28 *
29 * Authors: Vladimir Ivanov, Denis Vakatov
30 *
31 *
32 */
33
34 /// @file ncbifile.hpp
35 ///
36 /// Defines classes:
37 /// CDirEntry, CFile, CDir, CSymLink,
38 /// CMemoryFile,
39 /// CFileUtil,
40 /// CFileLock,
41 /// CFileIO,
42 /// CFileReader, CFileWriter, CFileReaderWriter,
43 /// CFileException.
44 /// Defines different file finding algorithms.
45 ///
46 /// @attention
47 /// The parts of API that returns bool usually set CNcbiError (ncbierror.hpp).
48 /// It can be used to get an error code and get a reason why some method
49 /// returns FALSE. PLEASE dont't rely on a regular 'errno' value.
50 /// It is still set there for some legacy code, but please avoid.
51
52
53 #include <corelib/ncbi_system.hpp>
54 #include <corelib/ncbi_mask.hpp>
55 #include <corelib/ncbi_param.hpp>
56 #include <corelib/ncbisys.hpp>
57 #include <corelib/reader_writer.hpp>
58
59 #include <sys/types.h>
60 #if defined(HAVE_SYS_STAT_H)
61 # include <sys/stat.h>
62 #endif
63
64 #if defined(NCBI_OS_UNIX)
65 # include <sys/param.h>
66 #endif
67 #if defined(NCBI_OS_MSWIN)
68 # include <stdio.h> // for FILENAME_MAX
69 #endif
70
71
72 /** @addtogroup Files
73 *
74 * @{
75 */
76
77 BEGIN_NCBI_SCOPE
78
79
80 // Define missing types
81
82 // mode_t
83 #if defined(NCBI_OS_MSWIN)
84 typedef unsigned int mode_t;
85 #endif
86
87 // FILENAME_MAX
88 #if !defined(FILENAME_MAX)
89 # if defined(MAXNAMELEN)
90 # define FILENAME_MAX MAXNAMELEN /* in <sys/param.h> on some systems */
91 # elif defined(_MAX_FNAME)
92 # define FILENAME_MAX _MAX_FNAME /* MS Windows */
93 # else
94 # define FILENAME_MAX 256
95 # endif
96 #endif
97
98 // PATH_MAX
99 #if !defined(PATH_MAX)
100 # if defined(MAXPATHLEN)
101 # define PATH_MAX MAXPATHLEN /* in <sys/param.h> on some systems */
102 # elif defined(_MAX_PATH)
103 # define PATH_MAX _MAX_PATH /* MS Windows */
104 # else
105 # if FILENAME_MAX > 255
106 # define PATH_MAX FILENAME_MAX
107 # else
108 # define PATH_MAX 1024
109 # endif
110 # endif
111 #endif
112
113 // File handle
114 #if defined(NCBI_OS_MSWIN)
115 typedef HANDLE TFileHandle;
116 const HANDLE kInvalidHandle = INVALID_HANDLE_VALUE;
117 #else
118 typedef int TFileHandle;
119 const int kInvalidHandle = -1;
120 #endif
121
122 // Forward declaration of struct containing OS-specific lock storage.
123 struct SLock;
124
125
126 /////////////////////////////////////////////////////////////////////////////
127 ///
128 /// CFileException --
129 ///
130 /// Define exceptions generated for file operations.
131 ///
132 /// CFileException inherits its basic functionality from CCoreException
133 /// and defines additional error codes for file operations.
134
135 class NCBI_XNCBI_EXPORT CFileException : public CCoreException
136 {
137 public:
138 /// Error types that file operations can generate.
139 enum EErrCode {
140 eMemoryMap,
141 eRelativePath,
142 eNotExists,
143 eFileSystemInfo,
144 eFileIO,
145 eTmpFile
146 };
147
148 /// Translate from an error code value to its string representation.
149 virtual const char* GetErrCodeString(void) const override;
150
151 // Standard exception boilerplate code.
152 NCBI_EXCEPTION_DEFAULT(CFileException, CCoreException);
153 };
154
155
156 // File exception with system errno-based message
157
158 #if defined(NCBI_OS_MSWIN)
159 typedef CErrnoTemplException_Win<CFileException> CFileErrnoException_Base;
160 #else
161 typedef CErrnoTemplException<CFileException> CFileErrnoException_Base;
162 #endif
163
164 class NCBI_XNCBI_EXPORT CFileErrnoException : public CFileErrnoException_Base
165 {
166 public:
167 /// Error types
168 enum EErrCode {
169 eFile,
170 eFileSystemInfo,
171 eFileLock,
172 eFileIO
173 };
174 /// Translate from an error code value to its string representation.
175 virtual const char* GetErrCodeString(void) const override;
176 // Standard exception boilerplate code.
177 NCBI_EXCEPTION_DEFAULT(CFileErrnoException, CFileErrnoException_Base);
178 };
179
180
181 /////////////////////////////////////////////////////////////////////////////
182 ///
183 /// Global settings related to the file API.
184 ///
185 ///
186
187 class NCBI_XNCBI_EXPORT CFileAPI
188 {
189 public:
190 /// Enable or disable logging of errors from the File API classes.
191 ///
192 /// Have the same effect as FileAPILogging global parameter:
193 /// Registry file:
194 /// [NCBI]
195 /// FileAPILogging = true/false
196 /// Environment variable:
197 /// NCBI_CONFIG__FILEAPILOGGING
198 ///
199 /// @param on_off_default
200 /// Switch between logging enabled (eOn), disabled (eOff),
201 /// or reset to the default state (currently disabled).
202 static void SetLogging(ESwitch on_off_default);
203
204 /// Enable or disable honoring umask settings on Unix for
205 /// newly created files/directories in the File API.
206 ///
207 /// Have the same effect as FileAPIHonorUmask global parameter:
208 /// Registry file:
209 /// [NCBI]
210 /// FileAPIHonorUmask = true/false
211 /// Environment variable:
212 /// NCBI_CONFIG__FILEAPIHONORUMASK
213 ///
214 /// @param on_off_default
215 /// When set to eOn, allows read-only files to be deleted.
216 /// Otherwise, an attempt to delete a read-only files will
217 /// return an error (EACCES).
218 /// @note
219 /// Unix only. On Windows umask affect only CRT function,
220 /// the part of API that use Windows API directly just ignore umask setting.
221 static void SetHonorUmask(ESwitch on_off_default);
222
223 /// Specify whether read-only files can be deleted via
224 /// CDirEntry::Remove() on Windows.
225 ///
226 /// Have the same effect as DeleteReadOnlyFiles global parameter:
227 /// Registry file:
228 /// [NCBI]
229 /// DeleteReadOnlyFiles = true/false
230 /// Environment variable:
231 /// NCBI_CONFIG__DELETEREADONLYFILES
232 ///
233 /// @param on_off_default
234 /// When set to eOn, allows read-only files to be deleted.
235 /// Otherwise, an attempt to delete a read-only files will
236 /// return an error (EACCES).
237 /// @note
238 /// Windows only.
239 static void SetDeleteReadOnlyFiles(ESwitch on_off_default);
240 };
241
242
243 /////////////////////////////////////////////////////////////////////////////
244 ///
245 /// CDirEntry --
246 ///
247 /// Base class to work with files and directories.
248 ///
249 /// Models a directory entry in the file system. Assumes that
250 /// the path argument has the following form, where any or
251 /// all components may be missing:
252 ///
253 /// <dir><base><ext>
254 ///
255 /// - dir - file path ("/usr/local/bin/" or "c:\\windows\\")
256 /// - base - file name without ext ("autoexec")
257 /// - ext - file extension (".bat" - whatever goes after a last dot)
258 ///
259 /// Supported filename formats: MS DOS/Windows, UNIX.
260
261 class NCBI_XNCBI_EXPORT CDirEntry
262 {
263 public:
264 /// Default constructor.
265 CDirEntry(void);
266
267 /// Constructor using specified path string.
268 CDirEntry(const string& path);
269
270 /// Copy constructor.
271 CDirEntry(const CDirEntry& other);
272
273 /// Destructor.
274 virtual ~CDirEntry(void);
275
276 /// Get entry path.
277 const string& GetPath(void) const;
278
279 /// Reset path string.
280 void Reset(const string& path);
281
282 /// Assignment operator.
283 CDirEntry& operator= (const CDirEntry& other);
284
285
286 //
287 // Path processing.
288 //
289
290 /// Split a path string into its basic components.
291 ///
292 /// @param path
293 /// Path string to be split.
294 /// @param dir
295 /// The directory component that is returned. This will always have
296 /// a terminating path separator (example: "/usr/local/").
297 /// @param base
298 /// File name with both directory (if any) and extension (if any)
299 /// parts stripped.
300 /// @param ext
301 /// The extension component (if any), always has a leading dot
302 /// (example: ".bat").
303 static void SplitPath(const string& path,
304 string* dir = 0, string* base = 0, string* ext = 0);
305
306 /// Split a path string into its basic components.
307 ///
308 /// Note that the arguments are not OS-specific.
309 /// @param path
310 /// Path string to be split.
311 /// @param disk
312 /// Disk name if present like "C:" (MS Windows paths only),
313 /// otherwise empty string.
314 /// @param dir
315 /// The directory component that is returned. This will always have
316 /// a terminating path separator (example: "/usr/local/").
317 /// @param base
318 /// File name with both directory (if any) and extension (if any)
319 /// parts stripped.
320 /// @param ext
321 /// The extension component (if any), always has a leading dot
322 /// (example: ".bat").
323 static void SplitPathEx(const string& path,
324 string* disk = 0, string* dir = 0,
325 string* base = 0, string* ext = 0);
326
327 /// What GetDir() should return if the dir entry does not contain path.
328 /// @sa GetDir
329 enum EIfEmptyPath {
330 eIfEmptyPath_Empty, ///< Return empty string
331 eIfEmptyPath_Current ///< Return current dir like "./"
332 };
333
334 /// Get the directory component for this directory entry.
335 //
336 /// @param path
337 /// Flag to control returning value for paths that don't have
338 /// directory name.
339 /// @return
340 /// The directory component for this directory entry, or empty string.
341 /// @sa EGetDirMode, SplitPath
342 string GetDir(EIfEmptyPath mode = eIfEmptyPath_Current) const;
343
344 /// Get the base entry name with extension (if any).
345 string GetName(void) const;
346
347 /// Get the base entry name without extension.
348 string GetBase(void) const;
349
350 /// Get extension name.
351 string GetExt (void) const;
352
353 /// Assemble a path from basic components.
354 ///
355 /// @param dir
356 /// The directory component to make the path string. This will always
357 /// have a terminating path separator (example: "/usr/local/").
358 /// @param base
359 /// The base name of the file component that is used to make up the path.
360 /// @param ext
361 /// The extension component. This will always be added with a leading dot
362 /// (input of either "bat" or ".bat" gets added to the path as ".bat").
363 /// @return
364 /// Path built from the components.
365 static string MakePath(const string& dir = kEmptyStr,
366 const string& base = kEmptyStr,
367 const string& ext = kEmptyStr);
368
369 /// Get path separator symbol specific for the current platform.
370 static char GetPathSeparator(void);
371
372 /// Check whether a character "c" is a path separator symbol
373 /// specific for the current platform.
374 static bool IsPathSeparator(const char c);
375
376 /// Add trailing path separator, if needed.
377 static string AddTrailingPathSeparator(const string& path);
378
379 /// Delete trailing path separator, if any.
380 static string DeleteTrailingPathSeparator(const string& path);
381
382 /// Convert "path" on any OS to the current OS-dependent path.
383 /// Converts related paths, normalizes absolute.
384 /// @sa
385 /// IsAbsolutePath, NormalizePath
386 static string ConvertToOSPath(const string& path);
387
388 /// Check if a "path" is absolute for the current OS.
389 ///
390 /// Note that the "path" must be for the current OS.
391 static bool IsAbsolutePath(const string& path);
392
393 /// Check if the "path" is absolute for any OS.
394 ///
395 /// Note that the "path" can be for any OS (MSWIN, UNIX).
396 static bool IsAbsolutePathEx(const string& path);
397
398 /// Given a path, gets the closest parent directory which actually exists.
399 ///
400 /// @param path
401 /// Some path to a directory entry.
402 /// @return
403 /// The closest parent directory which actually exists.
404 /// @throws
405 /// CFileException if no existing nearest parent directory was found.
406 /// @note
407 /// For relative not-existent path it always returns ".".
408 /// To avoid this, you can always use absolute path for "path":
409 /// CDirEntry::GetNearestExistingParentDir(CDirEntry::CreateAbsolutePath(path))
410 /// @note
411 /// On Unix, a non-empty path should always have some existing parent,
412 /// because '/' is a common path that should always exist.
413 /// @sa
414 /// GetDir, CreateAbsolutePath
415 static string GetNearestExistingParentDir(const string& path);
416
417 /// Create a relative path between two points in the file
418 /// system specified by their absolute paths.
419 ///
420 /// @param path_from
421 /// Absolute path that defines start of the relative path.
422 /// @param path_to
423 /// Absolute path that defines endpoint of the relative path.
424 /// @return
425 /// Relative path (empty string if the paths are the same).
426 /// Throw CFileException on error (e.g. if any of the paths is not
427 /// absolute, or if it is impossible to create a relative path, such
428 /// as in case of different disks on MS-Windows).
429 static string CreateRelativePath(const string& path_from,
430 const string& path_to);
431
432 /// How to interpret relative paths.
433 /// @sa CreateAbsolutePath
434 enum ERelativeToWhat {
435 /// Relative to the current working directory.
436 eRelativeToCwd,
437 /// Relative to the executable's location. If the executable was
438 /// invoked via a symlink, search the directory containing the symlink
439 /// before the directory (if different) containing the actual binary.
440 eRelativeToExe
441 };
442
443 /// Get an absolute path from some, possibly relative, path.
444 ///
445 /// @param path
446 /// Path to resolve, in native syntax; returned as is if absolute.
447 /// @param rtw
448 /// Starting point for relative path resolution -- the current directory
449 /// by default, but looking alongside the executable is also an option.
450 /// @return
451 /// Corresponding absolute path. May be the original string (if already
452 /// absolute) or the starting point indicated by rtw (if the input was
453 /// empty or ".").
454 /// @sa ERelativeToWhat, CreateAbsolutePath
455 static string CreateAbsolutePath(const string& path,
456 ERelativeToWhat rtw = eRelativeToCwd);
457
458 /// Get an absolute path from some, possibly relative, path.
459 ///
460 /// @param path
461 /// Path to resolve, in native syntax; returned as is if absolute.
462 /// @param rtw
463 /// Starting point for relative path resolution. Used as a base path
464 /// for "path" if the latter has a relative form. Must be an absolute.
465 /// @return
466 /// Corresponding absolute path. May be the original string (if already
467 /// absolute) or concatenation of rtw and path.
468 /// @sa CreateAbsolutePath
469 static string CreateAbsolutePath(const string& path, const string& rtw);
470
471 /// Concatenate two parts of the path for the current OS.
472 ///
473 /// Note that the arguments must be OS-specific.
474 /// @param first
475 /// First part of the path which can be either absolute or relative.
476 /// @param second
477 /// Second part of the path must always be relative.
478 /// @return
479 /// The concatenated path.
480 static string ConcatPath(const string& first, const string& second);
481
482 /// Concatenate two parts of the path for any OS.
483 ///
484 /// Note that the arguments are not OS-specific.
485 /// @param first
486 /// First part of the path which can be either absolute or relative.
487 /// @param second
488 /// Second part of the path must always be relative.
489 /// @return
490 /// The concatenated path.
491 static string ConcatPathEx(const string& first, const string& second);
492
493 /// Normalize a path.
494 ///
495 /// Remove from an input "path" all redundancy, and if possible,
496 /// convert it to more simple form for the current OS.
497 /// Note that "path" must be OS-specific.
498 /// @param follow_links
499 /// Whether to follow symlinks (shortcuts, aliases)
500 static string NormalizePath(const string& path,
501 EFollowLinks follow_links = eIgnoreLinks);
502
503
504 //
505 // Checks & manipulations.
506 //
507
508 /// Match a "name" against a simple filename "mask".
509 static bool MatchesMask(const string& name, const string& mask,
510 NStr::ECase use_case = NStr::eCase);
511
512 /// Match a "name" against a set of "masks"
513 /// Note that any name match to empty vector of masks.
514 static bool MatchesMask(const string& name, const vector<string>& masks,
515 NStr::ECase use_case = NStr::eCase);
516
517 /// Match a "name" against a set of "masks"
518 /// Note that any name match to empty set of masks.
519 static bool MatchesMask(const string& name, const CMask& mask,
520 NStr::ECase use_case = NStr::eCase);
521
522 /// Check the entry existence.
523 virtual bool Exists(void) const;
524
525 /// Copy flags.
526 /// Note that updating modification time for directory depends on the OS.
527 /// Normally it gets updated when a new directory entry is added/removed.
528 /// On the other hand, changing contents of files in that directory
529 /// doesn't usually affect the directory modification time.
530 enum ECopyFlags {
531 /// The following flags define what to do when the
532 /// destination entry already exists:
533 /// - Overwrite the destination
534 fCF_Overwrite = (1 << 1),
535 /// - Update older entries only (compare modification times)
536 fCF_Update = (1 << 2) | fCF_Overwrite,
537 /// - Backup destination (renames to ".bak" by default)
538 fCF_Backup = (1 << 3) | fCF_Overwrite,
539
540 /// Safe copy (copy to temporary object and rename).
541 /// Be aware if used together with fCF_TopDirOnly for copying directories:
542 /// if specified -- full copy of the source directory will be created,
543 /// after successful copying it replaces the destination.
544 /// if not specified -- existing destination directory will be "upgraded"
545 /// with files from source directory, safe copying will be applied
546 /// for every copied entry inside.
547 fCF_Safe = (1 << 4) | fCF_Overwrite,
548
549 /// All above flags can be applied to the top directory only
550 /// (not for every file therein), to process the directory
551 /// as a single entity for overwriting, updating or backing up.
552 fCF_TopDirOnly = (1 << 6),
553
554 /// If destination entry exists, it must have the same type as source.
555 fCF_EqualTypes = (1 << 7),
556 /// Copy entries following their sym.links, not the links themselves.
557 fCF_FollowLinks = (1 << 8),
558 fCF_Verify = (1 << 9), ///< Verify data after copying
559 fCF_PreserveOwner = (1 << 10), ///< Preserve owner/group
560 fCF_PreservePerm = (1 << 11), ///< Preserve permissions/attributes
561 fCF_PreserveTime = (1 << 12), ///< Preserve date/times
562 fCF_PreserveAll = fCF_PreserveOwner | fCF_PreservePerm | fCF_PreserveTime,
563 fCF_Recursive = (1 << 14), ///< Copy recursively (for dir only)
564 /// Skip all entries for which we don't have Copy() method.
565 fCF_SkipUnsupported = (1 << 15),
566 /// Default flags.
567 fCF_Default = fCF_Recursive | fCF_FollowLinks
568 };
569 typedef unsigned int TCopyFlags; ///< Binary OR of "ECopyFlags"
570
571 /// Copy the entry to a location specified by "new_path".
572 ///
573 /// The Copy() method must be overloaded in derived classes
574 /// that support copy operation.
575 /// @param new_path
576 /// New path/name of an entry.
577 /// @param flags
578 /// Flags specifying how to copy the entry.
579 /// @param buf_size
580 /// Buffer size to use while copying the file contents.
581 /// Zero value means using default buffer size. This parameter
582 /// have advisory status and can be override, depends from OS
583 /// and size of copied file.
584 /// @return
585 /// TRUE if the operation was completed successfully; FALSE, otherwise.
586 /// @sa
587 /// CFile::Copy, CDir::Copy, CLink::Copy, CopyToDir
588 virtual bool Copy(const string& new_path, TCopyFlags flags = fCF_Default,
589 size_t buf_size = 0) const;
590
591 /// Copy the entry to a specified directory.
592 ///
593 /// The target entry name will be "dir/entry".
594 /// @param dir
595 /// Directory name to copy into.
596 /// @param flags
597 /// Flags specifying how to copy the entry.
598 /// @param buf_size
599 /// Buffer size to use while copying the file contents.
600 /// Zero value means using default buffer size.
601 /// @return
602 /// TRUE if the operation was completed successfully; FALSE, otherwise.
603 /// @sa
604 /// Copy
605 bool CopyToDir(const string& dir, TCopyFlags flags = fCF_Default,
606 size_t buf_size = 0) const;
607
608 /// Rename flags
609 enum ERenameFlags {
610 /// Remove destination if it exists.
611 fRF_Overwrite = (1 << 1),
612 /// Update older entries only (compare modification times).
613 fRF_Update = (1 << 2) | fCF_Overwrite,
614 /// Backup destination if it exists before renaming.
615 fRF_Backup = (1 << 3) | fCF_Overwrite,
616 /// If destination entry exists, it must have the same type as source.
617 fRF_EqualTypes = (1 << 4),
618 /// Rename entries following sym.links, not the links themselves.
619 fRF_FollowLinks = (1 << 5),
620 /// Default flags
621 fRF_Default = 0
622 };
623 typedef unsigned int TRenameFlags; ///< Binary OR of "ERenameFlags"
624
625 /// Rename entry.
626 ///
627 /// @param new_path
628 /// New path/name of an entry.
629 /// @param flags
630 /// Flags specifying how to rename the entry.
631 /// @return
632 /// TRUE if the operation was completed successfully; FALSE, otherwise.
633 /// NOTE that if flag fRF_Update is set, the function returns TRUE and
634 /// just removes the current entry in case when destination entry
635 /// exists and has its modification time newer than the current entry.
636 /// @sa
637 /// ERenameFlags, Copy
638 bool Rename(const string& new_path, TRenameFlags flags = fRF_Default);
639
640 /// Move the entry to a specified directory.
641 ///
642 /// The target entry name will be "dir/entry".
643 /// @param dir
644 /// Directory name to move into.
645 /// @param flags
646 /// Flags specifying how to move the entry.
647 /// @return
648 /// TRUE if the operation was completed successfully; FALSE, otherwise.
649 /// @sa
650 /// CopyToDir, Rename, Copy
651 bool MoveToDir(const string& dir, TCopyFlags flags = fRF_Default);
652
653 /// Get backup suffix.
654 ///
655 /// @sa
656 /// SetBackupSuffix, Backup, Rename, Copy
657 static const char* GetBackupSuffix(void);
658
659 /// Set backup suffix.
660 ///
661 /// @sa
662 /// GetBackupSuffix, Backup, Rename, Copy
663 static void SetBackupSuffix(const char* suffix);
664
665 /// Backup modes
666 enum EBackupMode {
667 eBackup_Copy = (1 << 1), ///< Copy entry
668 eBackup_Rename = (1 << 2), ///< Rename entry
669 eBackup_Default = eBackup_Copy ///< Default mode
670 };
671
672 /// Backup an entry.
673 ///
674 /// Create a copy of the current entry with the same name and an extension
675 /// specified by SetBackupSuffix(). By default this extension is ".bak".
676 /// Backups can be automatically created in 'copy' or 'rename' operations.
677 /// If an entry with the name of the backup already exists, then it will
678 /// be deleted (if possible). The current entry name components are
679 /// changed to reflect the backed up copy.
680 /// @param suffix
681 /// Extension to add to backup entry. If empty, GetBackupSuffix() is be used.
682 /// @param mode
683 /// Backup mode. Specifies what to do, copy the entry or just rename it.
684 /// @param copyflags
685 /// Flags to copy the entry. Used only if mode is eBackup_Copy,
686 /// @param copybufsize
687 /// Buffer size to use while copying the file contents.
688 /// Used only if 'mode' is eBackup_Copy,
689 /// @return
690 /// TRUE if backup created successfully; FALSE otherwise.
691 /// @sa
692 /// EBackupMode
693 bool Backup(const string& suffix = kEmptyStr,
694 EBackupMode mode = eBackup_Default,
695 TCopyFlags copyflags = fCF_Default,
696 size_t copybufsize = 0);
697
698
699 /// Entries processing flags.
700 /// @note
701 /// Different methods use different sets of flags,
702 /// and ignore all other. Refer to method descriptions for details.
703 enum EProcessingFlags {
704
705 /// Current entry only
706 fEntry = (1 << 0),
707
708 // --- directory processing flags ---------------------------
709
710 fDir_Self = fEntry, ///< Top directory entry
711 fDir_Files = (1 << 1), ///< Non-directory entries
712 fDir_Subdirs = (1 << 2), ///< Subdirectory entries (non recursive)
713 fDir_Recursive = (1 << 3), ///< Add a recursion
714
715 /// Mask to check what should be processed in a directory
716 fDir_All = fDir_Self + fDir_Files + fDir_Subdirs,
717
718 // --- additional flags -------------------------------------
719
720 fIgnoreMissing = (1 << 4),
721
722 // --- directory processing modes ---------------------------
723 // "Enums", retained for backward compatibility.
724
725 /// Directory entry only, no other files or subdirectories
726 eOnlyEmpty = fDir_Self,
727 eEntryOnly = fDir_Self,
728
729 /// All files in the top directory only, no subdirectories
730 /// and any files in them.
731 eTopDirOnly = fDir_Self | fDir_Files,
732
733 /// All files and subdirectories in the top directory,
734 /// but no files in subdirectories
735 eNonRecursive = fDir_All,
736
737 /// Process all files and subdirectories recursively.
738 eRecursive = fDir_All | fDir_Recursive,
739
740 /// Same as eRecursive, but do not report an error for
741 /// disappeared entries (e.g. if the same directory is being
742 /// removed in a parallel thread for example).
743 eRecursiveIgnoreMissing = eRecursive | fIgnoreMissing
744 };
745 typedef unsigned int TProcessingFlags; ///< Binary OR of "EProcessingFlags"
746
747 /// Flags based on TProcessingFlags
748 typedef TProcessingFlags TRemoveFlags;
749 typedef TProcessingFlags TSetModeFlags;
750
751 /// Directory remove mode.
752 /// @deprecated Use TRemoveFlags instead
753 NCBI_DEPRECATED typedef TRemoveFlags EDirRemoveMode;
754
755
756 /// Remove a directory entry.
757 ///
758 /// @flags
759 /// Entry processing flags.
760 /// See EProcessingFlags and CDir::Remove() for details.
761 /// @sa
762 /// CDir::Remove, EProcessingFlags
763 virtual bool Remove(TRemoveFlags flags = eRecursive) const;
764
765 /// Remove a directory entry.
766 ///
767 /// Same as Remove(), but removes current entry only.
768 /// Don't process entries inside directories.
769 ///
770 /// @sa Remove
771 virtual bool RemoveEntry(TRemoveFlags flags = eEntryOnly) const;
772
773 /// Directory entry type.
774 enum EType {
775 eFile = 0, ///< Regular file
776 eDir, ///< Directory
777 ePipe, ///< Pipe
778 eLink, ///< Symbolic link (UNIX only)
779 eSymLink = eLink, ///< Symbolic link (UNIX only)
780 eSocket, ///< Socket (UNIX only)
781 eDoor, ///< Door (UNIX only)
782 eBlockSpecial, ///< Block special (UNIX only)
783 eCharSpecial, ///< Character special
784 //
785 eUnknown ///< Unknown type
786 };
787
788 /// Construct a directory entry object of a specified type.
789 ///
790 /// An object of specified type will be constructed in memory only,
791 /// file system will not be modified.
792 /// @param type
793 /// Define a type of the object to create.
794 /// @return
795 /// A pointer to newly created entry. If a class for specified type
796 /// is not defined, generic CDirEntry will be returned. Do not forget
797 /// to delete the returned pointer when it is no longer used.
798 /// @sa
799 /// CFile, CDir, CSymLink
800 static CDirEntry* CreateObject(EType type, const string& path = kEmptyStr);
801
802 /// Get a type of constructed object.
803 ///
804 /// @return
805 /// Return one of the values in EType. Return "eUnknown" for CDirEntry.
806 /// @sa
807 /// CreateObject, GetType
GetObjectType(void) const808 virtual EType GetObjectType(void) const { return eUnknown; };
809
810 /// Alternate stat structure for use instead of the standard struct stat.
811 /// The alternate stat can have useful, but non-posix fields, which
812 /// are usually highly platform-dependent, and named differently
813 /// in the underlying data structures on different systems.
814 struct SStat {
815 TNcbiSys_stat orig; ///< Original stat structure
816 // Nanoseconds for dir entry times (if available)
817 long mtime_nsec; ///< Nanoseconds for modification time
818 long ctime_nsec; ///< Nanoseconds for creation time
819 long atime_nsec; ///< Nanoseconds for last access time
820 };
821
822 /// Get status information on a dir entry.
823 ///
824 /// By default have the same behavior as UNIX's lstat().
825 /// @param buffer
826 /// Pointer to structure that stores results.
827 /// @param follow_links
828 /// Whether to follow symlinks (shortcuts, aliases).
829 /// @return
830 /// Return TRUE if the file-status information is obtained,
831 /// FALSE otherwise (errno may be set).
832 bool Stat(struct SStat *buffer,
833 EFollowLinks follow_links = eIgnoreLinks) const;
834
835 /// Get a type of a directory entry.
836 ///
837 /// @return
838 /// Return one of the values in EType. If the directory entry does
839 /// not exist, return "eUnknown".
840 /// @sa
841 /// IsFile, IsDir, IsLink
842 EType GetType(EFollowLinks follow = eIgnoreLinks) const;
843
844 /// Get a type of a directory entry by status information.
845 ///
846 /// @param st
847 /// Status file information.
848 /// @return
849 /// Return one of the values in EType. If the directory entry does
850 /// not exist, return "eUnknown".
851 /// @sa
852 /// IsFile, IsDir, IsLink
853 static EType GetType(const TNcbiSys_stat& st);
854
855 /// Check whether a directory entry is a file.
856 /// @sa
857 /// GetType
858 bool IsFile(EFollowLinks follow = eFollowLinks) const;
859
860 /// Check whether a directory entry is a directory.
861 /// @sa
862 /// GetType
863 bool IsDir(EFollowLinks follow = eFollowLinks) const;
864
865 /// Check whether a directory entry is a symbolic link (alias).
866 /// @sa
867 /// GetType
868 bool IsLink(void) const;
869
870 /// Get an entry name that a link points to.
871 ///
872 /// @return
873 /// The real entry name that the link points to. Return an empty
874 /// string if the entry is not a link, or cannot be dereferenced.
875 /// The dereferenced name can be another symbolic link.
876 /// @sa
877 /// GetType, IsLink, DereferenceLink
878 string LookupLink(void) const;
879
880 /// Dereference a link.
881 ///
882 /// If the current entry is a symbolic link, then dereference it
883 /// recursively until it is no further a link (but a file, directory,
884 /// etc, or does not exist). Replace the entry path string with
885 /// the dereferenced path.
886 /// @note
887 /// This method dereference only last component of the path.
888 /// To dereference all path components use DereferencePath() method.
889 /// @sa
890 /// DereferencePath, IsLink, LookupLink, NormalizePath
891 void DereferenceLink(ENormalizePath normalize = eNormalizePath);
892
893 /// Dereference a path.
894 ///
895 /// Very similar to DereferenceLink() method, but dereference all
896 /// path components recursively until it is no further a link
897 /// in the path (but a file, directory, etc, or does not exist).
898 /// Replace the entry path string with the dereferenced path.
899 /// @sa
900 /// DereferenceLink, IsLink, LookupLink
901 void DereferencePath(void);
902
903 /// Get time stamp(s) of a directory entry.
904 ///
905 /// The creation time under MS windows is an actual creation time of the
906 /// entry. Under UNIX "creation" time is the time of last entry status
907 /// change. If either OS or file system does not support some time type
908 /// (modification/last access/creation), then the corresponding CTime
909 /// gets returned "empty".
910 /// Returned times are always in CTime's time zone format (eLocal/eGMT).
911 /// NOTE that what GetTime returns may not be equal to the the time(s)
912 /// previously set by SetTime, as the behavior depends on the OS and
913 /// the file system used.
914 /// @return
915 /// TRUE if time(s) obtained successfully, FALSE otherwise.
916 /// @sa
917 /// GetTimeT, SetTime, Stat
918 bool GetTime(CTime* modification,
919 CTime* last_access = 0,
920 CTime* creation = 0) const;
921
922 /// Get time stamp(s) of a directory entry (time_t version).
923 ///
924 /// Use GetTime() if you need precision of more than 1 second.
925 /// Returned time(s) are always in GMT format.
926 /// @return
927 /// TRUE if time(s) obtained successfully, FALSE otherwise.
928 /// @sa
929 /// GetTime, SetTimeT
930 bool GetTimeT(time_t* modification,
931 time_t* last_access = 0,
932 time_t* creation = 0) const;
933
934 /// Set time stamp(s) of a directory entry.
935 ///
936 /// The process must own the file or have write permissions in order
937 /// to change the time(s). Any parameter with a value of zero will
938 /// not cause the corresponding time stamp change.
939 /// NOTE that what GetTime can later return may not be equal to the
940 /// the time(s) set by SetTime, as the behavior depends on the OS and
941 /// the file system used.
942 /// Also, on UNIX it is impossible to change creation time of an entry
943 /// (we silently ignore the "creation" time stamp on that platform).
944 /// @param modification
945 /// Entry modification time to set.
946 /// @param last_access
947 /// Entry last access time to set. It cannot be less than the entry
948 /// creation time, otherwise it will be set equal to the creation time.
949 /// @param creation
950 /// Entry creation time to set. On some platforms it cannot be changed,
951 /// so this parameter will be quietly ignored.
952 /// @return
953 /// TRUE if the time(s) changed successfully, FALSE otherwise.
954 /// @sa
955 /// SetTimeT, GetTime
956 bool SetTime(const CTime* modification = 0,
957 const CTime* last_access = 0,
958 const CTime* creation = 0) const;
959
960 /// Set time stamp(s) of a directory entry (time_t version).
961 ///
962 /// Use SetTime() if you need precision of more than 1 second.
963 /// @param modification
964 /// Entry modification time to set.
965 /// @param creation
966 /// Entry creation time to set. On some platforms it cannot be changed,
967 /// so this parameter will be quietly ignored.
968 /// @param last_access
969 /// Entry last access time to set. It cannot be less than the entry
970 /// creation time, otherwise it will be set equal to the creation time.
971 /// @return
972 /// TRUE if the time(s) changed successfully, FALSE otherwise.
973 /// @sa
974 /// SetTime, GetTimeT
975 bool SetTimeT(const time_t* modification = 0,
976 const time_t* last_access = 0,
977 const time_t* creation = 0) const;
978
979
980 /// What IsNewer() should do if the dir entry does not exist or
981 /// is not accessible.
982 /// @sa IsNewer
983 enum EIfAbsent {
984 eIfAbsent_Throw, ///< Throw an exception
985 eIfAbsent_Newer, ///< Deem absent entry to be "newer"
986 eIfAbsent_NotNewer ///< Deem absent entry to be "older"
987 };
988
989 /// Check if the current entry is newer than a specified date/time.
990 ///
991 /// @param tm
992 /// Time to compare with the current entry modification time.
993 /// @param if_absent
994 /// What to do if If the entry does not exist or is not accessible.
995 /// @return
996 /// TRUE if the entry's modification time is newer than specified time.
997 /// Return FALSE otherwise.
998 /// @sa
999 /// GetTime, EIfAbsent
1000 bool IsNewer(time_t tm,
1001 EIfAbsent if_absent /* = eIfAbsent_Throw*/) const;
1002
1003 /// Check if the current entry is newer than a specified date/time.
1004 ///
1005 /// @param tm
1006 /// Time to compare with the current entry modification time.
1007 /// @param if_absent
1008 /// What to do if If the entry does not exist or is not accessible.
1009 /// @return
1010 /// TRUE if the entry's modification time is newer than specified time.
1011 /// Return FALSE otherwise.
1012 /// @sa
1013 /// GetTime, EIfAbsent
1014 bool IsNewer(const CTime& tm,
1015 EIfAbsent if_absent /* = eIfAbsent_Throw*/) const;
1016
1017 /// What path version of IsNewer() should do if the dir entry or specified
1018 /// path does not exist or is not accessible. Default flags (0) mean
1019 /// throwing an exceptions if one of dir entries does not exists.
1020 /// But if you don't like to have an exception here, you can change IsNewer()
1021 /// behavior specifying flags. There are three cases: there's a problem only
1022 /// with the argument (HasThis-NoPath), there's a problem only with original
1023 /// entry (NoThis-HasPath), or there are problems with both (NoThis-NoPath).
1024 /// The EIfAbsent2 lets you independently select what to do in each of those
1025 /// scenarios: throw an exception (no flags set), return true (f*_Newer),
1026 /// or return false (f*_NotNewer).
1027 /// @sa IsNewer
1028 enum EIfAbsent2 {
1029 fHasThisNoPath_Newer = (1 << 0),
1030 fHasThisNoPath_NotNewer = (1 << 1),
1031 fNoThisHasPath_Newer = (1 << 2),
1032 fNoThisHasPath_NotNewer = (1 << 3),
1033 fNoThisNoPath_Newer = (1 << 4),
1034 fNoThisNoPath_NotNewer = (1 << 5)
1035 };
1036 typedef int TIfAbsent2; ///< Binary OR of "EIfAbsent2"
1037
1038 /// Check if the current entry is newer than some other.
1039 ///
1040 /// @param path
1041 /// An entry name, of which to compare the modification times.
1042 /// @return
1043 /// TRUE if the modification time of the current entry is newer than
1044 /// the modification time of the specified entry, or if that entry
1045 /// doesn't exist. Return FALSE otherwise.
1046 /// @sa GetTime, EIfAbsent2
1047 bool IsNewer(const string& path,
1048 TIfAbsent2 if_absent /* = 0 throw*/) const;
1049
1050 /// Check if the current entry and the given entry_name are identical.
1051 ///
1052 /// Note that entries can be checked accurately only on UNIX.
1053 /// On MS Windows function can check it only by file name.
1054 /// @param entry_name
1055 /// An entry name, of which to compare current entry.
1056 /// @return
1057 /// TRUE if both entries exists and identical. Return FALSE otherwise.
1058 /// @param follow_links
1059 /// Whether to follow symlinks (shortcuts, aliases)
1060 bool IsIdentical(const string& entry_name,
1061 EFollowLinks follow_links = eIgnoreLinks) const;
1062
1063 /// Get an entry owner.
1064 ///
1065 /// WINDOWS:
1066 /// Retrieve the name of the account and the name of the first
1067 /// group, which the account belongs to. The obtained group name may
1068 /// be an empty string, if we don't have permissions to get it.
1069 /// Windows 2000/XP: In addition to looking up for local accounts,
1070 /// local domain accounts, and explicitly trusted domain accounts,
1071 /// it also can look for any account in any known domain around.
1072 /// UNIX:
1073 /// Retrieve an entry owner:group pair.
1074 /// @param owner
1075 /// Pointer to a string to receive an owner name.
1076 /// @param group
1077 /// Pointer to a string to receive a group name.
1078 /// @param follow
1079 /// Whether to follow symbolic links when getting the information.
1080 /// @param uid
1081 /// Pointer to an unsigned int to receive numeric user id
1082 /// (this information is purely supplemental).
1083 /// @param gid
1084 /// Pointer to an unsigned int to receive numeric group id
1085 /// (this information is purely supplemental).
1086 /// @note
1087 /// Numeric uid/gid may be the fake ones on Windows (and may be 0).
1088 /// @note
1089 /// The call will fail if neither owner nor group is provided non-NULL
1090 /// (even though uid and/or gid may be non-NULL).
1091 /// @note
1092 /// It is in best interest of the caller to clear all strings and
1093 /// integers that are expected to get values out of this call prior
1094 /// to making the actual call.
1095 /// @return
1096 /// TRUE if successful, FALSE otherwise.
1097 /// @sa
1098 /// SetOwner
1099 bool GetOwner(string* owner, string* group = 0,
1100 EFollowLinks follow = eFollowLinks,
1101 unsigned int* uid = 0, unsigned int* gid = 0) const;
1102
1103 /// Set an entry owner and/or group.
1104 ///
1105 /// You should have administrative (super user) rights to change
1106 /// an owner or group.
1107 /// WINDOWS:
1108 /// Only administrative privileges (Restore and Take Ownership)
1109 /// grant rights to change ownership. Without one of the privileges,
1110 /// an administrator cannot take ownership of any file or give ownership
1111 /// back to the some user.
1112 /// UNIX:
1113 /// The owner of an entry can change the group to any group of which
1114 /// that owner is a member of. The super-user may assign the group
1115 /// arbitrarily.
1116 /// @param owner
1117 /// New owner name to set. Use empty string if dont want to change.
1118 /// @param group
1119 /// New group name to set. Use empty string if dont want to change.
1120 /// @param uid
1121 /// Pointer to an unsigned int to receive numeric user id of the
1122 /// prospective owner (this information is purely supplemental).
1123 /// @param gid
1124 /// Pointer to an unsigned int to receive numeric group id of the
1125 /// prospective owner (this information is purely supplemental).
1126 /// @note
1127 /// Numeric uid/gid can be returned even if the call was unsuccessful;
1128 /// they may be the fake ones on Windows (and may be 0).
1129 /// @return
1130 /// TRUE if successful, FALSE otherwise.
1131 /// @sa
1132 /// GetOwner
1133 bool SetOwner(const string& owner, const string& group = kEmptyStr,
1134 EFollowLinks follow = eFollowLinks,
1135 unsigned int* uid = 0, unsigned int* gid = 0) const;
1136
1137 //
1138 // Access permissions.
1139 //
1140
1141 /// Directory entry access permissions.
1142 enum EMode {
1143 fExecute = 1, ///< Execute / List(directory) permission
1144 fWrite = 2, ///< Write permission
1145 fRead = 4, ///< Read permission
1146 fDefault = 8, ///< Special flag: ignore all other flags, use current default mode
1147
1148 // initial defaults for directories
1149 fDefaultDirUser = fRead | fExecute | fWrite,
1150 ///< Default user permission for a dir.
1151 fDefaultDirGroup = fRead | fExecute,
1152 ///< Default group permission for a dir.
1153 fDefaultDirOther = fRead | fExecute,
1154 ///< Default other permission for a dir.
1155
1156 // initial defaults for non-dir entries (files, etc.)
1157 fDefaultUser = fRead | fWrite,
1158 ///< Default user permission for a file
1159 fDefaultGroup = fRead,
1160 ///< Default group permission for a file
1161 fDefaultOther = fRead
1162 ///< Default other permission for a file
1163 };
1164 typedef unsigned int TMode; ///< Bitwise OR of "EMode"
1165
1166 enum ESpecialModeBits {
1167 fSticky = 1,
1168 fSetGID = 2,
1169 fSetUID = 4
1170 };
1171 typedef unsigned int TSpecialModeBits; ///< Bitwise OR of ESpecialModeBits
1172
1173 /// Relative permissions change modes.
1174 /// Can be combined with TMode or TSpecialModeBits.
1175 /// Only one of these flags is allowed for each mode.
1176 enum EModeRelative {
1177 fModeAdd = 16, ///< Adds the argument permission mode to
1178 ///< the entry's current mode.
1179 fModeRemove = 32, ///< Removes the argument permission mode
1180 ///< from the entry's current mode.
1181 fModeNoChange = 64 ///< Do not change permission mode.
1182 };
1183
1184 /// Get permission mode(s) of a directory entry.
1185 ///
1186 /// On WINDOWS: There is only the "user_mode" permission setting,
1187 /// and "group_mode" and "other_mode" settings will be ignored.
1188 /// The "user_mode" will be combined with effective permissions for
1189 /// the current process owner on specified directory entry.
1190 /// @return
1191 /// TRUE upon successful retrieval of permission mode(s),
1192 /// FALSE otherwise.
1193 /// @sa
1194 /// SetMode
1195 bool GetMode(TMode* user_mode,
1196 TMode* group_mode = 0,
1197 TMode* other_mode = 0,
1198 TSpecialModeBits* special = 0) const;
1199
1200 /// Set permission mode(s) of a directory entry.
1201 ///
1202 /// Permissions are set as specified by the passed values for
1203 /// user_mode, group_mode and other_mode. This method rewrites
1204 /// each user/group/other/special permission by default.
1205 /// @note
1206 /// Adding one of the EModeRelative flags to mode change default
1207 /// behavior that replace modes with passed values and allow
1208 /// for relative mode change for any of user/group/other/special.
1209 /// It is possible to keep it as is, or add/remove some permission
1210 /// modes specified in parameters.
1211 /// @note
1212 /// Passing fDefault will cause the corresponding mode
1213 /// to be taken and set from its default setting.
1214 /// @flags
1215 /// Entry processing flags. Affect directories only,
1216 /// see CDir::SetMode() for details. For other type entris
1217 /// don't have any effect.
1218 /// @return
1219 /// TRUE if permission successfully set; FALSE, otherwise.
1220 /// @sa
1221 /// SetDefaultMode, SetDefaultModeGlobal, GetMode, EMode,
1222 /// EModeRelative, ESpecialModeBits, SetModeEntry, CDir::SetMode,
1223 /// EProcessingFlags
1224 virtual bool SetMode(
1225 TMode user_mode, // e.g. fDefault
1226 TMode group_mode = fDefault,
1227 TMode other_mode = fDefault,
1228 TSpecialModeBits special = 0,
1229 TSetModeFlags flags = eEntryOnly) const;
1230
1231
1232 /// Set permission mode(s) of a directory entry.
1233 ///
1234 /// Same as SetMode(), but process current entry only.
1235 /// Don't process entries inside directories.
1236 /// @sa SetMode
1237 virtual bool SetModeEntry(
1238 TMode user_mode, // e.g. fDefault
1239 TMode group_mode = fDefault,
1240 TMode other_mode = fDefault,
1241 TSpecialModeBits special = 0,
1242 TSetModeFlags flags = eEntryOnly) const;
1243
1244 /// Set default permission modes globally for all CDirEntry objects.
1245 ///
1246 /// The default mode is set globally for all CDirEntry objects except
1247 /// for those having their own mode set with individual
1248 /// SetDefaultMode().
1249 ///
1250 /// When "fDefault" is passed as a value of the mode parameters,
1251 /// the default mode takes places for the value as defined in EType:
1252 ///
1253 /// If user_mode is "fDefault", then the default is to take
1254 /// - "fDefaultDirUser" if this is a directory, or
1255 /// - "fDefaultUser" if this is a file.
1256 ///
1257 /// If group_mode is "fDefault", then the default is to take
1258 /// - "fDefaultDirGroup" if this is a directory, or
1259 /// - "fDefaultGroup" if this is a file.
1260 ///
1261 /// If other_mode is "fDefault", then the default is to take
1262 /// - "fDefaultDirOther" if this is a directory, or
1263 /// - "fDefaultOther" if this is a file.
1264 static void SetDefaultModeGlobal(
1265 EType entry_type,
1266 TMode user_mode, // e.g. fDefault
1267 TMode group_mode = fDefault,
1268 TMode other_mode = fDefault,
1269 TSpecialModeBits special = 0);
1270
1271 /// Set default mode(s) for this entry only.
1272 ///
1273 /// When "fDefault" is passed as a value of the parameters,
1274 /// the corresponding mode will be taken and set from the global mode
1275 /// as specified by SetDefaultModeGlobal().
1276 virtual void SetDefaultMode(EType entry_type,
1277 TMode user_mode, // e.g. fDefault
1278 TMode group_mode = fDefault,
1279 TMode other_mode = fDefault,
1280 TSpecialModeBits special = 0);
1281
1282 /// Check access rights.
1283 ///
1284 /// Use effective user ID (or process owner) to check the entry
1285 /// for accessibility accordingly to specified mask.
1286 /// @note
1287 /// - If an entry is a symbolic link, that the access rights
1288 /// will be checked for entry to which the link points.
1289 /// - Execute bit means 'search' for directories.
1290 /// - Success checking fExecute mode do not guarantee that
1291 /// the file will executable at all. This function just check
1292 /// permissions and not the file format.
1293 /// - On some platforms, if the file is currently open for execution,
1294 /// the function reports that it is not writable, regardless
1295 /// of the setting of its mode.
1296 /// @note
1297 /// This method may not work correctly
1298 /// On MS-Windows:
1299 /// - for network shares and mapped network drives.
1300 /// On Unix:
1301 /// - for entries on NFS file systems.
1302 /// @note
1303 /// Using CheckAccess() to check if a user is authorized to e.g. open
1304 /// a file before actually doing so creates a security hole, because
1305 /// the user might exploit the short time interval between checking
1306 /// and opening the file to manipulate it. Always is better to try to
1307 /// open a file with necessary permissions and check result.
1308 /// @param access_mode
1309 /// Checked access mode (any combination of fRead/fWrite/fExecute).
1310 /// @return
1311 /// TRUE if specified permissions granted, FALSE otherwise
1312 /// (also returns FALSE if the file doesn't exists or an error occurs).
1313 /// @sa
1314 /// GetMode
1315 bool CheckAccess(TMode access_mode) const;
1316
1317
1318 /// Construct mode_t value from permission modes.
1319 /// Parameters must not have "fDefault" values.
1320 /// @sa ModeFromModeT
1321 static mode_t MakeModeT(TMode user_mode,
1322 TMode group_mode,
1323 TMode other_mode,
1324 TSpecialModeBits special);
1325
1326 /// Convert mode_t to permission mode(s).
1327 ///
1328 /// @note
1329 /// On WINDOWS: There is only the "user_mode" permission setting,
1330 /// and "group_mode" and "other_mode" settings will be ignored.
1331 /// The "user_mode" will be combined with effective permissions for
1332 /// the current process owner on specified directory entry.
1333 /// @sa
1334 /// GetMode, SetMode, MakeModeT
1335 static void ModeFromModeT(mode_t mode,
1336 TMode* user_mode,
1337 TMode* group_mode = 0,
1338 TMode* other_mode = 0,
1339 TSpecialModeBits* special = 0);
1340
1341 /// Permission mode string format.
1342 /// @sa
1343 /// StringToMode, ModeToString
1344 enum EModeStringFormat {
1345 eModeFormat_Octal, ///< Octal format ("664")
1346 eModeFormat_Symbolic, ///< Shell symbolic format ("u=rwx,g=rwx,o=rx")
1347 eModeFormat_List, ///< Shell list 'ls -l' like format ("rwxrwxrwx")
1348 eModeFormat_Default = eModeFormat_Octal ///< Default mode
1349 };
1350
1351
1352 /// Convert permission modes to string representation using one of predefined formats.
1353 /// Parameters must not have "fDefault" values.
1354 /// @sa StringToMode, EModeStringFormat
1355 static string ModeToString(TMode user_mode,
1356 TMode group_mode,
1357 TMode other_mode,
1358 TSpecialModeBits special,
1359 EModeStringFormat format = eModeFormat_Default);
1360
1361 /// Convert string (in one of predefined formats, detects automatically) to permission mode(s).
1362 /// @return
1363 /// TRUE if the operation was completed successfully; FALSE, otherwise.
1364 /// @sa
1365 /// ModeToString, EModeStringFormat
1366 static bool StringToMode(const CTempString& mode,
1367 TMode* user_mode,
1368 TMode* group_mode = 0,
1369 TMode* other_mode = 0,
1370 TSpecialModeBits* special = 0);
1371
1372
1373 /// Get file/directory mode creation mask.
1374 /// @note
1375 /// umask can be useful on Unix platform only. On Windows only
1376 /// C Runtime library honor it, any methods that use Windows API
1377 /// ignore its setting.
1378 /// @sa
1379 /// SetUmask
1380 static void GetUmask(TMode* user_mode,
1381 TMode* group_mode = 0,
1382 TMode* other_mode = 0,
1383 TSpecialModeBits* special = 0);
1384
1385 /// Set file/directory mode creation mask.
1386 ///
1387 /// @note
1388 /// fDefault value for permission mode(s) mean 0.
1389 /// @note
1390 /// umask can be useful on Unix platform only. On Windows only
1391 /// C Runtime library honor it, any methods that use Windows API
1392 /// ignore its setting.
1393 /// @sa
1394 /// GetUmask
1395 static void SetUmask(TMode user_mode,
1396 TMode group_mode = fDefault,
1397 TMode other_mode = fDefault,
1398 TSpecialModeBits special = 0);
1399
1400 //
1401 // Temporary directory entries (and files)
1402 //
1403
1404 /// Temporary file creation mode
1405 enum ETmpFileCreationMode {
1406 eTmpFileCreate, ///< Create empty file for each GetTmpName* call.
1407 eTmpFileGetName ///< Get name of the file only.
1408 };
1409
1410 /// Get temporary file name.
1411 ///
1412 /// This class generates a temporary file name in the temporary directory
1413 /// specified by the OS. But this behavior can be changed -- just set the
1414 /// desired temporary directory using the global parameter 'TmpDir' in
1415 /// in the 'NCBI' registry section or the environment (see CParam class
1416 /// description), and it will used by default in this class.
1417 ///
1418 /// @param mode
1419 /// Temporary file creation mode. Note, that default mode eTmpFileGetName
1420 /// returns only the name of the temporary file, without creating it.
1421 /// This method can be faster, but it have potential race condition,
1422 /// when other process can leave as behind and create file with the same
1423 /// name first. Also, please note, that if you call GetTmpName() again,
1424 /// without creating file for previous call of this method, the same
1425 /// file name can be returned.
1426 /// @return
1427 /// Name of temporary file, or "kEmptyStr" if there was an error
1428 /// getting temporary file name.
1429 /// @sa
1430 /// GetTmpNameEx, ETmpFileCreationMode
1431 static string GetTmpName(ETmpFileCreationMode mode = eTmpFileGetName);
1432
1433 /// Get temporary file name.
1434 ///
1435 /// @param dir
1436 /// Directory in which temporary file is to be created;
1437 /// default of kEmptyStr means that function try to get application
1438 /// specific temporary directory name from global parameter (see
1439 /// GetTmpName description), then it try to get system temporary
1440 /// directory, and all of this fails - current directory will be used.
1441 /// @param prefix
1442 /// Temporary file name will be prefixed by value of this parameter;
1443 /// default of kEmptyStr means that, effectively, no prefix value will
1444 /// be used.
1445 /// @param mode
1446 /// Temporary file creation mode.
1447 /// If set to "eTmpFileCreate", empty file with unique name will be
1448 /// created. Please, do not forget to remove it yourself as soon as it
1449 /// is no longer needed. On some platforms "eTmpFileCreate" mode is
1450 /// equal to "eTmpFileGetName".
1451 /// If set to "eTmpFileGetName", returns only the name of the temporary
1452 /// file, without creating it. This method can be faster, but it have
1453 /// potential race condition, when other process can leave as behind and
1454 /// create file with the same name first.
1455 /// @return
1456 /// Name of temporary file, or "kEmptyStr" if there was an error
1457 /// getting temporary file name.
1458 /// @sa
1459 /// GetTmpName, ETmpFileCreationMode
1460 static string GetTmpNameEx(const string& dir = kEmptyStr,
1461 const string& prefix = kEmptyStr,
1462 ETmpFileCreationMode mode = eTmpFileGetName);
1463
1464
1465 /// What type of temporary file to create.
1466 enum ETextBinary {
1467 eText, ///< Create text file
1468 eBinary ///< Create binary file
1469 };
1470
1471 /// Which operations to allow on temporary file.
1472 enum EAllowRead {
1473 eAllowRead, ///< Allow read and write
1474 eWriteOnly ///< Allow write only
1475 };
1476
1477 /// Create temporary file and return pointer to corresponding stream.
1478 ///
1479 /// The temporary file will be automatically deleted after the stream
1480 /// object is deleted. If the file exists before the function call, then
1481 /// after the function call it will be removed. Also any previous contents
1482 /// of the file will be overwritten.
1483 /// @param filename
1484 /// Use this value as name of temporary file. If "kEmptyStr" is passed
1485 /// generate a temporary file name.
1486 /// @param text_binary
1487 /// Specifies if temporary filename should be text ("eText") or binary
1488 /// ("eBinary").
1489 /// @param allow_read
1490 /// If set to "eAllowRead", read and write are permitted on temporary
1491 /// file. If set to "eWriteOnly", only write is permitted on temporary
1492 /// file.
1493 /// @return
1494 /// - Pointer to corresponding stream, or
1495 /// - NULL if error encountered.
1496 /// @sa
1497 /// CreateTmpFileEx
1498 static fstream* CreateTmpFile(const string& filename = kEmptyStr,
1499 ETextBinary text_binary = eBinary,
1500 EAllowRead allow_read = eAllowRead);
1501
1502 /// Create temporary file and return pointer to corresponding stream.
1503 ///
1504 /// Similar to CreateTmpEx() except that you can also specify the directory
1505 /// in which to create the temporary file and the prefix string to be used
1506 /// for creating the temporary file.
1507 ///
1508 /// The temporary file will be automatically deleted after the stream
1509 /// object is deleted. If the file exists before the function call, then
1510 /// after the function call it will be removed. Also any previous contents
1511 /// of the file will be overwritten.
1512 /// @param dir
1513 /// The directory in which the temporary file is to be created. If not
1514 /// specified, the temporary file will be created in the current
1515 /// directory.
1516 /// @param prefix
1517 /// Use this value as the prefix for temporary file name. If "kEmptyStr"
1518 /// is passed generate a temporary file name.
1519 /// @param text_binary
1520 /// Specifies if temporary filename should be text ("eText") or binary
1521 /// ("eBinary").
1522 /// @param allow_read
1523 /// If set to "eAllowRead", read and write are permitted on temporary
1524 /// file. If set to "eWriteOnly", only write is permitted on temporary
1525 /// file.
1526 /// @return
1527 /// - Pointer to corresponding stream, or
1528 /// - NULL if error encountered.
1529 /// @sa
1530 /// CreateTmpFile
1531 static fstream* CreateTmpFileEx(const string& dir = ".",
1532 const string& prefix = kEmptyStr,
1533 ETextBinary text_binary = eBinary,
1534 EAllowRead allow_read = eAllowRead);
1535
1536 protected:
1537 /// Get the default global mode.
1538 ///
1539 /// For use in derived classes like CDir and CFile.
1540 static void GetDefaultModeGlobal(EType entry_type,
1541 TMode* user_mode,
1542 TMode* group_mode,
1543 TMode* other_mode,
1544 TSpecialModeBits* special);
1545
1546 /// Get the default mode.
1547 ///
1548 /// For use by derived classes like CDir and CFile.
1549 void GetDefaultMode(TMode* user_mode,
1550 TMode* group_mode,
1551 TMode* other_mode,
1552 TSpecialModeBits* special) const;
1553 mode_t GetDefaultModeT(void) const;
1554
1555 private:
1556 string m_Path; ///< Full path of this directory entry
1557
1558 /// Which default mode: user, group, or other.
1559 ///
1560 /// Used as an index into an array that contains default mode values;
1561 /// so there is no "fDefault" as an enumeration value for EWho here!
1562 enum EWho {
1563 eUser = 0, ///< User mode
1564 eGroup, ///< Group mode
1565 eOther, ///< Other mode
1566 eSpecial ///< Special bits
1567 };
1568
1569 /// Holds default mode values
1570 TMode m_DefaultMode[4/*EWho + Special bits*/];
1571
1572 /// Holds default mode global values, per entry type
1573 static TMode m_DefaultModeGlobal[eUnknown][4/*EWho + Special bits*/];
1574
1575 /// Backup suffix
1576 static const char* m_BackupSuffix;
1577
1578 private:
1579 /// Convert permission mode to symbolic string representation.
1580 static string x_ModeToSymbolicString(EWho who, TMode mode, bool special_bit, char filler);
1581 };
1582
1583
1584
1585 /////////////////////////////////////////////////////////////////////////////
1586 ///
1587 /// CFile --
1588 ///
1589 /// Define class to work with regular files.
1590 /// NOTE: it don't work with any special or block devices like /dev/null
1591 ///
1592 /// Models a file in a file system. Basic functionality is derived from
1593 /// CDirEntry and extended for files.
1594
1595 class NCBI_XNCBI_EXPORT CFile : public CDirEntry
1596 {
1597 typedef CDirEntry CParent; ///< CDirEntry is the parent class
1598
1599 public:
1600 /// Default constructor.
1601 CFile(void);
1602
1603 /// Constructor using specified path string.
1604 CFile(const string& file);
1605
1606 /// Copy constructor.
1607 CFile(const CDirEntry& file);
1608
1609 /// Destructor.
1610 virtual ~CFile(void);
1611
1612 /// Get a type of constructed object.
GetObjectType(void) const1613 virtual EType GetObjectType(void) const { return eFile; };
1614
1615 /// Check existence of file.
1616 /// @note
1617 /// CDirEntry::Exists() could be faster on some platforms,
1618 /// if you don't need to check that entry is a file.
1619 /// @sa CDirEntry::Exists
1620 virtual bool Exists(void) const;
1621
1622 /// Get size of file.
1623 ///
1624 /// @return
1625 /// Size of the file, if operation successful; -1, otherwise.
1626 Int8 GetLength(void) const;
1627
1628 /// Copy a file.
1629 ///
1630 /// @param new_path
1631 /// Target entry path/name.
1632 /// @param flags
1633 /// Flags specified how to copy entry.
1634 /// @param buf_size
1635 /// Size of buffer to read file.
1636 /// Zero value means using default buffer size.
1637 /// @return
1638 /// TRUE if operation successful; FALSE, otherwise.
1639 /// @sa
1640 /// TCopyFlags
1641 virtual bool Copy(const string& new_path, TCopyFlags flags = fCF_Default,
1642 size_t buf_size = 0) const;
1643
1644 /// Compare files contents in binary form.
1645 ///
1646 /// @param file
1647 /// File name to compare.
1648 /// @param buf_size
1649 /// Size of buffer to read file.
1650 /// Zero value means using default buffer size.
1651 /// @return
1652 /// TRUE if files content is equal; FALSE otherwise.
1653 bool Compare(const string& file, size_t buf_size = 0) const;
1654
1655 /// Mode to compare streams in text form.
1656 enum ECompareText {
1657 /// Skip end-of-line characters ('\r' and '\n')
1658 eIgnoreEol = eCompareText_IgnoreEol,
1659 ///< Skip white spaces (in terms of isspace(), including end-of-line)
1660 eIgnoreWs = eCompareText_IgnoreWhiteSpace
1661 };
1662
1663 /// Compare files contents in text form.
1664 ///
1665 /// @param file
1666 /// File name to compare.
1667 /// @param mode
1668 /// Type of white space characters to ignore
1669 /// @param buf_size
1670 /// Size of buffer to read file.
1671 /// Zero value means using default buffer size.
1672 /// @return
1673 /// TRUE if files content is equal; FALSE otherwise.
1674 bool CompareTextContents(const string& file, ECompareText mode,
1675 size_t buf_size = 0) const;
1676 };
1677
1678
1679 /////////////////////////////////////////////////////////////////////////////
1680 ///
1681 /// CDir --
1682 ///
1683 /// Define class to work with directories.
1684 ///
1685
1686 class NCBI_XNCBI_EXPORT CDir : public CDirEntry
1687 {
1688 typedef CDirEntry CParent; ///< CDirEntry is the parent class
1689
1690 public:
1691 /// Default constructor.
1692 CDir(void);
1693
1694 /// Constructor using specified directory name.
1695 CDir(const string& dirname);
1696
1697 /// Copy constructor.
1698 CDir(const CDirEntry& dir);
1699
1700 /// Destructor.
1701 virtual ~CDir(void);
1702
1703 /// Get a type of constructed object.
GetObjectType(void) const1704 virtual EType GetObjectType(void) const { return eDir; };
1705
1706 /// Check if directory "dirname" exists.
1707 /// @note
1708 /// CDirEntry::Exists() could be faster on some platforms,
1709 /// if you don't need to check that entry is a directory.
1710 virtual bool Exists(void) const;
1711
1712 /// Get user "home" directory.
1713 static string GetHome(void);
1714
1715 /// Get temporary directory.
1716 ///
1717 /// Return temporary directory name specified by OS via environment variables.
1718 /// @sa GetAppTmpDir
1719 static string GetTmpDir(void);
1720
1721 /// Get temporary directory name for application.
1722 ///
1723 /// Return temporary directory name specified in the application's registry file or via environment.
1724 /// Registry file:
1725 /// [NCBI]
1726 /// TmpDir = ...
1727 /// Environment variable:
1728 /// NCBI_CONFIG__NCBI__TmpDir
1729 ///
1730 /// If not specified, return GetTmpDir().
1731 /// @sa GetTmpDir
1732 static string GetAppTmpDir(void);
1733
1734 /// Get the current working directory.
1735 static string GetCwd(void);
1736
1737 /// Change the current working directory.
1738 static bool SetCwd(const string& dir);
1739
1740 /// Define a list of pointers to directory entries.
1741 typedef AutoPtr<CDirEntry> TEntry;
1742 typedef list< TEntry > TEntries;
1743
1744 /// Flags for GetEntries()
1745 /// @sa GetEntries, GetEntriesPtr
1746 enum EGetEntriesFlags {
1747 fIgnoreRecursive = (1<<1), ///< Suppress "self recursive"
1748 ///< elements (the directories "."
1749 ///< and "..").
1750 fCreateObjects = (1<<2), ///< Create appropriate subclasses
1751 ///< of CDirEntry (CFile,CDir,...),
1752 ///< not just CDirEntry objects.
1753 fNoCase = (1<<3), ///< Ignore upper and lower-case
1754 ///< differences when doing a mask
1755 ///< comparison. Makes the mask
1756 ///< case-insensitive.
1757 fIgnorePath = (1<<4), ///< Return only names of entries,
1758 ///< not their full paths.
1759 fThrowOnError = (1<<5), ///< Throws an exceptions on error,
1760 ///< instead of returning empty/null value.
1761
1762 // Deprecated entries to be removed in the future
1763 eAllEntries = 0, ///< \deprecated Only provided for
1764 ///< backward compatibility. Will be
1765 ///< removed in the future. Do not use.
1766 eIgnoreRecursive = fIgnoreRecursive
1767 ///< \deprecated Only provided for
1768 ///< backward compatibility. Will be
1769 ///< removed in the future. Do not use.
1770 };
1771 typedef int TGetEntriesFlags; ///< Binary OR of "EGetEntriesFlags"
1772
1773
1774 /// Get directory entries based on the specified "mask".
1775 ///
1776 /// @param mask
1777 /// Use to select only entries that match this mask.
1778 /// Do not use file mask if set to "kEmptyStr".
1779 /// @param flags
1780 /// Flags defines behavior and which entries to return.
1781 /// @return
1782 /// A list containing all directory entries.
1783 /// Return empty list on error.
1784 /// @note
1785 /// Use fThrowOnError to avoid getting empty list on error
1786 /// and throwing an exception instead.
1787 TEntries GetEntries(const string& mask = kEmptyStr,
1788 TGetEntriesFlags flags = 0) const;
1789
1790 /// Get directory entries based on the specified set of "masks".
1791 ///
1792 /// @param masks
1793 /// Use to select only entries that match this set of masks.
1794 /// @param flags
1795 /// Flags defines behavior and which entries to return.
1796 /// @return
1797 /// A list containing all directory entries.
1798 /// Return empty list on error.
1799 /// @note
1800 /// Use fThrowOnError to avoid getting empty list on error
1801 /// and throwing an exception instead.
1802 TEntries GetEntries(const vector<string>& masks,
1803 TGetEntriesFlags flags = 0) const;
1804
1805 /// Get directory entries based on the specified set of "masks".
1806 ///
1807 /// @param mask
1808 /// Use to select only entries that match this set of masks.
1809 /// @param flags
1810 /// Flags defines behavior and which entries to return.
1811 /// @return
1812 /// A list containing all directory entries.
1813 /// Return empty list on error.
1814 /// @note
1815 /// Use fThrowOnError to avoid getting empty list on error
1816 /// and throwing an exception instead.
1817 TEntries GetEntries(const CMask& masks,
1818 TGetEntriesFlags flags = 0) const;
1819
1820 /// Get directory entries based on the specified "mask".
1821 /// This methods are faster on big directories than GetEntries().
1822 ///
1823 /// @param mask
1824 /// Use to select only entries that match this mask.
1825 /// Do not use file mask if set to "kEmptyStr".
1826 /// @param flags
1827 /// Flags defines behavior and which entries to return.
1828 /// @return
1829 /// A pointer to list of directory entries.
1830 /// NULL in the case of error.
1831 /// @note
1832 /// Do not forget to release allocated memory using return pointer.
1833 TEntries* GetEntriesPtr(const string& mask = kEmptyStr,
1834 TGetEntriesFlags flags = 0) const;
1835
1836 /// Get directory entries based on the specified set of "masks".
1837 /// This methods are faster on big directories than GetEntries().
1838 ///
1839 /// @param mask
1840 /// Use to select only entries that match this set of masks.
1841 /// @param flags
1842 /// Flags defines behavior and which entries to return.
1843 /// @return
1844 /// A pointer to list of directory entries.
1845 /// NULL in the case of error.
1846 /// @note
1847 /// Do not forget to release allocated memory using return pointer.
1848 TEntries* GetEntriesPtr(const vector<string>& masks,
1849 TGetEntriesFlags flags = 0) const;
1850
1851 /// Get directory entries based on the specified set of "masks".
1852 /// This methods are faster on big directories than GetEntries().
1853 ///
1854 /// @param mask
1855 /// Use to select only entries that match this set of masks.
1856 /// @param flags
1857 /// Flags defines behavior and which entries to return.
1858 /// @return
1859 /// A pointer to list of directory entries.
1860 /// NULL in the case of error.
1861 /// @note
1862 /// Do not forget to release allocated memory using return pointer.
1863 TEntries* GetEntriesPtr(const CMask& masks,
1864 TGetEntriesFlags flags = 0) const;
1865
1866 // OBSOLETE functions. Will be deleted soon.
1867 // Please use versions of GetEntries*() listed above.
1868
1869 typedef TGetEntriesFlags EGetEntriesMode;
1870 /// @deprecated Use other variant of of GetEntries() instead.
1871 NCBI_DEPRECATED
1872 TEntries GetEntries (const string& mask,
1873 EGetEntriesMode mode,
1874 NStr::ECase use_case) const;
1875 /// @deprecated Use other variant of of GetEntries() instead.
1876 NCBI_DEPRECATED
1877 TEntries GetEntries (const vector<string>& masks,
1878 EGetEntriesMode mode,
1879 NStr::ECase use_case) const;
1880 /// @deprecated Use other variant of of GetEntries() instead.
1881 NCBI_DEPRECATED
1882 TEntries GetEntries (const CMask& masks,
1883 EGetEntriesMode mode,
1884 NStr::ECase use_case) const;
1885 /// @deprecated Use other variant of of GetEntries() instead.
1886 NCBI_DEPRECATED
1887 TEntries* GetEntriesPtr(const string& mask,
1888 EGetEntriesMode mode,
1889 NStr::ECase use_case) const;
1890 /// @deprecated Use other variant of of GetEntries() instead.
1891 NCBI_DEPRECATED
1892 TEntries* GetEntriesPtr(const vector<string>& masks,
1893 EGetEntriesMode mode,
1894 NStr::ECase use_case) const;
1895 /// @deprecated Use other variant of of GetEntries() instead.
1896 NCBI_DEPRECATED
1897 TEntries* GetEntriesPtr(const CMask& masks,
1898 EGetEntriesMode mode,
1899 NStr::ECase use_case) const;
1900
1901 /// Flags for Create()/CreatePath()
1902 /// @sa Create, CreatePath
1903 enum ECreateFlags {
1904 /// Default directory creation mode
1905 /// - no error if directory already exists;
1906 /// - don't change permissions if already exists;
1907 /// - use default mode for created directory
1908 /// see: SetDefaultMode(), SetDefaultModeGlobal(), CFileAPI::SetHonorUmask().
1909 fCreate_Default = 0,
1910 /// Don't change permissions after creation, leave it for OS and umask control.
1911 /// This flag have a priority over CFileAPI::SetHonorUmask(), that works with fCD_Default only.
1912 fCreate_PermByUmask = (1 << 1),
1913 /// Use same permissions as parent directory (umask ignored)
1914 fCreate_PermAsParent = (1 << 2),
1915 /// Error, if directory already exists. All other existent entry with
1916 /// the same name (including symbolic links to directory) lead to an error by default.
1917 fCreate_ErrorIfExists = (1 << 3),
1918 /// Allow to "update" permissions for already existent directory
1919 /// using default, umask or parent permissions as specified by previous flags.
1920 /// Note: Create() only, ignored by CreatePath().
1921 fCreate_UpdateIfExists = (1 << 4)
1922 };
1923 typedef unsigned int TCreateFlags; ///< Binary OR of "ECreateFlags"
1924
1925 /// Create the directory using "dirname" passed in the constructor.
1926 ///
1927 /// Default directory creation mode:
1928 /// - TRUE if directory already exists;
1929 /// - don't change permissions if already exists;
1930 /// - use default mode for created directory
1931 /// @return
1932 /// TRUE if operation successful; FALSE, otherwise.
1933 /// @sa
1934 /// SetDefaultMode, SetDefaultModeGlobal, CFileAPI::SetHonorUmask, CreatePath
1935 bool Create(TCreateFlags flags = fCreate_Default) const;
1936
1937 /// Create the directory path recursively possibly more than one at a time.
1938 ///
1939 /// @return
1940 /// TRUE if operation successful; FALSE otherwise.
1941 /// @sa Create
1942 bool CreatePath(TCreateFlags flags = fCreate_Default) const;
1943
1944 /// Copy directory.
1945 ///
1946 /// @param new_path
1947 /// New path/name for entry.
1948 /// @param flags
1949 /// Flags specified how to copy directory.
1950 /// @param buf_size
1951 /// Size of buffer to read file.
1952 /// Zero value means using default buffer size.
1953 /// @return
1954 /// TRUE if operation successful; FALSE, otherwise.
1955 /// @sa
1956 /// CDirEntry::TCopyFlags, CDirEntry::Copy, CFile::Copy
1957 virtual bool Copy(const string& new_path, TCopyFlags flags = fCF_Default,
1958 size_t buf_size = 0) const;
1959
1960 /// Delete existing directory.
1961 ///
1962 /// @param flags
1963 /// Directory processing flags. Some popular sets of flags
1964 /// combined together and listed below:
1965 /// - eOnlyEmpty
1966 /// directory can be removed only if it is empty;
1967 /// - eTopDirOnly
1968 /// remove all files in the top directory only,
1969 /// no any subdirectory or files in it;
1970 /// - eNonRecursive
1971 /// same as eTopDirOnly, but removes also empty
1972 /// subdirectories in the top directory only;
1973 /// - eRecursive
1974 /// remove all files in directory and all its subdirectories;
1975 /// - eRecursiveIgnoreMissing
1976 /// same as eRecursive, but do not report an error
1977 /// for missed entries.
1978 /// @return
1979 /// TRUE if operation successful; FALSE otherwise.
1980 /// @sa
1981 /// CDirEntry::Remove, EProcessingFlags
1982 virtual bool Remove(TRemoveFlags flags = eRecursive) const;
1983
1984
1985 /// Set permission mode(s) for a directory.
1986 ///
1987 /// Permissions are set as specified by the passed values for
1988 /// user_mode, group_mode and other_mode. This method rewrites
1989 /// each user/group/other/special permission by default.
1990 /// @note
1991 /// Adding one of the EModeRelative flags to mode change default
1992 /// behavior that replace modes with passed values and allow
1993 /// for relative mode change for any of user/group/other/special.
1994 /// It is possible to keep it as is, or add/remove some permission
1995 /// modes specified in parameters.
1996 /// @note
1997 /// Passing "fDefault" will cause the corresponding mode
1998 /// to be taken and set from its default setting.
1999 /// @param flags
2000 /// Directory processing flags. Some popular sets of flags
2001 /// combined together and listed below:
2002 /// - eEntryOnly
2003 /// change modes for the directory entry itself;
2004 /// - eTopDirOnly
2005 /// change modes for all files in the top directory only,
2006 /// no for any subdirectory or files in it;
2007 /// - eNonRecursive
2008 /// change modes for all entries in the top directory only,
2009 /// including subdirectory entries, but do not for any files
2010 /// in them;
2011 /// - eRecursive
2012 /// change modes for all files and subdirectories recursively;
2013 /// - eRecursiveIgnoreMissing
2014 /// same as eRecursive, but do not report an error
2015 /// for missed entries.
2016 /// @return
2017 /// TRUE if permissions successfully set for all entries; FALSE, otherwise.
2018 /// @sa
2019 /// SetMode, SetDefaultMode, SetDefaultModeGlobal,
2020 /// EMode, EModeRelative, EProcessingFlags
2021 virtual bool SetMode(TMode user_mode, // e.g. fDefault
2022 TMode group_mode = fDefault,
2023 TMode other_mode = fDefault,
2024 TSpecialModeBits special = 0,
2025 TSetModeFlags flags = eEntryOnly) const;
2026 };
2027
2028
2029 /////////////////////////////////////////////////////////////////////////////
2030 ///
2031 /// CSymLink --
2032 ///
2033 /// Define class to work with symbolic links.
2034 ///
2035 /// Models the files in a file system. Basic functionality is derived from
2036 /// CDirEntry and extended for files.
2037
2038 class NCBI_XNCBI_EXPORT CSymLink : public CDirEntry
2039 {
2040 typedef CDirEntry CParent; ///< CDirEntry is the parent class
2041
2042 public:
2043 /// Default constructor.
2044 CSymLink(void);
2045
2046 /// Constructor using specified path string.
2047 CSymLink(const string& link);
2048
2049 /// Copy constructor.
2050 CSymLink(const CDirEntry& link);
2051
2052 /// Destructor.
2053 virtual ~CSymLink(void);
2054
2055 /// Get a type of constructed object.
GetObjectType(void) const2056 virtual EType GetObjectType(void) const { return eLink; };
2057
2058 /// Check existence of link.
2059 virtual bool Exists(void) const;
2060
2061 /// Create symbolic link.
2062 ///
2063 /// @param path
2064 /// Path to some entry that link will be pointed to.
2065 /// @return
2066 /// TRUE if operation successful; FALSE, otherwise.
2067 /// Return FALSE also if link already exists.
2068 bool Create(const string& path) const;
2069
2070 /// Copy link.
2071 ///
2072 /// @param new_path
2073 /// Target entry path/name.
2074 /// @param flags
2075 /// Flags specified how to copy entry.
2076 /// @param buf_size
2077 /// Size of buffer to read file.
2078 /// Zero value means using default buffer size.
2079 /// @return
2080 /// TRUE if operation successful; FALSE, otherwise.
2081 /// @sa
2082 /// CDirEntry::TCopyFlags, CDirEntry::Copy, Create
2083 virtual bool Copy(const string& new_path, TCopyFlags flags = fCF_Default,
2084 size_t buf_size = 0) const;
2085 };
2086
2087
2088
2089 /////////////////////////////////////////////////////////////////////////////
2090 ///
2091 /// CFileUtil -- Utility functions.
2092 ///
2093 /// Throws an exceptions on error.
2094 ///
2095 /// NOTE: For some combinations of platform, file system, drivers and some
2096 /// other unknown factors, the systems calls used to get system
2097 /// information can return incorrect information about free/total
2098 /// disk space, be aware.
2099
2100 class NCBI_XNCBI_EXPORT CFileUtil
2101 {
2102 public:
2103 /// Unix:
2104 /// The path name to any file/dir withing file system.
2105 /// MS Windows:
2106 /// The path name to any file/dir withing file system.
2107 /// The root directory of the disk, or UNC name
2108 /// (for example, \\MyServer\MyShare\, C:\).
2109 /// The "." can be used to get disk space on current disk.
2110
2111 //// Type of file system
2112 enum EFileSystemType {
2113 eUnknown = 0, ///< File system type could not be determined
2114
2115 eADFS, ///< Acorn's Advanced Disc Filing System
2116 eAdvFS, ///< Tru64 UNIX Advanced File System
2117 eAFFS, ///< Amiga Fast File System
2118 eAFS, ///< AFS File System
2119 eAUTOFS, ///< Automount File System
2120 eBEFS, ///< The Be (BeOS) File System (BeFS)
2121 eBFS, ///< Boot File System
2122 eCacheFS, ///< Cache File System
2123 eCryptFS, ///< eCryptfs (Enterprise Cryptographic Filesystem)
2124 eCDFS, ///< ISO 9660 CD-ROM file system (CDFS/ISO9660)
2125 eCIFS, ///< Common Internet File System
2126 eCODA, ///< Coda File System
2127 eCOH, ///< Coherent (System V)
2128 eCRAMFS, ///< Compressed ROMFS
2129 eDebugFS, ///< Debug File System (Linux)
2130 eDEVFS, ///< Device File System
2131 eDFS, ///< DCE Distributed File System (DCE/DFS)
2132 eEFS, ///< The Encrypting File System (EFS) (MSWin)
2133 eEXOFS, ///< EXtended Object File System (EXOFS)
2134 eExt, ///< Extended file system
2135 eExt2, ///< Second Extended file system
2136 eExt3, ///< Journalled form of ext2
2137 eFAT, ///< Traditional 8.3 MSDOS-style file system
2138 eFAT32, ///< FAT32 file system
2139 eFDFS, ///< File Descriptor File System
2140 eFFM, ///< File-on-File Mounting file system
2141 eFFS, ///< Fast File System (*BSD)
2142 eFUSE, ///< Filesystem in Userspace (FUSE)
2143 eFUSE_CTL, ///< Fusectl (helper filesystem for FUSE)
2144 eGFS2, ///< Global File System
2145 eGPFS, ///< IBM General Parallel File System
2146 eHFS, ///< Hierarchical File System
2147 eHFSPLUS, ///< Hierarchical File System
2148 eHPFS, ///< OS/2 High-Performance File System
2149 eHSFS, ///< High Sierra File System
2150 eJFS, ///< Journalling File System
2151 eJFFS, ///< Journalling Flash File System
2152 eJFFS2, ///< Journalling Flash File System v2
2153 eLOFS, ///< Loopback File System
2154 eMFS, ///< Memory File System
2155 eMinix, ///< Minix v1
2156 eMinix2, ///< Minix v2
2157 eMinix3, ///< Minix v3
2158 eMSFS, ///< Mail Slot File System
2159 eNCPFS, ///< NetWare Core Protocol File System
2160 eNFS, ///< Network File System (NFS)
2161 eNTFS, ///< New Technology File System
2162 eOCFS2, ///< Oracle Cluster File System 2
2163 eOPENPROM, ///< /proc/openprom filesystem
2164 ePANFS, ///< Panasas FS
2165 ePROC, ///< /proc file system
2166 ePVFS2, ///< Parallel Virtual File System
2167 eReiserFS, ///< Reiser File System
2168 eRFS, ///< Remote File Share file system (AT&T RFS)
2169 eQNX4, ///< QNX4 file system
2170 eROMFS, ///< ROM File System
2171 eSELINUX, ///< Security-Enhanced Linux (SELinux)
2172 eSMBFS, ///< Samba File System
2173 eSPECFS, ///< SPECial File System
2174 eSquashFS, ///< Compressed read-only filesystem (Linux)
2175 eSYSFS, ///< (Linux)
2176 eSYSV2, ///< System V
2177 eSYSV4, ///< System V
2178 eTMPFS, ///< Virtual Memory File System (TMPFS/SHMFS)
2179 eUBIFS, ///< The Unsorted Block Image File System
2180 eUDF, ///< Universal Disk Format
2181 eUFS, ///< UNIX File System
2182 eUFS2, ///< UNIX File System
2183 eUSBDEVICE, ///< USBDevice file system
2184 eV7, ///< UNIX V7 File System
2185 eVxFS, ///< VERITAS File System (VxFS)
2186 eVZFS, ///< Virtuozzo File System (VZFS)
2187 eXENIX, ///< Xenix (SysV) file system
2188 eXFS, ///< XFS File System
2189 eXIAFS ///<
2190 };
2191
2192 /// Structure to store information about file system.
2193 struct SFileSystemInfo {
2194 EFileSystemType fs_type; ///< Type of filesystem
2195 Uint8 total_space; ///< Total disk space in bytes
2196 Uint8 free_space; ///< Free disk space in bytes
2197 Uint8 used_space; ///< Used disk space in bytes
2198 unsigned long block_size; ///< Allocation unit (block) size
2199 unsigned long filename_max; ///< Maximum filename length
2200 ///< (part between slashes)
2201 };
2202
2203 /// Get file system information.
2204 ///
2205 /// Get information for the user associated with the calling thread only.
2206 /// @param path
2207 /// String that specifies filesystem for which information
2208 /// is to be returned.
2209 /// @param info
2210 /// Pointer to structure which receives file system information.
2211 static void GetFileSystemInfo(const string& path, SFileSystemInfo* info);
2212
2213 /// Get free disk space information.
2214 ///
2215 /// Get information for the user associated with the calling thread only.
2216 /// If per-user quotas are in use, then the returned values may be less
2217 /// than the actual number of free bytes available on disk.
2218 /// @param path
2219 /// String that specifies the file system for which to return
2220 /// the number of free bytes available on disk.
2221 /// @return
2222 /// The amount of free space in bytes.
2223 /// @sa
2224 /// GetFileSystemInfo, GetTotalDiskSpace, GetUsedDiskSpace
2225 static Uint8 GetFreeDiskSpace(const string& path);
2226
2227 /// Get used disk space information.
2228 ///
2229 /// Get information for the user associated with the calling thread only.
2230 /// If per-user quotas are in use, then the returned values may be less
2231 /// than the actual number of free bytes available on disk.
2232 /// @param path
2233 /// String that specifies the file system for which to return
2234 /// the number of used bytes on disk.
2235 /// @return
2236 /// The amount of used space in bytes.
2237 /// @sa
2238 /// GetFileSystemInfo, GetTotalDiskSpace, GetFreeDiskSpace
2239 static Uint8 GetUsedDiskSpace(const string& path);
2240
2241 /// Get total disk space information.
2242 ///
2243 /// Get information for the user associated with the calling thread only.
2244 /// If per-user quotas are in use, then the returned value may be less
2245 /// than the actual total number of bytes on the disk.
2246 /// @param path
2247 /// String that specifies the file system for which to return
2248 /// the total disk space in bytes.
2249 /// @return
2250 /// The amount of total disk space in bytes.
2251 /// @sa
2252 /// GetFileSystemInfo, GetFreeDiskSpace, GetUsedDiskSpace
2253 static Uint8 GetTotalDiskSpace(const string& path);
2254 };
2255
2256
2257
2258 /////////////////////////////////////////////////////////////////////////////
2259 ///
2260 /// CFileDeleteList --
2261 ///
2262 /// Define a list of dir entries for deletion.
2263 ///
2264 /// Each object of this class maintains a list of paths that will be deleted
2265 /// from the file system when the object goes out of scope.
2266
2267 class NCBI_XNCBI_EXPORT CFileDeleteList : public CObject
2268 {
2269 public:
2270 /// Destructor removes all dir entries on list.
2271 ~CFileDeleteList();
2272
2273 typedef list<string> TList;
2274
2275 /// Add a path for later deletion.
2276 /// @param path
2277 /// String that specifies the file system entry to delete.
2278 /// It will be stored as the absolute normalized path, so relative names
2279 /// are safe to use.
2280 /// @note
2281 /// Directories will be removed recursively.
2282 /// Symbolic links -- without dir entries which they points to.
2283 void Add(const string& path);
2284
2285 /// Get the underlying list.
2286 const TList& GetList() const;
2287 /// Set the underlying list.
2288 void SetList(TList& list);
2289
2290 private:
2291 TList m_Paths; ///< List of dir entries for deletion
2292 };
2293
2294
2295 /////////////////////////////////////////////////////////////////////////////
2296 ///
2297 /// CFileDeleteAtExit --
2298 ///
2299 /// This class is used to mark dir entries for deletion at application exit.
2300 /// @sa CFileDeleteList
2301
2302 class NCBI_XNCBI_EXPORT CFileDeleteAtExit
2303 {
2304 public:
2305 /// Add the name of a dir entry; it will be deleted on (normal) exit
2306 static void Add(const string& path);
2307
2308 /// Get underlying static CFileDeleteList object
2309 static const CFileDeleteList& GetDeleteList();
2310 /// Set the underlying static CFileDeleteList object
2311 static void SetDeleteList(CFileDeleteList& list);
2312 };
2313
2314
2315 /////////////////////////////////////////////////////////////////////////////
2316 ///
2317 /// CTmpFile --
2318 ///
2319 /// Define class to generate temporary file name (or use specified), which
2320 /// can be automatically removed on the object destruction.
2321 ///
2322 /// This class generate temporary file name in the temporary directory
2323 /// specified by OS. But this behavior can be changed, just set desired
2324 /// temporary directory using global parameter (see CParam class description)
2325 /// in the registry or environment (section 'NCBI', name 'TmpDir') and it
2326 /// will used by default in this class.
2327 /// @note
2328 /// The files created this way are not really temporary. If application
2329 /// terminates abnormally, that such files can be left on the file system.
2330 /// To avoid this you can use CFile::CreateTmpFile().
2331 /// @sa CFile::CreateTmpFile, CFile::GetTmpName, CParam
2332
2333 class NCBI_XNCBI_EXPORT CTmpFile : public CObject
2334 {
2335 public:
2336 /// What to do with the file on object destruction.
2337 enum ERemoveMode {
2338 eRemove, ///< Remove file
2339 eNoRemove ///< Do not remove file
2340 };
2341
2342 /// Default constructor.
2343 ///
2344 /// Automatically generate temporary file name.
2345 CTmpFile(ERemoveMode remove_file = eRemove);
2346
2347 /// Constructor.
2348 ///
2349 /// Use given temporary file name.
2350 CTmpFile(const string& file_name, ERemoveMode remove_file = eRemove);
2351
2352 /// Destructor.
2353 ~CTmpFile(void);
2354
2355 /// What to do if stream already exists in the AsInputFile/AsOutputFile.
2356 enum EIfExists {
2357 /// You can make call of AsInputFile/AsOutputFile only once,
2358 /// on each following call throws CFileException exception.
2359 eIfExists_Throw,
2360 /// Delete previous stream and return reference to new object.
2361 /// Invalidate all previously returned references.
2362 eIfExists_Reset,
2363 /// Return reference to current stream, create new one if it
2364 /// does not exists yet.
2365 eIfExists_ReturnCurrent
2366 };
2367
2368 /// Create I/O stream on the base of our file.
2369 CNcbiIstream& AsInputFile (EIfExists if_exists,
2370 IOS_BASE::openmode mode = IOS_BASE::in);
2371 CNcbiOstream& AsOutputFile(EIfExists if_exists,
2372 IOS_BASE::openmode mode = IOS_BASE::out);
2373
2374 /// Return used file name (generated or given in the constructor).
2375 const string& GetFileName(void) const;
2376
2377 private:
2378 string m_FileName; ///< Name of temporary file.
2379 ERemoveMode m_RemoveOnDestruction; ///< Remove file on destruction
2380
2381 // Automatic pointers to store I/O streams.
2382 unique_ptr<CNcbiIstream> m_InFile;
2383 unique_ptr<CNcbiOstream> m_OutFile;
2384
2385 private:
2386 // Prevent copying
2387 CTmpFile(const CTmpFile&);
2388 CTmpFile& operator=(const CTmpFile&);
2389 };
2390
2391
2392 /////////////////////////////////////////////////////////////////////////////
2393 ///
2394 /// Forward declaration of struct containing OS-specific mem.-file handle.
2395
2396 struct SMemoryFileHandle;
2397 struct SMemoryFileAttrs;
2398
2399
2400 /////////////////////////////////////////////////////////////////////////////
2401 ///
2402 /// CMemoryFile_Base --
2403 ///
2404 /// Define base class for support file memory mapping.
2405
2406 class NCBI_XNCBI_EXPORT CMemoryFile_Base
2407 {
2408 public:
2409 typedef Int8 TOffsetType; // signed for POSIX compatibility
2410
2411 /// Which operations are permitted in memory map file.
2412 typedef enum {
2413 eMMP_Read, ///< Data can be read
2414 eMMP_Write, ///< Data can be written
2415 eMMP_ReadWrite ///< Data can be read and written
2416 } EMemMapProtect;
2417
2418 /// Whether to share changes or not.
2419 typedef enum {
2420 eMMS_Shared, ///< Changes are shared
2421 eMMS_Private ///< Changes are private (write do not change file)
2422 } EMemMapShare;
2423
2424 /// Memory file open mode.
2425 enum EOpenMode {
2426 eCreate, ///< Create new file or rewrite existent with zeros.
2427 eOpen, ///< Open existent file, throw exception otherwise.
2428 eExtend, ///< Extend file size with zeros if it exist,
2429 ///< throw exception otherwise.
2430 eDefault = eOpen ///< Default open mode
2431 };
2432
2433 /// Constructor.
2434 ///
2435 CMemoryFile_Base(void);
2436
2437
2438 /// Check if memory-mapping is supported by the C++ Toolkit on this
2439 /// platform.
2440 static bool IsSupported(void);
2441
2442
2443 /// What type of data access pattern will be used for mapped region.
2444 ///
2445 /// Advises the VM system that the a certain region of user mapped memory
2446 /// will be accessed following a type of pattern. The VM system uses this
2447 /// information to optimize work with mapped memory.
2448 ///
2449 /// NOTE: Works on UNIX platform only.
2450 /// @sa
2451 /// EMemoryAdvise, MemoryAdvise
2452 typedef enum {
2453 eMMA_Normal = eMADV_Normal,
2454 eMMA_Random = eMADV_Random,
2455 eMMA_Sequential = eMADV_Sequential,
2456 eMMA_WillNeed = eMADV_WillNeed,
2457 eMMA_DontNeed = eMADV_DontNeed,
2458 eMMA_DoFork = eMADV_DoFork,
2459 eMMA_DontFork = eMADV_DontFork,
2460 eMMA_Mergeable = eMADV_Mergeable,
2461 eMMA_Unmergeable = eMADV_Unmergeable
2462 } EMemMapAdvise;
2463
2464 /// Advise on memory map usage for specified region.
2465 ///
2466 /// @param addr
2467 /// Address of memory region whose usage is being advised.
2468 /// @param len
2469 /// Length of memory region whose usage is being advised.
2470 /// @param advise
2471 /// Advise on expected memory usage pattern.
2472 /// @return
2473 /// - TRUE, if memory advise operation successful.
2474 /// - FALSE, if memory advise operation not successful, or is not supported
2475 /// on current platform.
2476 /// @sa
2477 /// EMemMapAdvise, MemMapAdvise
2478 static bool MemMapAdviseAddr(void* addr, size_t len, EMemMapAdvise advise);
2479 };
2480
2481
2482
2483 /////////////////////////////////////////////////////////////////////////////
2484 ///
2485 /// CMemoryFileSegment --
2486 ///
2487 /// Define auxiliary class for mapping a memory file region of the file
2488 /// into the address space of the calling process.
2489 ///
2490 /// Throws an exceptions on error.
2491
2492 class NCBI_XNCBI_EXPORT CMemoryFileSegment : public CMemoryFile_Base
2493 {
2494 public:
2495 /// Constructor.
2496 ///
2497 /// Maps a view of the file, represented by "handle", into the address
2498 /// space of the calling process.
2499 /// @param handle
2500 /// Handle to view of the mapped file.
2501 /// @param attr
2502 /// Specify operations permitted on memory mapped region.
2503 /// @param offset
2504 /// The file offset where mapping is to begin.
2505 /// Cannot accept values less than 0.
2506 /// @param length
2507 /// Number of bytes to map. The parameter value should be more than 0.
2508 /// @sa
2509 /// EMemMapProtect, EMemMapShare, GetPtr, GetSize, GetOffset
2510 CMemoryFileSegment(SMemoryFileHandle& handle,
2511 SMemoryFileAttrs& attrs,
2512 TOffsetType offset,
2513 size_t length);
2514
2515 /// Destructor.
2516 ///
2517 /// Unmaps a mapped area of the file.
2518 ~CMemoryFileSegment(void);
2519
2520 /// Get pointer to beginning of data.
2521 ///
2522 /// @return
2523 /// - Pointer to start of data, or
2524 /// - NULL if mapped to a file of zero length, or if not mapped.
2525 void* GetPtr(void) const;
2526
2527 /// Get offset of the mapped area from beginning of file.
2528 ///
2529 /// @return
2530 /// Offset in bytes of mapped area from beginning of the file.
2531 /// Always return value passed in constructor even if data
2532 /// was not successfully mapped.
2533 TOffsetType GetOffset(void) const;
2534
2535 /// Get length of the mapped area.
2536 ///
2537 /// @return
2538 /// - Length in bytes of the mapped area, or
2539 /// - 0 if not mapped.
2540 size_t GetSize(void) const;
2541
2542 /// Get pointer to beginning of really mapped data.
2543 ///
2544 /// When the mapping object is creating and the offset is not a multiple
2545 /// of the allocation granularity, that offset and length can be adjusted
2546 /// to match it. The "length" value will be automatically increased on the
2547 /// difference between passed and real offsets.
2548 /// @return
2549 /// - Pointer to start of data, or
2550 /// - NULL if mapped to a file of zero length, or if not mapped.
2551 /// @sa
2552 /// GetRealOffset, GetRealSize, GetPtr
2553 void* GetRealPtr(void) const;
2554
2555 /// Get real offset of the mapped area from beginning of file.
2556 ///
2557 /// This real offset is adjusted to system's memory allocation granularity
2558 /// value and can be less than requested "offset" in the constructor.
2559 /// @return
2560 /// Offset in bytes of mapped area from beginning of the file.
2561 /// Always return adjusted value even if data was not successfully mapped.
2562 /// @sa
2563 /// GetRealPtr, GetRealSize, GetOffset
2564 TOffsetType GetRealOffset(void) const;
2565
2566 /// Get real length of the mapped area.
2567 ///
2568 /// Number of really mapped bytes of file. This length value can be
2569 /// increased if "offset" is not a multiple of the allocation granularity.
2570 /// @return
2571 /// - Length in bytes of the mapped area, or
2572 /// - 0 if not mapped.
2573 /// @sa
2574 /// GetRealPtr, GetRealOffset, GetSize
2575 size_t GetRealSize(void) const;
2576
2577 /// Flush by writing all modified copies of memory pages to the
2578 /// underlying file.
2579 ///
2580 /// NOTE: By default data will be flushed in the destructor.
2581 /// @return
2582 /// - TRUE, if all data was flushed successfully.
2583 /// - FALSE, if not mapped or if an error occurs.
2584 bool Flush(void) const;
2585
2586 /// Unmap file view from memory.
2587 ///
2588 /// @return
2589 /// TRUE on success; or FALSE on error.
2590 bool Unmap(void);
2591
2592 /// Advise on mapped memory map usage.
2593 ///
2594 /// @param advise
2595 /// Advise on expected memory usage pattern.
2596 /// @return
2597 /// - TRUE, if memory advise operation successful.
2598 /// - FALSE, if memory advise operation not successful, or is not supported
2599 /// on current platform.
2600 /// @sa
2601 /// EMemMapAdvise, MemMapAdviseAddr
2602 bool MemMapAdvise(EMemMapAdvise advise) const;
2603
2604 private:
2605 // Check that file is mapped, throw exception otherwise.
2606 void x_Verify(void) const;
2607
2608 private:
2609 // Values for user
2610 void* m_DataPtr; ///< Pointer to the beginning of the mapped area.
2611 ///> The user seen this one.
2612 TOffsetType m_Offset; ///< Requested starting offset of the
2613 ///< mapped area from beginning of file.
2614 size_t m_Length; ///< Requested length of the mapped area.
2615
2616 // Internal real values
2617 void* m_DataPtrReal; ///< Real pointer to the beginning of the mapped
2618 ///< area which should be fried later.
2619 TOffsetType m_OffsetReal; ///< Corrected starting offset of the
2620 ///< mapped area from beginning of file.
2621 size_t m_LengthReal; ///< Corrected length of the mapped area.
2622
2623 // Friend classes
2624 friend class CMemoryFile;
2625
2626 private:
2627 // Prevent copying
2628 CMemoryFileSegment(const CMemoryFileSegment&);
2629 void operator=(const CMemoryFileSegment&);
2630 };
2631
2632
2633
2634 /////////////////////////////////////////////////////////////////////////////
2635 ///
2636 /// CMemoryFileMap --
2637 ///
2638 /// Define class for support a partial file memory mapping.
2639 ///
2640 /// Note, that all mapped into memory file segments have equal protect and
2641 /// share attributes, because they restricted with file open mode.
2642 /// Note, that the mapping file must exists or can be create/extended.
2643 /// If file size changes after mapping, the effect of references to portions
2644 /// of the mapped region that correspond to added or removed portions of
2645 /// the file is unspecified.
2646 ///
2647 /// Throws an exceptions on error.
2648
2649 class NCBI_XNCBI_EXPORT CMemoryFileMap : public CMemoryFile_Base
2650 {
2651 public:
2652 /// Constructor.
2653 ///
2654 /// Initialize the memory mapping on file "file_name".
2655 /// @param filename
2656 /// Name of file to map to memory.
2657 /// @param protect_attr
2658 /// Specify operations permitted on memory mapped file.
2659 /// @param share_attr
2660 /// Specify if change to memory mapped file can be shared or not.
2661 /// @param mode
2662 /// File open mode.
2663 /// @param max_file_len
2664 /// The size of created file if 'mode' parameter is eCreate or eExtend.
2665 /// File will be never truncated if open mode is eExtend and real file
2666 /// size is more that specified maximum length.
2667 /// @sa
2668 /// EMemMapProtect, EMemMapShare, EOpenMode
2669 /// @note
2670 /// MS Windows: If file is open in eMMP_Read mode with eMMS_Private
2671 /// protection, that memory pages will be mapped in exclusive mode,
2672 /// and any other process cannot access the same file for writing.
2673 CMemoryFileMap(const string& file_name,
2674 EMemMapProtect protect_attr = eMMP_Read,
2675 EMemMapShare share_attr = eMMS_Shared,
2676 EOpenMode mode = eDefault,
2677 Uint8 max_file_len = 0);
2678
2679 /// Destructor.
2680 ///
2681 /// Calls Unmap() and cleans up memory.
2682 ~CMemoryFileMap(void);
2683
2684 /// Map file segment.
2685 ///
2686 /// @param offset
2687 /// The file offset where mapping is to begin. If the offset is not
2688 /// a multiple of the allocation granularity, that it can be decreased
2689 /// to match it. The "length" value will be automatically increased on
2690 /// the difference between passed and real offsets. The real offset can
2691 /// be obtained using GetRealOffset(). Cannot accept values less than 0.
2692 /// @param length
2693 /// Number of bytes to map. This value can be increased if "offset"
2694 /// is not a multiple of the allocation granularity.
2695 /// The real length of mapped region can be obtained using
2696 /// GetRealSize() method.
2697 /// The value 0 means that all file size will be mapped.
2698 /// @return
2699 /// - Pointer to start of data, or
2700 /// - NULL if mapped to a file of zero length, or if not mapped.
2701 /// @sa
2702 /// Unmap, GetOffset, GetSize, GetRealOffset, GetRealSize
2703 /// @note
2704 /// MS Windows: If file is open in eMMP_Read mode with eMMS_Private
2705 /// protection, that memory pages will be mapped in exclusive mode,
2706 /// and any other process cannot access the same file for writing.
2707 void* Map(TOffsetType offset, size_t length);
2708
2709 /// Unmap file segment.
2710 ///
2711 /// @param ptr
2712 /// Pointer returned by Map().
2713 /// @return
2714 /// TRUE on success; or FALSE on error.
2715 /// @sa
2716 /// Map
2717 bool Unmap(void* ptr);
2718
2719 /// Unmap all mapped segment.
2720 ///
2721 /// @return
2722 /// TRUE on success; or FALSE on error.
2723 /// In case of error some segments can be not unmapped.
2724 bool UnmapAll(void);
2725
2726 /// Get offset of the mapped segment from beginning of the file.
2727 ///
2728 /// @param prt
2729 /// Pointer to mapped data returned by Map().
2730 /// @return
2731 /// Offset in bytes of mapped segment from beginning of the file.
2732 /// Returned value is a value of "offset" parameter passed
2733 /// to Map() method for specified "ptr".
2734 TOffsetType GetOffset(void* ptr) const;
2735
2736 /// Get length of the mapped segment.
2737 ///
2738 /// @param prt
2739 /// Pointer to mapped data returned by Map().
2740 /// @return
2741 /// Length in bytes of the mapped area.
2742 /// Returned value is a value of "length" parameter passed
2743 /// to Map() method for specified "ptr".
2744 size_t GetSize(void* ptr) const;
2745
2746 /// Get length of the mapped file.
2747 ///
2748 /// @return
2749 /// Size in bytes of the mapped file.
2750 Int8 GetFileSize(void) const;
2751
2752 /// Flush memory mapped file segment.
2753 ///
2754 /// Flush specified mapped segment by writing all modified copies of
2755 /// memory pages to the underlying file.
2756 ///
2757 /// NOTE: By default data will be flushed in the destructor.
2758 /// @param prt
2759 /// Pointer to mapped data returned by Map().
2760 /// @return
2761 /// - TRUE, if all data was flushed successfully.
2762 /// - FALSE, if an error occurs.
2763 bool Flush(void* ptr) const;
2764
2765 /// Get pointer to memory mapped file segment by pointer to data.
2766 ///
2767 /// @param prt
2768 /// Pointer to mapped data returned by Map().
2769 /// @return
2770 /// Pointer to memory file mapped segment.
2771 const CMemoryFileSegment* GetMemoryFileSegment(void* ptr) const;
2772
2773 /// Advise on mapped memory map usage.
2774 ///
2775 /// @param advise
2776 /// Advise on expected memory usage pattern.
2777 /// @return
2778 /// - TRUE, if memory advise operation successful.
2779 /// - FALSE, if memory advise operation not successful, or is not supported
2780 /// on current platform.
2781 /// @sa
2782 /// EMemMapAdvise, MemMapAdviseAddr
2783 bool MemMapAdvise(void* ptr, EMemMapAdvise advise) const;
2784
2785 /// Shows filename of memory mapped file
2786 ///
2787 /// @return
2788 /// Reference to a file name of memory mapped file
GetFileName() const2789 const string& GetFileName() const noexcept
2790 {
2791 return m_FileName;
2792 }
2793
2794 protected:
2795 /// Open file mapping for file with name m_FileName.
2796 void x_Open(void);
2797 /// Unmap mapped memory and close mapped file.
2798 void x_Close(void);
2799 /// Create new file or rewrite existent with zeros.
2800 void x_Create(Uint8 size);
2801 /// Extend file size from 'size' to 'new_size' with zero bytes.
2802 /// Note, that 'new_size' should be greater that current file size 'size'.
2803 void x_Extend(Uint8 size, Uint8 new_size);
2804
2805 /// Get pointer to memory mapped file segment by pointer to data.
2806 CMemoryFileSegment* x_GetMemoryFileSegment(void* ptr) const;
2807
2808 protected:
2809 string m_FileName; ///< File name.
2810 SMemoryFileHandle* m_Handle; ///< Memory file handle.
2811 SMemoryFileAttrs* m_Attrs; ///< Specify operations permitted on
2812 ///< memory mapped file and mapping mode.
2813
2814 typedef map<void*,CMemoryFileSegment*> TSegments;
2815 TSegments m_Segments; ///< Map of pointers to mapped segments.
2816
2817 private:
2818 // Prevent copying
2819 CMemoryFileMap(const CMemoryFileMap&);
2820 void operator=(const CMemoryFileMap&);
2821 };
2822
2823
2824
2825 /////////////////////////////////////////////////////////////////////////////
2826 ///
2827 /// CMemoryFile --
2828 ///
2829 /// Define class to support file memory mapping.
2830 ///
2831 /// This is a simple version of the CMemoryFileMap class supporting one
2832 /// mapped segment only.
2833 ///
2834 /// Note that the file being mapped must exist or can be created/extended.
2835 /// If file size changes after mapping, the effect of references to portions
2836 /// of the mapped region that correspond to added or removed portions of
2837 /// the file is unspecified.
2838 ///
2839 /// Throws exceptions on errors.
2840
2841 class NCBI_XNCBI_EXPORT CMemoryFile : public CMemoryFileMap
2842 {
2843 public:
2844 /// Constructor.
2845 ///
2846 /// Initialize memory mapping for file "file_name".
2847 /// @param filename
2848 /// Name of file to map to memory.
2849 /// @param protect_attr
2850 /// Specify operations permitted on memory mapped file.
2851 /// @param share_attr
2852 /// Specify if change to memory mapped file can be shared or not.
2853 /// @param offset
2854 /// The file offset where mapping is to begin.
2855 /// @param length
2856 /// Number of bytes to map.
2857 /// The value 0 means that all file size will be mapped.
2858 /// @param mode
2859 /// File open mode.
2860 /// @param max_file_len
2861 /// The size of created file if 'mode' parameter is eCreate or eExtend.
2862 /// File will be never truncated if open mode is eExtend and real file
2863 /// size is more that specified maximum length.
2864 /// @sa
2865 /// EMemMapProtect, EMemMapShare, EOpenMode
2866 /// @sa
2867 /// EMemMapProtect, EMemMapShare, Map
2868 /// @note
2869 /// MS Windows: If file is open in eMMP_Read mode with eMMS_Private
2870 /// protection, that memory pages will be mapped in exclusive mode,
2871 /// and any other process cannot access the same file for writing.
2872 CMemoryFile(const string& file_name,
2873 EMemMapProtect protect_attr = eMMP_Read,
2874 EMemMapShare share_attr = eMMS_Shared,
2875 TOffsetType offset = 0,
2876 size_t lendth = 0,
2877 EOpenMode mode = eDefault,
2878 Uint8 max_file_len = 0);
2879
2880 /// Map file.
2881 ///
2882 /// @param offset
2883 /// The file offset where mapping is to begin. If the offset is not
2884 /// a multiple of the allocation granularity, that it can be decreased
2885 /// to match it. The "length" value will be automatically increased on
2886 /// the difference between passed and real offsets. The real offset can
2887 /// be obtained using GetRealOffset(). Cannot accept values less than 0.
2888 /// @param length
2889 /// Number of bytes to map. This value can be increased if "offset"
2890 /// is not a multiple of the allocation granularity.
2891 /// The real length of mapped region can be obtained using
2892 /// GetRealSize() method.
2893 /// The value 0 means that file will be mapped from 'offset'
2894 /// to the end of file.
2895 /// @return
2896 /// - Pointer to start of data, or
2897 /// - NULL if mapped to a file of zero length, or if not mapped.
2898 /// @sa
2899 /// Unmap, GetPtr, GetOffset, GetSize, Extend
2900 void* Map(TOffsetType offset = 0, size_t length = 0);
2901
2902 /// Unmap file if mapped.
2903 ///
2904 /// @return
2905 /// TRUE on success; or FALSE on error.
2906 /// @sa
2907 /// Map, Extend
2908 bool Unmap(void);
2909
2910 /// Extend length of the mapped region.
2911 ///
2912 /// If the sum of the current offset (from Map() method) and new size of
2913 /// the mapped region is more than current file size, that file size will
2914 /// be increased, added space filed with zeros and mapped region will
2915 /// be remapped.
2916 /// @param new_length
2917 /// New length of the mapped region.
2918 /// The value 0 means that file will be mapped from 'offset'
2919 /// to the end of file.
2920 /// @return
2921 /// New pointer to start of data.
2922 /// @sa
2923 /// GetPtr, GetOffset, GetSize
2924 void* Extend(size_t new_lendth = 0);
2925
2926 /// Get pointer to beginning of data.
2927 ///
2928 /// @return
2929 /// Pointer to start of data.
2930 /// @sa
2931 /// Map, Extend
2932 void* GetPtr(void) const;
2933
2934 /// Get offset of the mapped area from beginning of the file.
2935 ///
2936 /// @return
2937 /// Offset in bytes of mapped area from beginning of the file.
2938 TOffsetType GetOffset(void) const;
2939
2940 /// Get length of the mapped region.
2941 ///
2942 /// @return
2943 /// - Length in bytes of the mapped region, or
2944 /// - 0 if not mapped or file is empty.
2945 size_t GetSize(void) const;
2946
2947 /// Flush by writing all modified copies of memory pages to the
2948 /// underlying file.
2949 ///
2950 /// NOTE: By default data will be flushed in the destructor.
2951 /// @return
2952 /// - TRUE, if all data was flushed successfully.
2953 /// - FALSE, if an error occurs.
2954 bool Flush(void) const;
2955
2956 /// Advise on memory map usage.
2957 ///
2958 /// @param advise
2959 /// Advise on expected memory usage pattern.
2960 /// @return
2961 /// - TRUE, if memory advise operation successful.
2962 /// - FALSE, if memory advise operation not successful, or is not supported
2963 /// on current platform.
2964 /// @sa
2965 /// EMemMapAdvise, MemMapAdviseAddr
2966 bool MemMapAdvise(EMemMapAdvise advise) const;
2967
2968 private:
2969 // Check that file is mapped, throw exception otherwise.
2970 void x_Verify(void) const;
2971
2972 private:
2973 void* m_Ptr; ///< Pointer to mapped view of file.
2974
2975 private:
2976 // Prevent copying
2977 CMemoryFile(const CMemoryFile&);
2978 void operator=(const CMemoryFile&);
2979 };
2980
2981
2982
2983 /////////////////////////////////////////////////////////////////////////////
2984 //
2985 // Find files algorithms
2986 //
2987
2988 /// File finding flags
2989 enum EFindFiles {
2990 fFF_File = (1 << 0), ///< find files
2991 fFF_Dir = (1 << 1), ///< find directories
2992 fFF_All = fFF_File | fFF_Dir, ///< find files and directories
2993 ///< (used automatically if fFF_File or fFF_Dir has not specified)
2994 fFF_Recursive = (1 << 2), ///< descend into sub-dirs
2995 fFF_Nocase = (1 << 3), ///< case-insensitive name search
2996 fFF_Default = fFF_All ///< default behavior
2997 };
2998 /// Bitwise OR of "EFindFiles"
2999 typedef int TFindFiles;
3000
3001
3002 /// Find files in the specified directory
3003 template<class TFindFunc>
FindFilesInDir(const CDir & dir,const vector<string> & masks,const vector<string> & masks_subdir,TFindFunc & find_func,TFindFiles flags=fFF_Default)3004 void FindFilesInDir(const CDir& dir,
3005 const vector<string>& masks,
3006 const vector<string>& masks_subdir,
3007 TFindFunc& find_func,
3008 TFindFiles flags = fFF_Default)
3009 {
3010 TFindFiles find_type = flags & fFF_All;
3011 if ( find_type == 0 ) {
3012 flags |= fFF_All;
3013 }
3014 unique_ptr<CDir::TEntries>
3015 contents(dir.GetEntriesPtr(kEmptyStr, CDir::fIgnoreRecursive | CDir::fIgnorePath));
3016 if (contents.get() == NULL) {
3017 // error
3018 return;
3019 }
3020
3021 NStr::ECase use_case = (flags & fFF_Nocase) ? NStr::eNocase : NStr::eCase;
3022 string path;
3023
3024 if ( dir.GetPath().length() ) {
3025 path = CDirEntry::AddTrailingPathSeparator(dir.GetPath());
3026 }
3027 ITERATE(CDir::TEntries, it, *contents) {
3028 CDirEntry& dir_entry = **it;
3029 string name = dir_entry.GetPath();
3030 dir_entry.Reset(CDirEntry::MakePath(path, name));
3031
3032 TFindFiles entry_type = fFF_Dir | fFF_File; // unknown
3033 if ( CDirEntry::MatchesMask(name, masks, use_case) ) {
3034 if ( find_type != (fFF_Dir | fFF_File) ) {
3035 // need to check actual entry type
3036 entry_type = dir_entry.IsDir()? fFF_Dir: fFF_File;
3037 }
3038 if ( (entry_type & find_type) != 0 ) {
3039 // entry type matches
3040 find_func(dir_entry);
3041 }
3042 }
3043 if ( (flags & fFF_Recursive) &&
3044 (entry_type & fFF_Dir) /*possible dir*/ &&
3045 CDirEntry::MatchesMask(name, masks_subdir, use_case) &&
3046 (entry_type == fFF_Dir || dir_entry.IsDir()) /*real dir*/ ) {
3047 CDir nested_dir(dir_entry.GetPath());
3048 FindFilesInDir(nested_dir, masks, masks_subdir, find_func, flags);
3049 }
3050 }
3051 return;
3052 }
3053
3054
3055 /// Find files in the specified directory
3056 template<class TFindFunc>
FindFilesInDir(const CDir & dir,const CMask & masks,const CMask & masks_subdir,TFindFunc & find_func,TFindFiles flags=fFF_Default)3057 void FindFilesInDir(const CDir& dir,
3058 const CMask& masks,
3059 const CMask& masks_subdir,
3060 TFindFunc& find_func,
3061 TFindFiles flags = fFF_Default)
3062 {
3063 TFindFiles find_type = flags & fFF_All;
3064 if ( find_type == 0 ) {
3065 flags |= fFF_All;
3066 }
3067 unique_ptr<CDir::TEntries>
3068 contents(dir.GetEntriesPtr(kEmptyStr, CDir::fIgnoreRecursive | CDir::fIgnorePath));
3069 if (contents.get() == NULL) {
3070 // error
3071 return;
3072 }
3073
3074 NStr::ECase use_case = (flags & fFF_Nocase) ? NStr::eNocase : NStr::eCase;
3075 string path;
3076
3077 if ( dir.GetPath().length() ) {
3078 path = CDirEntry::AddTrailingPathSeparator(dir.GetPath());
3079 }
3080 ITERATE(CDir::TEntries, it, *contents) {
3081 CDirEntry& dir_entry = **it;
3082 string name = dir_entry.GetPath();
3083 dir_entry.Reset(CDirEntry::MakePath(path, name));
3084
3085 TFindFiles entry_type = fFF_Dir | fFF_File; // unknown
3086 if ( masks.Match(name, use_case) ) {
3087 if ( find_type != (fFF_Dir | fFF_File) ) {
3088 // need to check actual entry type
3089 entry_type = dir_entry.IsDir()? fFF_Dir: fFF_File;
3090 }
3091 if ( (entry_type & find_type) != 0 ) {
3092 // entry type matches
3093 find_func(dir_entry);
3094 }
3095 }
3096 if ( (flags & fFF_Recursive) &&
3097 (entry_type & fFF_Dir) /*possible dir*/ &&
3098 masks_subdir.Match(name, use_case) &&
3099 (entry_type == fFF_Dir || dir_entry.IsDir()) /*real dir*/ ) {
3100 CDir nested_dir(dir_entry.GetPath());
3101 FindFilesInDir(nested_dir, masks, masks_subdir, find_func, flags);
3102 }
3103 }
3104 return;
3105 }
3106
3107
3108
3109 /////////////////////////////////////////////////////////////////////////////
3110 ///
3111 /// Generic algorithm for file search
3112 ///
3113 /// Algorithm scans the provided directories using iterators,
3114 /// finds files to match the masks and stores all calls functor
3115 /// object for all found entries.
3116 /// Functor call should match: void Functor(const CDirEntry& dir_entry).
3117 ///
3118 /// The difference between FindFiles<> and FileFiles2<> is that last one
3119 /// use two different masks - one for dir entries (files and/or subdirs)
3120 /// and second for subdirectories, that will be used for recursive
3121 /// search. FindFiles<> use one set of masks for all subdirectories with
3122 /// recursive search.
3123 ///
3124
3125 template<class TPathIterator,
3126 class TFindFunc>
FindFiles(TPathIterator path_begin,TPathIterator path_end,const vector<string> & masks,TFindFunc & find_func,TFindFiles flags=fFF_Default)3127 void FindFiles(TPathIterator path_begin,
3128 TPathIterator path_end,
3129 const vector<string>& masks,
3130 TFindFunc& find_func,
3131 TFindFiles flags = fFF_Default)
3132 {
3133 vector<string> masks_empty;
3134 for (; path_begin != path_end; ++path_begin) {
3135 const string& dir_name = *path_begin;
3136 CDir dir(dir_name);
3137 FindFilesInDir(dir, masks, masks_empty, find_func, flags);
3138 }
3139 return;
3140 }
3141
3142
3143 template<class TPathIterator,
3144 class TFindFunc>
FindFiles2(TPathIterator path_begin,TPathIterator path_end,const vector<string> & masks,const vector<string> & masks_subdir,TFindFunc & find_func,TFindFiles flags=fFF_Default)3145 void FindFiles2(TPathIterator path_begin,
3146 TPathIterator path_end,
3147 const vector<string>& masks,
3148 const vector<string>& masks_subdir,
3149 TFindFunc& find_func,
3150 TFindFiles flags = fFF_Default)
3151 {
3152 for (; path_begin != path_end; ++path_begin) {
3153 const string& dir_name = *path_begin;
3154 CDir dir(dir_name);
3155 FindFilesInDir(dir, masks, masks_subdir, find_func, flags);
3156 }
3157 return;
3158 }
3159
3160
3161 /////////////////////////////////////////////////////////////////////////////
3162 ///
3163 /// Generic algorithm for file search
3164 ///
3165 /// Algorithm scans the provided directories using iterators,
3166 /// finds files to match the masks and stores all calls functor
3167 /// object for all found entries.
3168 /// Functor call should match: void Functor(const CDirEntry& dir_entry).
3169 ///
3170
3171 template<class TPathIterator,
3172 class TMaskIterator,
3173 class TFindFunc>
FindFiles(TPathIterator path_begin,TPathIterator path_end,TMaskIterator mask_begin,TMaskIterator mask_end,TFindFunc & find_func,TFindFiles flags=fFF_Default)3174 void FindFiles(TPathIterator path_begin,
3175 TPathIterator path_end,
3176 TMaskIterator mask_begin,
3177 TMaskIterator mask_end,
3178 TFindFunc& find_func,
3179 TFindFiles flags = fFF_Default)
3180 {
3181 vector<string> masks;
3182 for (; mask_begin != mask_end; ++mask_begin) {
3183 masks.push_back(*mask_begin);
3184 }
3185 FindFiles(path_begin, path_end, masks, find_func, flags);
3186 return;
3187 }
3188
3189
3190 /////////////////////////////////////////////////////////////////////////////
3191 ///
3192 /// Generic algorithm for file search
3193 ///
3194 /// Algorithm scans the provided directories using iterators,
3195 /// finds files to match the masks and stores all calls functor
3196 /// object for all found entries.
3197 /// Functor call should match: void Functor(const CDirEntry& dir_entry).
3198 ///
3199
3200 template<class TPathIterator,
3201 class TFindFunc>
FindFiles(TPathIterator path_begin,TPathIterator path_end,const CMask & masks,TFindFunc & find_func,TFindFiles flags=fFF_Default)3202 void FindFiles(TPathIterator path_begin,
3203 TPathIterator path_end,
3204 const CMask& masks,
3205 TFindFunc& find_func,
3206 TFindFiles flags = fFF_Default)
3207 {
3208 CMaskFileName masks_empty;
3209 for (; path_begin != path_end; ++path_begin) {
3210 const string& dir_name = *path_begin;
3211 CDir dir(dir_name);
3212 FindFilesInDir(dir, masks, masks_empty, find_func, flags);
3213 }
3214 return;
3215 }
3216
3217
3218 template<class TPathIterator,
3219 class TFindFunc>
FindFiles2(TPathIterator path_begin,TPathIterator path_end,const CMask & masks,const CMask & masks_subdir,TFindFunc & find_func,TFindFiles flags=fFF_Default)3220 void FindFiles2(TPathIterator path_begin,
3221 TPathIterator path_end,
3222 const CMask& masks,
3223 const CMask& masks_subdir,
3224 TFindFunc& find_func,
3225 TFindFiles flags = fFF_Default)
3226 {
3227 for (; path_begin != path_end; ++path_begin) {
3228 const string& dir_name = *path_begin;
3229 CDir dir(dir_name);
3230 FindFilesInDir(dir, masks, masks_subdir, find_func, flags);
3231 }
3232 return;
3233 }
3234
3235
3236 /// Functor for generic FindFiles, adds file name to the specified container
3237 template<class TNames>
3238 class CFindFileNamesFunc
3239 {
3240 public:
CFindFileNamesFunc(TNames & names)3241 CFindFileNamesFunc(TNames& names) : m_FileNames(&names) {}
3242
operator ()(const CDirEntry & dir_entry)3243 void operator()(const CDirEntry& dir_entry)
3244 {
3245 m_FileNames->push_back(dir_entry.GetPath());
3246 }
3247 protected:
3248 TNames* m_FileNames;
3249 };
3250
3251
3252 /////////////////////////////////////////////////////////////////////////////
3253 ///
3254 /// Utility algorithm scans the provided directories using iterators
3255 /// finds files to match the masks and stores all found files in
3256 /// the container object.
3257 ///
3258
3259 template<class TContainer, class TPathIterator>
FindFiles(TContainer & out,TPathIterator first_path,TPathIterator last_path,const vector<string> & masks,TFindFiles flags=fFF_Default)3260 void FindFiles(TContainer& out,
3261 TPathIterator first_path,
3262 TPathIterator last_path,
3263 const vector<string>& masks,
3264 TFindFiles flags = fFF_Default)
3265 {
3266 CFindFileNamesFunc<TContainer> func(out);
3267 FindFiles(first_path, last_path, masks, func, flags);
3268 }
3269
3270 template<class TContainer, class TPathIterator>
FindFiles2(TContainer & out,TPathIterator first_path,TPathIterator last_path,const vector<string> & masks,const vector<string> & masks_subdir,TFindFiles flags=fFF_Default)3271 void FindFiles2(TContainer& out,
3272 TPathIterator first_path,
3273 TPathIterator last_path,
3274 const vector<string>& masks,
3275 const vector<string>& masks_subdir,
3276 TFindFiles flags = fFF_Default)
3277 {
3278 CFindFileNamesFunc<TContainer> func(out);
3279 FindFiles2(first_path, last_path, masks, masks_subdir, func, flags);
3280 }
3281
3282
3283 /////////////////////////////////////////////////////////////////////////////
3284 ///
3285 /// Utility algorithm scans the provided directories using iterators
3286 /// finds files to match the masks and stores all found files in
3287 /// the container object.
3288 ///
3289
3290 template<class TContainer, class TPathIterator>
FindFiles(TContainer & out,TPathIterator first_path,TPathIterator last_path,const CMask & masks,TFindFiles flags=fFF_Default)3291 void FindFiles(TContainer& out,
3292 TPathIterator first_path,
3293 TPathIterator last_path,
3294 const CMask& masks,
3295 TFindFiles flags = fFF_Default)
3296 {
3297 CFindFileNamesFunc<TContainer> func(out);
3298 FindFiles(first_path, last_path, masks, func, flags);
3299 }
3300
3301 template<class TContainer, class TPathIterator>
FindFiles2(TContainer & out,TPathIterator first_path,TPathIterator last_path,const CMask & masks,const CMask & masks_subdir,TFindFiles flags=fFF_Default)3302 void FindFiles2(TContainer& out,
3303 TPathIterator first_path,
3304 TPathIterator last_path,
3305 const CMask& masks,
3306 const CMask& masks_subdir,
3307 TFindFiles flags = fFF_Default)
3308 {
3309 CFindFileNamesFunc<TContainer> func(out);
3310 FindFiles2(first_path, last_path, masks, masks_subdir, func, flags);
3311 }
3312
3313
3314 /////////////////////////////////////////////////////////////////////////////
3315 ///
3316 /// Utility algorithm scans the provided directories using iterators
3317 /// finds files to match the masks and stores all found files in
3318 /// the container object.
3319 ///
3320
3321 template<class TContainer, class TPathIterator, class TMaskIterator>
FindFiles(TContainer & out,TPathIterator first_path,TPathIterator last_path,TMaskIterator first_mask,TMaskIterator last_mask,TFindFiles flags=fFF_Default)3322 void FindFiles(TContainer& out,
3323 TPathIterator first_path,
3324 TPathIterator last_path,
3325 TMaskIterator first_mask,
3326 TMaskIterator last_mask,
3327 TFindFiles flags = fFF_Default)
3328 {
3329 CFindFileNamesFunc<TContainer> func(out);
3330 FindFiles(first_path, last_path, first_mask, last_mask, func, flags);
3331 }
3332
3333
3334 /////////////////////////////////////////////////////////////////////////////
3335 ///
3336 /// Utility function working like glob(): takes a pattern and fills the
3337 /// result list with files/directories matching the pattern.
3338 ///
3339
3340 void NCBI_XNCBI_EXPORT FindFiles(const string& pattern,
3341 list<string>& result,
3342 TFindFiles flags);
3343
3344
3345 /// Comparator for directory entries names.
3346 ///
3347 /// Compares two directory entries lexicographically, allow to sort
3348 /// elements in ascending order. Could be used with a list of entries
3349 /// obtained via CDir::GetEntries() or FindFiles().
3350 /// @param mode
3351 /// Entries sorting mode.
3352 /// @sa
3353 /// CDir::GetEntries, FindFiles
3354 /// @code
3355 /// CDir::TEntries entries = CDir(dir).GetEntries("*.*");
3356 /// entries.sort(SCompareDirEntries());
3357 /// @endcode
3358 /// @code
3359 /// vector<string> entries;
3360 /// FindFiles(entries, ...);
3361 /// std::sort(entries.begin(), entries.end(), SCompareDirEntries());
3362 /// @endcode
3363
3364 struct SCompareDirEntries
3365 {
3366 /// Sorting mode
3367 enum ESort {
3368 ePath, ///< Sort by full path (default)
3369 eDir, ///< Directory name
3370 eName, ///< Full file name
3371 eBase, ///< Base file name
3372 eExt ///< File extension
3373 };
3374 /// You can sort by up to 3 path components.
3375 /// If first components of both paths are equal, next one
3376 /// will be used for comparison, and etc.
3377 SCompareDirEntries(ESort s1 = ePath);
3378 SCompareDirEntries(ESort s1, ESort s2);
3379 SCompareDirEntries(ESort s1, ESort s2, ESort s3);
3380
3381 /// Comparison operators
3382 bool operator()(const CDir::TEntry& e1, const CDir::TEntry& e2);
3383 bool operator()(const string& e1, const string& e2);
3384
3385 private:
3386 int m_Sort[3];
3387 };
3388
3389
3390
3391 /////////////////////////////////////////////////////////////////////////////
3392 ///
3393 /// Base class for CFileIO, CFileReader, CFileWriter, CFileReaderWriter.
3394 ///
3395 /// Defines common types.
3396
3397 class NCBI_XNCBI_EXPORT CFileIO_Base
3398 {
3399 public:
3400 /// File open mode.
3401 enum EOpenMode {
3402 ///< Create a new file, or truncate an existing one.
3403 eCreate,
3404 ///< Create a new file, or fail if the file already exists.
3405 eCreateNew,
3406 ///< Open an existing file, or fail if the file does not exist.
3407 eOpen,
3408 ///< Open an existing file, or create a new one.
3409 eOpenAlways,
3410 /// Open an existing file and truncate its size to 0.
3411 /// Fail if the file does not exist.
3412 eTruncate
3413 };
3414
3415 /// Which I/O operations permitted on the file.
3416 enum EAccessMode {
3417 eRead, ///< File can be read.
3418 eWrite, ///< File can be written.
3419 eReadWrite ///< File can be read and written.
3420 };
3421
3422 /// Sharing mode for opened file.
3423 /// @note
3424 /// If OS does not support sharing mode for files, that it will be
3425 /// ignored. But you can use CFileLock to lock a file or its part.
3426 /// @sa CFileLock
3427 enum EShareMode {
3428 /// Enables subsequent open operations on the file that request read
3429 /// access. Otherwise, other processes cannot open the file for reading.
3430 eShareRead,
3431 /// Enables subsequent open operations on the file that request write
3432 /// access. Otherwise, other processes cannot open the file for writing.
3433 eShareWrite,
3434 /// Combines both eShareRead and eShareWrite modes.
3435 eShare,
3436 /// Open file for exclusive access. Disables any subsequent open
3437 /// operations on the file.
3438 eExclusive
3439 };
3440
3441 /// Which starting point to use for the moves of the file pointer.
3442 enum EPositionMoveMethod {
3443 eBegin, ///< Absolute position from beginning of the file.
3444 eCurrent, ///< Relative to current position.
3445 eEnd ///< The starting point is the current EOF position.
3446 };
3447 };
3448
3449
3450 /////////////////////////////////////////////////////////////////////////////
3451 ///
3452 /// Class for support low level input/output for files.
3453 ///
3454 /// Throw CFileException/CFileErrnoException on error.
3455
3456 class NCBI_XNCBI_EXPORT CFileIO : public CFileIO_Base
3457 {
3458 public:
3459 /// Default constructor
3460 CFileIO(void);
3461
3462 /// Destruct object closing system handle if necessary
3463 ~CFileIO(void);
3464
3465 /// Open file.
3466 void Open(const string& filename, EOpenMode open_mode,
3467 EAccessMode access_mode, EShareMode share_mode = eShare);
3468
3469 /// Controls how temporary file is removed.
3470 enum EAutoRemove {
3471 eDoNotRemove, ///< Do not ever remove temporary file.
3472 eRemoveInClose, ///< Remove temporary file immediately
3473 ///< after closing its handle in Close().
3474 eRemoveASAP, ///< Remove the file at the earliest
3475 ///< possible moment (in CreateTemporary()
3476 ///< on UNIX).
3477 };
3478 /// Create temporary file in the specified directory.
3479 /// The prefix argument is used to generate a unique file name.
3480 void CreateTemporary(const string& dir, const string& prefix,
3481 EAutoRemove auto_remove = eRemoveInClose);
3482
3483 /// Close file.
3484 void Close(void);
3485
3486 /// Read file.
3487 ///
3488 /// @return
3489 /// The number of bytes actually read.
3490 /// Can be less than 'count', zero indicates end of file.
3491 size_t Read(void* buf, size_t count) const;
3492
3493 /// Write file.
3494 ///
3495 /// Always write all 'count' bytes of data to the file.
3496 /// @return
3497 /// The number of bytes written; equal to 'count'.
3498 size_t Write(const void* buf, size_t count) const;
3499
3500 /// Flush file buffers.
3501 void Flush(void) const;
3502
3503 /// Return file path and name as it was specified in the
3504 /// Open() method or created in CreateTemporary().
GetPathname(void) const3505 const string& GetPathname(void) const { return m_Pathname; }
3506
3507 /// Return system file handle associated with the file.
GetFileHandle(void) const3508 TFileHandle GetFileHandle(void) const { return m_Handle; };
3509
3510 /// Close previous handle if needed and use given handle for all I/O.
3511 void SetFileHandle(TFileHandle handle);
3512
3513 /// Get file position.
3514 ///
3515 /// @return
3516 /// Current file position.
3517 Uint8 GetFilePos(void) const;
3518
3519 /// Set file position from beginning of the file.
3520 void SetFilePos(Uint8 position) const;
3521
3522 /// Set file position.
3523 ///
3524 /// @param offset
3525 /// Defines a number of bytes to move the file pointer. A positive value
3526 /// moves the pointer from the position indicated by 'whence' forward in
3527 /// the file, and a negative value backspaces the file pointer towards
3528 /// the beginning of the file.
3529 ///
3530 /// @param whence
3531 /// Defines a pointer move origin.
3532 void SetFilePos(Int8 offset, EPositionMoveMethod whence) const;
3533
3534 /// Get file size.
3535 ///
3536 /// @return
3537 /// Size of the file.
3538 Uint8 GetFileSize(void) const;
3539
3540 /// Set new size for the file.
3541 ///
3542 /// This method can be used to truncate or extend the file.
3543 /// @note
3544 /// The file must be opened with write access rights.
3545 /// Function repositions the offset of the file descriptor to the EOF.
3546 /// @param length
3547 /// New file size.
3548 /// If the file was previously longer than length, bytes past "length"
3549 /// will no longer be accessible. If it was shorter, the contents of
3550 /// the file between the old EOF position and the new position are
3551 /// not defined. Usually it will be read in as zeros, but this depends
3552 /// on the OS.
3553 /// @param pos
3554 /// Defines how to set current file position after changing file size.
3555 /// eCurrent means that file position does not change, eBegin and eEnd
3556 /// move it to the start or the end of the file accordingly.
3557 void SetFileSize(Uint8 length, EPositionMoveMethod pos = eCurrent) const;
3558
3559 /// Define whether the open file handle needs to be closed
3560 /// in the destructor.
SetAutoClose(bool auto_close=true)3561 void SetAutoClose(bool auto_close = true) { m_AutoClose = auto_close; }
3562
3563 /// Define whether the temporary file created by CreateTemporary()
3564 /// must be automatically removed in Close(). This method will
3565 /// also work for regular files created with Open().
SetAutoRemove(EAutoRemove auto_remove=eRemoveInClose)3566 void SetAutoRemove(EAutoRemove auto_remove = eRemoveInClose)
3567 { m_AutoRemove = auto_remove; }
3568
3569 protected:
3570 string m_Pathname; ///< File path and name.
3571 TFileHandle m_Handle; ///< System file handle.
3572 bool m_AutoClose; ///< Need to close file handle in destructor.
3573 EAutoRemove m_AutoRemove; ///< When (if ever) should the temporary
3574 ///< file be removed.
3575
3576 private:
3577 // prevent copying
3578 CFileIO(const CFileIO&);
3579 void operator=(const CFileIO&);
3580 };
3581
3582
3583
3584 /////////////////////////////////////////////////////////////////////////////
3585 ///
3586 /// File based IReader/IWriter/IReaderWriter with low level IO for speed
3587 ///
3588 /// Throw CFileException/CFileErrnoException on error.
3589
3590 class NCBI_XNCBI_EXPORT CFileReaderWriter_Base : public CFileIO_Base
3591 {
3592 public:
3593 /// Default constructor
CFileReaderWriter_Base(void)3594 CFileReaderWriter_Base(void) {};
3595 /// Return system file handle associated with the file.
GetFileHandle(void)3596 TFileHandle GetFileHandle(void) { return m_File.GetFileHandle(); };
3597 /// Get an underlaying file I/O object
GetFileIO(void)3598 CFileIO& GetFileIO(void) { return m_File; }
3599
3600 protected:
3601 CFileIO m_File;
3602 private:
3603 // prevent copying
3604 CFileReaderWriter_Base(const CFileReaderWriter_Base&);
3605 void operator=(const CFileReaderWriter_Base&);
3606 };
3607
3608
3609 class NCBI_XNCBI_EXPORT CFileReader : public IReader,
3610 public CFileReaderWriter_Base
3611 {
3612 public:
3613 /// Construct CFileReader for reading from the file with name 'filename'.
3614 /// Throw CFileErrnoException on error.
3615 CFileReader(const string& filename,
3616 EShareMode share_mode = eShareRead);
3617 CFileReader(const char* filename,
3618 EShareMode share_mode = eShareRead);
3619
3620 /// Construct CFileReader for reading from system handle 'handle'.
3621 /// Specified handle should have read access right.
3622 CFileReader(TFileHandle handle);
3623
3624 /// Return a new IReader object corresponding to the given
3625 /// filename, taking "-" (but not "./-") to read from the standard input.
3626 static IReader* New(const string& filename,
3627 EShareMode share_mode = eShareRead);
3628
3629 /// Virtual methods from IReader
3630 virtual ERW_Result Read(void* buf, size_t count, size_t* bytes_read = 0);
3631 virtual ERW_Result PendingCount(size_t* count);
3632
3633 private:
3634 // prevent copying
3635 CFileReader(const CFileReader&);
3636 void operator=(const CFileReader&);
3637 };
3638
3639
3640 class NCBI_XNCBI_EXPORT CFileWriter : public IWriter,
3641 public CFileReaderWriter_Base
3642 {
3643 public:
3644 /// Construct CFileWriter for writing to the file with name 'filename'.
3645 /// Throw CFileErrnoException on error.
3646 CFileWriter(const string& filename,
3647 EOpenMode open_mode = eCreate,
3648 EShareMode share_mode = eShareRead);
3649 CFileWriter(const char* filename,
3650 EOpenMode open_mode = eCreate,
3651 EShareMode share_mode = eShareRead);
3652
3653 /// Construct CFileWriter for writing to system handle 'handle'.
3654 /// Specified handle should have read/write access rights.
3655 CFileWriter(TFileHandle handle);
3656
3657 /// Return a new IWriter object corresponding to the given
3658 /// filename, taking "-" (but not "./-") to write to the standard output.
3659 static IWriter* New(const string& filename,
3660 EOpenMode open_mode = eCreate,
3661 EShareMode share_mode = eShareRead);
3662
3663 /// Virtual methods from IWriter
3664 virtual ERW_Result Write(const void* buf, size_t count,
3665 size_t* bytes_written = 0);
3666 virtual ERW_Result Flush(void);
3667
3668 private:
3669 // prevent copying
3670 CFileWriter(const CFileWriter&);
3671 void operator=(const CFileWriter&);
3672 };
3673
3674
3675 class NCBI_XNCBI_EXPORT CFileReaderWriter : public IReaderWriter,
3676 public CFileReaderWriter_Base
3677 {
3678 public:
3679 /// Construct CFileReaderWriter for reading/writing to/from
3680 /// the file with name 'filename'.
3681 /// Throw CFileErrnoException on error.
3682 CFileReaderWriter(const string& filename,
3683 EOpenMode open_mode = eOpen,
3684 EShareMode share_mode = eShareRead);
3685 CFileReaderWriter(const char* filename,
3686 EOpenMode open_mode = eOpen,
3687 EShareMode share_mode = eShareRead);
3688
3689 /// Construct CFileReaderWriter for writing to system handle 'handle'.
3690 /// Specified handle should have read and write access rights.
3691 CFileReaderWriter(TFileHandle handle);
3692
3693 /// Return a new IReaderWriter object corresponding to the given
3694 /// filename.
3695 static IReaderWriter* New(const string& filename,
3696 EOpenMode open_mode = eOpen,
3697 EShareMode share_mode = eShareRead);
3698
3699 /// Virtual methods from IReaderWriter
3700 virtual ERW_Result Read(void* buf, size_t count, size_t* bytes_read = 0);
3701 virtual ERW_Result PendingCount(size_t* count);
3702 virtual ERW_Result Write(const void* buf, size_t count,
3703 size_t* bytes_written = 0);
3704 virtual ERW_Result Flush(void);
3705
3706 private:
3707 // prevent copying
3708 CFileReaderWriter(const CFileReaderWriter&);
3709 void operator=(const CFileReaderWriter&);
3710 };
3711
3712
3713 /////////////////////////////////////////////////////////////////////////////
3714 ///
3715 /// File locking
3716 ///
3717 /// Lock a given file (by file descriptor or the file name) to read/write.
3718 ///
3719 /// Notes:
3720 ///
3721 /// 1) On majority of Unix platforms all locks are advisory, this means that
3722 /// cooperating processes may use locks to coordinate access to a file
3723 /// between themselves, but programs are also free to ignore locks and
3724 /// access the file in any way they choose to.
3725 /// MS Windows supports only mandatory locks, and operating system fully
3726 /// enforces them.
3727 ///
3728 /// 2) After locking the file you should work with this file using ONLY
3729 /// specified file descriptor, or if the constructor with file name was
3730 /// used, obtain a file descriptor from CFileLock object using method
3731 /// GetFileHandle(). Because on Unix all locks associated with a file
3732 /// for a given process are removed when any file descriptor for that
3733 /// file is closed by that process, even if a lock was never requested
3734 /// for that file descriptor. On Windows you cannot open the file for
3735 /// writing, if it already have an exclusive lock, even established
3736 /// by the same process.
3737 /// So, often is better to open file somewhere else and pass its file
3738 /// descriptor to CFileLock class. In this case you have more control
3739 /// over file. But note that lock type should match to the file open mode.
3740 ///
3741 /// 3) If you close a file that have locks, the locks will be unlocked by
3742 /// the operating system. However, the time it takes for the operating
3743 /// system to unlock these locks depends upon available system resources.
3744 /// Therefore, it is recommended that your process explicitly remove all
3745 /// locks, before closing a file. If this is not done, access to file
3746 /// may be denied if the operating system has not yet unlocked them.
3747 ///
3748 /// 4) Locks can be inherited or not by a child process, depending from OS.
3749 ///
3750 /// 5) Locked file cannot be empty. CFileLock can work with empty files,
3751 /// depending from OS, but it is better to avoid this for compatibility.
3752 ///
3753 /// All methods of this class except the destructor throw exceptions
3754 /// CFileErrnoException on errors.
3755
3756 class NCBI_XNCBI_EXPORT CFileLock
3757 {
3758 public:
3759 typedef Int8 TOffsetType; // signed for POSIX compatibility
3760
3761 /// Type of file lock.
3762 ///
3763 /// Shared lock allows all processes to read from the locked portion
3764 /// of the file, while denying to write into it.
3765 /// Exclusive lock denies other processes both read and write to
3766 /// the locked portion of the file, while allowing the locking process
3767 /// to read or write through a specified or obtained file handle.
3768 typedef enum {
3769 eShared, ///< "read" lock.
3770 eExclusive ///< "write" lock.
3771 } EType;
3772
3773 /// Flags, used in constructors.
3774 ///
3775 /// Default flag in each group have priority above non-default,
3776 /// if they are used together.
3777 enum EFlags {
3778 /// Lock file using parameters specified in constructor.
3779 fLockNow = (1 << 1),
3780 fLockLater = (1 << 2),
3781 /// Automatically remove all obtained locks in the destructor.
3782 /// Note, that you still can unlock any segment. All remaining locks
3783 /// will be removed in the destructor.
3784 fAutoUnlock = (1 << 3),
3785 fNoAutoUnlock = (1 << 4),
3786 /// Default flags
3787 fDefault = fLockNow | fAutoUnlock
3788 };
3789 typedef unsigned int TFlags; ///< Binary OR of "EFlags"
3790
3791
3792 /// Construct CFileLock for locking a file with a given name 'filename'.
3793 /// File will be automatically closed in destructor and all locks removed.
3794 /// Throw CFileException if file doesn't exist, or on error.
3795 /// @sa Lock, Unlock, GetFileHandle
3796 CFileLock(const string& filename,
3797 TFlags flags = fDefault,
3798 EType type = eShared,
3799 TOffsetType offset = 0,
3800 size_t length = 0);
3801 CFileLock(const char* filename,
3802 TFlags flags = fDefault,
3803 EType type = eShared,
3804 TOffsetType offset = 0,
3805 size_t length = 0);
3806
3807 /// Construct CFileLock for locking file by system file handle 'handle'.
3808 /// @note
3809 /// The file will not be closed at CFileLock destruction.
3810 /// @sa Lock, LockSegment
3811 CFileLock(TFileHandle handle,
3812 TFlags flags = fDefault,
3813 EType type = eShared,
3814 TOffsetType offset = 0,
3815 size_t length = 0);
3816
3817 /// Destruct the CFileLock, close file and remove all locks if necessary.
3818 ~CFileLock(void);
3819
3820 /// Lock file
3821 ///
3822 /// Lock whole file, or the part of the file.
3823 /// Previous lock will be removed. It do not remove locks,
3824 /// established on the file somewhere else.
3825 /// Throw CFileException if the lock cannot be obtained (since someone
3826 /// else has it locked already), or on error.
3827 /// @param type
3828 /// Type of the lock, one of eShared or eExclusive.
3829 /// @param offset
3830 /// The file offset where lock starts. Cannot accept values less than 0.
3831 /// @param length
3832 /// Number of bytes to lock.
3833 /// The value 0 means that whole file will be locked.
3834 /// @sa Unlock
3835 void Lock(EType type, TOffsetType offset = 0, size_t length = 0);
3836
3837 /// Unlock file.
3838 ///
3839 /// Unlock range of the file previously locked using Lock() method.
3840 /// The file remains open. Note, that this method cannot remove locks,
3841 /// established on the file somewhere else. Only closing a file can
3842 /// unlock all locks.
3843 /// @sa Lock
3844 void Unlock(void);
3845
3846 /// Return system file handle.
3847 ///
3848 /// If you want to read/write from/to the file, you should work with it
3849 /// using only the file descriptor, obtained using this method.
3850 /// It can be the same file descriptor as was given in the constructor.
3851 /// @return
3852 /// File descriptor associated with the file.
GetFileHandle(void)3853 TFileHandle GetFileHandle(void) { return m_Handle; };
3854
3855 protected:
3856 /// Auxiliary method for constructors.
3857 void x_Init(const char* filename, EType type, TOffsetType offset, size_t length);
3858
3859 private:
3860 TFileHandle m_Handle; ///< System file handle.
3861 bool m_CloseHandle; ///< Need to close file handle in destructor.
3862 TFlags m_Flags; ///< General flags.
3863 bool m_IsLocked; ///< Lock established.
3864 AutoPtr<SLock> m_Lock; ///< Offset and length of the locked area.
3865
3866 private:
3867 // Prevent copying
3868 CFileLock(const CFileLock&);
3869 void operator=(const CFileLock&);
3870 };
3871
3872
3873 /* @} */
3874
3875
3876
3877 //////////////////////////////////////////////////////////////////////////////
3878 //
3879 // Inline
3880 //
3881
3882
3883 // CDirEntry
3884
3885 inline
CDirEntry(void)3886 CDirEntry::CDirEntry(void)
3887 {
3888 return;
3889 }
3890
3891 inline
GetPath(void) const3892 const string& CDirEntry::GetPath(void) const
3893 {
3894 return m_Path;
3895 }
3896
3897 inline
GetName(void) const3898 string CDirEntry::GetName(void) const
3899 {
3900 string title, ext;
3901 SplitPath(GetPath(), 0, &title, &ext);
3902 return title + ext;
3903 }
3904
3905 inline
GetBase(void) const3906 string CDirEntry::GetBase(void) const
3907 {
3908 string base;
3909 SplitPath(GetPath(), 0, &base);
3910 return base;
3911 }
3912
3913 inline
GetExt(void) const3914 string CDirEntry::GetExt(void) const
3915 {
3916 string ext;
3917 SplitPath(GetPath(), 0, 0, &ext);
3918 return ext;
3919 }
3920
3921 inline
IsFile(EFollowLinks follow) const3922 bool CDirEntry::IsFile(EFollowLinks follow) const
3923 {
3924 return GetType(follow) == eFile;
3925 }
3926
3927 inline
IsDir(EFollowLinks follow) const3928 bool CDirEntry::IsDir(EFollowLinks follow) const
3929 {
3930 return GetType(follow) == eDir;
3931 }
3932
3933 inline
IsLink(void) const3934 bool CDirEntry::IsLink(void) const
3935 {
3936 return GetType(eIgnoreLinks) == eLink;
3937 }
3938
3939 #if !defined(NCBI_OS_MSWIN)
3940 // Default implementation. See Windows-specific implementation in the .cpp file
3941 inline
Exists(void) const3942 bool CDirEntry::Exists(void) const
3943 {
3944 return GetType() != eUnknown;
3945 }
3946 #endif
3947
3948 inline
MatchesMask(const string & name,const string & mask,NStr::ECase use_case)3949 bool CDirEntry::MatchesMask(const string& name, const string& mask,
3950 NStr::ECase use_case)
3951 {
3952 return NStr::MatchesMask(name, mask, use_case);
3953 }
3954
3955 inline
MatchesMask(const string & name,const CMask & mask,NStr::ECase use_case)3956 bool CDirEntry::MatchesMask(const string& name, const CMask& mask,
3957 NStr::ECase use_case)
3958 {
3959 return mask.Match(name, use_case);
3960 }
3961
3962 inline
CopyToDir(const string & dir,TCopyFlags flags,size_t buf_size) const3963 bool CDirEntry::CopyToDir(const string& dir, TCopyFlags flags,
3964 size_t buf_size) const
3965 {
3966 string path = MakePath(dir, GetName());
3967 return Copy(path, flags, buf_size);
3968 }
3969
3970 inline
MoveToDir(const string & dir,TRenameFlags flags)3971 bool CDirEntry::MoveToDir(const string& dir, TRenameFlags flags)
3972 {
3973 string path = MakePath(dir, GetName());
3974 return Rename(path, flags);
3975 }
3976
3977 inline
GetBackupSuffix(void)3978 const char* CDirEntry::GetBackupSuffix(void)
3979 {
3980 return m_BackupSuffix;
3981 }
3982
3983 inline
SetBackupSuffix(const char * suffix)3984 void CDirEntry::SetBackupSuffix(const char* suffix)
3985 {
3986 m_BackupSuffix = const_cast<char*>(suffix);
3987 }
3988
3989 inline
GetDefaultModeT() const3990 mode_t CDirEntry::GetDefaultModeT() const
3991 {
3992 return MakeModeT(m_DefaultMode[eUser], m_DefaultMode[eGroup],
3993 m_DefaultMode[eOther], m_DefaultMode[eSpecial]);
3994 }
3995
3996
3997
3998 // CFile
3999
4000 inline
CFile(void)4001 CFile::CFile(void)
4002 {
4003 SetDefaultMode(eFile, fDefault, fDefault, fDefault);
4004 }
4005
4006
4007 inline
CFile(const string & filename)4008 CFile::CFile(const string& filename) : CParent(filename)
4009 {
4010 SetDefaultMode(eFile, fDefault, fDefault, fDefault);
4011 }
4012
4013 inline
CFile(const CDirEntry & file)4014 CFile::CFile(const CDirEntry& file) : CParent(file)
4015 {
4016 return;
4017 }
4018
4019 inline
Exists(void) const4020 bool CFile::Exists(void) const
4021 {
4022 return IsFile();
4023 }
4024
4025
4026 // CDir
4027
4028 inline
CDir(void)4029 CDir::CDir(void)
4030 {
4031 SetDefaultMode(eDir, fDefault, fDefault, fDefault);
4032 }
4033
4034 inline
CDir(const string & dirname)4035 CDir::CDir(const string& dirname) : CParent(dirname)
4036 {
4037 SetDefaultMode(eDir, fDefault, fDefault, fDefault);
4038 }
4039
4040 inline
CDir(const CDirEntry & dir)4041 CDir::CDir(const CDirEntry& dir) : CDirEntry(dir)
4042 {
4043 return;
4044 }
4045
4046 inline
Exists(void) const4047 bool CDir::Exists(void) const
4048 {
4049 return IsDir();
4050 }
4051
4052 inline CDir::TEntries
GetEntries(const string & mask,EGetEntriesMode mode,NStr::ECase use_case) const4053 CDir::GetEntries(const string& mask,
4054 EGetEntriesMode mode,
4055 NStr::ECase use_case) const
4056 {
4057 if (use_case == NStr::eNocase) mode |= fNoCase;
4058 return GetEntries(mask, mode);
4059 }
4060
4061 inline CDir::TEntries
GetEntries(const vector<string> & masks,EGetEntriesMode mode,NStr::ECase use_case) const4062 CDir::GetEntries(const vector<string>& masks,
4063 EGetEntriesMode mode,
4064 NStr::ECase use_case) const
4065 {
4066 if (use_case == NStr::eNocase) mode |= fNoCase;
4067 return GetEntries(masks, mode);
4068 }
4069
4070 inline CDir::TEntries
GetEntries(const CMask & masks,EGetEntriesMode mode,NStr::ECase use_case) const4071 CDir::GetEntries(const CMask& masks,
4072 EGetEntriesMode mode,
4073 NStr::ECase use_case) const
4074 {
4075 if (use_case == NStr::eNocase) mode |= fNoCase;
4076 return GetEntries(masks, mode);
4077 }
4078
4079 inline CDir::TEntries*
GetEntriesPtr(const string & mask,EGetEntriesMode mode,NStr::ECase use_case) const4080 CDir::GetEntriesPtr(const string& mask,
4081 EGetEntriesMode mode,
4082 NStr::ECase use_case) const
4083 {
4084 if (use_case == NStr::eNocase) mode |= fNoCase;
4085 return GetEntriesPtr(mask, mode);
4086 }
4087
4088 inline CDir::TEntries*
GetEntriesPtr(const vector<string> & masks,EGetEntriesMode mode,NStr::ECase use_case) const4089 CDir::GetEntriesPtr(const vector<string>& masks,
4090 EGetEntriesMode mode,
4091 NStr::ECase use_case) const
4092 {
4093 if (use_case == NStr::eNocase) mode |= fNoCase;
4094 return GetEntriesPtr(masks, mode);
4095 }
4096
4097 inline CDir::TEntries*
GetEntriesPtr(const CMask & masks,EGetEntriesMode mode,NStr::ECase use_case) const4098 CDir::GetEntriesPtr(const CMask& masks,
4099 EGetEntriesMode mode,
4100 NStr::ECase use_case) const
4101 {
4102 if (use_case == NStr::eNocase) mode |= fNoCase;
4103 return GetEntriesPtr(masks, mode);
4104 }
4105
4106
4107 // SCompareDirEntries
4108
4109 inline
operator ()(const CDir::TEntry & e1,const CDir::TEntry & e2)4110 bool SCompareDirEntries::operator()(const CDir::TEntry& e1, const CDir::TEntry& e2)
4111 {
4112 return operator()(e1->GetPath(), e2->GetPath());
4113 }
4114
4115
4116 // CSymLink
4117
4118 inline
CSymLink(void)4119 CSymLink::CSymLink(void)
4120 {
4121 return;
4122 }
4123
4124 inline
CSymLink(const string & link)4125 CSymLink::CSymLink(const string& link) : CParent(link)
4126 {
4127 // We dont need SetDefaultMode() here
4128 return;
4129 }
4130
4131 inline
CSymLink(const CDirEntry & link)4132 CSymLink::CSymLink(const CDirEntry& link) : CDirEntry(link)
4133 {
4134 return;
4135 }
4136
4137 inline
Exists(void) const4138 bool CSymLink::Exists(void) const
4139 {
4140 return IsLink();
4141 }
4142
4143
4144 // CFileDelete*
4145
4146 inline
Add(const string & path)4147 void CFileDeleteList::Add(const string& path)
4148 {
4149 string p = CDirEntry::NormalizePath(CDirEntry::CreateAbsolutePath(path));
4150 m_Paths.push_back(p);
4151 }
4152
4153 inline
GetList(void) const4154 const CFileDeleteList::TList& CFileDeleteList::GetList(void) const
4155 {
4156 return m_Paths;
4157 }
4158
4159 inline
SetList(CFileDeleteList::TList & list)4160 void CFileDeleteList::SetList(CFileDeleteList::TList& list)
4161 {
4162 m_Paths = list;
4163 }
4164
4165
4166 // CMemoryFile_Base
4167
4168 inline
MemMapAdviseAddr(void * addr,size_t len,EMemMapAdvise advise)4169 bool CMemoryFile_Base::MemMapAdviseAddr(void* addr, size_t len,
4170 EMemMapAdvise advise)
4171 {
4172 return MemoryAdvise(addr, len, (EMemoryAdvise)advise);
4173 }
4174
4175
4176 // CMemoryFileSegment
4177
4178 inline
GetPtr(void) const4179 void* CMemoryFileSegment::GetPtr(void) const
4180 {
4181 return m_DataPtr;
4182 }
4183
4184 inline
GetSize(void) const4185 size_t CMemoryFileSegment::GetSize(void) const
4186 {
4187 return m_Length;
4188 }
4189
4190
4191 inline
GetOffset(void) const4192 CMemoryFileSegment::TOffsetType CMemoryFileSegment::GetOffset(void) const
4193 {
4194 return m_Offset;
4195 }
4196
4197 inline
GetRealPtr(void) const4198 void* CMemoryFileSegment::GetRealPtr(void) const
4199 {
4200 return m_DataPtrReal;
4201 }
4202
4203 inline
GetRealSize(void) const4204 size_t CMemoryFileSegment::GetRealSize(void) const
4205 {
4206 return m_LengthReal;
4207 }
4208
4209
4210 inline
GetRealOffset(void) const4211 CMemoryFileSegment::TOffsetType CMemoryFileSegment::GetRealOffset(void) const
4212 {
4213 return m_OffsetReal;
4214 }
4215
4216 inline
MemMapAdvise(EMemMapAdvise advise) const4217 bool CMemoryFileSegment::MemMapAdvise(EMemMapAdvise advise) const
4218 {
4219 if ( !m_DataPtr ) {
4220 return false;
4221 }
4222 return MemMapAdviseAddr(m_DataPtrReal, m_LengthReal, advise);
4223 }
4224
4225
4226 // CMemoryFileMap
4227
4228 inline const CMemoryFileSegment*
GetMemoryFileSegment(void * ptr) const4229 CMemoryFileMap::GetMemoryFileSegment(void* ptr) const
4230 {
4231 return x_GetMemoryFileSegment(ptr);
4232 }
4233
4234 inline
GetOffset(void * ptr) const4235 CMemoryFileMap::TOffsetType CMemoryFileMap::GetOffset(void* ptr) const
4236 {
4237 return GetMemoryFileSegment(ptr)->GetOffset();
4238 }
4239
4240 inline
GetSize(void * ptr) const4241 size_t CMemoryFileMap::GetSize(void* ptr) const
4242 {
4243 return GetMemoryFileSegment(ptr)->GetSize();
4244 }
4245
4246 inline
Flush(void * ptr) const4247 bool CMemoryFileMap::Flush(void* ptr) const
4248 {
4249 return GetMemoryFileSegment(ptr)->Flush();
4250 }
4251
4252 inline
MemMapAdvise(void * ptr,EMemMapAdvise advise) const4253 bool CMemoryFileMap::MemMapAdvise(void* ptr, EMemMapAdvise advise) const
4254 {
4255 return GetMemoryFileSegment(ptr)->MemMapAdvise(advise);
4256 }
4257
4258
4259
4260 // CMemoryFile
4261
4262 inline
GetPtr(void) const4263 void* CMemoryFile::GetPtr(void) const
4264 {
4265 return m_Ptr;
4266 }
4267
4268 inline
GetSize(void) const4269 size_t CMemoryFile::GetSize(void) const
4270 {
4271 // Special case: file is not mapped and its length is zero.
4272 if (!m_Ptr && GetFileSize() == 0) {
4273 return 0;
4274 }
4275 x_Verify();
4276 return CMemoryFileMap::GetSize(m_Ptr);
4277 }
4278
4279 inline
GetOffset(void) const4280 CMemoryFile::TOffsetType CMemoryFile::GetOffset(void) const
4281 {
4282 x_Verify();
4283 return CMemoryFileMap::GetOffset(m_Ptr);
4284 }
4285
4286 inline
Flush(void) const4287 bool CMemoryFile::Flush(void) const
4288 {
4289 x_Verify();
4290 return CMemoryFileMap::Flush(m_Ptr);
4291 }
4292
4293 inline
MemMapAdvise(EMemMapAdvise advise) const4294 bool CMemoryFile::MemMapAdvise(EMemMapAdvise advise) const
4295 {
4296 x_Verify();
4297 return CMemoryFileMap::MemMapAdvise(m_Ptr, advise);
4298 }
4299
4300
4301 END_NCBI_SCOPE
4302
4303 #endif /* CORELIB___NCBIFILE__HPP */
4304