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/disk_cache/blockfile/mapped_file.h"
6
7#include <stdlib.h>
8
9#include "base/files/file_path.h"
10#include "base/logging.h"
11
12namespace disk_cache {
13
14void* MappedFile::Init(const base::FilePath& name, size_t size) {
15  DCHECK(!init_);
16  if (init_ || !File::Init(name))
17    return NULL;
18
19  if (!size)
20    size = GetLength();
21
22  buffer_ = malloc(size);
23  snapshot_ = malloc(size);
24  if (buffer_ && snapshot_ && Read(buffer_, size, 0)) {
25    memcpy(snapshot_, buffer_, size);
26  } else {
27    free(buffer_);
28    free(snapshot_);
29    buffer_ = snapshot_ = 0;
30  }
31
32  init_ = true;
33  view_size_ = size;
34  return buffer_;
35}
36
37void MappedFile::Flush() {
38  DCHECK(buffer_);
39  DCHECK(snapshot_);
40  const char* buffer_ptr = static_cast<const char*>(buffer_);
41  char* snapshot_ptr = static_cast<char*>(snapshot_);
42  const size_t block_size = 4096;
43  for (size_t offset = 0; offset < view_size_; offset += block_size) {
44    size_t size = std::min(view_size_ - offset, block_size);
45    if (memcmp(snapshot_ptr + offset, buffer_ptr + offset, size)) {
46      memcpy(snapshot_ptr + offset, buffer_ptr + offset, size);
47      Write(snapshot_ptr + offset, size, offset);
48    }
49  }
50}
51
52MappedFile::~MappedFile() {
53  if (!init_)
54    return;
55
56  if (buffer_ && snapshot_) {
57    Flush();
58  }
59  free(buffer_);
60  free(snapshot_);
61}
62
63}  // namespace disk_cache
64