summaryrefslogtreecommitdiffstats
path: root/net/base
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-19 23:04:29 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-19 23:04:29 +0000
commit721c3f17a7fb36edaa17f607a11db9c82ba720ca (patch)
treec78e993a5474acdb2751c222db8787d7aa482301 /net/base
parentf785ad125747f9125c952c7e74f2154098ee15a9 (diff)
downloadchromium_src-721c3f17a7fb36edaa17f607a11db9c82ba720ca.zip
chromium_src-721c3f17a7fb36edaa17f607a11db9c82ba720ca.tar.gz
chromium_src-721c3f17a7fb36edaa17f607a11db9c82ba720ca.tar.bz2
Port directory lister so test shell can view file directories.
Review URL: http://codereview.chromium.org/11437 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5725 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base')
-rw-r--r--net/base/directory_lister.cc112
-rw-r--r--net/base/directory_lister.h30
-rw-r--r--net/base/net_util.cc25
-rw-r--r--net/base/net_util.h11
4 files changed, 92 insertions, 86 deletions
diff --git a/net/base/directory_lister.cc b/net/base/directory_lister.cc
index 0204ce4..a04aec2 100644
--- a/net/base/directory_lister.cc
+++ b/net/base/directory_lister.cc
@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <process.h>
-
#include "net/base/directory_lister.h"
+#include "base/file_util.h"
#include "base/message_loop.h"
+#include "base/platform_thread.h"
+#include "net/base/net_errors.h"
namespace net {
@@ -27,65 +28,24 @@ class DirectoryDataEvent : public Task {
}
scoped_refptr<DirectoryLister> lister;
- WIN32_FIND_DATA data[kFilesPerEvent];
- int count;
- DWORD error;
+ file_util::FileEnumerator::FindInfo data[kFilesPerEvent];
+ int count, error;
};
-/*static*/
-unsigned __stdcall DirectoryLister::ThreadFunc(void* param) {
- DirectoryLister* self = reinterpret_cast<DirectoryLister*>(param);
-
- std::wstring pattern = self->directory();
- if (pattern[pattern.size()-1] != '\\') {
- pattern.append(L"\\*");
- } else {
- pattern.append(L"*");
- }
-
- DirectoryDataEvent* e = new DirectoryDataEvent(self);
-
- HANDLE handle = FindFirstFile(pattern.c_str(), &e->data[e->count]);
- if (handle == INVALID_HANDLE_VALUE) {
- e->error = GetLastError();
- self->message_loop_->PostTask(FROM_HERE, e);
- e = NULL;
- } else {
- do {
- if (++e->count == kFilesPerEvent) {
- self->message_loop_->PostTask(FROM_HERE, e);
- e = new DirectoryDataEvent(self);
- }
- } while (!self->was_canceled() && FindNextFile(handle, &e->data[e->count]));
-
- FindClose(handle);
-
- if (e->count > 0) {
- self->message_loop_->PostTask(FROM_HERE, e);
- e = NULL;
- }
-
- // Notify done
- e = new DirectoryDataEvent(self);
- self->message_loop_->PostTask(FROM_HERE, e);
- }
-
- self->Release();
- return 0;
-}
-
-DirectoryLister::DirectoryLister(const std::wstring& dir, Delegate* delegate)
+DirectoryLister::DirectoryLister(const std::wstring& dir,
+ DirectoryListerDelegate* delegate)
: dir_(dir),
- message_loop_(NULL),
delegate_(delegate),
+ message_loop_(NULL),
thread_(NULL),
canceled_(false) {
DCHECK(!dir.empty());
}
DirectoryLister::~DirectoryLister() {
- if (thread_)
- CloseHandle(thread_);
+ if (thread_) {
+ PlatformThread::Join(thread_);
+ }
}
bool DirectoryLister::Start() {
@@ -97,12 +57,7 @@ bool DirectoryLister::Start() {
AddRef(); // the thread will release us when it is done
- unsigned thread_id;
- thread_ = reinterpret_cast<HANDLE>(
- _beginthreadex(NULL, 0, DirectoryLister::ThreadFunc, this, 0,
- &thread_id));
-
- if (!thread_) {
+ if (!PlatformThread::Create(0, this, &thread_)) {
Release();
return false;
}
@@ -114,13 +69,48 @@ void DirectoryLister::Cancel() {
canceled_ = true;
if (thread_) {
- WaitForSingleObject(thread_, INFINITE);
- CloseHandle(thread_);
+ PlatformThread::Join(thread_);
thread_ = NULL;
}
}
-void DirectoryLister::OnReceivedData(const WIN32_FIND_DATA* data, int count) {
+void DirectoryLister::ThreadMain() {
+ DirectoryDataEvent* e = new DirectoryDataEvent(this);
+
+ if (!file_util::DirectoryExists(directory())) {
+ e->error = net::ERR_FILE_NOT_FOUND;
+ message_loop_->PostTask(FROM_HERE, e);
+ Release();
+ return;
+ }
+
+ file_util::FileEnumerator file_enum(directory(), false,
+ file_util::FileEnumerator::FILES_AND_DIRECTORIES);
+
+ std::wstring filename;
+ while (!was_canceled() && !(filename = file_enum.Next()).empty()) {
+ file_enum.GetFindInfo(&e->data[e->count]);
+
+ if (++e->count == kFilesPerEvent) {
+ message_loop_->PostTask(FROM_HERE, e);
+ e = new DirectoryDataEvent(this);
+ }
+ }
+
+ if (e->count > 0) {
+ message_loop_->PostTask(FROM_HERE, e);
+ e = NULL;
+ }
+
+ // Notify done
+ e = new DirectoryDataEvent(this);
+ message_loop_->PostTask(FROM_HERE, e);
+
+ Release();
+}
+
+void DirectoryLister::OnReceivedData(
+ const file_util::FileEnumerator::FindInfo* data, int count) {
// Since the delegate can clear itself during the OnListFile callback, we
// need to null check it during each iteration of the loop. Similarly, it is
// necessary to check the canceled_ flag to avoid sending data to a delegate
@@ -133,7 +123,7 @@ void DirectoryLister::OnDone(int error) {
// If canceled, we need to report some kind of error, but don't overwrite the
// error condition if it is already set.
if (!error && canceled_)
- error = ERROR_OPERATION_ABORTED;
+ error = net::ERR_ABORTED;
if (delegate_)
delegate_->OnListDone(error);
diff --git a/net/base/directory_lister.h b/net/base/directory_lister.h
index 5f826ce..06d1b37 100644
--- a/net/base/directory_lister.h
+++ b/net/base/directory_lister.h
@@ -5,9 +5,10 @@
#ifndef NET_BASE_DIRECTORY_LISTER_H__
#define NET_BASE_DIRECTORY_LISTER_H__
-#include <windows.h>
#include <string>
+#include "base/file_util.h"
+#include "base/platform_thread.h"
#include "base/ref_counted.h"
class MessageLoop;
@@ -21,16 +22,18 @@ namespace net {
// structs over to the main application thread. The consumer of this class
// is insulated from any of the multi-threading details.
//
-class DirectoryLister : public base::RefCountedThreadSafe<DirectoryLister> {
+class DirectoryLister : public base::RefCountedThreadSafe<DirectoryLister>,
+ public PlatformThread::Delegate {
public:
// Implement this class to receive directory entries.
- class Delegate {
+ class DirectoryListerDelegate {
public:
- virtual void OnListFile(const WIN32_FIND_DATA& data) = 0;
+ virtual void OnListFile(
+ const file_util::FileEnumerator::FindInfo& data) = 0;
virtual void OnListDone(int error) = 0;
};
- DirectoryLister(const std::wstring& dir, Delegate* delegate);
+ DirectoryLister(const std::wstring& dir, DirectoryListerDelegate* delegate);
~DirectoryLister();
// Call this method to start the directory enumeration thread.
@@ -42,8 +45,8 @@ class DirectoryLister : public base::RefCountedThreadSafe<DirectoryLister> {
void Cancel();
// The delegate pointer may be modified at any time.
- Delegate* delegate() const { return delegate_; }
- void set_delegate(Delegate* d) { delegate_ = d; }
+ DirectoryListerDelegate* delegate() const { return delegate_; }
+ void set_delegate(DirectoryListerDelegate* d) { delegate_ = d; }
// Returns the directory being enumerated.
const std::wstring& directory() const { return dir_; }
@@ -51,18 +54,21 @@ class DirectoryLister : public base::RefCountedThreadSafe<DirectoryLister> {
// Returns true if the directory enumeration was canceled.
bool was_canceled() const { return canceled_; }
+ // PlatformThread::Delegate implementation
+ void ThreadMain();
+
private:
friend class DirectoryDataEvent;
+ friend class ThreadDelegate;
- void OnReceivedData(const WIN32_FIND_DATA* data, int count);
+ void OnReceivedData(const file_util::FileEnumerator::FindInfo* data,
+ int count);
void OnDone(int error);
- static unsigned __stdcall ThreadFunc(void* param);
-
std::wstring dir_;
- Delegate* delegate_;
+ DirectoryListerDelegate* delegate_;
MessageLoop* message_loop_;
- HANDLE thread_;
+ PlatformThreadHandle thread_;
bool canceled_;
};
diff --git a/net/base/net_util.cc b/net/base/net_util.cc
index 05419fb..3946c6b 100644
--- a/net/base/net_util.cc
+++ b/net/base/net_util.cc
@@ -23,6 +23,7 @@
#include "net/base/net_util.h"
#include "base/basictypes.h"
+#include "base/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
@@ -798,12 +799,22 @@ std::string CanonicalizeHost(const std::wstring& host, bool* is_ip_address) {
return CanonicalizeHost(converted_host, is_ip_address);
}
-#ifdef OS_WIN
std::string GetDirectoryListingHeader(const std::string& title) {
+#if defined(OS_WIN)
std::string result = NetModule::GetResource(IDR_DIR_HEADER_HTML);
if (result.empty()) {
NOTREACHED() << "expected resource not found";
}
+#elif defined(OS_POSIX)
+ // TODO(estade): Temporary hack. Remove these platform #ifdefs when we
+ // have implemented resources for non-Windows platforms.
+ LOG(INFO) << "FIXME: hacked resource loading";
+ FilePath path;
+ PathService::Get(base::DIR_EXE, &path);
+ path = path.Append("../../net/base/dir_header.html");
+ std::string result;
+ file_util::ReadFileToString(path.ToWStringHack(), &result);
+#endif
result.append("<script>start(");
string_escape::JavascriptDoubleQuote(title, true, &result);
@@ -813,16 +824,16 @@ std::string GetDirectoryListingHeader(const std::string& title) {
}
std::string GetDirectoryListingEntry(const std::string& name,
- DWORD attrib,
+ bool is_dir,
int64 size,
- const FILETIME* modified) {
+ const Time& modified) {
std::string result;
result.append("<script>addRow(");
string_escape::JavascriptDoubleQuote(name, true, &result);
result.append(",");
string_escape::JavascriptDoubleQuote(
EscapePath(name), true, &result);
- if (attrib & FILE_ATTRIBUTE_DIRECTORY) {
+ if (is_dir) {
result.append(",1,");
} else {
result.append(",0,");
@@ -835,9 +846,8 @@ std::string GetDirectoryListingEntry(const std::string& name,
std::wstring modified_str;
// |modified| can be NULL in FTP listings.
- if (modified) {
- Time time(Time::FromFileTime(*modified));
- modified_str = base::TimeFormatShortDateAndTime(time);
+ if (!modified.is_null()) {
+ modified_str = base::TimeFormatShortDateAndTime(modified);
}
string_escape::JavascriptDoubleQuote(modified_str, true, &result);
@@ -845,7 +855,6 @@ std::string GetDirectoryListingEntry(const std::string& name,
return result;
}
-#endif
std::wstring StripWWW(const std::wstring& text) {
const std::wstring www(L"www.");
diff --git a/net/base/net_util.h b/net/base/net_util.h
index 7adfc57..f8f49b8 100644
--- a/net/base/net_util.h
+++ b/net/base/net_util.h
@@ -19,6 +19,10 @@
class GURL;
+namespace base {
+class Time;
+}
+
namespace net {
// Given the full path to a file name, creates a file: URL. The returned URL
@@ -95,15 +99,12 @@ void IDNToUnicode(const char* host,
std::string CanonicalizeHost(const std::string& host, bool* is_ip_address);
std::string CanonicalizeHost(const std::wstring& host, bool* is_ip_address);
-#ifdef OS_WIN
-// TODO: Port GetDirectoryListingEntry for OSX and linux.
// Call these functions to get the html for a directory listing.
// They will pass non-7bit-ascii characters unescaped, allowing
// the browser to interpret the encoding (utf8, etc).
std::string GetDirectoryListingHeader(const std::string& title);
-std::string GetDirectoryListingEntry(const std::string& name, DWORD attrib,
- int64 size, const FILETIME* modified);
-#endif
+std::string GetDirectoryListingEntry(const std::string& name, bool is_dir,
+ int64 size, const base::Time& modified);
// If text starts with "www." it is removed, otherwise text is returned
// unmodified.