summaryrefslogtreecommitdiffstats
path: root/net/base/directory_lister.h
blob: 999b8577dba6b7bf5f33cda886871a3bccd4e385 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// Copyright (c) 2012 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 NET_BASE_DIRECTORY_LISTER_H_
#define NET_BASE_DIRECTORY_LISTER_H_

#include <vector>

#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop_proxy.h"
#include "net/base/net_export.h"

namespace net {

//
// This class provides an API for listing the contents of a directory on the
// filesystem asynchronously.  It spawns a background thread, and enumerates
// the specified directory on that thread.  It marshalls WIN32_FIND_DATA
// structs over to the main application thread.  The consumer of this class
// is insulated from any of the multi-threading details.
//
class NET_EXPORT DirectoryLister  {
 public:
  // Represents one file found.
  struct DirectoryListerData {
    file_util::FileEnumerator::FindInfo info;
    base::FilePath path;
  };

  // Implement this class to receive directory entries.
  class DirectoryListerDelegate {
   public:
    // Called for each file found by the lister.
    virtual void OnListFile(const DirectoryListerData& data) = 0;

    // Called when the listing is complete.
    virtual void OnListDone(int error) = 0;

   protected:
    virtual ~DirectoryListerDelegate() {}
  };

  // Sort options
  // ALPHA_DIRS_FIRST is the default sort :
  //   directories first in name order, then files by name order
  // FULL_PATH sorts by paths as strings, ignoring files v. directories
  // DATE sorts by last modified date
  enum SortType {
    NO_SORT,
    DATE,
    ALPHA_DIRS_FIRST,
    FULL_PATH
  };

  DirectoryLister(const base::FilePath& dir,
                  DirectoryListerDelegate* delegate);

  DirectoryLister(const base::FilePath& dir,
                  bool recursive,
                  SortType sort,
                  DirectoryListerDelegate* delegate);

  // Will invoke Cancel().
  ~DirectoryLister();

  // Call this method to start the directory enumeration thread.
  bool Start();

  // Call this method to asynchronously stop directory enumeration.  The
  // delegate will not be called back.
  void Cancel();

 private:
  class Core : public base::RefCountedThreadSafe<Core> {
   public:
    Core(const base::FilePath& dir,
         bool recursive,
         SortType sort,
         DirectoryLister* lister);

    bool Start();

    void Cancel();

   private:
    friend class base::RefCountedThreadSafe<Core>;
    class DataEvent;

    ~Core();

    // This method runs on a WorkerPool thread.
    void StartInternal();

    void SendData(const std::vector<DirectoryListerData>& data);

    void OnDone(int error);

    base::FilePath dir_;
    bool recursive_;
    SortType sort_;
    scoped_refptr<base::MessageLoopProxy> origin_loop_;

    // |lister_| gets set to NULL when canceled.
    DirectoryLister* lister_;

    DISALLOW_COPY_AND_ASSIGN(Core);
  };

  void OnReceivedData(const DirectoryListerData& data);
  void OnDone(int error);

  const scoped_refptr<Core> core_;
  DirectoryListerDelegate* const delegate_;

  DISALLOW_COPY_AND_ASSIGN(DirectoryLister);
};

}  // namespace net

#endif  // NET_BASE_DIRECTORY_LISTER_H_