12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/tools/dump_cache/simple_cache_dumper.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/at_exit.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
119ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread.h"
14a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "net/base/cache_type.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/io_buffer.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_errors.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/disk_cache/disk_cache.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/tools/dump_cache/cache_dumper.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace net {
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SimpleCacheDumper::SimpleCacheDumper(base::FilePath input_path,
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     base::FilePath output_path)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : state_(STATE_NONE),
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      input_path_(input_path),
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      output_path_(output_path),
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      writer_(new DiskDumper(output_path)),
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cache_thread_(new base::Thread("CacheThead")),
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      iter_(NULL),
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      src_entry_(NULL),
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dst_entry_(NULL),
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      io_callback_(base::Bind(&SimpleCacheDumper::OnIOComplete,
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              base::Unretained(this))),
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      rv_(0) {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SimpleCacheDumper::~SimpleCacheDumper() {
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int SimpleCacheDumper::Run() {
4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoopForIO main_message_loop;
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LOG(INFO) << "Reading cache from: " << input_path_.value();
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LOG(INFO) << "Writing cache to: " << output_path_.value();
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!cache_thread_->StartWithOptions(
4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          base::Thread::Options(base::MessageLoop::TYPE_IO, 0))) {
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << "Unable to start thread";
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ERR_UNEXPECTED;
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_ = STATE_CREATE_CACHE;
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = DoLoop(OK);
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rv == ERR_IO_PENDING) {
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    main_message_loop.Run();
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return rv_;
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return rv;
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int SimpleCacheDumper::DoLoop(int rv) {
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  do {
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    State state = state_;
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    state_ = STATE_NONE;
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    switch (state) {
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_CREATE_CACHE:
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CHECK_EQ(OK, rv);
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoCreateCache();
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_CREATE_CACHE_COMPLETE:
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoCreateCacheComplete(rv);
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_OPEN_ENTRY:
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CHECK_EQ(OK, rv);
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoOpenEntry();
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_OPEN_ENTRY_COMPLETE:
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoOpenEntryComplete(rv);
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_CREATE_ENTRY:
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CHECK_EQ(OK, rv);
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoCreateEntry();
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_CREATE_ENTRY_COMPLETE:
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoCreateEntryComplete(rv);
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_READ_HEADERS:
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CHECK_EQ(OK, rv);
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoReadHeaders();
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_READ_HEADERS_COMPLETE:
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoReadHeadersComplete(rv);
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_WRITE_HEADERS:
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CHECK_EQ(OK, rv);
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoWriteHeaders();
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_WRITE_HEADERS_COMPLETE:
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoWriteHeadersComplete(rv);
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_READ_BODY:
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CHECK_EQ(OK, rv);
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoReadBody();
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_READ_BODY_COMPLETE:
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoReadBodyComplete(rv);
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_WRITE_BODY:
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CHECK_EQ(OK, rv);
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoWriteBody();
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case STATE_WRITE_BODY_COMPLETE:
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rv = DoWriteBodyComplete(rv);
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      default:
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        NOTREACHED() << "state_: " << state_;
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } while (state_ != STATE_NONE && rv != ERR_IO_PENDING);
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return rv;
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int SimpleCacheDumper::DoCreateCache() {
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!cache_);
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_ = STATE_CREATE_CACHE_COMPLETE;
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return disk_cache::CreateCacheBackend(
1267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      DISK_CACHE,
1277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      CACHE_BACKEND_DEFAULT,
1287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      input_path_,
1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      0,
1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      false,
1317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      cache_thread_->message_loop_proxy().get(),
1327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      NULL,
1337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      &cache_,
1347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      io_callback_);
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int SimpleCacheDumper::DoCreateCacheComplete(int rv) {
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rv < 0)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return rv;
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
141a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  reinterpret_cast<disk_cache::BackendImpl*>(cache_.get())->SetUpgradeMode();
142a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  reinterpret_cast<disk_cache::BackendImpl*>(cache_.get())->SetFlags(
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      disk_cache::kNoRandom);
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_ = STATE_OPEN_ENTRY;
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return OK;
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int SimpleCacheDumper::DoOpenEntry() {
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!dst_entry_);
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!src_entry_);
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_ = STATE_OPEN_ENTRY_COMPLETE;
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return cache_->OpenNextEntry(&iter_, &src_entry_, io_callback_);
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int SimpleCacheDumper::DoOpenEntryComplete(int rv) {
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // ERR_FAILED indicates iteration finished.
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rv == ERR_FAILED) {
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    cache_->EndEnumeration(&iter_);
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return OK;
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rv < 0)
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return rv;
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_ = STATE_CREATE_ENTRY;
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return OK;
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int SimpleCacheDumper::DoCreateEntry() {
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!dst_entry_);
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_ = STATE_CREATE_ENTRY_COMPLETE;
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return writer_->CreateEntry(src_entry_->GetKey(), &dst_entry_,
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              io_callback_);
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int SimpleCacheDumper::DoCreateEntryComplete(int rv) {
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rv < 0)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return rv;
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_ = STATE_READ_HEADERS;
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return OK;
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int SimpleCacheDumper::DoReadHeaders() {
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_ = STATE_READ_HEADERS_COMPLETE;
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int32 size = src_entry_->GetDataSize(0);
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  buf_ = new IOBufferWithSize(size);
190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return src_entry_->ReadData(0, 0, buf_.get(), size, io_callback_);
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int SimpleCacheDumper::DoReadHeadersComplete(int rv) {
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rv < 0)
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return rv;
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_ = STATE_WRITE_HEADERS;
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return OK;
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int SimpleCacheDumper::DoWriteHeaders() {
202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int rv = writer_->WriteEntry(
203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      dst_entry_, 0, 0, buf_.get(), buf_->size(), io_callback_);
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rv == 0)
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ERR_FAILED;
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_ = STATE_WRITE_HEADERS_COMPLETE;
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return OK;
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int SimpleCacheDumper::DoWriteHeadersComplete(int rv) {
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rv < 0)
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return rv;
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_ = STATE_READ_BODY;
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return OK;
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int SimpleCacheDumper::DoReadBody() {
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_ = STATE_READ_BODY_COMPLETE;
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int32 size = src_entry_->GetDataSize(1);
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If the body is empty, we can neither read nor write it, so
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // just move to the next.
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (size <= 0) {
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    state_ = STATE_WRITE_BODY_COMPLETE;
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return OK;
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  buf_ = new IOBufferWithSize(size);
229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return src_entry_->ReadData(1, 0, buf_.get(), size, io_callback_);
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int SimpleCacheDumper::DoReadBodyComplete(int rv) {
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rv < 0)
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return rv;
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_ = STATE_WRITE_BODY;
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return OK;
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int SimpleCacheDumper::DoWriteBody() {
241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int rv = writer_->WriteEntry(
242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      dst_entry_, 1, 0, buf_.get(), buf_->size(), io_callback_);
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rv == 0)
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ERR_FAILED;
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_ = STATE_WRITE_BODY_COMPLETE;
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return OK;
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int SimpleCacheDumper::DoWriteBodyComplete(int rv) {
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rv < 0)
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return rv;
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  src_entry_->Close();
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  writer_->CloseEntry(dst_entry_, base::Time::Now(), base::Time::Now());
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  src_entry_ = NULL;
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dst_entry_ = NULL;
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_ = STATE_OPEN_ENTRY;
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return OK;
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SimpleCacheDumper::OnIOComplete(int rv) {
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = DoLoop(rv);
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rv != ERR_IO_PENDING) {
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    rv_ = rv;
268a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    cache_.reset();
26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->Quit();
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace net
274