Home | History | Annotate | Download | only in flash
      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 "base/logging.h"
      6 #include "net/base/io_buffer.h"
      7 #include "net/base/net_errors.h"
      8 #include "net/disk_cache/flash/format.h"
      9 #include "net/disk_cache/flash/log_store.h"
     10 #include "net/disk_cache/flash/log_store_entry.h"
     11 
     12 namespace disk_cache {
     13 
     14 LogStoreEntry::LogStoreEntry(LogStore* store)
     15     : store_(store), id_(-1), init_(false), closed_(false), deleted_(false) {
     16   DCHECK(store);
     17 }
     18 
     19 LogStoreEntry::LogStoreEntry(LogStore* store, int32 id)
     20     : store_(store), id_(id), init_(false), closed_(false), deleted_(false) {
     21   DCHECK(store);
     22 }
     23 
     24 LogStoreEntry::~LogStoreEntry() {
     25   DCHECK(!init_ || closed_);
     26 }
     27 
     28 bool LogStoreEntry::Init() {
     29   DCHECK(!init_);
     30   if (IsNew()) {
     31     init_ = true;
     32     return true;
     33   }
     34 
     35   int32 stream_sizes[kFlashLogStoreEntryNumStreams];
     36   COMPILE_ASSERT(sizeof(stream_sizes) == kFlashLogStoreEntryHeaderSize,
     37                  invalid_log_store_entry_header_size);
     38 
     39   if (!store_->OpenEntry(id_) ||
     40       !store_->ReadData(id_, stream_sizes, kFlashLogStoreEntryHeaderSize, 0)) {
     41     return false;
     42   }
     43   for (int i = 0, offset = kFlashLogStoreEntryHeaderSize;
     44        i < kFlashLogStoreEntryNumStreams; ++i) {
     45     streams_[i].offset = offset;
     46     streams_[i].size = stream_sizes[i];
     47     offset += stream_sizes[i];
     48   }
     49   init_ = true;
     50   return true;
     51 }
     52 
     53 bool LogStoreEntry::Close() {
     54   DCHECK(init_ && !closed_);
     55 
     56   if (IsNew()) {
     57     closed_ = deleted_ ? true : Save();
     58   } else {
     59     store_->CloseEntry(id_);
     60     if (deleted_)
     61       store_->DeleteEntry(id_, Size());
     62     closed_ = true;
     63   }
     64   return closed_;
     65 }
     66 
     67 int32 LogStoreEntry::id() const {
     68   DCHECK(init_);
     69   return id_;
     70 }
     71 
     72 int32 LogStoreEntry::GetDataSize(int index) const {
     73   DCHECK(init_);
     74   return InvalidStream(index) ? 0 : streams_[index].size;
     75 }
     76 
     77 int LogStoreEntry::ReadData(int index, int offset, net::IOBuffer* buf,
     78                             int buf_len) {
     79   DCHECK(init_);
     80   if (InvalidStream(index))
     81     return net::ERR_INVALID_ARGUMENT;
     82 
     83   int stream_size = streams_[index].size;
     84   if (offset >= stream_size || offset < 0 || buf_len == 0)
     85     return 0;
     86   if (offset + buf_len > stream_size)
     87     buf_len = stream_size - offset;
     88 
     89   if (!IsNew()) {
     90     offset += streams_[index].offset;
     91     if (store_->ReadData(id_, buf->data(), buf_len, offset))
     92       return buf_len;
     93     return net::ERR_FAILED;
     94   }
     95   memcpy(buf->data(), &streams_[index].write_buffer[offset], buf_len);
     96   return buf_len;
     97 }
     98 
     99 int LogStoreEntry::WriteData(int index, int offset, net::IOBuffer* buf,
    100                              int buf_len) {
    101   DCHECK(init_ && !closed_);
    102   if (InvalidStream(index))
    103     return net::ERR_INVALID_ARGUMENT;
    104 
    105   DCHECK(offset >= 0 && buf_len >= 0);
    106   Stream& stream = streams_[index];
    107   size_t new_size = static_cast<size_t>(offset + buf_len);
    108   if (new_size) {
    109     // TODO(agayev): Currently, only append and overwrite is supported.  Add
    110     // support for arbitrary writes.
    111     DCHECK(!offset || offset == stream.size);
    112     if (stream.write_buffer.size() < new_size)
    113       stream.write_buffer.resize(new_size);
    114     memcpy(&streams_[index].write_buffer[offset], buf->data(), buf_len);
    115   }
    116   stream.size = new_size;
    117   return buf_len;
    118 }
    119 
    120 void LogStoreEntry::Delete() {
    121   DCHECK(init_ && !closed_);
    122   deleted_ = true;
    123 }
    124 
    125 bool LogStoreEntry::IsNew() const {
    126   return id_ == -1;
    127 }
    128 
    129 bool LogStoreEntry::InvalidStream(int stream_index) const {
    130   return stream_index < 0 || stream_index >= kFlashLogStoreEntryNumStreams;
    131 }
    132 
    133 int32 LogStoreEntry::Size() const {
    134   DCHECK(init_);
    135   int32 size = kFlashLogStoreEntryHeaderSize;
    136   for (int i = 0; i < kFlashLogStoreEntryNumStreams; ++i)
    137     size += streams_[i].size;
    138   DCHECK(size > 0 && size <= kFlashSegmentFreeSpace);
    139   return size;
    140 }
    141 
    142 bool LogStoreEntry::Save() {
    143   DCHECK(init_ && !closed_ && !deleted_ && IsNew());
    144   int32 stream_sizes[kFlashLogStoreEntryNumStreams];
    145   COMPILE_ASSERT(sizeof(stream_sizes) == kFlashLogStoreEntryHeaderSize,
    146                  invalid_log_store_entry_header_size);
    147 
    148   for (int i = 0; i < kFlashLogStoreEntryNumStreams; ++i)
    149     stream_sizes[i] = streams_[i].size;
    150 
    151   if (!store_->CreateEntry(Size(), &id_))
    152     return false;
    153   if (!store_->WriteData(stream_sizes, kFlashLogStoreEntryHeaderSize))
    154     return false;
    155   for (int i = 0; i < kFlashLogStoreEntryNumStreams; ++i) {
    156     if (streams_[i].size > 0 &&
    157         !store_->WriteData(&streams_[i].write_buffer[0], streams_[i].size)) {
    158       return false;
    159     }
    160   }
    161   store_->CloseEntry(id_);
    162   return true;
    163 }
    164 
    165 LogStoreEntry::Stream::Stream() : offset(0), size(0) {
    166 }
    167 
    168 LogStoreEntry::Stream::~Stream() {
    169 }
    170 
    171 }  // namespace disk_cache
    172