2012-01-10 16:50:14 +00:00
|
|
|
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
2011-10-05 05:20:07 +00:00
|
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
|
2016-10-26 07:26:03 +00:00
|
|
|
#ifndef RUNTIME_BIN_DIRECTORY_H_
|
|
|
|
#define RUNTIME_BIN_DIRECTORY_H_
|
2011-10-05 05:20:07 +00:00
|
|
|
|
|
|
|
#include "bin/builtin.h"
|
2012-02-21 11:35:42 +00:00
|
|
|
#include "bin/dartutils.h"
|
2017-08-30 16:34:34 +00:00
|
|
|
#include "bin/namespace.h"
|
2016-04-21 14:57:02 +00:00
|
|
|
#include "bin/reference_counting.h"
|
2014-08-12 23:19:53 +00:00
|
|
|
#include "bin/thread.h"
|
2012-01-06 11:28:21 +00:00
|
|
|
#include "platform/globals.h"
|
2011-10-05 05:20:07 +00:00
|
|
|
|
2013-04-25 14:22:30 +00:00
|
|
|
namespace dart {
|
|
|
|
namespace bin {
|
|
|
|
|
2013-06-17 07:27:19 +00:00
|
|
|
enum ListType {
|
|
|
|
kListFile = 0,
|
|
|
|
kListDirectory = 1,
|
|
|
|
kListLink = 2,
|
|
|
|
kListError = 3,
|
|
|
|
kListDone = 4
|
|
|
|
};
|
|
|
|
|
|
|
|
class PathBuffer {
|
|
|
|
public:
|
|
|
|
PathBuffer();
|
2016-03-14 18:08:52 +00:00
|
|
|
~PathBuffer();
|
2013-06-17 07:27:19 +00:00
|
|
|
|
|
|
|
bool Add(const char* name);
|
|
|
|
bool AddW(const wchar_t* name);
|
|
|
|
|
|
|
|
char* AsString() const;
|
|
|
|
wchar_t* AsStringW() const;
|
|
|
|
|
2016-03-14 18:08:52 +00:00
|
|
|
// Makes a scope allocated copy of the string.
|
|
|
|
const char* AsScopedString() const;
|
|
|
|
|
|
|
|
void Reset(intptr_t new_length);
|
2013-06-17 07:27:19 +00:00
|
|
|
|
2016-11-04 19:30:56 +00:00
|
|
|
intptr_t length() const { return length_; }
|
2013-06-17 07:27:19 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
void* data_;
|
2016-03-14 18:08:52 +00:00
|
|
|
intptr_t length_;
|
2013-06-17 07:27:19 +00:00
|
|
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(PathBuffer);
|
|
|
|
};
|
|
|
|
|
|
|
|
class DirectoryListing;
|
|
|
|
|
2013-06-17 07:31:46 +00:00
|
|
|
struct LinkList;
|
2013-06-17 07:27:19 +00:00
|
|
|
|
|
|
|
// 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)
|
2023-04-12 01:11:05 +00:00
|
|
|
: parent_(parent), fd_(-1), lister_(0), done_(false), link_(nullptr) {}
|
2013-06-17 07:27:19 +00:00
|
|
|
|
2013-10-29 15:04:59 +00:00
|
|
|
~DirectoryListingEntry();
|
2013-06-17 07:27:19 +00:00
|
|
|
|
|
|
|
ListType Next(DirectoryListing* listing);
|
|
|
|
|
2016-11-04 19:30:56 +00:00
|
|
|
DirectoryListingEntry* parent() const { return parent_; }
|
2013-06-17 07:27:19 +00:00
|
|
|
|
2016-11-04 19:30:56 +00:00
|
|
|
LinkList* link() { return link_; }
|
2013-06-17 07:27:19 +00:00
|
|
|
|
2016-11-04 19:30:56 +00:00
|
|
|
void set_link(LinkList* link) { link_ = link; }
|
2013-06-17 07:27:19 +00:00
|
|
|
|
2013-06-18 15:44:21 +00:00
|
|
|
void ResetLink();
|
2013-06-17 07:27:19 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
DirectoryListingEntry* parent_;
|
2017-08-30 16:34:34 +00:00
|
|
|
intptr_t fd_;
|
2013-06-17 07:27:19 +00:00
|
|
|
intptr_t lister_;
|
|
|
|
bool done_;
|
|
|
|
int path_length_;
|
|
|
|
LinkList* link_;
|
|
|
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(DirectoryListingEntry);
|
|
|
|
};
|
|
|
|
|
2012-02-21 11:35:42 +00:00
|
|
|
class DirectoryListing {
|
2013-01-04 13:51:15 +00:00
|
|
|
public:
|
2017-08-30 16:34:34 +00:00
|
|
|
DirectoryListing(Namespace* namespc,
|
|
|
|
const char* dir_name,
|
|
|
|
bool recursive,
|
|
|
|
bool follow_links)
|
|
|
|
: namespc_(namespc),
|
2023-04-12 01:11:05 +00:00
|
|
|
top_(nullptr),
|
2016-11-04 19:30:56 +00:00
|
|
|
error_(false),
|
|
|
|
recursive_(recursive),
|
|
|
|
follow_links_(follow_links) {
|
2013-06-17 07:27:19 +00:00
|
|
|
if (!path_buffer_.Add(dir_name)) {
|
|
|
|
error_ = true;
|
|
|
|
}
|
2023-04-12 01:11:05 +00:00
|
|
|
Push(new DirectoryListingEntry(nullptr));
|
2013-06-17 07:27:19 +00:00
|
|
|
}
|
|
|
|
|
2016-11-04 19:30:56 +00:00
|
|
|
virtual ~DirectoryListing() { PopAll(); }
|
2013-06-17 07:27:19 +00:00
|
|
|
|
2016-03-14 18:08:52 +00:00
|
|
|
virtual bool HandleDirectory(const char* dir_name) = 0;
|
|
|
|
virtual bool HandleFile(const char* file_name) = 0;
|
|
|
|
virtual bool HandleLink(const char* link_name) = 0;
|
|
|
|
virtual bool HandleError() = 0;
|
2013-06-17 07:27:19 +00:00
|
|
|
virtual void HandleDone() {}
|
|
|
|
|
2016-11-04 19:30:56 +00:00
|
|
|
void Push(DirectoryListingEntry* directory) { top_ = directory; }
|
2013-06-17 07:27:19 +00:00
|
|
|
|
|
|
|
void Pop() {
|
|
|
|
ASSERT(!IsEmpty());
|
|
|
|
DirectoryListingEntry* current = top_;
|
|
|
|
top_ = top_->parent();
|
|
|
|
delete current;
|
|
|
|
}
|
|
|
|
|
2023-04-12 01:11:05 +00:00
|
|
|
bool IsEmpty() const { return top_ == nullptr; }
|
2013-06-17 07:27:19 +00:00
|
|
|
|
2016-04-21 14:57:02 +00:00
|
|
|
void PopAll() {
|
|
|
|
while (!IsEmpty()) {
|
|
|
|
Pop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-30 16:34:34 +00:00
|
|
|
Namespace* namespc() const { return namespc_; }
|
|
|
|
|
2016-11-04 19:30:56 +00:00
|
|
|
DirectoryListingEntry* top() const { return top_; }
|
2013-06-17 07:27:19 +00:00
|
|
|
|
2016-11-04 19:30:56 +00:00
|
|
|
bool recursive() const { return recursive_; }
|
2013-06-17 07:27:19 +00:00
|
|
|
|
2016-11-04 19:30:56 +00:00
|
|
|
bool follow_links() const { return follow_links_; }
|
2013-06-17 07:27:19 +00:00
|
|
|
|
2016-11-04 19:30:56 +00:00
|
|
|
const char* CurrentPath() { return path_buffer_.AsScopedString(); }
|
2013-06-17 07:27:19 +00:00
|
|
|
|
2016-11-04 19:30:56 +00:00
|
|
|
PathBuffer& path_buffer() { return path_buffer_; }
|
2013-06-17 07:27:19 +00:00
|
|
|
|
2016-11-04 19:30:56 +00:00
|
|
|
bool error() const { return error_; }
|
2013-06-17 07:27:19 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
PathBuffer path_buffer_;
|
2017-08-30 16:34:34 +00:00
|
|
|
Namespace* namespc_;
|
2013-06-17 07:27:19 +00:00
|
|
|
DirectoryListingEntry* top_;
|
|
|
|
bool error_;
|
|
|
|
bool recursive_;
|
|
|
|
bool follow_links_;
|
2013-01-04 13:51:15 +00:00
|
|
|
};
|
|
|
|
|
2016-04-21 14:57:02 +00:00
|
|
|
class AsyncDirectoryListing : public ReferenceCounted<AsyncDirectoryListing>,
|
|
|
|
public DirectoryListing {
|
2012-02-21 11:35:42 +00:00
|
|
|
public:
|
|
|
|
enum Response {
|
2013-02-21 11:58:11 +00:00
|
|
|
kListFile = 0,
|
|
|
|
kListDirectory = 1,
|
2013-03-22 09:56:14 +00:00
|
|
|
kListLink = 2,
|
|
|
|
kListError = 3,
|
|
|
|
kListDone = 4
|
2012-02-21 11:35:42 +00:00
|
|
|
};
|
|
|
|
|
2017-08-30 16:34:34 +00:00
|
|
|
AsyncDirectoryListing(Namespace* namespc,
|
|
|
|
const char* dir_name,
|
|
|
|
bool recursive,
|
|
|
|
bool follow_links)
|
2016-04-21 14:57:02 +00:00
|
|
|
: ReferenceCounted(),
|
2017-08-30 16:34:34 +00:00
|
|
|
DirectoryListing(namespc, dir_name, recursive, follow_links),
|
2023-04-12 01:11:05 +00:00
|
|
|
array_(nullptr),
|
2016-04-21 14:57:02 +00:00
|
|
|
index_(0),
|
|
|
|
length_(0) {}
|
2013-06-17 07:27:19 +00:00
|
|
|
|
2016-03-14 18:08:52 +00:00
|
|
|
virtual bool HandleDirectory(const char* dir_name);
|
|
|
|
virtual bool HandleFile(const char* file_name);
|
|
|
|
virtual bool HandleLink(const char* file_name);
|
|
|
|
virtual bool HandleError();
|
2013-06-17 07:27:19 +00:00
|
|
|
virtual void HandleDone();
|
|
|
|
|
|
|
|
void SetArray(CObjectArray* array, intptr_t length) {
|
|
|
|
ASSERT(length % 2 == 0);
|
|
|
|
array_ = array;
|
|
|
|
index_ = 0;
|
|
|
|
length_ = length;
|
|
|
|
}
|
|
|
|
|
2016-11-04 19:30:56 +00:00
|
|
|
intptr_t index() const { return index_; }
|
2012-02-21 11:35:42 +00:00
|
|
|
|
|
|
|
private:
|
2016-04-21 14:57:02 +00:00
|
|
|
virtual ~AsyncDirectoryListing() {}
|
2016-03-14 18:08:52 +00:00
|
|
|
bool AddFileSystemEntityToResponse(Response response, const char* arg);
|
2013-06-17 07:27:19 +00:00
|
|
|
CObjectArray* array_;
|
|
|
|
intptr_t index_;
|
|
|
|
intptr_t length_;
|
2012-02-21 11:35:42 +00:00
|
|
|
|
2016-04-21 14:57:02 +00:00
|
|
|
friend class ReferenceCounted<AsyncDirectoryListing>;
|
2013-01-04 13:51:15 +00:00
|
|
|
DISALLOW_IMPLICIT_CONSTRUCTORS(AsyncDirectoryListing);
|
|
|
|
};
|
|
|
|
|
2016-11-04 19:30:56 +00:00
|
|
|
class SyncDirectoryListing : public DirectoryListing {
|
2013-01-04 13:51:15 +00:00
|
|
|
public:
|
2013-06-17 07:27:19 +00:00
|
|
|
SyncDirectoryListing(Dart_Handle results,
|
2017-08-30 16:34:34 +00:00
|
|
|
Namespace* namespc,
|
2013-06-17 07:27:19 +00:00
|
|
|
const char* dir_name,
|
|
|
|
bool recursive,
|
|
|
|
bool follow_links)
|
2017-08-30 16:34:34 +00:00
|
|
|
: DirectoryListing(namespc, dir_name, recursive, follow_links),
|
2017-01-23 18:45:28 +00:00
|
|
|
results_(results),
|
|
|
|
dart_error_(Dart_Null()) {
|
2013-01-04 13:51:15 +00:00
|
|
|
add_string_ = DartUtils::NewString("add");
|
2018-05-23 21:01:44 +00:00
|
|
|
from_raw_path_string_ = DartUtils::NewString("fromRawPath");
|
2016-11-04 19:30:56 +00:00
|
|
|
directory_type_ = DartUtils::GetDartType(DartUtils::kIOLibURL, "Directory");
|
|
|
|
file_type_ = DartUtils::GetDartType(DartUtils::kIOLibURL, "File");
|
|
|
|
link_type_ = DartUtils::GetDartType(DartUtils::kIOLibURL, "Link");
|
2013-01-04 13:51:15 +00:00
|
|
|
}
|
|
|
|
virtual ~SyncDirectoryListing() {}
|
2016-03-14 18:08:52 +00:00
|
|
|
virtual bool HandleDirectory(const char* dir_name);
|
|
|
|
virtual bool HandleFile(const char* file_name);
|
|
|
|
virtual bool HandleLink(const char* file_name);
|
|
|
|
virtual bool HandleError();
|
2013-01-04 13:51:15 +00:00
|
|
|
|
2017-01-23 18:45:28 +00:00
|
|
|
Dart_Handle dart_error() { return dart_error_; }
|
|
|
|
|
2013-01-04 13:51:15 +00:00
|
|
|
private:
|
|
|
|
Dart_Handle results_;
|
|
|
|
Dart_Handle add_string_;
|
2018-05-23 21:01:44 +00:00
|
|
|
Dart_Handle from_raw_path_string_;
|
2013-06-20 18:11:47 +00:00
|
|
|
Dart_Handle directory_type_;
|
|
|
|
Dart_Handle file_type_;
|
|
|
|
Dart_Handle link_type_;
|
2017-01-23 18:45:28 +00:00
|
|
|
Dart_Handle dart_error_;
|
2013-01-04 13:51:15 +00:00
|
|
|
|
2016-04-21 14:57:02 +00:00
|
|
|
DISALLOW_ALLOCATION()
|
2013-01-04 13:51:15 +00:00
|
|
|
DISALLOW_IMPLICIT_CONSTRUCTORS(SyncDirectoryListing);
|
2012-02-21 11:35:42 +00:00
|
|
|
};
|
|
|
|
|
2011-10-05 05:20:07 +00:00
|
|
|
class Directory {
|
|
|
|
public:
|
2016-11-04 19:30:56 +00:00
|
|
|
enum ExistsResult { UNKNOWN, EXISTS, DOES_NOT_EXIST };
|
2011-10-14 12:42:44 +00:00
|
|
|
|
2013-06-17 07:27:19 +00:00
|
|
|
static void List(DirectoryListing* listing);
|
2017-08-30 16:34:34 +00:00
|
|
|
static ExistsResult Exists(Namespace* namespc, const char* path);
|
2016-03-14 18:08:52 +00:00
|
|
|
|
|
|
|
// Returns the current working directory. The caller must call
|
|
|
|
// free() on the result.
|
|
|
|
static char* CurrentNoScope();
|
|
|
|
|
|
|
|
// Returns the current working directory. The returned string is allocated
|
|
|
|
// with Dart_ScopeAllocate(). It lasts only as long as the current API scope.
|
2017-08-30 16:34:34 +00:00
|
|
|
static const char* Current(Namespace* namespc);
|
|
|
|
static const char* SystemTemp(Namespace* namespc);
|
|
|
|
static const char* CreateTemp(Namespace* namespc, const char* path);
|
2016-07-18 17:45:53 +00:00
|
|
|
// Set the system temporary directory.
|
|
|
|
static void SetSystemTemp(const char* path);
|
2017-08-30 16:34:34 +00:00
|
|
|
static bool SetCurrent(Namespace* namespc, const char* path);
|
|
|
|
static bool Create(Namespace* namespc, const char* path);
|
|
|
|
static bool Delete(Namespace* namespc, const char* path, bool recursive);
|
|
|
|
static bool Rename(Namespace* namespc,
|
|
|
|
const char* path,
|
|
|
|
const char* new_path);
|
2012-03-01 14:29:12 +00:00
|
|
|
|
2013-09-25 15:03:24 +00:00
|
|
|
static CObject* CreateRequest(const CObjectArray& request);
|
|
|
|
static CObject* DeleteRequest(const CObjectArray& request);
|
|
|
|
static CObject* ExistsRequest(const CObjectArray& request);
|
|
|
|
static CObject* CreateTempRequest(const CObjectArray& request);
|
2013-10-01 15:38:01 +00:00
|
|
|
static CObject* CreateSystemTempRequest(const CObjectArray& request);
|
2013-09-25 15:03:24 +00:00
|
|
|
static CObject* ListStartRequest(const CObjectArray& request);
|
|
|
|
static CObject* ListNextRequest(const CObjectArray& request);
|
|
|
|
static CObject* ListStopRequest(const CObjectArray& request);
|
|
|
|
static CObject* RenameRequest(const CObjectArray& request);
|
2012-03-01 14:29:12 +00:00
|
|
|
|
2013-09-25 15:03:24 +00:00
|
|
|
private:
|
2016-07-18 17:45:53 +00:00
|
|
|
static char* system_temp_path_override_;
|
2011-10-05 05:20:07 +00:00
|
|
|
DISALLOW_ALLOCATION();
|
|
|
|
DISALLOW_IMPLICIT_CONSTRUCTORS(Directory);
|
|
|
|
};
|
|
|
|
|
2013-04-25 14:22:30 +00:00
|
|
|
} // namespace bin
|
|
|
|
} // namespace dart
|
2012-02-21 11:35:42 +00:00
|
|
|
|
2016-10-26 07:26:03 +00:00
|
|
|
#endif // RUNTIME_BIN_DIRECTORY_H_
|