File: directory_lister.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (141 lines) | stat: -rw-r--r-- 4,373 bytes parent folder | download | duplicates (6)
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright 2012 The Chromium Authors
// 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 <memory>
#include <vector>

#include "base/atomicops.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "net/base/net_export.h"

namespace base {
class SequencedTaskRunner;
}

namespace net {

// This class provides an API for asynchronously listing the contents of a
// directory on the filesystem.  It runs a task on a background thread, and
// enumerates all files in the specified directory on that thread.  Destroying
// the lister cancels the list operation.  The DirectoryLister must only be
// used on a thread with a MessageLoop.
class NET_EXPORT DirectoryLister  {
 public:
  // Represents one file found.
  struct DirectoryListerData {
    base::FileEnumerator::FileInfo info;
    base::FilePath path;
    base::FilePath absolute_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() = default;
  };

  // Listing options
  // ALPHA_DIRS_FIRST is the default listing type:
  //   directories first in name order, then files by name order
  // Listing is recursive only if listing type is NO_SORT_RECURSIVE.
  // TODO(mmenke): Improve testing.
  enum ListingType {
    NO_SORT,
    NO_SORT_RECURSIVE,
    ALPHA_DIRS_FIRST,
  };

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

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

  DirectoryLister(const DirectoryLister&) = delete;
  DirectoryLister& operator=(const DirectoryLister&) = delete;

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

  // Call this method to start the asynchronous directory enumeration.
  void Start();

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

 private:
  typedef std::vector<DirectoryListerData> DirectoryList;

  // Class responsible for retrieving and sorting the actual directory list on
  // a worker pool thread. Created on the DirectoryLister's thread. As it's
  // refcounted, it's destroyed when the final reference is released, which may
  // happen on either thread.
  //
  // It's kept alive during the calls to Start() and DoneOnOriginSequence() by
  // the reference owned by the callback itself.
  class Core : public base::RefCountedThreadSafe<Core> {
   public:
    Core(const base::FilePath& dir, ListingType type, DirectoryLister* lister);
    Core(const Core&) = delete;
    Core& operator=(const Core&) = delete;

    // May only be called on a worker pool thread.
    void Start();

    // Must be called on the origin thread.
    void CancelOnOriginSequence();

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

    ~Core();

    // Called on both threads.
    bool IsCancelled() const;

    // Called on origin thread.
    void DoneOnOriginSequence(std::unique_ptr<DirectoryList> directory_list,
                              int error) const;

    const base::FilePath dir_;
    const ListingType type_;
    const scoped_refptr<base::SequencedTaskRunner> origin_task_runner_;

    // Only used on the origin thread.
    raw_ptr<DirectoryLister> lister_;

    // Set to true on cancellation. Used both to abort listing files early on the
    // worker pool thread for performance reasons and to ensure |lister_| isn't
    // called after cancellation on the origin thread.
    std::atomic<bool> cancelled_ = {};
  };

  // Call into the corresponding DirectoryListerDelegate. Must not be called
  // after cancellation.
  void OnListFile(const DirectoryListerData& data);
  void OnListDone(int error);

  scoped_refptr<Core> core_;
  const raw_ptr<DirectoryListerDelegate> delegate_;
};

}  // namespace net

#endif  // NET_BASE_DIRECTORY_LISTER_H_