Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(742)

Unified Diff: runtime/bin/directory.h

Issue 16813006: Make Directory.list pull-based, making it possible to pause, resume and cancel directory listing. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Review update. Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | runtime/bin/directory.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/bin/directory.h
diff --git a/runtime/bin/directory.h b/runtime/bin/directory.h
index a19d27468628ec6da24b1823fffbdfbac805f919..5339d2ff24e7a49b82a93db48bdea7ee5ac318a7 100644
--- a/runtime/bin/directory.h
+++ b/runtime/bin/directory.h
@@ -15,13 +15,165 @@
namespace dart {
namespace bin {
+enum ListType {
+ kListFile = 0,
+ kListDirectory = 1,
+ kListLink = 2,
+ kListError = 3,
+ kListDone = 4
+};
+
+class PathBuffer {
+ public:
+ PathBuffer();
+ ~PathBuffer() {
+ free(data_);
+ }
+
+ bool Add(const char* name);
+ bool AddW(const wchar_t* name);
+
+ char* AsString() const;
+ wchar_t* AsStringW() const;
+
+ void Reset(int new_length);
+
+ int length() const {
+ return length_;
+ }
+
+ private:
+ void* data_;
+ int length_;
+
+ DISALLOW_COPY_AND_ASSIGN(PathBuffer);
+};
+
+class DirectoryListing;
+
+class LinkList;
+
+// DirectoryListingEntry is used as a stack item, when performing recursive
+// directory listing. By using DirectoryListingEntry as stack elements, a
+// directory listing can be paused e.g. when a buffer is full, and resumed
+// later on.
+//
+// The stack is managed by the DirectoryListing's PathBuffer. Each
+// DirectoryListingEntry stored a entry-length, that it'll reset the PathBuffer
+// to on each call to Next.
+class DirectoryListingEntry {
+ public:
+ explicit DirectoryListingEntry(DirectoryListingEntry* parent)
+ : parent_(parent), lister_(0), done_(false), link_(NULL) {}
+
+ ~DirectoryListingEntry() {
+ ResetLink();
+ }
+
+ ListType Next(DirectoryListing* listing);
+
+ DirectoryListingEntry* parent() const {
+ return parent_;
+ }
+
+ LinkList* link() {
+ return link_;
+ }
+
+ void set_link(LinkList* link) {
+ link_ = link;
+ }
+
+ void ResetLink() {
+ if (link_ != NULL && (parent_ == NULL || parent_->link_ != link_)) {
+ free(link_);
+ link_ = NULL;
+ }
+ if (parent_ != NULL) {
+ link_ = parent_->link_;
+ }
+ }
+
+ private:
+ DirectoryListingEntry* parent_;
+ intptr_t lister_;
+ bool done_;
+ int path_length_;
+ LinkList* link_;
+
+ DISALLOW_COPY_AND_ASSIGN(DirectoryListingEntry);
+};
+
class DirectoryListing {
public:
- virtual ~DirectoryListing() {}
+ DirectoryListing(const char* dir_name, bool recursive, bool follow_links)
+ : top_(NULL),
+ error_(false),
+ recursive_(recursive),
+ follow_links_(follow_links) {
+ if (!path_buffer_.Add(dir_name)) {
+ error_ = true;
+ }
+ Push(new DirectoryListingEntry(NULL));
+ }
+
+ virtual ~DirectoryListing() {
+ while (!IsEmpty()) {
+ Pop();
+ }
+ }
+
virtual bool HandleDirectory(char* dir_name) = 0;
virtual bool HandleFile(char* file_name) = 0;
- virtual bool HandleLink(char* file_name) = 0;
+ virtual bool HandleLink(char* link_name) = 0;
virtual bool HandleError(const char* dir_name) = 0;
+ virtual void HandleDone() {}
+
+ void Push(DirectoryListingEntry* directory) {
+ top_ = directory;
+ }
+
+ void Pop() {
+ ASSERT(!IsEmpty());
+ DirectoryListingEntry* current = top_;
+ top_ = top_->parent();
+ delete current;
+ }
+
+ bool IsEmpty() const {
+ return top_ == NULL;
+ }
+
+ DirectoryListingEntry* top() const {
+ return top_;
+ }
+
+ bool recursive() const {
+ return recursive_;
+ }
+
+ bool follow_links() const {
+ return follow_links_;
+ }
+
+ char* CurrentPath() {
+ return path_buffer_.AsString();
+ }
+
+ PathBuffer& path_buffer() {
+ return path_buffer_;
+ }
+
+ bool error() const {
+ return error_;
+ }
+
+ private:
+ PathBuffer path_buffer_;
+ DirectoryListingEntry* top_;
+ bool error_;
+ bool recursive_;
+ bool follow_links_;
};
@@ -35,17 +187,34 @@ class AsyncDirectoryListing : public DirectoryListing {
kListDone = 4
};
- explicit AsyncDirectoryListing(Dart_Port response_port)
- : response_port_(response_port) {}
+ AsyncDirectoryListing(const char* dir_name,
+ bool recursive,
+ bool follow_links)
+ : DirectoryListing(dir_name, recursive, follow_links) {}
+
virtual ~AsyncDirectoryListing() {}
virtual bool HandleDirectory(char* dir_name);
virtual bool HandleFile(char* file_name);
virtual bool HandleLink(char* file_name);
virtual bool HandleError(const char* dir_name);
+ virtual void HandleDone();
+
+ void SetArray(CObjectArray* array, intptr_t length) {
+ ASSERT(length % 2 == 0);
+ array_ = array;
+ index_ = 0;
+ length_ = length;
+ }
+
+ intptr_t index() const {
+ return index_;
+ }
private:
- CObjectArray* NewResponse(Response response, char* arg);
- Dart_Port response_port_;
+ bool AddFileSystemEntityToResponse(Response response, char* arg);
+ CObjectArray* array_;
+ intptr_t index_;
+ intptr_t length_;
DISALLOW_IMPLICIT_CONSTRUCTORS(AsyncDirectoryListing);
};
@@ -53,8 +222,12 @@ class AsyncDirectoryListing : public DirectoryListing {
class SyncDirectoryListing: public DirectoryListing {
public:
- explicit SyncDirectoryListing(Dart_Handle results)
- : results_(results) {
+ SyncDirectoryListing(Dart_Handle results,
+ const char* dir_name,
+ bool recursive,
+ bool follow_links)
+ : DirectoryListing(dir_name, recursive, follow_links),
+ results_(results) {
add_string_ = DartUtils::NewString("add");
directory_class_ =
DartUtils::GetDartClass(DartUtils::kIOLibURL, "Directory");
@@ -95,14 +268,13 @@ class Directory {
kDeleteRequest = 1,
kExistsRequest = 2,
kCreateTempRequest = 3,
- kListRequest = 4,
- kRenameRequest = 5
+ kListStartRequest = 4,
+ kListNextRequest = 5,
+ kListStopRequest = 6,
+ kRenameRequest = 7
};
- static bool List(const char* path,
- bool recursive,
- bool follow_links,
- DirectoryListing* listing);
+ static void List(DirectoryListing* listing);
static ExistsResult Exists(const char* path);
static char* Current();
static bool SetCurrent(const char* path);
« no previous file with comments | « no previous file | runtime/bin/directory.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698