1ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman// Use of this source code is governed by a BSD-style license that can be
3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// found in the LICENSE file.
4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner#ifndef NET_BASE_DIRECTORY_LISTER_H_
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner#define NET_BASE_DIRECTORY_LISTER_H_
7fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman
8b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell#include <vector>
9ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner
10ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner#include "base/files/file_enumerator.h"
11ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner#include "base/files/file_path.h"
12ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner#include "base/memory/ref_counted.h"
13ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner#include "base/message_loop/message_loop_proxy.h"
14ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner#include "net/base/net_export.h"
15ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner
163787e765facfad5ea62753922d940bcdd52afd57Chris Lattnernamespace net {
177152c237b46a920b29d5605af934766b8f9a07a1Chris Lattner
180a205a459884ec745df1c529396dd921f029dafdOwen Anderson//
19ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner// This class provides an API for listing the contents of a directory on the
2080a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner// filesystem asynchronously.  It spawns a background thread, and enumerates
21517576d6f96a0acde9bab79553d89f4ceba20cf6Devang Patel// the specified directory on that thread.  It marshalls WIN32_FIND_DATA
2280a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner// structs over to the main application thread.  The consumer of this class
23eaf42abab6d465c38891345d999255871cf03943Devang Patel// is insulated from any of the multi-threading details.
24468fb1df7db466e5682ee44341c3990b599e8d6aChris Lattner//
25517576d6f96a0acde9bab79553d89f4ceba20cf6Devang Patelclass NET_EXPORT DirectoryLister  {
26c93adca35856d0eaae088e52ba30cfefbd7ad910Chris Lattner public:
2793e985f1b17aef62d58e3198a4604f9f6cfe8d19Chris Lattner  // Represents one file found.
28641ca93cff0f957fc5fb9dfb05d2a4a340aa8af7Devang Patel  struct DirectoryListerData {
2980a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner    base::FileEnumerator::FileInfo info;
30f7703df4968084c18c248c1feea9961c19a32e6aChris Lattner    base::FilePath path;
31ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner  };
328f2718fbef6177966ff807af0732eb2431bd9a5fChris Lattner
338f2718fbef6177966ff807af0732eb2431bd9a5fChris Lattner  // Implement this class to receive directory entries.
348f2718fbef6177966ff807af0732eb2431bd9a5fChris Lattner  class DirectoryListerDelegate {
35468fb1df7db466e5682ee44341c3990b599e8d6aChris Lattner   public:
368f2718fbef6177966ff807af0732eb2431bd9a5fChris Lattner    // Called for each file found by the lister.
378f2718fbef6177966ff807af0732eb2431bd9a5fChris Lattner    virtual void OnListFile(const DirectoryListerData& data) = 0;
388f2718fbef6177966ff807af0732eb2431bd9a5fChris Lattner
39468fb1df7db466e5682ee44341c3990b599e8d6aChris Lattner    // Called when the listing is complete.
4080a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner    virtual void OnListDone(int error) = 0;
41135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner
42135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner   protected:
43135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner    virtual ~DirectoryListerDelegate() {}
44135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner  };
45135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner
4681dfb3885252fbf621b080827a080099864415f8Chris Lattner  // Sort options
47135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner  // ALPHA_DIRS_FIRST is the default sort :
48135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner  //   directories first in name order, then files by name order
49135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner  // FULL_PATH sorts by paths as strings, ignoring files v. directories
5081dfb3885252fbf621b080827a080099864415f8Chris Lattner  // DATE sorts by last modified date
51135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner  enum SortType {
52135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner    NO_SORT,
53135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner    DATE,
54135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner    ALPHA_DIRS_FIRST,
55135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner    FULL_PATH
56135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner  };
57135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner
58135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner  DirectoryLister(const base::FilePath& dir,
59135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner                  DirectoryListerDelegate* delegate);
60135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner
61135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner  DirectoryLister(const base::FilePath& dir,
62135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner                  bool recursive,
63135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner                  SortType sort,
64135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner                  DirectoryListerDelegate* delegate);
65135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner
66135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner  // Will invoke Cancel().
67135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner  ~DirectoryLister();
68135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner
69135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner  // Call this method to start the directory enumeration thread.
70135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner  bool Start();
71135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner
72135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner  // Call this method to asynchronously stop directory enumeration.  The
73135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner  // delegate will not be called back.
74135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner  void Cancel();
75135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner
76135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner private:
7781dfb3885252fbf621b080827a080099864415f8Chris Lattner  class Core : public base::RefCountedThreadSafe<Core> {
7881dfb3885252fbf621b080827a080099864415f8Chris Lattner   public:
79135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner    Core(const base::FilePath& dir,
80135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner         bool recursive,
81135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner         SortType sort,
82135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner         DirectoryLister* lister);
83135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner
84135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner    bool Start();
85135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner
86135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner    void Cancel();
87135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner
88135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner   private:
89135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner    friend class base::RefCountedThreadSafe<Core>;
90135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner    class DataEvent;
91135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner
92135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner    ~Core();
93135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner
94135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner    // This method runs on a WorkerPool thread.
95135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner    void StartInternal();
96135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner
97135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner    void SendData(const std::vector<DirectoryListerData>& data);
98135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner
99cd4d339ec187182c9abc22b80560349f8ba5010fChris Lattner    void OnDone(int error);
100cd4d339ec187182c9abc22b80560349f8ba5010fChris Lattner
101cd4d339ec187182c9abc22b80560349f8ba5010fChris Lattner    base::FilePath dir_;
102cd4d339ec187182c9abc22b80560349f8ba5010fChris Lattner    bool recursive_;
103dac5c4b10b387b55c2394cd98a64f3f1394df2e8Nick Lewycky    SortType sort_;
104cd4d339ec187182c9abc22b80560349f8ba5010fChris Lattner    scoped_refptr<base::MessageLoopProxy> origin_loop_;
105cd4d339ec187182c9abc22b80560349f8ba5010fChris Lattner
106cd4d339ec187182c9abc22b80560349f8ba5010fChris Lattner    // |lister_| gets set to NULL when canceled.
10781dfb3885252fbf621b080827a080099864415f8Chris Lattner    DirectoryLister* lister_;
108cd4d339ec187182c9abc22b80560349f8ba5010fChris Lattner
109135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner    DISALLOW_COPY_AND_ASSIGN(Core);
110cd4d339ec187182c9abc22b80560349f8ba5010fChris Lattner  };
111cd4d339ec187182c9abc22b80560349f8ba5010fChris Lattner
112cd4d339ec187182c9abc22b80560349f8ba5010fChris Lattner  void OnReceivedData(const DirectoryListerData& data);
113cd4d339ec187182c9abc22b80560349f8ba5010fChris Lattner  void OnDone(int error);
114cd4d339ec187182c9abc22b80560349f8ba5010fChris Lattner
115cd4d339ec187182c9abc22b80560349f8ba5010fChris Lattner  const scoped_refptr<Core> core_;
116cd4d339ec187182c9abc22b80560349f8ba5010fChris Lattner  DirectoryListerDelegate* const delegate_;
117cd4d339ec187182c9abc22b80560349f8ba5010fChris Lattner
118cd4d339ec187182c9abc22b80560349f8ba5010fChris Lattner  DISALLOW_COPY_AND_ASSIGN(DirectoryLister);
119cd4d339ec187182c9abc22b80560349f8ba5010fChris Lattner};
120cd4d339ec187182c9abc22b80560349f8ba5010fChris Lattner
121cd4d339ec187182c9abc22b80560349f8ba5010fChris Lattner}  // namespace net
122a7212e58260f6d1ead0c4eec7af400cf6c0d289eDuncan Sands
123cd4d339ec187182c9abc22b80560349f8ba5010fChris Lattner#endif  // NET_BASE_DIRECTORY_LISTER_H_
124cd4d339ec187182c9abc22b80560349f8ba5010fChris Lattner