/** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ #pragma once #include #include #include #include #include namespace Aws { namespace FileSystem { struct DirectoryEntry; class Directory; #ifdef _WIN32 static const char PATH_DELIM = '\\'; #else static const char PATH_DELIM = '/'; #endif /** * Returns the directory path for the home dir env variable */ AWS_CORE_API Aws::String GetHomeDirectory(); /** * Returns the directory path for the directory containing the currently running executable */ AWS_CORE_API Aws::String GetExecutableDirectory(); /** * @brief Creates directory if it doesn't exist. Returns true if the directory was created or already exists. False for failure. * @param path, the absolute path of the directory. * @param createParentDirs, if true, then this function will create missing directories on the path like linux command: mkdir -p */ AWS_CORE_API bool CreateDirectoryIfNotExists(const char* path, bool createParentDirs = false); /** * Creates directory if it doesn't exist. Returns true if the directory was created * or already exists. False for failure. */ AWS_CORE_API bool RemoveDirectoryIfExists(const char* path); /** * Deletes file if it exists. Returns true if file doesn't exist or on success. */ AWS_CORE_API bool RemoveFileIfExists(const char* fileName); /** * Moves the file. Returns true on success */ AWS_CORE_API bool RelocateFileOrDirectory(const char* from, const char* to); /** * Copies a directory and all of its contents. */ AWS_CORE_API bool DeepCopyDirectory(const char* from, const char* to); /** * Deletes a directory and all of its contents. */ AWS_CORE_API bool DeepDeleteDirectory(const char* toDelete); /** * Computes a unique tmp file path */ AWS_CORE_API Aws::String CreateTempFilePath(); /** * Opens a directory for traversal. */ AWS_CORE_API Aws::UniquePtr OpenDirectory(const Aws::String& path, const Aws::String& relativePath = ""); /** * Joins the leftSegment and rightSegment of a path together using platform specific delimiter. * e.g. C:\users\name\ and .aws becomes C:\users\name\.aws */ AWS_CORE_API Aws::String Join(const Aws::String& leftSegment, const Aws::String& rightSegment); /** * Joins the leftSegment and rightSegment of a path together using the specified delimiter. * e.g. with delimiter & C:\users\name\ and .aws becomes C:\users\name&.aws */ AWS_CORE_API Aws::String Join(char delimiter, const Aws::String& leftSegment, const Aws::String& rightSegment); /** * Type of directory entry encountered. */ enum class FileType { None, File, Symlink, Directory }; struct DirectoryEntry { DirectoryEntry() : fileType(FileType::None), fileSize(0) {} operator bool() const { return !path.empty() && fileType != FileType::None; } Aws::String path; Aws::String relativePath; FileType fileType = FileType::None; int64_t fileSize = 0; }; /** * Base level representation of a directory. Provides the ability to iterate all entries in a directory and to descend into directories. * We don't recommend you use this class directly. Instead see DirectoryTree. */ class AWS_CORE_API Directory { public: virtual ~Directory() = default; /** * Initialize a directory with it's absolute path. If the path is invalid, the bool operator will return false. */ Directory(const Aws::String& path, const Aws::String& relativePath); /** * If this directory is valid for use. */ virtual operator bool() const { return m_directoryEntry.operator bool(); } /** * Get the entry representing this current directory object. */ const DirectoryEntry& GetDirectoryEntry() const { return m_directoryEntry; } /** * Get the current path of this directory object. */ const Aws::String& GetPath() const { return m_directoryEntry.path; } /** * Get the next entry inside this directory. */ virtual DirectoryEntry Next() = 0; /** * Descend into a directory if it is a directory. Returns a shared pointer to a Directory object which you can then call Next() and Descend on. * The original Directory object you use is responsible for the memory this method allocates, so do not attempt to delete the return value. */ Aws::UniquePtr Descend(const DirectoryEntry& directoryEntry); /** * Recursively search directories with path as root directory, return all normal(non directory and non symlink) files' paths. */ static Aws::Vector GetAllFilePathsInDirectory(const Aws::String& path); protected: DirectoryEntry m_directoryEntry; }; class DirectoryTree; /** * Visitor for a Directory Tree traversal. Return true to continue the traversal, false to exit the traversal immediately. */ typedef std::function DirectoryEntryVisitor; /** * Wrapper around directory. Currently provides a Depth-first and Breadth-first traversal of the provided path. This is most likely the class you are * looking for. */ class AWS_CORE_API DirectoryTree { public: /** * Create a directory object for use with traversal using the provided path. */ DirectoryTree(const Aws::String& path); /** * Returns true if the Directory Tree structures match. Otherwise false. */ bool operator==(DirectoryTree& other); /** * Returns true if the Directory tree structure at path matches. Otherwise false. */ bool operator==(const Aws::String& path); /** * Computes the difference between two directory trees based on their relative paths. * File contents are not taken into account, only the tree structure. * * Returns the diff between the two trees where the key is the relative path. The Directory entry will * contain the absolute path and file size. */ Aws::Map Diff(DirectoryTree& other); /** * If the object is valid for use: true. Otherwise: false. */ operator bool() const; /** * Performs a depth-first traversal of the directory tree. Upon encountering an entry, visitor will be invoked. * If postOrder is true, a pre-order traversal will be used. otherwise pre-order will be used. */ void TraverseDepthFirst(const DirectoryEntryVisitor& visitor, bool postOrderTraversal = false); /** * Performs a breadth-first traversal of the directory tree. Upon encountering an entry, visitor will be invoked. */ void TraverseBreadthFirst(const DirectoryEntryVisitor& visitor); private: bool TraverseDepthFirst(Directory& dir, const DirectoryEntryVisitor& visitor, bool postOrder = false); void TraverseBreadthFirst(Directory& dir, const DirectoryEntryVisitor& visitor); Aws::UniquePtr m_dir; }; } // namespace FileSystem } // namespace Aws