Experimental push messaging api reference docs.
[chromium-blink-merge.git] / webkit / fileapi / file_system_dir_url_request_job.cc
blob1be93947aadbe6f17fb0472a3f2aec1221410db1
1 // Copyright (c) 2012 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.
5 #include "webkit/fileapi/file_system_dir_url_request_job.h"
7 #include <algorithm>
9 #include "base/bind.h"
10 #include "base/compiler_specific.h"
11 #include "base/file_util_proxy.h"
12 #include "base/message_loop.h"
13 #include "base/platform_file.h"
14 #include "base/sys_string_conversions.h"
15 #include "base/time.h"
16 #include "base/utf_string_conversions.h"
17 #include "build/build_config.h"
18 #include "googleurl/src/gurl.h"
19 #include "net/base/io_buffer.h"
20 #include "net/base/net_errors.h"
21 #include "net/base/net_util.h"
22 #include "net/url_request/url_request.h"
23 #include "webkit/fileapi/file_system_context.h"
24 #include "webkit/fileapi/file_system_operation.h"
25 #include "webkit/fileapi/file_system_url.h"
27 using net::NetworkDelegate;
28 using net::URLRequest;
29 using net::URLRequestJob;
30 using net::URLRequestStatus;
32 namespace fileapi {
34 FileSystemDirURLRequestJob::FileSystemDirURLRequestJob(
35 URLRequest* request,
36 NetworkDelegate* network_delegate,
37 FileSystemContext* file_system_context)
38 : URLRequestJob(request, network_delegate),
39 file_system_context_(file_system_context),
40 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
43 FileSystemDirURLRequestJob::~FileSystemDirURLRequestJob() {
46 bool FileSystemDirURLRequestJob::ReadRawData(net::IOBuffer* dest, int dest_size,
47 int *bytes_read) {
48 int count = std::min(dest_size, static_cast<int>(data_.size()));
49 if (count > 0) {
50 memcpy(dest->data(), data_.data(), count);
51 data_.erase(0, count);
53 *bytes_read = count;
54 return true;
57 void FileSystemDirURLRequestJob::Start() {
58 MessageLoop::current()->PostTask(
59 FROM_HERE,
60 base::Bind(&FileSystemDirURLRequestJob::StartAsync,
61 weak_factory_.GetWeakPtr()));
64 void FileSystemDirURLRequestJob::Kill() {
65 URLRequestJob::Kill();
66 weak_factory_.InvalidateWeakPtrs();
69 bool FileSystemDirURLRequestJob::GetMimeType(std::string* mime_type) const {
70 *mime_type = "text/html";
71 return true;
74 bool FileSystemDirURLRequestJob::GetCharset(std::string* charset) {
75 *charset = "utf-8";
76 return true;
79 void FileSystemDirURLRequestJob::StartAsync() {
80 if (!request_)
81 return;
82 url_ = FileSystemURL(request_->url());
83 base::PlatformFileError error_code;
84 FileSystemOperation* operation = GetNewOperation(&error_code);
85 if (error_code != base::PLATFORM_FILE_OK) {
86 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED,
87 net::PlatformFileErrorToNetError(error_code)));
88 return;
90 operation->ReadDirectory(
91 url_,
92 base::Bind(&FileSystemDirURLRequestJob::DidReadDirectory, this));
95 void FileSystemDirURLRequestJob::DidReadDirectory(
96 base::PlatformFileError result,
97 const std::vector<base::FileUtilProxy::Entry>& entries,
98 bool has_more) {
99 if (result != base::PLATFORM_FILE_OK) {
100 int rv = net::ERR_FILE_NOT_FOUND;
101 if (result == base::PLATFORM_FILE_ERROR_INVALID_URL)
102 rv = net::ERR_INVALID_URL;
103 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv));
104 return;
107 if (!request_)
108 return;
110 if (data_.empty()) {
111 FilePath relative_path = url_.path();
112 #if defined(OS_POSIX)
113 relative_path = FilePath(FILE_PATH_LITERAL("/") + relative_path.value());
114 #endif
115 const string16& title = relative_path.LossyDisplayName();
116 data_.append(net::GetDirectoryListingHeader(title));
119 typedef std::vector<base::FileUtilProxy::Entry>::const_iterator EntryIterator;
120 for (EntryIterator it = entries.begin(); it != entries.end(); ++it) {
121 const string16& name = FilePath(it->name).LossyDisplayName();
122 data_.append(net::GetDirectoryListingEntry(
123 name, std::string(), it->is_directory, it->size,
124 it->last_modified_time));
127 if (has_more) {
128 base::PlatformFileError error_code;
129 FileSystemOperation* operation = GetNewOperation(&error_code);
130 if (error_code != base::PLATFORM_FILE_OK) {
131 NotifyDone(URLRequestStatus(
132 URLRequestStatus::FAILED,
133 net::PlatformFileErrorToNetError(error_code)));
134 return;
137 operation->ReadDirectory(
138 url_,
139 base::Bind(&FileSystemDirURLRequestJob::DidReadDirectory, this));
140 } else {
141 set_expected_content_size(data_.size());
142 NotifyHeadersComplete();
146 FileSystemOperation* FileSystemDirURLRequestJob::GetNewOperation(
147 base::PlatformFileError* error_code) {
148 return file_system_context_->CreateFileSystemOperation(url_, error_code);
151 } // namespace fileapi