We started redesigning GpuMemoryBuffer interface to handle multiple buffers [0].
[chromium-blink-merge.git] / net / tools / dump_cache / simple_cache_dumper.cc
blobdd5ecbf15f65c010896502d80379468257fa7f06
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 "net/tools/dump_cache/simple_cache_dumper.h"
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/threading/thread.h"
14 #include "net/base/cache_type.h"
15 #include "net/base/io_buffer.h"
16 #include "net/base/net_errors.h"
17 #include "net/disk_cache/disk_cache.h"
18 #include "net/tools/dump_cache/cache_dumper.h"
20 namespace net {
22 SimpleCacheDumper::SimpleCacheDumper(base::FilePath input_path,
23 base::FilePath output_path)
24 : state_(STATE_NONE),
25 input_path_(input_path),
26 output_path_(output_path),
27 writer_(new DiskDumper(output_path)),
28 cache_thread_(new base::Thread("CacheThead")),
29 src_entry_(NULL),
30 dst_entry_(NULL),
31 io_callback_(base::Bind(&SimpleCacheDumper::OnIOComplete,
32 base::Unretained(this))),
33 rv_(0) {
36 SimpleCacheDumper::~SimpleCacheDumper() {
39 int SimpleCacheDumper::Run() {
40 base::MessageLoopForIO main_message_loop;
42 LOG(INFO) << "Reading cache from: " << input_path_.value();
43 LOG(INFO) << "Writing cache to: " << output_path_.value();
45 if (!cache_thread_->StartWithOptions(
46 base::Thread::Options(base::MessageLoop::TYPE_IO, 0))) {
47 LOG(ERROR) << "Unable to start thread";
48 return ERR_UNEXPECTED;
50 state_ = STATE_CREATE_CACHE;
51 int rv = DoLoop(OK);
52 if (rv == ERR_IO_PENDING) {
53 main_message_loop.Run();
54 return rv_;
56 return rv;
59 int SimpleCacheDumper::DoLoop(int rv) {
60 do {
61 State state = state_;
62 state_ = STATE_NONE;
63 switch (state) {
64 case STATE_CREATE_CACHE:
65 CHECK_EQ(OK, rv);
66 rv = DoCreateCache();
67 break;
68 case STATE_CREATE_CACHE_COMPLETE:
69 rv = DoCreateCacheComplete(rv);
70 break;
71 case STATE_OPEN_ENTRY:
72 CHECK_EQ(OK, rv);
73 rv = DoOpenEntry();
74 break;
75 case STATE_OPEN_ENTRY_COMPLETE:
76 rv = DoOpenEntryComplete(rv);
77 break;
78 case STATE_CREATE_ENTRY:
79 CHECK_EQ(OK, rv);
80 rv = DoCreateEntry();
81 break;
82 case STATE_CREATE_ENTRY_COMPLETE:
83 rv = DoCreateEntryComplete(rv);
84 break;
85 case STATE_READ_HEADERS:
86 CHECK_EQ(OK, rv);
87 rv = DoReadHeaders();
88 break;
89 case STATE_READ_HEADERS_COMPLETE:
90 rv = DoReadHeadersComplete(rv);
91 break;
92 case STATE_WRITE_HEADERS:
93 CHECK_EQ(OK, rv);
94 rv = DoWriteHeaders();
95 break;
96 case STATE_WRITE_HEADERS_COMPLETE:
97 rv = DoWriteHeadersComplete(rv);
98 break;
99 case STATE_READ_BODY:
100 CHECK_EQ(OK, rv);
101 rv = DoReadBody();
102 break;
103 case STATE_READ_BODY_COMPLETE:
104 rv = DoReadBodyComplete(rv);
105 break;
106 case STATE_WRITE_BODY:
107 CHECK_EQ(OK, rv);
108 rv = DoWriteBody();
109 break;
110 case STATE_WRITE_BODY_COMPLETE:
111 rv = DoWriteBodyComplete(rv);
112 break;
113 default:
114 NOTREACHED() << "state_: " << state_;
115 break;
117 } while (state_ != STATE_NONE && rv != ERR_IO_PENDING);
118 return rv;
121 int SimpleCacheDumper::DoCreateCache() {
122 DCHECK(!cache_);
123 state_ = STATE_CREATE_CACHE_COMPLETE;
124 return disk_cache::CreateCacheBackend(
125 DISK_CACHE,
126 CACHE_BACKEND_DEFAULT,
127 input_path_,
129 false,
130 cache_thread_->message_loop_proxy().get(),
131 NULL,
132 &cache_,
133 io_callback_);
136 int SimpleCacheDumper::DoCreateCacheComplete(int rv) {
137 if (rv < 0)
138 return rv;
140 reinterpret_cast<disk_cache::BackendImpl*>(cache_.get())->SetUpgradeMode();
141 reinterpret_cast<disk_cache::BackendImpl*>(cache_.get())->SetFlags(
142 disk_cache::kNoRandom);
144 state_ = STATE_OPEN_ENTRY;
145 return OK;
148 int SimpleCacheDumper::DoOpenEntry() {
149 DCHECK(!dst_entry_);
150 DCHECK(!src_entry_);
151 state_ = STATE_OPEN_ENTRY_COMPLETE;
152 if (!iter_)
153 iter_ = cache_->CreateIterator();
154 return iter_->OpenNextEntry(&src_entry_, io_callback_);
157 int SimpleCacheDumper::DoOpenEntryComplete(int rv) {
158 // ERR_FAILED indicates iteration finished.
159 if (rv == ERR_FAILED)
160 return OK;
162 if (rv < 0)
163 return rv;
165 state_ = STATE_CREATE_ENTRY;
166 return OK;
169 int SimpleCacheDumper::DoCreateEntry() {
170 DCHECK(!dst_entry_);
171 state_ = STATE_CREATE_ENTRY_COMPLETE;
173 return writer_->CreateEntry(src_entry_->GetKey(), &dst_entry_,
174 io_callback_);
177 int SimpleCacheDumper::DoCreateEntryComplete(int rv) {
178 if (rv < 0)
179 return rv;
181 state_ = STATE_READ_HEADERS;
182 return OK;
185 int SimpleCacheDumper::DoReadHeaders() {
186 state_ = STATE_READ_HEADERS_COMPLETE;
187 int32 size = src_entry_->GetDataSize(0);
188 buf_ = new IOBufferWithSize(size);
189 return src_entry_->ReadData(0, 0, buf_.get(), size, io_callback_);
192 int SimpleCacheDumper::DoReadHeadersComplete(int rv) {
193 if (rv < 0)
194 return rv;
196 state_ = STATE_WRITE_HEADERS;
197 return OK;
200 int SimpleCacheDumper::DoWriteHeaders() {
201 int rv = writer_->WriteEntry(
202 dst_entry_, 0, 0, buf_.get(), buf_->size(), io_callback_);
203 if (rv == 0)
204 return ERR_FAILED;
206 state_ = STATE_WRITE_HEADERS_COMPLETE;
207 return OK;
210 int SimpleCacheDumper::DoWriteHeadersComplete(int rv) {
211 if (rv < 0)
212 return rv;
214 state_ = STATE_READ_BODY;
215 return OK;
218 int SimpleCacheDumper::DoReadBody() {
219 state_ = STATE_READ_BODY_COMPLETE;
220 int32 size = src_entry_->GetDataSize(1);
221 // If the body is empty, we can neither read nor write it, so
222 // just move to the next.
223 if (size <= 0) {
224 state_ = STATE_WRITE_BODY_COMPLETE;
225 return OK;
227 buf_ = new IOBufferWithSize(size);
228 return src_entry_->ReadData(1, 0, buf_.get(), size, io_callback_);
231 int SimpleCacheDumper::DoReadBodyComplete(int rv) {
232 if (rv < 0)
233 return rv;
235 state_ = STATE_WRITE_BODY;
236 return OK;
239 int SimpleCacheDumper::DoWriteBody() {
240 int rv = writer_->WriteEntry(
241 dst_entry_, 1, 0, buf_.get(), buf_->size(), io_callback_);
242 if (rv == 0)
243 return ERR_FAILED;
245 state_ = STATE_WRITE_BODY_COMPLETE;
246 return OK;
249 int SimpleCacheDumper::DoWriteBodyComplete(int rv) {
250 if (rv < 0)
251 return rv;
253 src_entry_->Close();
254 writer_->CloseEntry(dst_entry_, base::Time::Now(), base::Time::Now());
255 src_entry_ = NULL;
256 dst_entry_ = NULL;
258 state_ = STATE_OPEN_ENTRY;
259 return OK;
262 void SimpleCacheDumper::OnIOComplete(int rv) {
263 rv = DoLoop(rv);
265 if (rv != ERR_IO_PENDING) {
266 rv_ = rv;
267 cache_.reset();
268 base::MessageLoop::current()->Quit();
272 } // namespace net