1// Copyright (c) 2006-2008 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#ifndef NET_DISK_CACHE_STORAGE_BLOCK_INL_H_ 6#define NET_DISK_CACHE_STORAGE_BLOCK_INL_H_ 7#pragma once 8 9#include "net/disk_cache/storage_block.h" 10 11#include "base/logging.h" 12#include "net/disk_cache/trace.h" 13 14namespace disk_cache { 15 16template<typename T> StorageBlock<T>::StorageBlock(MappedFile* file, 17 Addr address) 18 : data_(NULL), file_(file), address_(address), modified_(false), 19 own_data_(false), extended_(false) { 20 if (address.num_blocks() > 1) 21 extended_ = true; 22 DCHECK(!address.is_initialized() || sizeof(*data_) == address.BlockSize()); 23} 24 25template<typename T> StorageBlock<T>::~StorageBlock() { 26 if (modified_) 27 Store(); 28 DeleteData(); 29} 30 31template<typename T> void* StorageBlock<T>::buffer() const { 32 return data_; 33} 34 35template<typename T> size_t StorageBlock<T>::size() const { 36 if (!extended_) 37 return sizeof(*data_); 38 return address_.num_blocks() * sizeof(*data_); 39} 40 41template<typename T> int StorageBlock<T>::offset() const { 42 return address_.start_block() * address_.BlockSize(); 43} 44 45template<typename T> bool StorageBlock<T>::LazyInit(MappedFile* file, 46 Addr address) { 47 if (file_ || address_.is_initialized()) { 48 NOTREACHED(); 49 return false; 50 } 51 file_ = file; 52 address_.set_value(address.value()); 53 if (address.num_blocks() > 1) 54 extended_ = true; 55 56 DCHECK(sizeof(*data_) == address.BlockSize()); 57 return true; 58} 59 60template<typename T> void StorageBlock<T>::SetData(T* other) { 61 DCHECK(!modified_); 62 DeleteData(); 63 data_ = other; 64} 65 66template<typename T> void StorageBlock<T>::Discard() { 67 if (!data_) 68 return; 69 if (!own_data_) { 70 NOTREACHED(); 71 return; 72 } 73 DeleteData(); 74 data_ = NULL; 75 modified_ = false; 76 extended_ = false; 77} 78 79template<typename T> void StorageBlock<T>::StopSharingData() { 80 if (!data_ || own_data_) 81 return; 82 DCHECK(!modified_); 83 data_ = NULL; 84} 85 86template<typename T> void StorageBlock<T>::set_modified() { 87 DCHECK(data_); 88 modified_ = true; 89} 90 91template<typename T> T* StorageBlock<T>::Data() { 92 if (!data_) 93 AllocateData(); 94 return data_; 95} 96 97template<typename T> bool StorageBlock<T>::HasData() const { 98 return (NULL != data_); 99} 100 101template<typename T> bool StorageBlock<T>::own_data() const { 102 return own_data_; 103} 104 105template<typename T> const Addr StorageBlock<T>::address() const { 106 return address_; 107} 108 109template<typename T> bool StorageBlock<T>::Load() { 110 if (file_) { 111 if (!data_) 112 AllocateData(); 113 114 if (file_->Load(this)) { 115 modified_ = false; 116 return true; 117 } 118 } 119 LOG(WARNING) << "Failed data load."; 120 Trace("Failed data load."); 121 return false; 122} 123 124template<typename T> bool StorageBlock<T>::Store() { 125 if (file_ && data_) { 126 if (file_->Store(this)) { 127 modified_ = false; 128 return true; 129 } 130 } 131 LOG(ERROR) << "Failed data store."; 132 Trace("Failed data store."); 133 return false; 134} 135 136template<typename T> void StorageBlock<T>::AllocateData() { 137 DCHECK(!data_); 138 if (!extended_) { 139 data_ = new T; 140 } else { 141 void* buffer = new char[address_.num_blocks() * sizeof(*data_)]; 142 data_ = new(buffer) T; 143 } 144 own_data_ = true; 145} 146 147template<typename T> void StorageBlock<T>::DeleteData() { 148 if (own_data_) { 149 if (!extended_) { 150 delete data_; 151 } else { 152 data_->~T(); 153 delete[] reinterpret_cast<char*>(data_); 154 } 155 own_data_ = false; 156 } 157} 158 159} // namespace disk_cache 160 161#endif // NET_DISK_CACHE_STORAGE_BLOCK_INL_H_ 162