OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/indexed_db/indexed_db_callbacks.h" | 5 #include "content/browser/indexed_db/indexed_db_callbacks.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
| 9 #include "base/strings/utf_string_conversions.h" |
| 10 #include "base/time/time.h" |
| 11 #include "content/browser/child_process_security_policy_impl.h" |
| 12 #include "content/browser/fileapi/fileapi_message_filter.h" |
| 13 #include "content/browser/indexed_db/indexed_db_blob_info.h" |
9 #include "content/browser/indexed_db/indexed_db_connection.h" | 14 #include "content/browser/indexed_db/indexed_db_connection.h" |
| 15 #include "content/browser/indexed_db/indexed_db_context_impl.h" |
10 #include "content/browser/indexed_db/indexed_db_cursor.h" | 16 #include "content/browser/indexed_db/indexed_db_cursor.h" |
11 #include "content/browser/indexed_db/indexed_db_database_callbacks.h" | 17 #include "content/browser/indexed_db/indexed_db_database_callbacks.h" |
12 #include "content/browser/indexed_db/indexed_db_database_error.h" | 18 #include "content/browser/indexed_db/indexed_db_database_error.h" |
13 #include "content/browser/indexed_db/indexed_db_metadata.h" | 19 #include "content/browser/indexed_db/indexed_db_metadata.h" |
| 20 #include "content/browser/indexed_db/indexed_db_value.h" |
14 #include "content/common/indexed_db/indexed_db_messages.h" | 21 #include "content/common/indexed_db/indexed_db_messages.h" |
15 #include "webkit/browser/quota/quota_manager.h" | 22 #include "webkit/browser/quota/quota_manager.h" |
| 23 #include "webkit/common/blob/blob_data.h" |
| 24 #include "webkit/common/blob/shareable_file_reference.cc" |
16 | 25 |
17 using WebKit::WebIDBCallbacks; | 26 using WebKit::WebIDBCallbacks; |
| 27 using webkit_blob::ShareableFileReference; |
18 | 28 |
19 namespace content { | 29 namespace content { |
20 | 30 |
21 namespace { | 31 namespace { |
22 const int32 kNoCursor = -1; | 32 const int32 kNoCursor = -1; |
23 const int32 kNoDatabase = -1; | 33 const int32 kNoDatabase = -1; |
24 const int32 kNoDatabaseCallbacks = -1; | 34 const int32 kNoDatabaseCallbacks = -1; |
25 const int64 kNoTransaction = -1; | 35 const int64 kNoTransaction = -1; |
26 } | 36 } |
27 | 37 |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 | 161 |
152 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIDBDatabase( | 162 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIDBDatabase( |
153 ipc_thread_id_, | 163 ipc_thread_id_, |
154 ipc_callbacks_id_, | 164 ipc_callbacks_id_, |
155 ipc_database_callbacks_id_, | 165 ipc_database_callbacks_id_, |
156 ipc_object_id, | 166 ipc_object_id, |
157 IndexedDBDispatcherHost::ConvertMetadata(metadata))); | 167 IndexedDBDispatcherHost::ConvertMetadata(metadata))); |
158 dispatcher_host_ = NULL; | 168 dispatcher_host_ = NULL; |
159 } | 169 } |
160 | 170 |
| 171 // Version 4 UUIDs have the form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx |
| 172 // TODO: Remove this. |
| 173 static std::string MakeFakeGuid() { |
| 174 static int32 counter = 0; |
| 175 return base::StringPrintf("00000000-0000-4000-8000-0000%08x", counter++); |
| 176 } |
| 177 |
| 178 // TODO: Remove this when Michael gives us a better way to do it. |
| 179 static GURL CreateBlob( |
| 180 const IndexedDBBlobInfo& blob_info, |
| 181 FileAPIMessageFilter* file_api_message_filter, |
| 182 base::TaskRunner* task_runner) { |
| 183 scoped_refptr<ShareableFileReference> shareable_file = |
| 184 ShareableFileReference::Get(blob_info.file_path()); |
| 185 if (!shareable_file.get()) { |
| 186 shareable_file = ShareableFileReference::GetOrCreate( |
| 187 blob_info.file_path(), |
| 188 ShareableFileReference::DONT_DELETE_ON_FINAL_RELEASE, |
| 189 task_runner); |
| 190 shareable_file->AddFinalReleaseCallback(blob_info.release_callback()); |
| 191 } |
| 192 |
| 193 std::string blob_uuid(MakeFakeGuid()); |
| 194 GURL blob_url("blob:blobinternal%a///" + MakeFakeGuid()); |
| 195 webkit_blob::BlobData::Item item; |
| 196 item.SetToFilePath(blob_info.file_path()); |
| 197 |
| 198 // It would be much nicer not to go through the FileAPIMessageFilter here, but |
| 199 // if we go around it, it doesn't know about the blob we create, and can't |
| 200 // free it later when the renderer exits. |
| 201 file_api_message_filter->OnStartBuildingBlob(blob_uuid); |
| 202 file_api_message_filter->OnAppendBlobDataItemToBlob(blob_uuid, item); |
| 203 file_api_message_filter->OnFinishBuildingBlob(blob_uuid, |
| 204 base::UTF16ToUTF8(blob_info.type())); |
| 205 file_api_message_filter->OnDeprecatedRegisterBlobURL(blob_url, blob_uuid); |
| 206 // We've just added an extra refcount for blob_uuid that will never be cleaned |
| 207 // up. We should remove it as soon as the blob gets cloned by the renderer, |
| 208 // but we have no way of knowing when that's happened. So for now I put in |
| 209 // this huge HACK to do a delayed decrement after what should be a safe delay |
| 210 // in most cases. |
| 211 if (!BrowserThread::PostDelayedTask(BrowserThread::IO, FROM_HERE, |
| 212 base::Bind(&FileAPIMessageFilter::OnDeprecatedRevokeBlobURL, |
| 213 file_api_message_filter, blob_url), base::TimeDelta::FromSeconds(10))) { |
| 214 fprintf(stderr, "ERICU: We're going to leak a blob.\n"); |
| 215 } |
| 216 return blob_url; |
| 217 } |
| 218 |
| 219 static void CreateAllBlobs( |
| 220 const std::vector<IndexedDBBlobInfo>& blob_info, |
| 221 std::vector<IndexedDBMsg_BlobOrFileInfo>* blob_or_file_info, |
| 222 FileAPIMessageFilter* file_api_message_filter, |
| 223 base::TaskRunner* task_runner) { |
| 224 size_t i; |
| 225 for (i = 0; i < blob_info.size(); ++i) { |
| 226 (*blob_or_file_info)[i].url = |
| 227 CreateBlob(blob_info[i], file_api_message_filter, task_runner); |
| 228 } |
| 229 } |
| 230 |
| 231 static void BlobLookupForIDBCursor( |
| 232 IndexedDBMsg_CallbacksSuccessIDBCursor_Params* params, |
| 233 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host, |
| 234 const std::vector<IndexedDBBlobInfo>& blob_info, |
| 235 std::vector<IndexedDBMsg_BlobOrFileInfo>* blob_or_file_info) { |
| 236 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 237 CreateAllBlobs(blob_info, blob_or_file_info, |
| 238 dispatcher_host->file_api_message_filter(), |
| 239 dispatcher_host->Context()->TaskRunner()); |
| 240 dispatcher_host->Send( |
| 241 new IndexedDBMsg_CallbacksSuccessIDBCursor(*params)); |
| 242 } |
| 243 |
| 244 static void BlobLookupForCursorContinue( |
| 245 IndexedDBMsg_CallbacksSuccessCursorContinue_Params* params, |
| 246 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host, |
| 247 const std::vector<IndexedDBBlobInfo>& blob_info, |
| 248 std::vector<IndexedDBMsg_BlobOrFileInfo>* blob_or_file_info) { |
| 249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 250 CreateAllBlobs(blob_info, blob_or_file_info, |
| 251 dispatcher_host->file_api_message_filter(), |
| 252 dispatcher_host->Context()->TaskRunner()); |
| 253 dispatcher_host->Send( |
| 254 new IndexedDBMsg_CallbacksSuccessCursorContinue(*params)); |
| 255 } |
| 256 |
| 257 static void BlobLookupForValueWithKey( |
| 258 IndexedDBMsg_CallbacksSuccessValueWithKey_Params* params, |
| 259 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host, |
| 260 const std::vector<IndexedDBBlobInfo>& blob_info, |
| 261 std::vector<IndexedDBMsg_BlobOrFileInfo>* blob_or_file_info) { |
| 262 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 263 CreateAllBlobs(blob_info, blob_or_file_info, |
| 264 dispatcher_host->file_api_message_filter(), |
| 265 dispatcher_host->Context()->TaskRunner()); |
| 266 dispatcher_host->Send( |
| 267 new IndexedDBMsg_CallbacksSuccessValueWithKey(*params)); |
| 268 } |
| 269 |
| 270 static void BlobLookupForValue( |
| 271 IndexedDBMsg_CallbacksSuccessValue_Params* params, |
| 272 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host, |
| 273 const std::vector<IndexedDBBlobInfo>& blob_info, |
| 274 std::vector<IndexedDBMsg_BlobOrFileInfo>* blob_or_file_info) { |
| 275 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 276 CreateAllBlobs(blob_info, blob_or_file_info, |
| 277 dispatcher_host->file_api_message_filter(), |
| 278 dispatcher_host->Context()->TaskRunner()); |
| 279 dispatcher_host->Send(new IndexedDBMsg_CallbacksSuccessValue(*params)); |
| 280 } |
| 281 |
| 282 static void BlobLookupForCursorPrefetch( |
| 283 IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params* params, |
| 284 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host, |
| 285 const std::vector<IndexedDBValue>& values, |
| 286 std::vector<std::vector<IndexedDBMsg_BlobOrFileInfo> >* |
| 287 blob_or_file_infos) { |
| 288 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 289 DCHECK(values.size() == blob_or_file_infos->size()); |
| 290 |
| 291 std::vector<IndexedDBValue>::const_iterator value_iter; |
| 292 std::vector<std::vector<IndexedDBMsg_BlobOrFileInfo> >::iterator blob_iter; |
| 293 for (value_iter = values.begin(), blob_iter = blob_or_file_infos->begin(); |
| 294 value_iter != values.end(); ++value_iter, ++blob_iter) { |
| 295 CreateAllBlobs(value_iter->blob_info, &*blob_iter, |
| 296 dispatcher_host->file_api_message_filter(), |
| 297 dispatcher_host->Context()->TaskRunner()); |
| 298 } |
| 299 dispatcher_host->Send( |
| 300 new IndexedDBMsg_CallbacksSuccessCursorPrefetch(*params)); |
| 301 } |
| 302 |
| 303 static void FillInBlobData( |
| 304 const std::vector<IndexedDBBlobInfo>& blob_info, |
| 305 std::vector<IndexedDBMsg_BlobOrFileInfo>* blob_or_file_info) { |
| 306 for (std::vector<IndexedDBBlobInfo>::const_iterator iter = blob_info.begin(); |
| 307 iter != blob_info.end(); ++iter) { |
| 308 if (iter->is_file()) { |
| 309 IndexedDBMsg_BlobOrFileInfo info; |
| 310 info.is_file = true; |
| 311 info.mime_type = iter->type(); |
| 312 info.file_name = iter->file_name(); |
| 313 info.file_path = iter->file_path().AsUTF16Unsafe(); |
| 314 DCHECK_NE(-1, iter->size()); |
| 315 info.size = iter->size(); |
| 316 info.last_modified = iter->last_modified().ToDoubleT(); |
| 317 blob_or_file_info->push_back(info); |
| 318 } else { |
| 319 IndexedDBMsg_BlobOrFileInfo info; |
| 320 info.mime_type = iter->type(); |
| 321 info.size = iter->size(); |
| 322 blob_or_file_info->push_back(info); |
| 323 } |
| 324 } |
| 325 } |
| 326 |
| 327 void IndexedDBCallbacks::RegisterBlobsAndSend( |
| 328 const std::vector<IndexedDBBlobInfo>& blob_info, |
| 329 const base::Closure& callback) { |
| 330 std::vector<IndexedDBBlobInfo>::const_iterator iter; |
| 331 for (iter = blob_info.begin(); iter != blob_info.end(); ++iter) { |
| 332 iter->mark_used_callback().Run(); |
| 333 } |
| 334 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 335 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, callback); |
| 336 } |
| 337 |
161 void IndexedDBCallbacks::OnSuccess(scoped_refptr<IndexedDBCursor> cursor, | 338 void IndexedDBCallbacks::OnSuccess(scoped_refptr<IndexedDBCursor> cursor, |
162 const IndexedDBKey& key, | 339 const IndexedDBKey& key, |
163 const IndexedDBKey& primary_key, | 340 const IndexedDBKey& primary_key, |
164 std::string* value) { | 341 IndexedDBValue* value) { |
165 DCHECK(dispatcher_host_.get()); | 342 DCHECK(dispatcher_host_.get()); |
166 | 343 |
167 DCHECK_EQ(kNoCursor, ipc_cursor_id_); | 344 DCHECK_EQ(kNoCursor, ipc_cursor_id_); |
168 DCHECK_EQ(kNoTransaction, host_transaction_id_); | 345 DCHECK_EQ(kNoTransaction, host_transaction_id_); |
169 DCHECK_EQ(kNoDatabase, ipc_database_id_); | 346 DCHECK_EQ(kNoDatabase, ipc_database_id_); |
170 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_); | 347 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_); |
171 | 348 |
172 int32 ipc_object_id = dispatcher_host_->Add(cursor.get()); | 349 int32 ipc_object_id = dispatcher_host_->Add(cursor.get()); |
173 IndexedDBMsg_CallbacksSuccessIDBCursor_Params params; | 350 scoped_ptr<IndexedDBMsg_CallbacksSuccessIDBCursor_Params> params( |
174 params.ipc_thread_id = ipc_thread_id_; | 351 new IndexedDBMsg_CallbacksSuccessIDBCursor_Params()); |
175 params.ipc_callbacks_id = ipc_callbacks_id_; | 352 params->ipc_thread_id = ipc_thread_id_; |
176 params.ipc_cursor_id = ipc_object_id; | 353 params->ipc_callbacks_id = ipc_callbacks_id_; |
177 params.key = key; | 354 params->ipc_cursor_id = ipc_object_id; |
178 params.primary_key = primary_key; | 355 params->key = key; |
| 356 params->primary_key = primary_key; |
179 if (value && !value->empty()) | 357 if (value && !value->empty()) |
180 std::swap(params.value, *value); | 358 std::swap(params->value, value->bits); |
181 // TODO(alecflett): Avoid a copy here: the whole params object is | 359 // TODO(alecflett): Avoid a copy here: the whole params object is |
182 // being copied into the message. | 360 // being copied into the message. |
183 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIDBCursor(params)); | 361 if (value->blob_info.empty()) { |
184 | 362 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIDBCursor(*params)); |
| 363 } else { |
| 364 IndexedDBMsg_CallbacksSuccessIDBCursor_Params* p = params.get(); |
| 365 FillInBlobData(value->blob_info, &p->blob_or_file_info); |
| 366 RegisterBlobsAndSend( |
| 367 value->blob_info, |
| 368 base::Bind(BlobLookupForIDBCursor, base::Owned(params.release()), |
| 369 dispatcher_host_, value->blob_info, |
| 370 base::Unretained(&p->blob_or_file_info))); |
| 371 } |
185 dispatcher_host_ = NULL; | 372 dispatcher_host_ = NULL; |
186 } | 373 } |
187 | 374 |
188 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& key, | 375 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& key, |
189 const IndexedDBKey& primary_key, | 376 const IndexedDBKey& primary_key, |
190 std::string* value) { | 377 IndexedDBValue* value) { |
191 DCHECK(dispatcher_host_.get()); | 378 DCHECK(dispatcher_host_.get()); |
192 | 379 |
193 DCHECK_NE(kNoCursor, ipc_cursor_id_); | 380 DCHECK_NE(kNoCursor, ipc_cursor_id_); |
194 DCHECK_EQ(kNoTransaction, host_transaction_id_); | 381 DCHECK_EQ(kNoTransaction, host_transaction_id_); |
195 DCHECK_EQ(kNoDatabase, ipc_database_id_); | 382 DCHECK_EQ(kNoDatabase, ipc_database_id_); |
196 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_); | 383 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_); |
197 | 384 |
198 IndexedDBCursor* idb_cursor = | 385 IndexedDBCursor* idb_cursor = |
199 dispatcher_host_->GetCursorFromId(ipc_cursor_id_); | 386 dispatcher_host_->GetCursorFromId(ipc_cursor_id_); |
200 | 387 |
201 DCHECK(idb_cursor); | 388 DCHECK(idb_cursor); |
202 if (!idb_cursor) | 389 if (!idb_cursor) |
203 return; | 390 return; |
204 IndexedDBMsg_CallbacksSuccessCursorContinue_Params params; | 391 |
205 params.ipc_thread_id = ipc_thread_id_; | 392 scoped_ptr<IndexedDBMsg_CallbacksSuccessCursorContinue_Params> params( |
206 params.ipc_callbacks_id = ipc_callbacks_id_; | 393 new IndexedDBMsg_CallbacksSuccessCursorContinue_Params()); |
207 params.ipc_cursor_id = ipc_cursor_id_; | 394 params->ipc_thread_id = ipc_thread_id_; |
208 params.key = key; | 395 params->ipc_callbacks_id = ipc_callbacks_id_; |
209 params.primary_key = primary_key; | 396 params->ipc_cursor_id = ipc_cursor_id_; |
| 397 params->key = key; |
| 398 params->primary_key = primary_key; |
210 if (value && !value->empty()) | 399 if (value && !value->empty()) |
211 std::swap(params.value, *value); | 400 std::swap(params->value, value->bits); |
212 // TODO(alecflett): Avoid a copy here: the whole params object is | 401 // TODO(alecflett): Avoid a copy here: the whole params object is |
213 // being copied into the message. | 402 // being copied into the message. |
214 dispatcher_host_->Send( | 403 if (value->blob_info.empty()) { |
215 new IndexedDBMsg_CallbacksSuccessCursorContinue(params)); | 404 dispatcher_host_->Send( |
| 405 new IndexedDBMsg_CallbacksSuccessCursorContinue(*params)); |
| 406 } else { |
| 407 IndexedDBMsg_CallbacksSuccessCursorContinue_Params* p = params.get(); |
| 408 FillInBlobData(value->blob_info, &p->blob_or_file_info); |
| 409 RegisterBlobsAndSend( |
| 410 value->blob_info, |
| 411 base::Bind(BlobLookupForCursorContinue, base::Owned(params.release()), |
| 412 dispatcher_host_, value->blob_info, |
| 413 base::Unretained(&p->blob_or_file_info))); |
| 414 } |
216 dispatcher_host_ = NULL; | 415 dispatcher_host_ = NULL; |
217 } | 416 } |
218 | 417 |
219 void IndexedDBCallbacks::OnSuccessWithPrefetch( | 418 void IndexedDBCallbacks::OnSuccessWithPrefetch( |
220 const std::vector<IndexedDBKey>& keys, | 419 const std::vector<IndexedDBKey>& keys, |
221 const std::vector<IndexedDBKey>& primary_keys, | 420 const std::vector<IndexedDBKey>& primary_keys, |
222 const std::vector<std::string>& values) { | 421 std::vector<IndexedDBValue>& values) { |
223 DCHECK_EQ(keys.size(), primary_keys.size()); | 422 DCHECK_EQ(keys.size(), primary_keys.size()); |
224 DCHECK_EQ(keys.size(), values.size()); | 423 DCHECK_EQ(keys.size(), values.size()); |
225 | 424 |
226 DCHECK(dispatcher_host_.get()); | 425 DCHECK(dispatcher_host_.get()); |
227 | 426 |
228 DCHECK_NE(kNoCursor, ipc_cursor_id_); | 427 DCHECK_NE(kNoCursor, ipc_cursor_id_); |
229 DCHECK_EQ(kNoTransaction, host_transaction_id_); | 428 DCHECK_EQ(kNoTransaction, host_transaction_id_); |
230 DCHECK_EQ(kNoDatabase, ipc_database_id_); | 429 DCHECK_EQ(kNoDatabase, ipc_database_id_); |
231 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_); | 430 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_); |
232 | 431 |
233 std::vector<IndexedDBKey> msgKeys; | 432 std::vector<IndexedDBKey> msgKeys; |
234 std::vector<IndexedDBKey> msgPrimaryKeys; | 433 std::vector<IndexedDBKey> msgPrimaryKeys; |
235 | 434 |
236 for (size_t i = 0; i < keys.size(); ++i) { | 435 for (size_t i = 0; i < keys.size(); ++i) { |
237 msgKeys.push_back(keys[i]); | 436 msgKeys.push_back(keys[i]); |
238 msgPrimaryKeys.push_back(primary_keys[i]); | 437 msgPrimaryKeys.push_back(primary_keys[i]); |
239 } | 438 } |
240 | 439 |
241 IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params params; | 440 scoped_ptr<IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params> params( |
242 params.ipc_thread_id = ipc_thread_id_; | 441 new IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params()); |
243 params.ipc_callbacks_id = ipc_callbacks_id_; | 442 params->ipc_thread_id = ipc_thread_id_; |
244 params.ipc_cursor_id = ipc_cursor_id_; | 443 params->ipc_callbacks_id = ipc_callbacks_id_; |
245 params.keys = msgKeys; | 444 params->ipc_cursor_id = ipc_cursor_id_; |
246 params.primary_keys = msgPrimaryKeys; | 445 params->keys = msgKeys; |
247 params.values = values; | 446 params->primary_keys = msgPrimaryKeys; |
248 dispatcher_host_->Send( | 447 std::vector<std::string> values_bits(values.size()); |
249 new IndexedDBMsg_CallbacksSuccessCursorPrefetch(params)); | 448 std::vector<std::vector<IndexedDBMsg_BlobOrFileInfo> > |
| 449 values_blob_infos(values.size()); |
| 450 std::vector<IndexedDBValue>::iterator iter = values.begin(); |
| 451 |
| 452 bool found_blob_info = false; |
| 453 for (size_t i = 0; iter != values.end(); ++iter, ++i) { |
| 454 values_bits[i].swap(iter->bits); |
| 455 if (iter->blob_info.size()) { |
| 456 found_blob_info = true; |
| 457 FillInBlobData(iter->blob_info, &values_blob_infos[i]); |
| 458 std::vector<IndexedDBBlobInfo>::const_iterator blob_iter; |
| 459 for (blob_iter = iter->blob_info.begin(); |
| 460 blob_iter != iter->blob_info.end(); ++blob_iter) { |
| 461 blob_iter->mark_used_callback(); |
| 462 } |
| 463 } |
| 464 } |
| 465 |
| 466 params->values.swap(values_bits); |
| 467 if (found_blob_info) { |
| 468 params->blob_or_file_infos.swap(values_blob_infos); |
| 469 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 470 base::Bind(BlobLookupForCursorPrefetch, base::Owned(params.release()), |
| 471 dispatcher_host_, values, |
| 472 base::Unretained(¶ms->blob_or_file_infos))); |
| 473 } else { |
| 474 dispatcher_host_->Send( |
| 475 new IndexedDBMsg_CallbacksSuccessCursorPrefetch(*params.get())); |
| 476 } |
250 dispatcher_host_ = NULL; | 477 dispatcher_host_ = NULL; |
251 } | 478 } |
252 | 479 |
253 void IndexedDBCallbacks::OnSuccess(std::string* value, | 480 void IndexedDBCallbacks::OnSuccess(IndexedDBValue* value, |
254 const IndexedDBKey& key, | 481 const IndexedDBKey& key, |
255 const IndexedDBKeyPath& key_path) { | 482 const IndexedDBKeyPath& key_path) { |
256 DCHECK(dispatcher_host_.get()); | 483 DCHECK(dispatcher_host_.get()); |
257 | 484 |
258 DCHECK_EQ(kNoCursor, ipc_cursor_id_); | 485 DCHECK_EQ(kNoCursor, ipc_cursor_id_); |
259 DCHECK_EQ(kNoTransaction, host_transaction_id_); | 486 DCHECK_EQ(kNoTransaction, host_transaction_id_); |
260 DCHECK_EQ(kNoDatabase, ipc_database_id_); | 487 DCHECK_EQ(kNoDatabase, ipc_database_id_); |
261 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_); | 488 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_); |
262 | 489 |
263 std::string value_copy; | 490 scoped_ptr<IndexedDBMsg_CallbacksSuccessValueWithKey_Params> params(new |
| 491 IndexedDBMsg_CallbacksSuccessValueWithKey_Params()); |
| 492 params->ipc_thread_id = ipc_thread_id_; |
| 493 params->ipc_callbacks_id = ipc_callbacks_id_; |
| 494 params->primary_key = key; |
| 495 params->key_path = key_path; |
264 if (value && !value->empty()) | 496 if (value && !value->empty()) |
265 std::swap(value_copy, *value); | 497 std::swap(params->value, value->bits); |
266 | 498 if (value->blob_info.empty()) { |
267 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessValueWithKey( | 499 dispatcher_host_->Send( |
268 ipc_thread_id_, | 500 new IndexedDBMsg_CallbacksSuccessValueWithKey(*params)); |
269 ipc_callbacks_id_, | 501 } else { |
270 // TODO(alecflett): Avoid a copy here. | 502 IndexedDBMsg_CallbacksSuccessValueWithKey_Params* p = params.get(); |
271 value_copy, | 503 FillInBlobData(value->blob_info, &p->blob_or_file_info); |
272 key, | 504 RegisterBlobsAndSend( |
273 key_path)); | 505 value->blob_info, |
| 506 base::Bind(BlobLookupForValueWithKey, base::Owned(params.release()), |
| 507 dispatcher_host_, value->blob_info, |
| 508 base::Unretained(&p->blob_or_file_info))); |
| 509 } |
274 dispatcher_host_ = NULL; | 510 dispatcher_host_ = NULL; |
275 } | 511 } |
276 | 512 |
277 void IndexedDBCallbacks::OnSuccess(std::string* value) { | 513 void IndexedDBCallbacks::OnSuccess(IndexedDBValue* value) { |
278 DCHECK(dispatcher_host_.get()); | 514 DCHECK(dispatcher_host_.get()); |
279 | |
280 DCHECK(kNoCursor == ipc_cursor_id_ || value == NULL); | 515 DCHECK(kNoCursor == ipc_cursor_id_ || value == NULL); |
281 DCHECK_EQ(kNoTransaction, host_transaction_id_); | 516 DCHECK_EQ(kNoTransaction, host_transaction_id_); |
282 DCHECK_EQ(kNoDatabase, ipc_database_id_); | 517 DCHECK_EQ(kNoDatabase, ipc_database_id_); |
283 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_); | 518 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_); |
284 | 519 |
285 std::string value_copy; | 520 scoped_ptr<IndexedDBMsg_CallbacksSuccessValue_Params> params(new |
| 521 IndexedDBMsg_CallbacksSuccessValue_Params()); |
| 522 params->ipc_thread_id = ipc_thread_id_; |
| 523 params->ipc_callbacks_id = ipc_callbacks_id_; |
286 if (value && !value->empty()) | 524 if (value && !value->empty()) |
287 std::swap(value_copy, *value); | 525 std::swap(params->value, value->bits); |
288 | 526 if (value->blob_info.empty()) { |
289 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessValue( | 527 dispatcher_host_->Send( |
290 ipc_thread_id_, | 528 new IndexedDBMsg_CallbacksSuccessValue(*params)); |
291 ipc_callbacks_id_, | 529 } else { |
292 // TODO(alecflett): avoid a copy here. | 530 IndexedDBMsg_CallbacksSuccessValue_Params* p = params.get(); |
293 value_copy)); | 531 FillInBlobData(value->blob_info, &p->blob_or_file_info); |
| 532 RegisterBlobsAndSend( |
| 533 value->blob_info, |
| 534 base::Bind(BlobLookupForValue, base::Owned(params.release()), |
| 535 dispatcher_host_, value->blob_info, |
| 536 base::Unretained(&p->blob_or_file_info))); |
| 537 } |
294 dispatcher_host_ = NULL; | 538 dispatcher_host_ = NULL; |
295 } | 539 } |
296 | 540 |
297 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& value) { | 541 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& value) { |
298 DCHECK(dispatcher_host_.get()); | 542 DCHECK(dispatcher_host_.get()); |
299 | 543 |
300 DCHECK_EQ(kNoCursor, ipc_cursor_id_); | 544 DCHECK_EQ(kNoCursor, ipc_cursor_id_); |
301 DCHECK_EQ(kNoTransaction, host_transaction_id_); | 545 DCHECK_EQ(kNoTransaction, host_transaction_id_); |
302 DCHECK_EQ(kNoDatabase, ipc_database_id_); | 546 DCHECK_EQ(kNoDatabase, ipc_database_id_); |
303 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_); | 547 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_); |
(...skipping 23 matching lines...) Expand all Loading... |
327 DCHECK_EQ(kNoTransaction, host_transaction_id_); | 571 DCHECK_EQ(kNoTransaction, host_transaction_id_); |
328 DCHECK_EQ(kNoDatabase, ipc_database_id_); | 572 DCHECK_EQ(kNoDatabase, ipc_database_id_); |
329 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_); | 573 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_); |
330 | 574 |
331 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessUndefined( | 575 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessUndefined( |
332 ipc_thread_id_, ipc_callbacks_id_)); | 576 ipc_thread_id_, ipc_callbacks_id_)); |
333 dispatcher_host_ = NULL; | 577 dispatcher_host_ = NULL; |
334 } | 578 } |
335 | 579 |
336 } // namespace content | 580 } // namespace content |
OLD | NEW |