directory_lister.h revision 72a454cd3513ac24fbdd0e0cb9ad70b86a99b801
1// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef NET_BASE_DIRECTORY_LISTER_H_
6#define NET_BASE_DIRECTORY_LISTER_H_
7#pragma once
8
9#include <vector>
10
11#include "base/file_path.h"
12#include "base/file_util.h"
13#include "base/ref_counted.h"
14#include "base/synchronization/cancellation_flag.h"
15#include "base/task.h"
16#include "base/threading/platform_thread.h"
17
18class MessageLoop;
19
20namespace net {
21
22//
23// This class provides an API for listing the contents of a directory on the
24// filesystem asynchronously.  It spawns a background thread, and enumerates
25// the specified directory on that thread.  It marshalls WIN32_FIND_DATA
26// structs over to the main application thread.  The consumer of this class
27// is insulated from any of the multi-threading details.
28//
29class DirectoryLister : public base::RefCountedThreadSafe<DirectoryLister>,
30                        public base::PlatformThread::Delegate {
31 public:
32  // Represents one file found.
33  struct DirectoryListerData {
34    file_util::FileEnumerator::FindInfo info;
35    FilePath path;
36  };
37
38  // Implement this class to receive directory entries.
39  class DirectoryListerDelegate {
40   public:
41    // Called for each file found by the lister.
42    virtual void OnListFile(const DirectoryListerData& data) = 0;
43
44    // Called when the listing is complete.
45    virtual void OnListDone(int error) = 0;
46
47   protected:
48    virtual ~DirectoryListerDelegate() {}
49  };
50
51  // Sort options
52  // ALPHA_DIRS_FIRST is the default sort :
53  //   directories first in name order, then files by name order
54  // FULL_PATH sorts by paths as strings, ignoring files v. directories
55  // DATE sorts by last modified date
56  enum SORT_TYPE {
57    NO_SORT,
58    DATE,
59    ALPHA_DIRS_FIRST,
60    FULL_PATH
61  };
62
63  DirectoryLister(const FilePath& dir,
64                  DirectoryListerDelegate* delegate);
65
66  DirectoryLister(const FilePath& dir,
67                  bool recursive,
68                  SORT_TYPE sort,
69                  DirectoryListerDelegate* delegate);
70
71
72  // Call this method to start the directory enumeration thread.
73  bool Start();
74
75  // Call this method to asynchronously stop directory enumeration.  The
76  // delegate will receive the OnListDone notification with an error code of
77  // net::ERR_ABORTED.
78  void Cancel();
79
80  // The delegate pointer may be modified at any time.
81  DirectoryListerDelegate* delegate() const { return delegate_; }
82  void set_delegate(DirectoryListerDelegate* d) { delegate_ = d; }
83
84  // PlatformThread::Delegate implementation
85  virtual void ThreadMain();
86
87 private:
88  friend class base::RefCountedThreadSafe<DirectoryLister>;
89  friend class DirectoryDataEvent;
90
91  ~DirectoryLister();
92
93  // Comparison methods for sorting, chosen based on |sort_|.
94  static bool CompareAlphaDirsFirst(const DirectoryListerData& a,
95                                    const DirectoryListerData& b);
96  static bool CompareDate(const DirectoryListerData& a,
97                          const DirectoryListerData& b);
98  static bool CompareFullPath(const DirectoryListerData& a,
99                              const DirectoryListerData& b);
100
101  void OnReceivedData(const DirectoryListerData* data, int count);
102  void OnDone(int error);
103
104  FilePath dir_;
105  bool recursive_;
106  DirectoryListerDelegate* delegate_;
107  SORT_TYPE sort_;
108  MessageLoop* message_loop_;
109  base::PlatformThreadHandle thread_;
110  base::CancellationFlag canceled_;
111};
112
113}  // namespace net
114
115#endif  // NET_BASE_DIRECTORY_LISTER_H_
116