blob: 5fbc9dc6fa15abd3c409aa4502327663dfa57e78 [file] [log] [blame]
// 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/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/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 {
base::FileEnumerator::FileInfo 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_