1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#ifndef ANDROID_DVR_PERFORMANCED_DIRECTORY_READER_H_
2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define ANDROID_DVR_PERFORMANCED_DIRECTORY_READER_H_
3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <dirent.h>
5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <errno.h>
6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <fcntl.h>
7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <sys/stat.h>
8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <sys/types.h>
9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <android-base/unique_fd.h>
11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android {
13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace dvr {
14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Utility class around readdir() that handles automatic cleanup.
16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass DirectoryReader {
17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public:
18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  explicit DirectoryReader(base::unique_fd directory_fd) {
19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    directory_ = fdopendir(directory_fd.get());
20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    error_ = errno;
21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (directory_ != nullptr)
22e27d5eb7339ac12222e60002ca2697d95b23f1c2Chih-Hung Hsieh      (void) directory_fd.release(); // ignore return result?
23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ~DirectoryReader() {
26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (directory_)
27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      closedir(directory_);
28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  bool IsValid() const { return directory_ != nullptr; }
31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  explicit operator bool() const { return IsValid(); }
32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int GetError() const { return error_; }
33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Returns a pointer to a dirent describing the next directory entry. The
35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // pointer is only valid unitl the next call to Next() or the DirectoryReader
36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // is destroyed. Returns nullptr when the end of the directory is reached.
37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  dirent* Next() {
38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (directory_)
39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return readdir(directory_);
40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    else
41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return nullptr;
42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private:
45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  DIR* directory_;
46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int error_;
47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  DirectoryReader(const DirectoryReader&) = delete;
49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  void operator=(const DirectoryReader&) = delete;
50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko};
51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // namespace dvr
53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // namespace android
54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#endif  // ANDROID_DVR_PERFORMANCED_DIRECTORY_READER_H_
56