diff options
author | adlr@google.com <adlr@google.com@06c00378-0e64-4dae-be16-12b19f9950a1> | 2009-12-04 20:57:17 +0000 |
---|---|---|
committer | adlr@google.com <adlr@google.com@06c00378-0e64-4dae-be16-12b19f9950a1> | 2009-12-04 20:57:17 +0000 |
commit | 3defe6acb3609e70e851a6eff062577d25a2af9d (patch) | |
tree | 341e979027fde117dd8906483db7a5c703a2e1cf /filesystem_iterator.h | |
parent | c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9 (diff) |
Missed new files in last commit
Review URL: http://codereview.chromium.org/465067
git-svn-id: svn://chrome-svn/chromeos/trunk@336 06c00378-0e64-4dae-be16-12b19f9950a1
Diffstat (limited to 'filesystem_iterator.h')
-rw-r--r-- | filesystem_iterator.h | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/filesystem_iterator.h b/filesystem_iterator.h new file mode 100644 index 00000000..a1ba8af7 --- /dev/null +++ b/filesystem_iterator.h @@ -0,0 +1,126 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_ITERATOR_H__ +#define CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_ITERATOR_H__ + +// This class is used to walk a filesystem. It will iterate over every file +// on the same device as the file passed in the ctor. Directories will be +// visited before their children. Children will be visited in no particular +// order. + +// The iterator is a forward iterator. It's not random access nor can it be +// decremented. + +// Note: If the iterator comes across a mount point where another filesystem +// is mounted, that mount point will be present, but none of its children +// will be. Technically the mount point is on the other filesystem (and +// the Stat() call will verify that), but we return it anyway since: +// 1. Such a folder must exist in the first filesystem if it got used +// as a mount point. +// 2. You probably want to copy if it you're using the iterator to do a +// filesystem copy +// 3. If you don't want that, you can just check Stat().st_dev and skip +// foreign filesystems manually. + +#include <sys/stat.h> +#include <sys/types.h> +#include <dirent.h> +#include <unistd.h> +#include <string> +#include <set> +#include <vector> + +namespace chromeos_update_engine { + +class FilesystemIterator { + public: + FilesystemIterator(const std::string& path, + const std::set<std::string>& excl_prefixes); + + ~FilesystemIterator(); + + // Returns stat struct for the current file. + struct stat GetStat() const { + return stbuf_; + } + + // Returns full path for current file. + std::string GetFullPath() const; + + // Returns the path that's part of the iterator. For example, if + // the object were constructed by passing in "/foo/bar" and Path() + // returns "/foo/bar/baz/bat.txt", IterPath would return + // "/baz/bat.txt". When this object is on root (ie, the very first + // path), IterPath will return "", otherwise the first character of + // IterPath will be "/". + std::string GetPartialPath() const; + + // Returns name for current file. + std::string GetBasename() const { + return names_.back(); + } + + // Increments to the next file. + void Increment(); + + // If we're at the end. If at the end, do not call Stat(), Path(), etc., + // since this iterator currently isn't pointing to any file at all. + bool IsEnd() const { + return is_end_; + } + + // Returns true if the iterator is in an error state. + bool IsErr() const { + return is_err_; + } + private: + // Helper for Increment. + void IncrementInternal(); + + // Returns true if path exists and it's a directory. + bool DirectoryExists(const std::string& path); + + // In general (i.e., not midway through a call to Increment()), there is a + // relationship between dirs_ and names_: dirs[i] == names_[i - 1]. + // For example, say we are asked to iterate "/usr/local" and we're currently + // at /usr/local/share/dict/words. dirs_ contains DIR* variables for the + // dirs at: {"/usr/local", ".../share", ".../dict"} and names_ contains: + // {"share", "dict", "words"}. root_path_ contains "/usr/local". + // root_dev_ would be the dev for root_path_ + // (and /usr/local/share/dict/words). stbuf_ would be the stbuf for + // /usr/local/share/dict/words. + + // All opened directories. If this is empty, we're currently on the root, + // but not descended into the root. + // This will always contain the current directory and all it's ancestors + // in root-to-leaf order. For more details, see comment above. + std::vector<DIR*> dirs_; + + // The list of all filenames for the current path that we've descended into. + std::vector<std::string> names_; + + // The device of the root path we've been asked to iterate. + dev_t root_dev_; + + // The root path we've been asked to iteratate. + std::string root_path_; + + // Exclude items w/ this prefix. + std::set<std::string> excl_prefixes_; + + // The struct stat of the current file we're at. + struct stat stbuf_; + + // Generally false; set to true when we reach the end of files to iterate + // or error occurs. + bool is_end_; + + // Generally false; set to true if an error occurrs. + bool is_err_; +}; + +} // namespace chromeos_update_engine + +#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_ITERATOR_H__ |