ncbifile.hpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:41k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: ncbifile.hpp,v $
  4.  * PRODUCTION Revision 1000.5  2004/06/01 19:08:05  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.42
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. #ifndef CORELIB__NCBIFILE__HPP
  10. #define CORELIB__NCBIFILE__HPP
  11. /*  $Id: ncbifile.hpp,v 1000.5 2004/06/01 19:08:05 gouriano Exp $
  12.  * ===========================================================================
  13.  *
  14.  *                            PUBLIC DOMAIN NOTICE
  15.  *               National Center for Biotechnology Information
  16.  *
  17.  *  This software/database is a "United States Government Work" under the
  18.  *  terms of the United States Copyright Act.  It was written as part of
  19.  *  the author's official duties as a United States Government employee and
  20.  *  thus cannot be copyrighted.  This software/database is freely available
  21.  *  to the public for use. The National Library of Medicine and the U.S.
  22.  *  Government have not placed any restriction on its use or reproduction.
  23.  *
  24.  *  Although all reasonable efforts have been taken to ensure the accuracy
  25.  *  and reliability of the software and data, the NLM and the U.S.
  26.  *  Government do not and cannot warrant the performance or results that
  27.  *  may be obtained by using this software or data. The NLM and the U.S.
  28.  *  Government disclaim all warranties, express or implied, including
  29.  *  warranties of performance, merchantability or fitness for any particular
  30.  *  purpose.
  31.  *
  32.  *  Please cite the author in any work or product based on this material.
  33.  *
  34.  * ===========================================================================
  35.  *
  36.  * Author: Vladimir Ivanov, Denis Vakatov
  37.  *
  38.  *
  39.  */
  40. /// @file ncbifile.hpp
  41. /// Define files and directories accessory functions.
  42. ///
  43. /// Defines classes CDirEntry, CFile, CDir, CMemoryFile, CFileException
  44. /// to allow various file and directory operations.
  45. #include <corelib/ncbistd.hpp>
  46. #include <corelib/ncbitime.hpp>
  47. #include <vector>
  48. #if defined(NCBI_OS_MAC)
  49. struct FSSpec;
  50. #endif
  51. /** @addtogroup Files
  52.  *
  53.  * @{
  54.  */
  55. BEGIN_NCBI_SCOPE
  56. /////////////////////////////////////////////////////////////////////////////
  57. ///
  58. /// CFileException --
  59. ///
  60. /// Define exceptions generated for file operations.
  61. ///
  62. /// CFileException inherits its basic functionality from CCoreException
  63. /// and defines additional error codes for file operations.
  64. class NCBI_XNCBI_EXPORT CFileException : public CCoreException
  65. {
  66. public:
  67.     /// Error types that file operations can generate.
  68.     enum EErrCode {
  69.         eMemoryMap,
  70.         eRelativePath
  71.     };
  72.     /// Translate from the error code value to its string representation.
  73.     virtual const char* GetErrCodeString(void) const
  74.     {
  75.         switch (GetErrCode()) {
  76.         case eMemoryMap: return "eMemoryMap";
  77.         default:         return CException::GetErrCodeString();
  78.         }
  79.     }
  80.     // Standard exception boilerplate code.
  81.     NCBI_EXCEPTION_DEFAULT(CFileException, CCoreException);
  82. };
  83. /// Whether to follow symbolic links (aka shortcuts or aliases)
  84. enum EFollowLinks {
  85.     eIgnoreLinks,
  86.     eFollowLinks
  87. };
  88. /////////////////////////////////////////////////////////////////////////////
  89. ///
  90. /// CDirEntry --
  91. ///
  92. /// Base class to work with files and directories.
  93. ///
  94. /// Models the directory entry structure for the file system. Assumes that
  95. /// the path argument has the following form, where any or all components may
  96. /// be missing:
  97. ///
  98. /// <dir><title><ext>
  99. ///
  100. /// - dir   - file path             ("/usr/local/bin/"  or  "c:windows")
  101. /// - title - file name without ext ("autoexec")
  102. /// - ext   - file extension        (".bat" - whatever goes after the last dot)
  103. ///
  104. /// Supported filename formats:  MS DOS/Windows, UNIX and MAC.
  105. class NCBI_XNCBI_EXPORT CDirEntry
  106. {
  107. public:
  108.     /// Constructor.
  109.     CDirEntry();
  110. #  ifdef NCBI_OS_MAC
  111.     /// Copy constructor - for Mac file system.
  112.     CDirEntry(const CDirEntry& other);
  113.     /// Constructor with FSSpec argument - for Mac file system.
  114.     CDirEntry(const FSSpec& fss);
  115.     /// Assignment operator - for Mac file system.
  116.     CDirEntry& operator= (const CDirEntry& other);
  117.     /// Equality operator.
  118.     bool operator== (const CDirEntry& other) const;
  119. #  endif
  120.     /// Constructor using specified path string.
  121.     CDirEntry(const string& path);
  122.     /// Reset path string.
  123.     void Reset(const string& path);
  124.     /// Destructor.
  125.     virtual ~CDirEntry(void);
  126. # if defined(NCBI_OS_MAC)
  127.     /// Get FSSpec setting - for Mac file system.
  128.     const FSSpec& FSS() const;
  129. #endif
  130.     /// Get directory entry path.
  131.     string GetPath(void) const;
  132.     //
  133.     // Path processing.
  134.     //
  135.     /// Split the path string into its basic components.
  136.     ///
  137.     /// @param path
  138.     ///   Path string to be split.
  139.     /// @param dir
  140.     ///   The directory component that is returned. This will always have
  141.     ///   a terminating path separator (example: "/usr/local/").
  142.     /// @param ext
  143.     ///   The extension component. This will always start with a dot
  144.     ///   (example: ".bat").
  145.     static void SplitPath(const string& path,
  146.                           string* dir = 0, string* base = 0, string* ext = 0);
  147.     /// Get the Directory component for this directory entry.
  148.     string GetDir (void) const;
  149.     /// Get the base entry name with extension.
  150.     string GetName(void) const;
  151.     /// Get the base entry name without extension.
  152.     string GetBase(void) const;
  153.     /// Get extension name.
  154.     string GetExt (void) const;
  155.     /// Make a path from the basic components.
  156.     ///
  157.     /// @param dir
  158.     ///   The directory component to make the path string. This will always
  159.     ///   have a terminating path separator (example: "/usr/local/").
  160.     /// @param base
  161.     ///   The basename of the file component that is used to make up the path.
  162.     /// @param ext
  163.     ///   The extension component. This will always start with a dot
  164.     ///   (example: ".bat").
  165.     /// @return
  166.     ///   Path built from the components.
  167.     static string MakePath(const string& dir  = kEmptyStr,
  168.                            const string& base = kEmptyStr,
  169.                            const string& ext  = kEmptyStr);
  170.     /// Get path separator symbol specific for the platform.
  171.     static char GetPathSeparator(void);
  172.     /// Check character "c" as path separator symbol specific for the platform.
  173.     static bool IsPathSeparator(const char c);
  174.     /// Add trailing path separator, if needed.
  175.     static string AddTrailingPathSeparator(const string& path);
  176.     /// Delete trailing path separator, if needed.
  177.     static string DeleteTrailingPathSeparator(const string& path);
  178.     /// Convert relative "path" on any OS to current OS dependent relative
  179.     /// path. 
  180.     static string ConvertToOSPath(const string& path);
  181.     /// Check if the "path" is absolute for the current OS.
  182.     ///
  183.     /// Note that the "path" must be for current OS. 
  184.     static bool IsAbsolutePath(const string& path);
  185.     /// Check if the "path" is absolute for any OS.
  186.     ///
  187.     /// Note that the "path" can be for any OS (MSWIN, UNIX, MAC).
  188.     static bool IsAbsolutePathEx(const string& path);
  189.     /// Create relative path from 2 absolute pathes.
  190.     ///
  191.     /// @param path_from 
  192.     ///   Absolute path that defines the start of the relative path.
  193.     /// @param path_to
  194.     ///   Absolute path that defines the endpoint of the relative path.
  195.     /// @return
  196.     ///   Return the relative path (empty string if the paths are the same).
  197.     ///   Throw CFileException on error (e.g. if any of the paths is not
  198.     ///   absolute, or if it is impossible to create relative path, such
  199.     ///   as in case of different disks on MS-Windows).
  200.     static string CreateRelativePath(const string& path_from, 
  201.                                      const string& path_to);
  202.     /// Concatenate the two parts of the path for the current OS.
  203.     ///
  204.     /// Note that the arguments must be for the current OS.
  205.     /// @param first
  206.     ///   The first part of the path which can be either absolute or relative.
  207.     /// @param second
  208.     ///   The second part of the path must always be relative.
  209.     /// @return
  210.     ///   The concatenated path.
  211.     static string ConcatPath(const string& first, const string& second);
  212.     /// Concatenate the two parts of the path for any OS.
  213.     ///
  214.     /// Note that the arguments must be for any OS (MSWIN, UNIX, MAC).
  215.     /// @param first
  216.     ///   The first part of the path which can be either absolute or relative.
  217.     /// @param second
  218.     ///   The second part of the path must always be relative.
  219.     /// @return
  220.     ///   The concatenated path.
  221.     static string ConcatPathEx(const string& first, const string& second);
  222.     /// Normalize path.
  223.     ///
  224.     /// Remove from the "path" all redundancy, convert it to the more
  225.     /// simple form, if possible.
  226.     /// Note that the "path" must be for current OS. 
  227.     /// @param follow_links
  228.     ///   Whether to follow symlinks (shortcuts, aliases)
  229.     static string NormalizePath(const string& path,
  230.                                 EFollowLinks  follow_links = eIgnoreLinks);
  231.     //
  232.     // Checks & manipulations
  233.     //
  234.     /// Match "name" against the filename "mask".
  235.     static bool MatchesMask(const char *name, const char *mask);
  236.     /// Check existence of entry "path".
  237.     virtual bool Exists(void) const;
  238.     /// Rename entry to specified "new_path".
  239.     bool Rename(const string& new_path);
  240.     /// Directory remove mode.
  241.     enum EDirRemoveMode {
  242.         eOnlyEmpty,     ///< Remove only empty directory
  243.         eNonRecursive,  ///< Remove all files in directory, but not remove
  244.                         ///< subdirectories and files in it
  245.         eRecursive      ///< Remove all files and subdirectories
  246.     };
  247.     /// Remove directory entry.
  248.     ///
  249.     /// Remove directory using the specified "mode".
  250.     /// @sa
  251.     ///   EDirRemoveMode
  252.     virtual bool Remove(EDirRemoveMode mode = eRecursive) const;
  253.     
  254.     /// Check if directory entry a file.
  255.     /// @sa
  256.     ///   IsDir(), GetType()
  257.     bool IsFile(EFollowLinks follow = eFollowLinks) const;
  258.     /// Check if directory entry a directory.
  259.     /// @sa
  260.     ///   IsFile(), GetType()
  261.     bool IsDir(EFollowLinks follow = eFollowLinks) const;
  262.     /// Which directory entry type.
  263.     enum EType {
  264.         eFile = 0,     ///< Regular file
  265.         eDir,          ///< Directory
  266.         ePipe,         ///< Pipe
  267.         eLink,         ///< Symbolic link     (UNIX only)
  268.         eSocket,       ///< Socket            (UNIX only)
  269.         eDoor,         ///< Door              (UNIX only)
  270.         eBlockSpecial, ///< Block special     (UNIX only)
  271.         eCharSpecial,  ///< Character special
  272.         //
  273.         eUnknown       ///< Unknown type
  274.     };
  275.     /// Get type of directory entry.
  276.     ///
  277.     /// @return
  278.     ///   Return one of the values in EType. If the directory entry does
  279.     ///   not exist return "eUnknown".
  280.     EType GetType(EFollowLinks follow = eIgnoreLinks) const;
  281.     /// Get time stamp of directory entry.
  282.     ///
  283.     /// The "creation" time under MS windows is actual creation time of the
  284.     /// entry. Under UNIX "creation" time is the time of last entry status
  285.     /// change. 
  286.     /// @return
  287.     ///   TRUE if time was acquired or FALSE otherwise.
  288.     /// @sa
  289.     ///   SetTime()
  290.     bool GetTime(CTime *modification, CTime *creation = 0, 
  291.                  CTime *last_access = 0) const;
  292.     /// Set time stamp on directory entry.
  293.     ///
  294.     /// The process must be the owner of the file or have write permissions
  295.     /// in order to change the time. If value of parameters modification or
  296.     /// last access time is zero that current time will be used.
  297.     /// @param modification
  298.     ///   New file modification time.
  299.     /// @param last_access
  300.     ///   New last file access time. It cannot be less than the file
  301.     ///   creation time. In last case it will be set equal to creation time.
  302.     /// @return
  303.     ///   TRUE if time was changed or FALSE otherwise.
  304.     /// @sa
  305.     ///   GetTime()
  306.     bool SetTime(CTime *modification = 0 , CTime *last_access = 0) const;
  307.     //
  308.     // Access permissions.
  309.     //
  310.     /// Directory entry's access permissions.
  311.     enum EMode {
  312.         fExecute = 1,       ///< Execute permission
  313.         fWrite   = 2,       ///< Write permission
  314.         fRead    = 4,       ///< Read permission
  315.         // initial defaults for dirs
  316.         fDefaultDirUser  = fRead | fExecute | fWrite,
  317.                             ///< Default user permission for dir.
  318.         fDefaultDirGroup = fRead | fExecute,
  319.                             ///< Default group permission for dir.
  320.         fDefaultDirOther = fRead | fExecute,
  321.                             ///< Default other permission for dir.
  322.         // initial defaults for non-dir entries (files, etc.)
  323.         fDefaultUser     = fRead | fWrite,
  324.                             ///< Default user permission for file
  325.         fDefaultGroup    = fRead,
  326.                             ///< Default group permission for file
  327.         fDefaultOther    = fRead,
  328.                             ///< Default other permission for file
  329.         fDefault = 8        ///< Special flag:  ignore all other flags,
  330.                             ///< use current default mode
  331.     };
  332.     typedef unsigned int TMode;  ///< Binary OR of "EMode"
  333.     /// Get the directory entry's permission settings.
  334.     ///
  335.     /// On WINDOWS, there is only the "user_mode" permission setting, and
  336.     /// "group_mode" and "other_mode" settings will be ignored.
  337.     /// @return
  338.     ///   TRUE if successful return of permission settings; FALSE, otherwise.
  339.     /// @sa
  340.     ///   SetMode()
  341.     bool GetMode(TMode* user_mode,
  342.                  TMode* group_mode = 0,
  343.                  TMode* other_mode = 0) const;
  344.     /// Set permission mode for the directory entry.
  345.     ///
  346.     /// Permissions are set as specified by the passed values for user_mode,
  347.     /// group_mode and other_mode. The default value for group_mode and
  348.     /// other mode is "fDefault". Setting to "fDefault" will set the mode to
  349.     /// its default permission settings.
  350.     /// @return
  351.     ///   TRUE if permission successfully set;  FALSE, otherwise.
  352.     /// @sa
  353.     ///   SetDefaultMode(), SetDefaultModeGlobal(), GetMode()
  354.     bool SetMode(TMode user_mode,  // e.g. fDefault
  355.                  TMode group_mode = fDefault,
  356.                  TMode other_mode = fDefault) const;
  357.     /// Set default mode globally for all CDirEntry objects.
  358.     ///
  359.     /// The default mode is set globally for all CDirEntry objects except for
  360.     /// those having their own mode set with SetDefaultMode().
  361.     ///
  362.     /// When "fDefault" is passed as value of the mode parameters, the default
  363.     /// mode will be set to the default values defined in EType:
  364.     ///
  365.     /// If user_mode is "fDefault", then default for user mode is set to
  366.     /// - "fDefaultDirUser" if this is a directory or to
  367.     /// - "fDefaultUser" if this is a file.
  368.     /// 
  369.     /// If group_mode is "fDefault", then default for group mode is set to
  370.     /// - "fDefaultDirGroup" if this is a directory or to
  371.     /// - "fDefaultGroup" if this is a file.
  372.     ///
  373.     /// If other_mode is "fDefault", then default for other mode is set to
  374.     /// - "fDefaultDirOther" if this is a directory or to
  375.     /// - "fDefaultOther" if this is a file.
  376.     static void SetDefaultModeGlobal(EType entry_type,
  377.                                      TMode user_mode,  // e.g. fDefault
  378.                                      TMode group_mode = fDefault,
  379.                                      TMode other_mode = fDefault);
  380.     /// Set mode for this one object only.
  381.     ///
  382.     /// When "fDefault" is passed as value of the mode parameters, the mode
  383.     /// will be set to the current global mode as specified
  384.     /// by SetDefaultModeGlobal().
  385.     virtual void SetDefaultMode(EType entry_type,
  386.                                 TMode user_mode,  // e.g. fDefault
  387.                                 TMode group_mode = fDefault,
  388.                                 TMode other_mode = fDefault);
  389. protected:
  390.     /// Get the default global mode.
  391.     ///
  392.     /// Used by derived classes like CDir and CFile.
  393.     static void GetDefaultModeGlobal(EType  entry_type,
  394.                                      TMode* user_mode,
  395.                                      TMode* group_mode,
  396.                                      TMode* other_mode);
  397.     /// Get the default mode.
  398.     ///
  399.     /// Used by derived classes like CDir and CFile.
  400.     void GetDefaultMode(TMode* user_mode,
  401.                         TMode* group_mode,
  402.                         TMode* other_mode) const;
  403. private:
  404. #  ifdef NCBI_OS_MAC
  405.     FSSpec* m_FSS;      ///< Mac OS specific file description
  406. #  else
  407.     string m_Path;      ///< Full directory entry path
  408. #  endif
  409.     /// Which default mode: user, group, or other.
  410.     ///
  411.     /// Used as index into array that contains default mode values;
  412.     /// so there is no "fDefault" as an enumeration value for EWho, here!
  413.     enum EWho {
  414.         eUser = 0,      ///< User mode
  415.         eGroup,         ///< Group mode
  416.         eOther          ///< Other mode
  417.     };
  418.     /// Holds default mode global values.
  419.     static TMode m_DefaultModeGlobal[eUnknown][3/*EWho*/];
  420.     /// Holds default mode values.
  421.     TMode        m_DefaultMode[3/*EWho*/];
  422. };
  423. /////////////////////////////////////////////////////////////////////////////
  424. ///
  425. /// CFile --
  426. ///
  427. /// Define class to work with files.
  428. ///
  429. /// Models the files in a file system. Basic functionality is derived from
  430. /// CDirEntry and extended for files.
  431. class NCBI_XNCBI_EXPORT CFile : public CDirEntry
  432. {
  433.     typedef CDirEntry CParent;    ///< CDirEntry is parent class
  434. public:
  435.     /// Constructor.
  436.     CFile(const string& file);
  437.     /// Destructor.
  438.     virtual ~CFile(void);
  439.     /// Check existence of file.
  440.     virtual bool Exists(void) const;
  441.     /// Get size of file.
  442.     ///
  443.     /// @return
  444.     /// - size of file, if no error.
  445.     /// - -1, if there was an error obtaining file size.
  446.     Int8 GetLength(void) const;
  447.     //
  448.     // Temporary files
  449.     //
  450.     /// Temporary file creation mode
  451.     enum ETmpFileCreationMode {
  452.         eTmpFileCreate,     ///< Create empty file for each GetTmpName* call.
  453.         eTmpFileGetName     ///< Get name of the file only.
  454.     };
  455.     /// Get temporary file name.
  456.     ///
  457.     /// @param mode
  458.     ///   Temporary file creation mode.
  459.     /// @return
  460.     ///   Name of temporary file, or "kEmptyStr" if there was an error
  461.     ///   getting temporary file name.
  462.     /// @sa
  463.     ///    GetTmpNameEx(), ETmpFileCreationMode
  464.     static string GetTmpName(ETmpFileCreationMode mode = eTmpFileGetName);
  465.     /// Get temporary file name.
  466.     ///
  467.     /// @param dir
  468.     ///   Directory in which temporary file is to be created;
  469.     ///   default of kEmptyStr means that system temporary directory will
  470.     ///   be used or current, if a system temporary directory cannot
  471.     ///   be determined.
  472.     /// @param prefix
  473.     ///   Temporary file name will be prefixed by value of this parameter;
  474.     ///   default of kEmptyStr means that, effectively, no prefix value will
  475.     ///   be used.
  476.     /// @param mode
  477.     ///   Temporary file creation mode. 
  478.     ///   If set to "eTmpFileCreate", empty file with unique name will be
  479.     ///   created. Please, do not forget to remove it youself as soon as it
  480.     ///   is no longer needed. On some platforms "eTmpFileCreate" mode is 
  481.     ///   equal to "eTmpFileGetName".
  482.     ///   If set to "eTmpFileGetName", returns only the name of the temporary
  483.     ///   file, without creating it. This method is faster but it have
  484.     ///   potential race condition, when other process can leave as behind and
  485.     ///   create file with the same name first.
  486.     /// @return
  487.     ///   Name of temporary file, or "kEmptyStr" if there was an error
  488.     ///   getting temporary file name.
  489.     /// @sa
  490.     ///    GetTmpName(), ETmpFileCreationMode
  491.     static string GetTmpNameEx(const string&        dir    = kEmptyStr,
  492.                                const string&        prefix = kEmptyStr,
  493.                                ETmpFileCreationMode mode   = eTmpFileGetName);
  494.     /// What type of temporary file to create.
  495.     enum ETextBinary {
  496.         eText,          ///< Create text file
  497.         eBinary         ///< Create binary file
  498.     };
  499.     /// Which operations to allow on temporary file.
  500.     enum EAllowRead {
  501.         eAllowRead,     ///< Allow read and write
  502.         eWriteOnly      ///< Allow write only
  503.     };
  504.     /// Create temporary file and return pointer to corresponding stream.
  505.     ///
  506.     /// The temporary file will be automatically deleted after the stream
  507.     /// object is deleted. If the file exists before the function call, then
  508.     /// after the function call it will be removed. Also any previous contents
  509.     /// of the file will be overwritten.
  510.     /// @param filename
  511.     ///   Use this value as name of temporary file. If "kEmptyStr" is passed
  512.     ///   generate a temporary file name.
  513.     /// @param text_binary
  514.     ///   Specifies if temporary filename should be text ("eText") or binary
  515.     ///   ("eBinary").
  516.     /// @param allow_read
  517.     ///   If set to "eAllowRead", read and write are permitted on temporary
  518.     ///   file. If set to "eWriteOnly", only write is permitted on temporary
  519.     ///   file.
  520.     /// @return
  521.     ///   - Pointer to corresponding stream, or
  522.     ///   - NULL if error encountered.
  523.     /// @sa
  524.     ///   CreateTmpFileEx()
  525.     static fstream* CreateTmpFile(const string& filename    = kEmptyStr,
  526.                                   ETextBinary   text_binary = eBinary,
  527.                                   EAllowRead    allow_read  = eAllowRead);
  528.     /// Create temporary file and return pointer to corresponding stream.
  529.     ///
  530.     /// Similar to CreateTmpEx() except that you can also specify the directory
  531.     /// in which to create the temporary file and the prefix string to be used
  532.     /// for creating the temporary file.
  533.     ///
  534.     /// The temporary file will be automatically deleted after the stream
  535.     /// object is deleted. If the file exists before the function call, then
  536.     /// after the function call it will be removed. Also any previous contents
  537.     /// of the file will be overwritten.
  538.     /// @param dir
  539.     ///   The directory in which the temporary file is to be created. If not
  540.     ///   specified, the temporary file will be created in the current 
  541.     ///   directory.
  542.     /// @param prefix
  543.     ///   Use this value as the prefix for temporary file name. If "kEmptyStr"
  544.     ///   is passed generate a temporary file name.
  545.     /// @param text_binary
  546.     ///   Specifies if temporary filename should be text ("eText") or binary
  547.     ///   ("eBinary").
  548.     /// @param allow_read
  549.     ///   If set to "eAllowRead", read and write are permitted on temporary
  550.     ///   file. If set to "eWriteOnly", only write is permitted on temporary
  551.     ///   file.
  552.     /// @return
  553.     ///   - Pointer to corresponding stream, or
  554.     ///   - NULL if error encountered.
  555.     /// @sa
  556.     ///   CreateTmpFile()
  557.     static fstream* CreateTmpFileEx(const string& dir         = ".",
  558.                                     const string& prefix      = kEmptyStr,
  559.                                     ETextBinary   text_binary = eBinary,
  560.                                     EAllowRead    allow_read  = eAllowRead);
  561. };
  562. /////////////////////////////////////////////////////////////////////////////
  563. ///
  564. /// CDir --
  565. ///
  566. /// Define class to work with directories.
  567. ///
  568. /// NOTE: Next functions are unsafe in multithreaded applications:
  569. ///       - static bool Exists() (for Mac only);
  570. ///       - bool Exists() (for Mac only).
  571. class NCBI_XNCBI_EXPORT CDir : public CDirEntry
  572. {
  573.     typedef CDirEntry CParent;  ///< CDirEntry is the parent class
  574. public:
  575.     /// Constructor.
  576.     CDir();
  577. #  if defined(NCBI_OS_MAC)
  578.     /// Constructor - for Mac OS.
  579.     CDir(const FSSpec& fss);
  580. #  endif
  581.     /// Constructor using specified directory name.
  582.     CDir(const string& dirname);
  583.     /// Destructor.
  584.     virtual ~CDir(void);
  585.     /// Check if directory "dirname" exists.
  586.     virtual bool Exists(void) const;
  587.     /// Get user "home" directory.
  588.     static string GetHome(void);
  589.     /// Get temporary directory.
  590.     static string GetTmpDir(void);
  591.     /// Get the current working directory.
  592.     static string GetCwd();
  593.     /// Define a vector of pointers to directory entries.
  594.     typedef vector< AutoPtr<CDirEntry> > TEntries;
  595.     /// Modes for GetEntries
  596.     /// @sa GetEntries
  597.     enum EGetEntriesMode {
  598.         eAllEntries,        ///< All included
  599.         eIgnoreRecursive    ///< Supress self recursive elements (like "..")
  600.     };
  601.     /// Get directory entries based on the specified "mask".
  602.     ///
  603.     /// @param mask
  604.     ///   Use to select only files that match this mask. Do not use file mask
  605.     ///   if set to "kEmptyStr".
  606.     /// @return
  607.     ///   An array containing all directory entries.
  608.     TEntries GetEntries(const string&   mask = kEmptyStr,
  609.                         EGetEntriesMode mode = eAllEntries) const;
  610.     /// Get directory entries based on the specified set of"masks".
  611.     ///
  612.     /// @param mask
  613.     ///   Use to select only files that match this set of masks.
  614.     /// @return
  615.     ///   An array containing all directory entries.
  616.     TEntries GetEntries(const vector<string>& masks,
  617.                         EGetEntriesMode       mode = eAllEntries) const;
  618.     /// Create the directory using "dirname" passed in the constructor.
  619.     /// 
  620.     /// @return
  621.     ///   TRUE if operation successful; FALSE, otherwise.
  622.     bool Create(void) const;
  623.     /// Create the directory path recursively possibly more than one at a time.
  624.     ///
  625.     /// @return
  626.     ///   TRUE if operation successful; FALSE otherwise.
  627.     bool CreatePath(void) const;
  628.     /// Delete existing directory.
  629.     ///
  630.     /// @param mode
  631.     ///   - If set to "eOnlyEmpty" the directory can be removed only if it
  632.     ///   is empty.
  633.     ///   - If set to "eNonRecursive" remove only files in directory, but do
  634.     ///   not remove subdirectories and files in them.
  635.     ///   - If set to "eRecursive" remove all files in directory, and
  636.     ///   subdirectories.
  637.     /// @return
  638.     ///   TRUE if operation successful; FALSE otherwise.
  639.     /// @sa
  640.     ///   EDirRemoveMode
  641.     virtual bool Remove(EDirRemoveMode mode = eRecursive) const;
  642. };
  643. /// File finding flags
  644. enum EFindFiles {
  645.     fFF_File       = (1<<0),             ///< find files
  646.     fFF_Dir        = (1<<1),             ///< find directories
  647.     fFF_Recursive  = (1<<2),             ///< decsend into sub-dirs
  648.     fFF_Default    = fFF_File | fFF_Dir  ///< default behaviour
  649. };
  650. /// bitwise OR of "EFindFiles"
  651. typedef int TFindFiles; 
  652. /// Find files in the specified directory
  653. template<class TFindFunc>
  654. TFindFunc FindFilesInDir(const CDir&            dir,
  655.                          const vector<string>&  masks,
  656.                          TFindFunc              find_func,
  657.                          TFindFiles             flags = fFF_Default)
  658. {
  659.     CDir::TEntries contents = dir.GetEntries(masks, CDir::eIgnoreRecursive);
  660.     ITERATE(CDir::TEntries, it, contents) {
  661.         const CDirEntry& dir_entry = **it;
  662.         if (dir_entry.IsDir()) {
  663.             if (flags & fFF_Dir) {
  664.                 find_func(dir_entry);
  665.             }
  666.             if (flags & fFF_Recursive) {
  667.                 CDir nested_dir(dir_entry.GetPath());
  668.                 find_func = 
  669.                   FindFilesInDir(nested_dir, masks, find_func, flags);
  670.             }
  671.         }
  672.         else
  673.         if (dir_entry.IsFile() && (flags & fFF_File)) {
  674.             find_func(dir_entry);
  675.         }
  676.     } // ITERATE
  677.     return find_func;
  678. }
  679. /// Generic algorithm for file search
  680. ///
  681. /// Algorithm scans the provided directories using iterators,
  682. /// finds files to match the masks and stores all calls functor
  683. /// object for all found entries
  684. /// Functor call should match: void Functor(const CDirEntry& dir_entry)
  685. ///
  686. template<class TPathIterator, 
  687.          class TMaskIterator, 
  688.          class TFindFunc>
  689. TFindFunc FindFiles(TPathIterator path_begin,
  690.                     TPathIterator path_end,
  691.                     TMaskIterator mask_begin,
  692.                     TMaskIterator mask_end,
  693.                     TFindFunc     find_func,
  694.                     TFindFiles    flags = fFF_Default)
  695. {
  696.     vector<string> masks;
  697.     for (; mask_begin != mask_end; ++mask_begin) {
  698.         masks.push_back(*mask_begin);
  699.     }
  700.     for (; path_begin != path_end; ++path_begin) {
  701.         const string& dir_name = *path_begin;
  702.         CDir dir(dir_name);
  703.         find_func = FindFilesInDir(dir, masks, find_func, flags);
  704.     } // for
  705.     return find_func;
  706. }
  707. /// Functor for generic FindFiles, adds file name to the specified container
  708. template<class TNames>
  709. class CFindFileNamesFunc
  710. {
  711. public:
  712.     CFindFileNamesFunc(TNames& names) : m_FileNames(&names) {}
  713.     void operator()(const CDirEntry& dir_entry)
  714.     {
  715.         m_FileNames->push_back(dir_entry.GetPath());
  716.     }
  717. protected:
  718.     TNames*  m_FileNames;
  719. };
  720. /////////////////////////////////////////////////////////////////////////////
  721. ///
  722. /// Utility algorithm scans the provided directories using iterators
  723. /// finds files to match the masks and stores all found files in 
  724. /// the container object.
  725. ///
  726. template<class TContainer, class It1>
  727. void FindFiles(TContainer&           out, 
  728.                It1                   first_path, 
  729.                It1                   last_path, 
  730.                const vector<string>& masks,
  731.                TFindFiles            flags = fFF_Default)
  732. {
  733.     CFindFileNamesFunc<TContainer> func(out);
  734.     FindFiles(first_path, last_path, 
  735.               masks.begin(), masks.end(), func, flags);
  736. }
  737. /////////////////////////////////////////////////////////////////////////////
  738. ///
  739. /// Utility algorithm scans the provided directories using iterators
  740. /// finds files to match the masks and stores all found files in 
  741. /// the container object.
  742. ///
  743. template<class TContainer, class It1, class It2>
  744. void FindFiles(TContainer&      out, 
  745.                It1  first_path, It1 last_path, 
  746.                It2  first_mask, It2 last_mask,
  747.                TFindFiles           flags = fFF_Default)
  748. {
  749.     CFindFileNamesFunc<TContainer> func(out);
  750.     FindFiles(first_path, last_path, 
  751.               first_mask, last_mask, func, flags);
  752. }
  753. /////////////////////////////////////////////////////////////////////////////
  754. ///
  755. /// fwd-decl of struct containing OS-specific mem.-file handle.
  756. struct SMemoryFileHandle;
  757. /////////////////////////////////////////////////////////////////////////////
  758. ///
  759. /// CMemoryFile --
  760. ///
  761. /// Define class for support file memory mapping.
  762. class NCBI_XNCBI_EXPORT CMemoryFile
  763. {
  764. public:
  765.     /// Which operations are permitted in memory map file.
  766.     typedef enum {
  767.         eMMP_Read,            ///< Data can be read
  768.         eMMP_Write,           ///< Data can be written
  769.         eMMP_ReadWrite    ///< Data can be read and written
  770.     } EMemMapProtect;
  771.     /// Whether to share changes or not.
  772.     typedef enum {
  773.         eMMS_Shared,      ///< Changes are shared.
  774.         eMMS_Private      ///< Changes are private.
  775.     } EMemMapShare;
  776.     /// Constructor.
  777.     ///
  778.     /// Initialize the memory mapping on file "file_name".  Throws an
  779.     /// exception on error.
  780.     /// @param filename
  781.     ///   Name of file to map to memory.
  782.     /// @param protect_attr
  783.     ///   Specify operations permitted on memory mapped file.
  784.     /// @param share_attr
  785.     ///   Specify if change to memory mapped file can be shared or not.
  786.     /// @sa
  787.     ///   EMemMapProtect, EMemMapShare
  788.     CMemoryFile(const string&  file_name,
  789.                 EMemMapProtect protect_attr = eMMP_Read,
  790.                 EMemMapShare   share_attr   = eMMS_Private);
  791.     /// Destructor.
  792.     ///
  793.     /// Calls Unmap() and cleans up memory mapped file.
  794.     ~CMemoryFile(void);
  795.     /// Check if memory-mapping is supported by the C++ Toolkit on this
  796.     /// platform.
  797.     static bool IsSupported(void);
  798.     /// Get pointer to beginning of data.
  799.     ///
  800.     /// @return
  801.     ///    - Pointer to start of data, or
  802.     ///    - NULL if mapped to a file of zero length, or if unmapped already.
  803.     void* GetPtr(void) const;
  804.     /// Get size of the mapped area.
  805.     ///
  806.     /// @return
  807.     ///   - Size in bytes of mapped area, or
  808.     ///   - -1 if unmapped already.
  809.     Int8 GetSize(void) const;
  810.     /// Flush by writing all modified copies of memory pages to the
  811.     /// underlying file.
  812.     ///
  813.     /// NOTE: By default data will be flushed in Unmap() or destructor.
  814.     bool Flush(void) const;
  815.     /// Unmap file if mapped.
  816.     ///
  817.     /// @return
  818.     ///   TRUE on success; or FALSE on error.
  819.     bool Unmap(void);
  820.     /// What type of data access pattern will be used for mapped region.
  821.     ///
  822.     /// Advises the VM system that the a certain region of user mapped memory 
  823.     /// will be accessed following a type of pattern. The VM system uses this 
  824.     /// information to optimize work with mapped memory.
  825.     ///
  826.     /// NOTE: Now works on UNIX platform only.
  827.     typedef enum {
  828.         eMMA_Normal,      ///< No further special treatment
  829.         eMMA_Random,      ///< Expect random page references
  830.         eMMA_Sequential,  ///< Expect sequential page references
  831.         eMMA_WillNeed,    ///< Will need these pages
  832.         eMMA_DontNeed     ///< Don't need these pages
  833.     } EMemMapAdvise;
  834.     /// Advise on memory map usage.
  835.     ///
  836.     /// @param advise
  837.     ///   One of the values in EMemMapAdvise that advises on expected
  838.     ///   usage pattern.
  839.     /// @return
  840.     ///   - TRUE, if memory advise operation successful. Always return
  841.     ///   TRUE if memory advise not implemented such as on Windows system.
  842.     ///   - FALSE, if memory advise operation not successful.
  843.     /// @sa
  844.     ///   EMemMapAdvise, MemMapAdviseAddr
  845.     bool MemMapAdvise(EMemMapAdvise advise);
  846.     /// Advise on memory map usage for specified region.
  847.     ///
  848.     /// @param addr
  849.     ///   Address of memory region whose usage is being advised.
  850.     /// @param len
  851.     ///   Length of memory region whose usage is being advised.
  852.     /// @param advise
  853.     ///   One of the values in EMemMapAdvise that advises on expected
  854.     ///   usage pattern.
  855.     /// @return
  856.     ///   - TRUE, if memory advise operation successful. Always return
  857.     ///   TRUE if memory advise not implemented such as on Windows system.
  858.     ///   - FALSE, if memory advise operation not successful.
  859.     /// @sa
  860.     ///   EMemMapAdvise, MemMapAdvise
  861.     static bool MemMapAdviseAddr(void* addr, size_t len, EMemMapAdvise advise);
  862. private:
  863.     /// Helper method to map file to memory.
  864.     ///
  865.     /// @param filename
  866.     ///   Name of file to map to memory.
  867.     /// @param protect_attr
  868.     ///   Specify operations permitted on memory mapped file.
  869.     /// @param share_attr
  870.     ///   Specify if change to memory mapped file can be shared or not.
  871.     /// @sa
  872.     ///   EMemMapProtect, EMemMapShare
  873.     void x_Map(const string&  file_name,
  874.                EMemMapProtect protect_attr,
  875.                EMemMapShare   share_attr);
  876. private:
  877.     SMemoryFileHandle*  m_Handle;   ///< Memory file handle
  878.     Int8                m_Size;     ///< Size (in bytes) of the mapped area
  879.     void*               m_DataPtr;  ///< Pointer to the begining of mapped
  880.                                     ///< data
  881. };
  882. /* @} */
  883. //////////////////////////////////////////////////////////////////////////////
  884. //
  885. // Inline
  886. //
  887. // CDirEntry
  888. #ifndef NCBI_OS_MAC
  889. inline
  890. void CDirEntry::Reset(const string& path)
  891. {
  892.     m_Path = DeleteTrailingPathSeparator(path);
  893. }
  894. inline
  895. string CDirEntry::GetPath(void) const
  896. {
  897.     return m_Path;
  898. }
  899. #endif
  900. inline
  901. string CDirEntry::GetDir(void) const
  902. {
  903.     string dir;
  904.     SplitPath(GetPath(), &dir);
  905.     return dir;
  906. }
  907. inline
  908. string CDirEntry::GetName(void) const
  909. {
  910.     string title, ext;
  911.     SplitPath(GetPath(), 0, &title, &ext);
  912.     return title + ext;
  913. }
  914. inline
  915. string CDirEntry::GetBase(void) const
  916. {
  917.     string base;
  918.     SplitPath(GetPath(), 0, &base);
  919.     return base;
  920. }
  921. inline
  922. string CDirEntry::GetExt(void) const
  923. {
  924.     string ext;
  925.     SplitPath(GetPath(), 0, 0, &ext);
  926.     return ext;
  927. }
  928. inline
  929. bool CDirEntry::IsFile(EFollowLinks follow) const
  930. {
  931.     return GetType(follow) == eFile;
  932. }
  933. inline
  934. bool CDirEntry::IsDir(EFollowLinks follow) const
  935. {
  936.     return GetType(follow) == eDir;
  937. }
  938. inline
  939. bool CDirEntry::Exists(void) const
  940. {
  941.     return GetType() != eUnknown;
  942. }
  943. // CFile
  944. inline
  945. bool CFile::Exists(void) const
  946. {
  947.     return IsFile();
  948. }
  949. // CDir
  950. inline
  951. bool CDir::Exists(void) const
  952. {
  953.     return IsDir();
  954. }
  955. // CMemoryFile
  956. inline
  957. void* CMemoryFile::GetPtr(void) const
  958. {
  959.     return m_DataPtr;
  960. }
  961. inline
  962. Int8 CMemoryFile::GetSize(void) const
  963. {
  964.     return m_Size;
  965. }
  966. END_NCBI_SCOPE
  967. /*
  968.  * ===========================================================================
  969.  * $Log: ncbifile.hpp,v $
  970.  * Revision 1000.5  2004/06/01 19:08:05  gouriano
  971.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.42
  972.  *
  973.  * Revision 1.42  2004/05/18 16:51:25  ivanov
  974.  * Added CDir::GetTmpDir()
  975.  *
  976.  * Revision 1.41  2004/04/29 16:18:58  ivanov
  977.  * operator== defined only for MAC OS
  978.  *
  979.  * Revision 1.40  2004/04/29 16:14:03  kuznets
  980.  * Removed unnecessary typename
  981.  *
  982.  * Revision 1.39  2004/04/29 15:14:17  kuznets
  983.  * + Generic FindFile algorithm capable of recursive searches
  984.  * CDir::GetEntries received additional parameter to ignore self
  985.  * recursive directory entries (".", "..")
  986.  *
  987.  * Revision 1.38  2004/04/28 19:04:16  ucko
  988.  * Give GetType(), IsFile(), and IsDir() an optional EFollowLinks
  989.  * parameter (currently only honored on Unix).
  990.  *
  991.  * Revision 1.37  2004/03/17 15:39:37  ivanov
  992.  * CFile:: Fixed possible race condition concerned with temporary file name
  993.  * generation. Added ETmpFileCreationMode enum. Fixed GetTmpName[Ex] and
  994.  * CreateTmpFile[Ex] class methods.
  995.  *
  996.  * Revision 1.36  2004/03/11 22:16:52  vakatov
  997.  * Cosmetics
  998.  *
  999.  * Revision 1.35  2004/01/05 21:41:55  gorelenk
  1000.  * += Exception throwing in CDirEntry::CreateRelativePath()
  1001.  *
  1002.  * Revision 1.34  2004/01/05 20:06:44  gorelenk
  1003.  * + CDirEntry::CreateRelativePath()
  1004.  *
  1005.  * Revision 1.33  2003/11/28 16:23:03  ivanov
  1006.  * + CDirEntry::SetTime()
  1007.  *
  1008.  * Revision 1.32  2003/11/05 16:27:18  kuznets
  1009.  * +FindFile template algorithm
  1010.  *
  1011.  * Revision 1.31  2003/11/05 15:35:44  kuznets
  1012.  * Added CDir::GetEntries() based on set of masks
  1013.  *
  1014.  * Revision 1.30  2003/10/23 12:11:37  ucko
  1015.  * Drop <memory> (now unneeded, and should have gone to ncbifile.cpp anyway)
  1016.  *
  1017.  * Revision 1.29  2003/10/23 03:18:53  ucko
  1018.  * +<memory> for auto_ptr
  1019.  *
  1020.  * Revision 1.28  2003/10/08 15:44:53  ivanov
  1021.  * Added CDirEntry::DeleteTrailingPathSeparator()
  1022.  *
  1023.  * Revision 1.27  2003/10/01 14:32:09  ucko
  1024.  * +EFollowLinks
  1025.  *
  1026.  * Revision 1.26  2003/09/30 15:08:28  ucko
  1027.  * Reworked CDirEntry::NormalizePath, which now handles .. correctly in
  1028.  * all cases and optionally resolves symlinks (on Unix).
  1029.  *
  1030.  * Revision 1.25  2003/09/16 15:18:13  ivanov
  1031.  * + CDirEntry::NormalizePath()
  1032.  *
  1033.  * Revision 1.24  2003/08/29 16:56:27  ivanov
  1034.  * Removed commit about unsafe GetTmpName() and CreateTmpFile() functions in the MT env
  1035.  *
  1036.  * Revision 1.23  2003/08/08 13:35:29  siyan
  1037.  * Changed GetTmpNameExt to GetTmpNameEx, as this is the more appropriate name.
  1038.  *
  1039.  * Revision 1.22  2003/08/06 13:45:35  siyan
  1040.  * Document changes.
  1041.  *
  1042.  * Revision 1.21  2003/05/29 17:21:31  gouriano
  1043.  * added CreatePath() which creates directories recursively
  1044.  *
  1045.  * Revision 1.20  2003/03/31 16:54:25  siyan
  1046.  * Added doxygen support
  1047.  *
  1048.  * Revision 1.19  2003/02/05 22:07:32  ivanov
  1049.  * Added protect and sharing parameters to the CMemoryFile constructor.
  1050.  * Added CMemoryFile::Flush() method.
  1051.  *
  1052.  * Revision 1.18  2003/01/16 13:03:47  dicuccio
  1053.  * Added CDir::GetCwd()
  1054.  *
  1055.  * Revision 1.17  2002/12/18 22:53:21  dicuccio
  1056.  * Added export specifier for building DLLs in windows.  Added global list of
  1057.  * all such specifiers in mswin_exports.hpp, included through ncbistl.hpp
  1058.  *
  1059.  * Revision 1.16  2002/07/15 18:17:51  gouriano
  1060.  * renamed CNcbiException and its descendents
  1061.  *
  1062.  * Revision 1.15  2002/07/11 19:21:58  ivanov
  1063.  * Added CMemoryFile::MemMapAdvise[Addr]()
  1064.  *
  1065.  * Revision 1.14  2002/07/11 14:17:54  gouriano
  1066.  * exceptions replaced by CNcbiException-type ones
  1067.  *
  1068.  * Revision 1.13  2002/06/07 16:11:09  ivanov
  1069.  * Chenget GetTime() -- using CTime instead time_t, modification time by default
  1070.  *
  1071.  * Revision 1.12  2002/06/07 15:20:41  ivanov
  1072.  * Added CDirEntry::GetTime()
  1073.  *
  1074.  * Revision 1.11  2002/04/11 20:39:18  ivanov
  1075.  * CVS log moved to end of the file
  1076.  *
  1077.  * Revision 1.10  2002/04/01 18:49:07  ivanov
  1078.  * Added class CMemoryFile
  1079.  *
  1080.  * Revision 1.9  2002/01/24 22:17:40  ivanov
  1081.  * Changed CDirEntry::Remove() and CDir::Remove()
  1082.  *
  1083.  * Revision 1.8  2002/01/10 16:46:09  ivanov
  1084.  * Added CDir::GetHome() and some CDirEntry:: path processing functions
  1085.  *
  1086.  * Revision 1.7  2001/12/26 20:58:23  juran
  1087.  * Use an FSSpec* member instead of an FSSpec, so a forward declaration can 
  1088.  * be used.
  1089.  * Add copy constructor and assignment operator for CDirEntry on Mac OS,
  1090.  * thus avoiding memberwise copy which would blow up upon deleting the 
  1091.  * pointer twice.
  1092.  *
  1093.  * Revision 1.6  2001/12/13 20:14:34  juran
  1094.  * Add forward declaration of struct FSSpec for Mac OS.
  1095.  *
  1096.  * Revision 1.5  2001/11/19 18:07:38  juran
  1097.  * Change Contents() to GetEntries().
  1098.  * Implement MatchesMask().
  1099.  *
  1100.  * Revision 1.4  2001/11/15 16:30:46  ivanov
  1101.  * Moved from util to corelib
  1102.  *
  1103.  * Revision 1.3  2001/11/01 21:02:18  ucko
  1104.  * Fix to work on non-MacOS platforms again.
  1105.  *
  1106.  * Revision 1.2  2001/11/01 20:06:49  juran
  1107.  * Replace directory streams with Contents() method.
  1108.  * Implement and test Mac OS platform.
  1109.  *
  1110.  * Revision 1.1  2001/09/19 13:04:18  ivanov
  1111.  * Initial revision
  1112.  * ===========================================================================
  1113.  */
  1114. #endif  /* CORELIB__NCBIFILE__HPP */