Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2011 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/memory/ref_counted.h"
     14 #include "base/synchronization/cancellation_flag.h"
     15 #include "base/task.h"
     16 #include "base/threading/platform_thread.h"
     17 
     18 class MessageLoop;
     19 
     20 namespace 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 //
     29 class 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   // 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