- add sources.
[platform/framework/web/crosswalk.git] / src / net / disk_cache / flash / log_store_entry.cc
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