OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "net/tools/dump_cache/simple_cache_dumper.h" | |
6 | |
7 #include "base/at_exit.h" | |
8 #include "base/command_line.h" | |
9 #include "base/logging.h" | |
10 #include "base/memory/scoped_ptr.h" | |
11 #include "base/message_loop/message_loop.h" | |
12 #include "base/message_loop/message_loop_proxy.h" | |
13 #include "base/profiler/scoped_tracker.h" | |
14 #include "base/threading/thread.h" | |
15 #include "net/base/cache_type.h" | |
16 #include "net/base/io_buffer.h" | |
17 #include "net/base/net_errors.h" | |
18 #include "net/disk_cache/disk_cache.h" | |
19 #include "net/tools/dump_cache/cache_dumper.h" | |
20 | |
21 namespace net { | |
22 | |
23 SimpleCacheDumper::SimpleCacheDumper(base::FilePath input_path, | |
24 base::FilePath output_path) | |
25 : state_(STATE_NONE), | |
26 input_path_(input_path), | |
27 output_path_(output_path), | |
28 writer_(new DiskDumper(output_path)), | |
29 cache_thread_(new base::Thread("CacheThead")), | |
30 src_entry_(NULL), | |
31 dst_entry_(NULL), | |
32 io_callback_(base::Bind(&SimpleCacheDumper::OnIOComplete, | |
33 base::Unretained(this))), | |
34 rv_(0) { | |
35 } | |
36 | |
37 SimpleCacheDumper::~SimpleCacheDumper() { | |
38 } | |
39 | |
40 int SimpleCacheDumper::Run() { | |
41 base::MessageLoopForIO main_message_loop; | |
42 | |
43 LOG(INFO) << "Reading cache from: " << input_path_.value(); | |
44 LOG(INFO) << "Writing cache to: " << output_path_.value(); | |
45 | |
46 if (!cache_thread_->StartWithOptions( | |
47 base::Thread::Options(base::MessageLoop::TYPE_IO, 0))) { | |
48 LOG(ERROR) << "Unable to start thread"; | |
49 return ERR_UNEXPECTED; | |
50 } | |
51 state_ = STATE_CREATE_CACHE; | |
52 int rv = DoLoop(OK); | |
53 if (rv == ERR_IO_PENDING) { | |
54 main_message_loop.Run(); | |
55 return rv_; | |
56 } | |
57 return rv; | |
58 } | |
59 | |
60 int SimpleCacheDumper::DoLoop(int rv) { | |
61 do { | |
62 State state = state_; | |
63 state_ = STATE_NONE; | |
64 switch (state) { | |
65 case STATE_CREATE_CACHE: | |
66 CHECK_EQ(OK, rv); | |
67 rv = DoCreateCache(); | |
68 break; | |
69 case STATE_CREATE_CACHE_COMPLETE: | |
70 rv = DoCreateCacheComplete(rv); | |
71 break; | |
72 case STATE_OPEN_ENTRY: | |
73 CHECK_EQ(OK, rv); | |
74 rv = DoOpenEntry(); | |
75 break; | |
76 case STATE_OPEN_ENTRY_COMPLETE: | |
77 rv = DoOpenEntryComplete(rv); | |
78 break; | |
79 case STATE_CREATE_ENTRY: | |
80 CHECK_EQ(OK, rv); | |
81 rv = DoCreateEntry(); | |
82 break; | |
83 case STATE_CREATE_ENTRY_COMPLETE: | |
84 rv = DoCreateEntryComplete(rv); | |
85 break; | |
86 case STATE_READ_HEADERS: | |
87 CHECK_EQ(OK, rv); | |
88 rv = DoReadHeaders(); | |
89 break; | |
90 case STATE_READ_HEADERS_COMPLETE: | |
91 rv = DoReadHeadersComplete(rv); | |
92 break; | |
93 case STATE_WRITE_HEADERS: | |
94 CHECK_EQ(OK, rv); | |
95 rv = DoWriteHeaders(); | |
96 break; | |
97 case STATE_WRITE_HEADERS_COMPLETE: | |
98 rv = DoWriteHeadersComplete(rv); | |
99 break; | |
100 case STATE_READ_BODY: | |
101 CHECK_EQ(OK, rv); | |
102 rv = DoReadBody(); | |
103 break; | |
104 case STATE_READ_BODY_COMPLETE: | |
105 rv = DoReadBodyComplete(rv); | |
106 break; | |
107 case STATE_WRITE_BODY: | |
108 CHECK_EQ(OK, rv); | |
109 rv = DoWriteBody(); | |
110 break; | |
111 case STATE_WRITE_BODY_COMPLETE: | |
112 rv = DoWriteBodyComplete(rv); | |
113 break; | |
114 default: | |
115 NOTREACHED() << "state_: " << state_; | |
116 break; | |
117 } | |
118 } while (state_ != STATE_NONE && rv != ERR_IO_PENDING); | |
119 return rv; | |
120 } | |
121 | |
122 int SimpleCacheDumper::DoCreateCache() { | |
123 DCHECK(!cache_); | |
124 state_ = STATE_CREATE_CACHE_COMPLETE; | |
125 return disk_cache::CreateCacheBackend( | |
126 DISK_CACHE, | |
127 CACHE_BACKEND_DEFAULT, | |
128 input_path_, | |
129 0, | |
130 false, | |
131 cache_thread_->message_loop_proxy().get(), | |
132 NULL, | |
133 &cache_, | |
134 io_callback_); | |
135 } | |
136 | |
137 int SimpleCacheDumper::DoCreateCacheComplete(int rv) { | |
138 if (rv < 0) | |
139 return rv; | |
140 | |
141 reinterpret_cast<disk_cache::BackendImpl*>(cache_.get())->SetUpgradeMode(); | |
142 reinterpret_cast<disk_cache::BackendImpl*>(cache_.get())->SetFlags( | |
143 disk_cache::kNoRandom); | |
144 | |
145 state_ = STATE_OPEN_ENTRY; | |
146 return OK; | |
147 } | |
148 | |
149 int SimpleCacheDumper::DoOpenEntry() { | |
150 DCHECK(!dst_entry_); | |
151 DCHECK(!src_entry_); | |
152 state_ = STATE_OPEN_ENTRY_COMPLETE; | |
153 if (!iter_) | |
154 iter_ = cache_->CreateIterator(); | |
155 return iter_->OpenNextEntry(&src_entry_, io_callback_); | |
156 } | |
157 | |
158 int SimpleCacheDumper::DoOpenEntryComplete(int rv) { | |
159 // ERR_FAILED indicates iteration finished. | |
160 if (rv == ERR_FAILED) | |
161 return OK; | |
162 | |
163 if (rv < 0) | |
164 return rv; | |
165 | |
166 state_ = STATE_CREATE_ENTRY; | |
167 return OK; | |
168 } | |
169 | |
170 int SimpleCacheDumper::DoCreateEntry() { | |
171 DCHECK(!dst_entry_); | |
172 state_ = STATE_CREATE_ENTRY_COMPLETE; | |
173 | |
174 return writer_->CreateEntry(src_entry_->GetKey(), &dst_entry_, | |
175 io_callback_); | |
176 } | |
177 | |
178 int SimpleCacheDumper::DoCreateEntryComplete(int rv) { | |
179 if (rv < 0) | |
180 return rv; | |
181 | |
182 state_ = STATE_READ_HEADERS; | |
183 return OK; | |
184 } | |
185 | |
186 int SimpleCacheDumper::DoReadHeaders() { | |
187 state_ = STATE_READ_HEADERS_COMPLETE; | |
188 int32 size = src_entry_->GetDataSize(0); | |
189 buf_ = new IOBufferWithSize(size); | |
190 return src_entry_->ReadData(0, 0, buf_.get(), size, io_callback_); | |
191 } | |
192 | |
193 int SimpleCacheDumper::DoReadHeadersComplete(int rv) { | |
194 if (rv < 0) | |
195 return rv; | |
196 | |
197 state_ = STATE_WRITE_HEADERS; | |
198 return OK; | |
199 } | |
200 | |
201 int SimpleCacheDumper::DoWriteHeaders() { | |
202 int rv = writer_->WriteEntry( | |
203 dst_entry_, 0, 0, buf_.get(), buf_->size(), io_callback_); | |
204 if (rv == 0) | |
205 return ERR_FAILED; | |
206 | |
207 state_ = STATE_WRITE_HEADERS_COMPLETE; | |
208 return OK; | |
209 } | |
210 | |
211 int SimpleCacheDumper::DoWriteHeadersComplete(int rv) { | |
212 if (rv < 0) | |
213 return rv; | |
214 | |
215 state_ = STATE_READ_BODY; | |
216 return OK; | |
217 } | |
218 | |
219 int SimpleCacheDumper::DoReadBody() { | |
220 state_ = STATE_READ_BODY_COMPLETE; | |
221 int32 size = src_entry_->GetDataSize(1); | |
222 // If the body is empty, we can neither read nor write it, so | |
223 // just move to the next. | |
224 if (size <= 0) { | |
225 state_ = STATE_WRITE_BODY_COMPLETE; | |
226 return OK; | |
227 } | |
228 buf_ = new IOBufferWithSize(size); | |
229 return src_entry_->ReadData(1, 0, buf_.get(), size, io_callback_); | |
230 } | |
231 | |
232 int SimpleCacheDumper::DoReadBodyComplete(int rv) { | |
233 if (rv < 0) | |
234 return rv; | |
235 | |
236 state_ = STATE_WRITE_BODY; | |
237 return OK; | |
238 } | |
239 | |
240 int SimpleCacheDumper::DoWriteBody() { | |
241 int rv = writer_->WriteEntry( | |
242 dst_entry_, 1, 0, buf_.get(), buf_->size(), io_callback_); | |
243 if (rv == 0) | |
244 return ERR_FAILED; | |
245 | |
246 state_ = STATE_WRITE_BODY_COMPLETE; | |
247 return OK; | |
248 } | |
249 | |
250 int SimpleCacheDumper::DoWriteBodyComplete(int rv) { | |
251 if (rv < 0) | |
252 return rv; | |
253 | |
254 src_entry_->Close(); | |
255 writer_->CloseEntry(dst_entry_, base::Time::Now(), base::Time::Now()); | |
256 src_entry_ = NULL; | |
257 dst_entry_ = NULL; | |
258 | |
259 state_ = STATE_OPEN_ENTRY; | |
260 return OK; | |
261 } | |
262 | |
263 void SimpleCacheDumper::OnIOComplete(int rv) { | |
264 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | |
265 tracked_objects::ScopedTracker tracking_profile( | |
266 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
267 "422516 SimpleCacheDumper::OnIOComplete")); | |
268 | |
269 rv = DoLoop(rv); | |
270 | |
271 if (rv != ERR_IO_PENDING) { | |
272 rv_ = rv; | |
273 cache_.reset(); | |
274 base::MessageLoop::current()->Quit(); | |
275 } | |
276 } | |
277 | |
278 } // namespace net | |
OLD | NEW |