Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(102)

Side by Side Diff: content/browser/indexed_db/indexed_db_callbacks.cc

Issue 18023022: Blob support for IDB [Chromium] (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge fixes [builds, untested] Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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(&params->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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698