| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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_leveldb_coding.h" | 5 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h" |
| 6 | 6 |
| 7 #include <iterator> | 7 #include <iterator> |
| 8 #include <limits> | 8 #include <limits> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 | 250 |
| 251 do { | 251 do { |
| 252 unsigned char c = n & 0x7f; | 252 unsigned char c = n & 0x7f; |
| 253 n >>= 7; | 253 n >>= 7; |
| 254 if (n) | 254 if (n) |
| 255 c |= 0x80; | 255 c |= 0x80; |
| 256 into->push_back(c); | 256 into->push_back(c); |
| 257 } while (n); | 257 } while (n); |
| 258 } | 258 } |
| 259 | 259 |
| 260 void EncodeString(const string16& value, std::string* into) { | 260 void EncodeString(const base::string16& value, std::string* into) { |
| 261 if (value.empty()) | 261 if (value.empty()) |
| 262 return; | 262 return; |
| 263 // Backing store is UTF-16BE, convert from host endianness. | 263 // Backing store is UTF-16BE, convert from host endianness. |
| 264 size_t length = value.length(); | 264 size_t length = value.length(); |
| 265 size_t current = into->size(); | 265 size_t current = into->size(); |
| 266 into->resize(into->size() + length * sizeof(char16)); | 266 into->resize(into->size() + length * sizeof(char16)); |
| 267 | 267 |
| 268 const char16* src = value.c_str(); | 268 const char16* src = value.c_str(); |
| 269 char16* dst = reinterpret_cast<char16*>(&*into->begin() + current); | 269 char16* dst = reinterpret_cast<char16*>(&*into->begin() + current); |
| 270 for (unsigned i = 0; i < length; ++i) | 270 for (unsigned i = 0; i < length; ++i) |
| 271 *dst++ = htons(*src++); | 271 *dst++ = htons(*src++); |
| 272 } | 272 } |
| 273 | 273 |
| 274 void EncodeBinary(const std::string& value, std::string* into) { | 274 void EncodeBinary(const std::string& value, std::string* into) { |
| 275 EncodeVarInt(value.length(), into); | 275 EncodeVarInt(value.length(), into); |
| 276 into->append(value.begin(), value.end()); | 276 into->append(value.begin(), value.end()); |
| 277 DCHECK(into->size() >= value.size()); | 277 DCHECK(into->size() >= value.size()); |
| 278 } | 278 } |
| 279 | 279 |
| 280 void EncodeStringWithLength(const string16& value, std::string* into) { | 280 void EncodeStringWithLength(const base::string16& value, std::string* into) { |
| 281 EncodeVarInt(value.length(), into); | 281 EncodeVarInt(value.length(), into); |
| 282 EncodeString(value, into); | 282 EncodeString(value, into); |
| 283 } | 283 } |
| 284 | 284 |
| 285 void EncodeDouble(double value, std::string* into) { | 285 void EncodeDouble(double value, std::string* into) { |
| 286 // This always has host endianness. | 286 // This always has host endianness. |
| 287 const char* p = reinterpret_cast<char*>(&value); | 287 const char* p = reinterpret_cast<char*>(&value); |
| 288 into->insert(into->end(), p, p + sizeof(value)); | 288 into->insert(into->end(), p, p + sizeof(value)); |
| 289 } | 289 } |
| 290 | 290 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 EncodeByte(kIndexedDBKeyPathTypeCodedByte2, into); | 348 EncodeByte(kIndexedDBKeyPathTypeCodedByte2, into); |
| 349 EncodeByte(static_cast<char>(value.type()), into); | 349 EncodeByte(static_cast<char>(value.type()), into); |
| 350 switch (value.type()) { | 350 switch (value.type()) { |
| 351 case WebIDBKeyPathTypeNull: | 351 case WebIDBKeyPathTypeNull: |
| 352 break; | 352 break; |
| 353 case WebIDBKeyPathTypeString: { | 353 case WebIDBKeyPathTypeString: { |
| 354 EncodeStringWithLength(value.string(), into); | 354 EncodeStringWithLength(value.string(), into); |
| 355 break; | 355 break; |
| 356 } | 356 } |
| 357 case WebIDBKeyPathTypeArray: { | 357 case WebIDBKeyPathTypeArray: { |
| 358 const std::vector<string16>& array = value.array(); | 358 const std::vector<base::string16>& array = value.array(); |
| 359 size_t count = array.size(); | 359 size_t count = array.size(); |
| 360 EncodeVarInt(count, into); | 360 EncodeVarInt(count, into); |
| 361 for (size_t i = 0; i < count; ++i) { | 361 for (size_t i = 0; i < count; ++i) { |
| 362 EncodeStringWithLength(array[i], into); | 362 EncodeStringWithLength(array[i], into); |
| 363 } | 363 } |
| 364 break; | 364 break; |
| 365 } | 365 } |
| 366 } | 366 } |
| 367 } | 367 } |
| 368 | 368 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 | 414 |
| 415 unsigned char c = *it; | 415 unsigned char c = *it; |
| 416 ret |= static_cast<int64>(c & 0x7f) << shift; | 416 ret |= static_cast<int64>(c & 0x7f) << shift; |
| 417 shift += 7; | 417 shift += 7; |
| 418 } while (*it++ & 0x80); | 418 } while (*it++ & 0x80); |
| 419 *value = ret; | 419 *value = ret; |
| 420 slice->remove_prefix(it - slice->begin()); | 420 slice->remove_prefix(it - slice->begin()); |
| 421 return true; | 421 return true; |
| 422 } | 422 } |
| 423 | 423 |
| 424 bool DecodeString(StringPiece* slice, string16* value) { | 424 bool DecodeString(StringPiece* slice, base::string16* value) { |
| 425 if (slice->empty()) { | 425 if (slice->empty()) { |
| 426 value->clear(); | 426 value->clear(); |
| 427 return true; | 427 return true; |
| 428 } | 428 } |
| 429 | 429 |
| 430 // Backing store is UTF-16BE, convert to host endianness. | 430 // Backing store is UTF-16BE, convert to host endianness. |
| 431 DCHECK(!(slice->size() % sizeof(char16))); | 431 DCHECK(!(slice->size() % sizeof(char16))); |
| 432 size_t length = slice->size() / sizeof(char16); | 432 size_t length = slice->size() / sizeof(char16); |
| 433 string16 decoded; | 433 base::string16 decoded; |
| 434 decoded.reserve(length); | 434 decoded.reserve(length); |
| 435 const char16* encoded = reinterpret_cast<const char16*>(slice->begin()); | 435 const char16* encoded = reinterpret_cast<const char16*>(slice->begin()); |
| 436 for (unsigned i = 0; i < length; ++i) | 436 for (unsigned i = 0; i < length; ++i) |
| 437 decoded.push_back(ntohs(*encoded++)); | 437 decoded.push_back(ntohs(*encoded++)); |
| 438 | 438 |
| 439 *value = decoded; | 439 *value = decoded; |
| 440 slice->remove_prefix(length * sizeof(char16)); | 440 slice->remove_prefix(length * sizeof(char16)); |
| 441 return true; | 441 return true; |
| 442 } | 442 } |
| 443 | 443 |
| 444 bool DecodeStringWithLength(StringPiece* slice, string16* value) { | 444 bool DecodeStringWithLength(StringPiece* slice, base::string16* value) { |
| 445 if (slice->empty()) | 445 if (slice->empty()) |
| 446 return false; | 446 return false; |
| 447 | 447 |
| 448 int64 length = 0; | 448 int64 length = 0; |
| 449 if (!DecodeVarInt(slice, &length) || length < 0) | 449 if (!DecodeVarInt(slice, &length) || length < 0) |
| 450 return false; | 450 return false; |
| 451 size_t bytes = length * sizeof(char16); | 451 size_t bytes = length * sizeof(char16); |
| 452 if (slice->size() < bytes) | 452 if (slice->size() < bytes) |
| 453 return false; | 453 return false; |
| 454 | 454 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 return true; | 503 return true; |
| 504 } | 504 } |
| 505 case kIndexedDBKeyBinaryTypeByte: { | 505 case kIndexedDBKeyBinaryTypeByte: { |
| 506 std::string binary; | 506 std::string binary; |
| 507 if (!DecodeBinary(slice, &binary)) | 507 if (!DecodeBinary(slice, &binary)) |
| 508 return false; | 508 return false; |
| 509 *value = make_scoped_ptr(new IndexedDBKey(binary)); | 509 *value = make_scoped_ptr(new IndexedDBKey(binary)); |
| 510 return true; | 510 return true; |
| 511 } | 511 } |
| 512 case kIndexedDBKeyStringTypeByte: { | 512 case kIndexedDBKeyStringTypeByte: { |
| 513 string16 s; | 513 base::string16 s; |
| 514 if (!DecodeStringWithLength(slice, &s)) | 514 if (!DecodeStringWithLength(slice, &s)) |
| 515 return false; | 515 return false; |
| 516 *value = make_scoped_ptr(new IndexedDBKey(s)); | 516 *value = make_scoped_ptr(new IndexedDBKey(s)); |
| 517 return true; | 517 return true; |
| 518 } | 518 } |
| 519 case kIndexedDBKeyDateTypeByte: { | 519 case kIndexedDBKeyDateTypeByte: { |
| 520 double d; | 520 double d; |
| 521 if (!DecodeDouble(slice, &d)) | 521 if (!DecodeDouble(slice, &d)) |
| 522 return false; | 522 return false; |
| 523 *value = make_scoped_ptr(new IndexedDBKey(d, WebIDBKeyTypeDate)); | 523 *value = make_scoped_ptr(new IndexedDBKey(d, WebIDBKeyTypeDate)); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 544 slice->remove_prefix(sizeof(*value)); | 544 slice->remove_prefix(sizeof(*value)); |
| 545 return true; | 545 return true; |
| 546 } | 546 } |
| 547 | 547 |
| 548 bool DecodeIDBKeyPath(StringPiece* slice, IndexedDBKeyPath* value) { | 548 bool DecodeIDBKeyPath(StringPiece* slice, IndexedDBKeyPath* value) { |
| 549 // May be typed, or may be a raw string. An invalid leading | 549 // May be typed, or may be a raw string. An invalid leading |
| 550 // byte sequence is used to identify typed coding. New records are | 550 // byte sequence is used to identify typed coding. New records are |
| 551 // always written as typed. | 551 // always written as typed. |
| 552 if (slice->size() < 3 || (*slice)[0] != kIndexedDBKeyPathTypeCodedByte1 || | 552 if (slice->size() < 3 || (*slice)[0] != kIndexedDBKeyPathTypeCodedByte1 || |
| 553 (*slice)[1] != kIndexedDBKeyPathTypeCodedByte2) { | 553 (*slice)[1] != kIndexedDBKeyPathTypeCodedByte2) { |
| 554 string16 s; | 554 base::string16 s; |
| 555 if (!DecodeString(slice, &s)) | 555 if (!DecodeString(slice, &s)) |
| 556 return false; | 556 return false; |
| 557 *value = IndexedDBKeyPath(s); | 557 *value = IndexedDBKeyPath(s); |
| 558 return true; | 558 return true; |
| 559 } | 559 } |
| 560 | 560 |
| 561 slice->remove_prefix(2); | 561 slice->remove_prefix(2); |
| 562 DCHECK(!slice->empty()); | 562 DCHECK(!slice->empty()); |
| 563 WebIDBKeyPathType type = static_cast<WebIDBKeyPathType>((*slice)[0]); | 563 WebIDBKeyPathType type = static_cast<WebIDBKeyPathType>((*slice)[0]); |
| 564 slice->remove_prefix(1); | 564 slice->remove_prefix(1); |
| 565 | 565 |
| 566 switch (type) { | 566 switch (type) { |
| 567 case WebIDBKeyPathTypeNull: | 567 case WebIDBKeyPathTypeNull: |
| 568 DCHECK(slice->empty()); | 568 DCHECK(slice->empty()); |
| 569 *value = IndexedDBKeyPath(); | 569 *value = IndexedDBKeyPath(); |
| 570 return true; | 570 return true; |
| 571 case WebIDBKeyPathTypeString: { | 571 case WebIDBKeyPathTypeString: { |
| 572 string16 string; | 572 base::string16 string; |
| 573 if (!DecodeStringWithLength(slice, &string)) | 573 if (!DecodeStringWithLength(slice, &string)) |
| 574 return false; | 574 return false; |
| 575 DCHECK(slice->empty()); | 575 DCHECK(slice->empty()); |
| 576 *value = IndexedDBKeyPath(string); | 576 *value = IndexedDBKeyPath(string); |
| 577 return true; | 577 return true; |
| 578 } | 578 } |
| 579 case WebIDBKeyPathTypeArray: { | 579 case WebIDBKeyPathTypeArray: { |
| 580 std::vector<string16> array; | 580 std::vector<base::string16> array; |
| 581 int64 count; | 581 int64 count; |
| 582 if (!DecodeVarInt(slice, &count)) | 582 if (!DecodeVarInt(slice, &count)) |
| 583 return false; | 583 return false; |
| 584 DCHECK_GE(count, 0); | 584 DCHECK_GE(count, 0); |
| 585 while (count--) { | 585 while (count--) { |
| 586 string16 string; | 586 base::string16 string; |
| 587 if (!DecodeStringWithLength(slice, &string)) | 587 if (!DecodeStringWithLength(slice, &string)) |
| 588 return false; | 588 return false; |
| 589 array.push_back(string); | 589 array.push_back(string); |
| 590 } | 590 } |
| 591 DCHECK(slice->empty()); | 591 DCHECK(slice->empty()); |
| 592 *value = IndexedDBKeyPath(array); | 592 *value = IndexedDBKeyPath(array); |
| 593 return true; | 593 return true; |
| 594 } | 594 } |
| 595 } | 595 } |
| 596 NOTREACHED(); | 596 NOTREACHED(); |
| (...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1317 return false; | 1317 return false; |
| 1318 DCHECK_EQ(type_byte, kDatabaseNameTypeByte); | 1318 DCHECK_EQ(type_byte, kDatabaseNameTypeByte); |
| 1319 if (!DecodeStringWithLength(slice, &result->origin_)) | 1319 if (!DecodeStringWithLength(slice, &result->origin_)) |
| 1320 return false; | 1320 return false; |
| 1321 if (!DecodeStringWithLength(slice, &result->database_name_)) | 1321 if (!DecodeStringWithLength(slice, &result->database_name_)) |
| 1322 return false; | 1322 return false; |
| 1323 return true; | 1323 return true; |
| 1324 } | 1324 } |
| 1325 | 1325 |
| 1326 std::string DatabaseNameKey::Encode(const std::string& origin_identifier, | 1326 std::string DatabaseNameKey::Encode(const std::string& origin_identifier, |
| 1327 const string16& database_name) { | 1327 const base::string16& database_name) { |
| 1328 std::string ret = KeyPrefix::EncodeEmpty(); | 1328 std::string ret = KeyPrefix::EncodeEmpty(); |
| 1329 ret.push_back(kDatabaseNameTypeByte); | 1329 ret.push_back(kDatabaseNameTypeByte); |
| 1330 EncodeStringWithLength(base::ASCIIToUTF16(origin_identifier), &ret); | 1330 EncodeStringWithLength(base::ASCIIToUTF16(origin_identifier), &ret); |
| 1331 EncodeStringWithLength(database_name, &ret); | 1331 EncodeStringWithLength(database_name, &ret); |
| 1332 return ret; | 1332 return ret; |
| 1333 } | 1333 } |
| 1334 | 1334 |
| 1335 std::string DatabaseNameKey::EncodeMinKeyForOrigin( | 1335 std::string DatabaseNameKey::EncodeMinKeyForOrigin( |
| 1336 const std::string& origin_identifier) { | 1336 const std::string& origin_identifier) { |
| 1337 return Encode(origin_identifier, string16()); | 1337 return Encode(origin_identifier, base::string16()); |
| 1338 } | 1338 } |
| 1339 | 1339 |
| 1340 std::string DatabaseNameKey::EncodeStopKeyForOrigin( | 1340 std::string DatabaseNameKey::EncodeStopKeyForOrigin( |
| 1341 const std::string& origin_identifier) { | 1341 const std::string& origin_identifier) { |
| 1342 // just after origin in collation order | 1342 // just after origin in collation order |
| 1343 return EncodeMinKeyForOrigin(origin_identifier + '\x01'); | 1343 return EncodeMinKeyForOrigin(origin_identifier + '\x01'); |
| 1344 } | 1344 } |
| 1345 | 1345 |
| 1346 int DatabaseNameKey::Compare(const DatabaseNameKey& other) { | 1346 int DatabaseNameKey::Compare(const DatabaseNameKey& other) { |
| 1347 if (int x = origin_.compare(other.origin_)) | 1347 if (int x = origin_.compare(other.origin_)) |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1597 DCHECK(!prefix.index_id_); | 1597 DCHECK(!prefix.index_id_); |
| 1598 unsigned char type_byte = 0; | 1598 unsigned char type_byte = 0; |
| 1599 if (!DecodeByte(slice, &type_byte)) | 1599 if (!DecodeByte(slice, &type_byte)) |
| 1600 return false; | 1600 return false; |
| 1601 DCHECK_EQ(type_byte, kObjectStoreNamesTypeByte); | 1601 DCHECK_EQ(type_byte, kObjectStoreNamesTypeByte); |
| 1602 if (!DecodeStringWithLength(slice, &result->object_store_name_)) | 1602 if (!DecodeStringWithLength(slice, &result->object_store_name_)) |
| 1603 return false; | 1603 return false; |
| 1604 return true; | 1604 return true; |
| 1605 } | 1605 } |
| 1606 | 1606 |
| 1607 std::string ObjectStoreNamesKey::Encode(int64 database_id, | 1607 std::string ObjectStoreNamesKey::Encode( |
| 1608 const string16& object_store_name) { | 1608 int64 database_id, |
| 1609 const base::string16& object_store_name) { |
| 1609 KeyPrefix prefix(database_id); | 1610 KeyPrefix prefix(database_id); |
| 1610 std::string ret = prefix.Encode(); | 1611 std::string ret = prefix.Encode(); |
| 1611 ret.push_back(kObjectStoreNamesTypeByte); | 1612 ret.push_back(kObjectStoreNamesTypeByte); |
| 1612 EncodeStringWithLength(object_store_name, &ret); | 1613 EncodeStringWithLength(object_store_name, &ret); |
| 1613 return ret; | 1614 return ret; |
| 1614 } | 1615 } |
| 1615 | 1616 |
| 1616 int ObjectStoreNamesKey::Compare(const ObjectStoreNamesKey& other) { | 1617 int ObjectStoreNamesKey::Compare(const ObjectStoreNamesKey& other) { |
| 1617 return object_store_name_.compare(other.object_store_name_); | 1618 return object_store_name_.compare(other.object_store_name_); |
| 1618 } | 1619 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1634 DCHECK_EQ(type_byte, kIndexNamesKeyTypeByte); | 1635 DCHECK_EQ(type_byte, kIndexNamesKeyTypeByte); |
| 1635 if (!DecodeVarInt(slice, &result->object_store_id_)) | 1636 if (!DecodeVarInt(slice, &result->object_store_id_)) |
| 1636 return false; | 1637 return false; |
| 1637 if (!DecodeStringWithLength(slice, &result->index_name_)) | 1638 if (!DecodeStringWithLength(slice, &result->index_name_)) |
| 1638 return false; | 1639 return false; |
| 1639 return true; | 1640 return true; |
| 1640 } | 1641 } |
| 1641 | 1642 |
| 1642 std::string IndexNamesKey::Encode(int64 database_id, | 1643 std::string IndexNamesKey::Encode(int64 database_id, |
| 1643 int64 object_store_id, | 1644 int64 object_store_id, |
| 1644 const string16& index_name) { | 1645 const base::string16& index_name) { |
| 1645 KeyPrefix prefix(database_id); | 1646 KeyPrefix prefix(database_id); |
| 1646 std::string ret = prefix.Encode(); | 1647 std::string ret = prefix.Encode(); |
| 1647 ret.push_back(kIndexNamesKeyTypeByte); | 1648 ret.push_back(kIndexNamesKeyTypeByte); |
| 1648 EncodeVarInt(object_store_id, &ret); | 1649 EncodeVarInt(object_store_id, &ret); |
| 1649 EncodeStringWithLength(index_name, &ret); | 1650 EncodeStringWithLength(index_name, &ret); |
| 1650 return ret; | 1651 return ret; |
| 1651 } | 1652 } |
| 1652 | 1653 |
| 1653 int IndexNamesKey::Compare(const IndexNamesKey& other) { | 1654 int IndexNamesKey::Compare(const IndexNamesKey& other) { |
| 1654 DCHECK_GE(object_store_id_, 0); | 1655 DCHECK_GE(object_store_id_, 0); |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1898 scoped_ptr<IndexedDBKey> IndexDataKey::primary_key() const { | 1899 scoped_ptr<IndexedDBKey> IndexDataKey::primary_key() const { |
| 1899 scoped_ptr<IndexedDBKey> key; | 1900 scoped_ptr<IndexedDBKey> key; |
| 1900 StringPiece slice(encoded_primary_key_); | 1901 StringPiece slice(encoded_primary_key_); |
| 1901 if (!DecodeIDBKey(&slice, &key)) { | 1902 if (!DecodeIDBKey(&slice, &key)) { |
| 1902 // TODO(jsbell): Return error. | 1903 // TODO(jsbell): Return error. |
| 1903 } | 1904 } |
| 1904 return key.Pass(); | 1905 return key.Pass(); |
| 1905 } | 1906 } |
| 1906 | 1907 |
| 1907 } // namespace content | 1908 } // namespace content |
| OLD | NEW |