| 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 #include <string> | 9 #include <string> |
| 10 | 10 |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 // the primary key in the data. The "version" field is used to weed out | 143 // the primary key in the data. The "version" field is used to weed out |
| 144 // stale | 144 // stale |
| 145 // index data. Whenever new object store data is inserted, it gets a new | 145 // index data. Whenever new object store data is inserted, it gets a new |
| 146 // "version" number, and new index data is written with this number. When | 146 // "version" number, and new index data is written with this number. When |
| 147 // the index is used for look-ups, entries are validated against the | 147 // the index is used for look-ups, entries are validated against the |
| 148 // "exists" entries, and records with old "version" numbers are deleted | 148 // "exists" entries, and records with old "version" numbers are deleted |
| 149 // when they are encountered in get_primary_key_via_index, | 149 // when they are encountered in get_primary_key_via_index, |
| 150 // IndexCursorImpl::load_current_row, and | 150 // IndexCursorImpl::load_current_row, and |
| 151 // IndexKeyCursorImpl::load_current_row). | 151 // IndexKeyCursorImpl::load_current_row). |
| 152 | 152 |
| 153 using base::StringPiece; |
| 153 using WebKit::WebIDBKey; | 154 using WebKit::WebIDBKey; |
| 154 using WebKit::WebIDBKeyPath; | 155 using WebKit::WebIDBKeyPath; |
| 155 | 156 |
| 156 namespace content { | 157 namespace content { |
| 157 | 158 |
| 158 // As most of the IndexedDBKeys and encoded values are short, we | 159 // As most of the IndexedDBKeys and encoded values are short, we |
| 159 // initialize some Vectors with a default inline buffer size to reduce | 160 // initialize some Vectors with a default inline buffer size to reduce |
| 160 // the memory re-allocations when the Vectors are appended. | 161 // the memory re-allocations when the Vectors are appended. |
| 161 static const size_t kDefaultInlineBufferSize = 32; | 162 static const size_t kDefaultInlineBufferSize = 32; |
| 162 | 163 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 186 static const unsigned char kObjectStoreFreeListTypeByte = 150; | 187 static const unsigned char kObjectStoreFreeListTypeByte = 150; |
| 187 static const unsigned char kIndexFreeListTypeByte = 151; | 188 static const unsigned char kIndexFreeListTypeByte = 151; |
| 188 static const unsigned char kObjectStoreNamesTypeByte = 200; | 189 static const unsigned char kObjectStoreNamesTypeByte = 200; |
| 189 static const unsigned char kIndexNamesKeyTypeByte = 201; | 190 static const unsigned char kIndexNamesKeyTypeByte = 201; |
| 190 | 191 |
| 191 static const unsigned char kObjectMetaDataTypeMaximum = 255; | 192 static const unsigned char kObjectMetaDataTypeMaximum = 255; |
| 192 static const unsigned char kIndexMetaDataTypeMaximum = 255; | 193 static const unsigned char kIndexMetaDataTypeMaximum = 255; |
| 193 | 194 |
| 194 const unsigned char kMinimumIndexId = 30; | 195 const unsigned char kMinimumIndexId = 30; |
| 195 | 196 |
| 196 void EncodeByte(unsigned char c, std::vector<char>* into) { | 197 inline void EncodeIntSafely(int64 nParam, int64 max, std::vector<char>* into) { |
| 197 into->push_back(c); | 198 DCHECK_LE(nParam, max); |
| 198 } | 199 return EncodeInt(nParam, into); |
| 199 | |
| 200 const char* DecodeByte(const char* p, | |
| 201 const char* limit, | |
| 202 unsigned char& found_char) { | |
| 203 DCHECK_GE(limit, p); | |
| 204 if (p >= limit) | |
| 205 return 0; | |
| 206 | |
| 207 found_char = *p++; | |
| 208 return p; | |
| 209 } | 200 } |
| 210 | 201 |
| 211 std::vector<char> MaxIDBKey() { | 202 std::vector<char> MaxIDBKey() { |
| 212 std::vector<char> ret; | 203 std::vector<char> ret; |
| 213 EncodeByte(kIndexedDBKeyNullTypeByte, &ret); | 204 EncodeByte(kIndexedDBKeyNullTypeByte, &ret); |
| 214 return ret; | 205 return ret; |
| 215 } | 206 } |
| 216 | 207 |
| 217 std::vector<char> MinIDBKey() { | 208 std::vector<char> MinIDBKey() { |
| 218 std::vector<char> ret; | 209 std::vector<char> ret; |
| 219 EncodeByte(kIndexedDBKeyMinKeyTypeByte, &ret); | 210 EncodeByte(kIndexedDBKeyMinKeyTypeByte, &ret); |
| 220 return ret; | 211 return ret; |
| 221 } | 212 } |
| 222 | 213 |
| 223 bool DecodeBool(const char* p, const char* limit) { | 214 void EncodeByte(unsigned char value, std::vector<char>* into) { |
| 224 DCHECK_GT(limit, p); | 215 into->push_back(value); |
| 225 return !!*p; | |
| 226 } | 216 } |
| 227 | 217 |
| 228 void EncodeBool(bool b, std::vector<char>* into) { into->push_back(b ? 1 : 0); } | 218 void EncodeBool(bool value, std::vector<char>* into) { |
| 219 into->push_back(value ? 1 : 0); |
| 220 } |
| 229 | 221 |
| 230 void EncodeInt(int64 nParam, std::vector<char>* into) { | 222 void EncodeInt(int64 value, std::vector<char>* into) { |
| 231 #ifndef NDEBUG | 223 #ifndef NDEBUG |
| 232 // Exercised by unit tests in debug only. | 224 // Exercised by unit tests in debug only. |
| 233 DCHECK_GE(nParam, 0); | 225 DCHECK_GE(value, 0); |
| 234 #endif | 226 #endif |
| 235 uint64 n = static_cast<uint64>(nParam); | 227 uint64 n = static_cast<uint64>(value); |
| 236 | 228 |
| 237 do { | 229 do { |
| 238 unsigned char c = n; | 230 unsigned char c = n; |
| 239 into->push_back(c); | 231 into->push_back(c); |
| 240 n >>= 8; | 232 n >>= 8; |
| 241 } while (n); | 233 } while (n); |
| 242 } | 234 } |
| 243 | 235 |
| 244 static int CompareInts(int64 a, int64 b) { | 236 void EncodeVarInt(int64 value, std::vector<char>* into) { |
| 245 #ifndef NDEBUG | 237 #ifndef NDEBUG |
| 246 // Exercised by unit tests in debug only. | 238 // Exercised by unit tests in debug only. |
| 247 DCHECK_GE(a, 0); | 239 DCHECK_GE(value, 0); |
| 248 DCHECK_GE(b, 0); | |
| 249 #endif | 240 #endif |
| 250 int64 diff = a - b; | 241 uint64 n = static_cast<uint64>(value); |
| 251 if (diff < 0) | |
| 252 return -1; | |
| 253 if (diff > 0) | |
| 254 return 1; | |
| 255 return 0; | |
| 256 } | |
| 257 | |
| 258 void EncodeVarInt(int64 nParam, std::vector<char>* into) { | |
| 259 #ifndef NDEBUG | |
| 260 // Exercised by unit tests in debug only. | |
| 261 DCHECK_GE(nParam, 0); | |
| 262 #endif | |
| 263 uint64 n = static_cast<uint64>(nParam); | |
| 264 | 242 |
| 265 do { | 243 do { |
| 266 unsigned char c = n & 0x7f; | 244 unsigned char c = n & 0x7f; |
| 267 n >>= 7; | 245 n >>= 7; |
| 268 if (n) | 246 if (n) |
| 269 c |= 0x80; | 247 c |= 0x80; |
| 270 into->push_back(c); | 248 into->push_back(c); |
| 271 } while (n); | 249 } while (n); |
| 272 } | 250 } |
| 273 | 251 |
| 274 const char* DecodeVarInt(const char* p, const char* limit, int64& found_int) { | 252 void EncodeString(const string16& value, std::vector<char>* into) { |
| 275 DCHECK_GE(limit, p); | 253 if (value.empty()) |
| 276 found_int = 0; | |
| 277 int shift = 0; | |
| 278 | |
| 279 do { | |
| 280 if (p >= limit) | |
| 281 return 0; | |
| 282 | |
| 283 unsigned char c = *p; | |
| 284 found_int |= static_cast<int64>(c & 0x7f) << shift; | |
| 285 shift += 7; | |
| 286 } while (*p++ & 0x80); | |
| 287 return p; | |
| 288 } | |
| 289 | |
| 290 void EncodeString(const string16& s, std::vector<char>* into) { | |
| 291 if (s.empty()) | |
| 292 return; | 254 return; |
| 293 // Backing store is UTF-16BE, convert from host endianness. | 255 // Backing store is UTF-16BE, convert from host endianness. |
| 294 size_t length = s.length(); | 256 size_t length = value.length(); |
| 295 size_t current = into->size(); | 257 size_t current = into->size(); |
| 296 into->resize(into->size() + length * sizeof(char16)); | 258 into->resize(into->size() + length * sizeof(char16)); |
| 297 | 259 |
| 298 const char16* src = s.c_str(); | 260 const char16* src = value.c_str(); |
| 299 char16* dst = reinterpret_cast<char16*>(&*into->begin() + current); | 261 char16* dst = reinterpret_cast<char16*>(&*into->begin() + current); |
| 300 for (unsigned i = 0; i < length; ++i) | 262 for (unsigned i = 0; i < length; ++i) |
| 301 *dst++ = htons(*src++); | 263 *dst++ = htons(*src++); |
| 302 } | 264 } |
| 303 | 265 |
| 304 string16 DecodeString(const char* p, const char* limit) { | 266 void EncodeStringWithLength(const string16& value, std::vector<char>* into) { |
| 305 // Backing store is UTF-16BE, convert to host endianness. | 267 EncodeVarInt(value.length(), into); |
| 306 DCHECK_GE(limit, p); | 268 EncodeString(value, into); |
| 307 DCHECK(!((limit - p) % sizeof(char16))); | |
| 308 | |
| 309 size_t length = (limit - p) / sizeof(char16); | |
| 310 string16 decoded; | |
| 311 decoded.reserve(length); | |
| 312 const char16* encoded = reinterpret_cast<const char16*>(p); | |
| 313 for (unsigned i = 0; i < length; ++i) | |
| 314 decoded.push_back(ntohs(*encoded++)); | |
| 315 return decoded; | |
| 316 } | 269 } |
| 317 | 270 |
| 318 void EncodeStringWithLength(const string16& s, std::vector<char>* into) { | 271 void EncodeDouble(double value, std::vector<char>* into) { |
| 319 EncodeVarInt(s.length(), into); | 272 // This always has host endianness. |
| 320 EncodeString(s, into); | 273 const char* p = reinterpret_cast<char*>(&value); |
| 274 into->insert(into->end(), p, p + sizeof(value)); |
| 321 } | 275 } |
| 322 | 276 |
| 323 const char* DecodeStringWithLength(const char* p, | 277 void EncodeIDBKey(const IndexedDBKey& value, std::vector<char>* into) { |
| 324 const char* limit, | |
| 325 string16& found_string) { | |
| 326 DCHECK_GE(limit, p); | |
| 327 int64 len; | |
| 328 p = DecodeVarInt(p, limit, len); | |
| 329 if (!p || len < 0 || p + len * 2 > limit) | |
| 330 return 0; | |
| 331 | |
| 332 found_string = DecodeString(p, p + len * 2); | |
| 333 p += len * 2; | |
| 334 return p; | |
| 335 } | |
| 336 | |
| 337 int CompareEncodedStringsWithLength(const char*& p, | |
| 338 const char* limit_p, | |
| 339 const char*& q, | |
| 340 const char* limit_q, | |
| 341 bool& ok) { | |
| 342 DCHECK_NE(&p, &q); | |
| 343 DCHECK_GT(limit_p, p); | |
| 344 DCHECK_GT(limit_q, q); | |
| 345 int64 len_p, len_q; | |
| 346 p = DecodeVarInt(p, limit_p, len_p); | |
| 347 q = DecodeVarInt(q, limit_q, len_q); | |
| 348 if (!p || !q || len_p < 0 || len_q < 0) { | |
| 349 ok = false; | |
| 350 return 0; | |
| 351 } | |
| 352 DCHECK(p && q); | |
| 353 DCHECK_GE(len_p, 0); | |
| 354 DCHECK_GE(len_q, 0); | |
| 355 DCHECK_LE(p + len_p * 2, limit_p); | |
| 356 DCHECK_LE(q + len_q * 2, limit_q); | |
| 357 | |
| 358 const char* start_p = p; | |
| 359 const char* start_q = q; | |
| 360 p += len_p * 2; | |
| 361 q += len_q * 2; | |
| 362 | |
| 363 if (p > limit_p || q > limit_q) { | |
| 364 ok = false; | |
| 365 return 0; | |
| 366 } | |
| 367 | |
| 368 ok = true; | |
| 369 const size_t lmin = static_cast<size_t>(len_p < len_q ? len_p : len_q); | |
| 370 if (int x = memcmp(start_p, start_q, lmin * 2)) | |
| 371 return x; | |
| 372 | |
| 373 if (len_p == len_q) | |
| 374 return 0; | |
| 375 | |
| 376 return (len_p > len_q) ? 1 : -1; | |
| 377 } | |
| 378 | |
| 379 void EncodeDouble(double x, std::vector<char>* into) { | |
| 380 // TODO(jsbell): It would be nice if we could be byte order independent. | |
| 381 const char* p = reinterpret_cast<char*>(&x); | |
| 382 into->insert(into->end(), p, p + sizeof(x)); | |
| 383 } | |
| 384 | |
| 385 const char* DecodeDouble(const char* p, const char* limit, double* d) { | |
| 386 if (p + sizeof(*d) > limit) | |
| 387 return 0; | |
| 388 | |
| 389 char* x = reinterpret_cast<char*>(d); | |
| 390 for (size_t i = 0; i < sizeof(*d); ++i) | |
| 391 *x++ = *p++; | |
| 392 return p; | |
| 393 } | |
| 394 | |
| 395 std::vector<char> EncodeIDBKey(const IndexedDBKey& key) { | |
| 396 std::vector<char> buffer; | |
| 397 buffer.reserve(kDefaultInlineBufferSize); | |
| 398 EncodeIDBKey(key, &buffer); | |
| 399 return buffer; | |
| 400 } | |
| 401 | |
| 402 void EncodeIDBKey(const IndexedDBKey& key, std::vector<char>* into) { | |
| 403 size_t previous_size = into->size(); | 278 size_t previous_size = into->size(); |
| 404 DCHECK(key.IsValid()); | 279 DCHECK(value.IsValid()); |
| 405 switch (key.type()) { | 280 switch (value.type()) { |
| 406 case WebIDBKey::NullType: | 281 case WebIDBKey::NullType: |
| 407 case WebIDBKey::InvalidType: | 282 case WebIDBKey::InvalidType: |
| 408 case WebIDBKey::MinType: { | 283 case WebIDBKey::MinType: { |
| 409 NOTREACHED(); | 284 NOTREACHED(); |
| 410 EncodeByte(kIndexedDBKeyNullTypeByte, into); | 285 EncodeByte(kIndexedDBKeyNullTypeByte, into); |
| 411 return; | 286 return; |
| 412 } | 287 } |
| 413 case WebIDBKey::ArrayType: { | 288 case WebIDBKey::ArrayType: { |
| 414 EncodeByte(kIndexedDBKeyArrayTypeByte, into); | 289 EncodeByte(kIndexedDBKeyArrayTypeByte, into); |
| 415 size_t length = key.array().size(); | 290 size_t length = value.array().size(); |
| 416 EncodeVarInt(length, into); | 291 EncodeVarInt(length, into); |
| 417 for (size_t i = 0; i < length; ++i) | 292 for (size_t i = 0; i < length; ++i) |
| 418 EncodeIDBKey(key.array()[i], into); | 293 EncodeIDBKey(value.array()[i], into); |
| 419 DCHECK_GT(into->size(), previous_size); | 294 DCHECK_GT(into->size(), previous_size); |
| 420 return; | 295 return; |
| 421 } | 296 } |
| 422 case WebIDBKey::StringType: { | 297 case WebIDBKey::StringType: { |
| 423 EncodeByte(kIndexedDBKeyStringTypeByte, into); | 298 EncodeByte(kIndexedDBKeyStringTypeByte, into); |
| 424 EncodeStringWithLength(key.string(), into); | 299 EncodeStringWithLength(value.string(), into); |
| 425 DCHECK_GT(into->size(), previous_size); | 300 DCHECK_GT(into->size(), previous_size); |
| 426 return; | 301 return; |
| 427 } | 302 } |
| 428 case WebIDBKey::DateType: { | 303 case WebIDBKey::DateType: { |
| 429 EncodeByte(kIndexedDBKeyDateTypeByte, into); | 304 EncodeByte(kIndexedDBKeyDateTypeByte, into); |
| 430 EncodeDouble(key.date(), into); | 305 EncodeDouble(value.date(), into); |
| 431 DCHECK_EQ(static_cast<size_t>(9), | 306 DCHECK_EQ(static_cast<size_t>(9), |
| 432 static_cast<size_t>(into->size() - previous_size)); | 307 static_cast<size_t>(into->size() - previous_size)); |
| 433 return; | 308 return; |
| 434 } | 309 } |
| 435 case WebIDBKey::NumberType: { | 310 case WebIDBKey::NumberType: { |
| 436 EncodeByte(kIndexedDBKeyNumberTypeByte, into); | 311 EncodeByte(kIndexedDBKeyNumberTypeByte, into); |
| 437 EncodeDouble(key.number(), into); | 312 EncodeDouble(value.number(), into); |
| 438 DCHECK_EQ(static_cast<size_t>(9), | 313 DCHECK_EQ(static_cast<size_t>(9), |
| 439 static_cast<size_t>(into->size() - previous_size)); | 314 static_cast<size_t>(into->size() - previous_size)); |
| 440 return; | 315 return; |
| 441 } | 316 } |
| 442 } | 317 } |
| 443 | 318 |
| 444 NOTREACHED(); | 319 NOTREACHED(); |
| 445 } | 320 } |
| 446 | 321 |
| 447 const char* DecodeIDBKey(const char* p, | 322 void EncodeIDBKeyPath(const IndexedDBKeyPath& value, std::vector<char>* into) { |
| 448 const char* limit, | 323 // May be typed, or may be a raw string. An invalid leading |
| 449 scoped_ptr<IndexedDBKey>* found_key) { | 324 // byte is used to identify typed coding. New records are |
| 450 DCHECK_GE(limit, p); | 325 // always written as typed. |
| 451 if (p >= limit) | 326 EncodeByte(kIndexedDBKeyPathTypeCodedByte1, into); |
| 452 return 0; | 327 EncodeByte(kIndexedDBKeyPathTypeCodedByte2, into); |
| 453 | 328 EncodeByte(static_cast<char>(value.type()), into); |
| 454 unsigned char type = *p++; | 329 switch (value.type()) { |
| 330 case WebIDBKeyPath::NullType: |
| 331 break; |
| 332 case WebIDBKeyPath::StringType: { |
| 333 EncodeStringWithLength(value.string(), into); |
| 334 break; |
| 335 } |
| 336 case WebIDBKeyPath::ArrayType: { |
| 337 const std::vector<string16>& array = value.array(); |
| 338 size_t count = array.size(); |
| 339 EncodeVarInt(count, into); |
| 340 for (size_t i = 0; i < count; ++i) { |
| 341 EncodeStringWithLength(array[i], into); |
| 342 } |
| 343 break; |
| 344 } |
| 345 } |
| 346 } |
| 347 |
| 348 bool DecodeByte(StringPiece* slice, unsigned char* value) { |
| 349 if (slice->empty()) |
| 350 return false; |
| 351 |
| 352 *value = (*slice)[0]; |
| 353 slice->remove_prefix(1); |
| 354 return true; |
| 355 } |
| 356 |
| 357 bool DecodeBool(StringPiece* slice, bool* value) { |
| 358 if (slice->empty()) |
| 359 return false; |
| 360 |
| 361 *value = !!(*slice)[0]; |
| 362 slice->remove_prefix(1); |
| 363 return true; |
| 364 } |
| 365 |
| 366 bool DecodeInt(StringPiece* slice, int64* value) { |
| 367 if (slice->empty()) |
| 368 return false; |
| 369 |
| 370 StringPiece::const_iterator it = slice->begin(); |
| 371 int shift = 0; |
| 372 int64 ret = 0; |
| 373 while (it != slice->end()) { |
| 374 unsigned char c = *it++; |
| 375 ret |= static_cast<int64>(c) << shift; |
| 376 shift += 8; |
| 377 } |
| 378 *value = ret; |
| 379 slice->remove_prefix(it - slice->begin()); |
| 380 return true; |
| 381 } |
| 382 |
| 383 bool DecodeVarInt(StringPiece* slice, int64* value) { |
| 384 if (slice->empty()) |
| 385 return false; |
| 386 |
| 387 StringPiece::const_iterator it = slice->begin(); |
| 388 int shift = 0; |
| 389 int64 ret = 0; |
| 390 do { |
| 391 if (it == slice->end()) |
| 392 return 0; |
| 393 |
| 394 unsigned char c = *it; |
| 395 ret |= static_cast<int64>(c & 0x7f) << shift; |
| 396 shift += 7; |
| 397 } while (*it++ & 0x80); |
| 398 *value = ret; |
| 399 slice->remove_prefix(it - slice->begin()); |
| 400 return true; |
| 401 } |
| 402 |
| 403 bool DecodeString(StringPiece* slice, string16* value) { |
| 404 if (slice->empty()) { |
| 405 *value = string16(); |
| 406 return true; |
| 407 } |
| 408 |
| 409 // Backing store is UTF-16BE, convert to host endianness. |
| 410 DCHECK(!(slice->size() % sizeof(char16))); |
| 411 size_t length = slice->size() / sizeof(char16); |
| 412 string16 decoded; |
| 413 decoded.reserve(length); |
| 414 const char16* encoded = reinterpret_cast<const char16*>(slice->begin()); |
| 415 for (unsigned i = 0; i < length; ++i) |
| 416 decoded.push_back(ntohs(*encoded++)); |
| 417 |
| 418 *value = decoded; |
| 419 slice->remove_prefix(length * sizeof(char16)); |
| 420 return true; |
| 421 } |
| 422 |
| 423 bool DecodeStringWithLength(StringPiece* slice, string16* value) { |
| 424 if (slice->empty()) |
| 425 return false; |
| 426 |
| 427 int64 len; |
| 428 if (!DecodeVarInt(slice, &len) || len < 0) |
| 429 return false; |
| 430 size_t bytes = len * sizeof(char16); |
| 431 if (slice->size() < bytes) |
| 432 return false; |
| 433 |
| 434 StringPiece subpiece(slice->begin(), bytes); |
| 435 slice->remove_prefix(bytes); |
| 436 if (!DecodeString(&subpiece, value)) |
| 437 return false; |
| 438 |
| 439 return true; |
| 440 } |
| 441 |
| 442 bool DecodeIDBKey(StringPiece* slice, scoped_ptr<IndexedDBKey>* value) { |
| 443 if (slice->empty()) |
| 444 return false; |
| 445 |
| 446 unsigned char type = (*slice)[0]; |
| 447 slice->remove_prefix(1); |
| 455 | 448 |
| 456 switch (type) { | 449 switch (type) { |
| 457 case kIndexedDBKeyNullTypeByte: | 450 case kIndexedDBKeyNullTypeByte: |
| 458 *found_key = make_scoped_ptr(new IndexedDBKey()); | 451 *value = make_scoped_ptr(new IndexedDBKey()); |
| 459 return p; | 452 return true; |
| 460 | 453 |
| 461 case kIndexedDBKeyArrayTypeByte: { | 454 case kIndexedDBKeyArrayTypeByte: { |
| 462 int64 length; | 455 int64 length; |
| 463 p = DecodeVarInt(p, limit, length); | 456 if (!DecodeVarInt(slice, &length) || length < 0) |
| 464 if (!p || length < 0) | 457 return false; |
| 465 return 0; | |
| 466 IndexedDBKey::KeyArray array; | 458 IndexedDBKey::KeyArray array; |
| 467 while (length--) { | 459 while (length--) { |
| 468 scoped_ptr<IndexedDBKey> key; | 460 scoped_ptr<IndexedDBKey> key; |
| 469 p = DecodeIDBKey(p, limit, &key); | 461 if (!DecodeIDBKey(slice, &key)) |
| 470 if (!p) | 462 return false; |
| 471 return 0; | |
| 472 array.push_back(*key); | 463 array.push_back(*key); |
| 473 } | 464 } |
| 474 *found_key = make_scoped_ptr(new IndexedDBKey(array)); | 465 *value = make_scoped_ptr(new IndexedDBKey(array)); |
| 475 return p; | 466 return true; |
| 476 } | 467 } |
| 477 case kIndexedDBKeyStringTypeByte: { | 468 case kIndexedDBKeyStringTypeByte: { |
| 478 string16 s; | 469 string16 s; |
| 479 p = DecodeStringWithLength(p, limit, s); | 470 if (!DecodeStringWithLength(slice, &s)) |
| 480 if (!p) | 471 return false; |
| 481 return 0; | 472 *value = make_scoped_ptr(new IndexedDBKey(s)); |
| 482 *found_key = make_scoped_ptr(new IndexedDBKey(s)); | 473 return true; |
| 483 return p; | |
| 484 } | 474 } |
| 485 case kIndexedDBKeyDateTypeByte: { | 475 case kIndexedDBKeyDateTypeByte: { |
| 486 double d; | 476 double d; |
| 487 p = DecodeDouble(p, limit, &d); | 477 if (!DecodeDouble(slice, &d)) |
| 488 if (!p) | 478 return false; |
| 489 return 0; | 479 *value = make_scoped_ptr(new IndexedDBKey(d, WebIDBKey::DateType)); |
| 490 *found_key = make_scoped_ptr(new IndexedDBKey(d, WebIDBKey::DateType)); | 480 return true; |
| 491 return p; | |
| 492 } | 481 } |
| 493 case kIndexedDBKeyNumberTypeByte: { | 482 case kIndexedDBKeyNumberTypeByte: { |
| 494 double d; | 483 double d; |
| 495 p = DecodeDouble(p, limit, &d); | 484 if (!DecodeDouble(slice, &d)) |
| 496 if (!p) | 485 return false; |
| 497 return 0; | 486 *value = make_scoped_ptr(new IndexedDBKey(d, WebIDBKey::NumberType)); |
| 498 *found_key = make_scoped_ptr(new IndexedDBKey(d, WebIDBKey::NumberType)); | 487 return true; |
| 499 return p; | 488 } |
| 500 } | 489 } |
| 501 } | 490 |
| 502 | 491 NOTREACHED(); |
| 503 NOTREACHED(); | 492 return false; |
| 504 return 0; | 493 } |
| 505 } | 494 |
| 506 | 495 bool DecodeDouble(StringPiece* slice, double* value) { |
| 507 const char* ExtractEncodedIDBKey(const char* start, | 496 if (slice->size() < sizeof(double)) |
| 508 const char* limit, | 497 return false; |
| 509 std::vector<char>* result = 0) { | 498 |
| 510 DCHECK_GT(limit, start); | 499 *value = *reinterpret_cast<const double*>(slice->begin()); |
| 511 const char* p = start; | 500 slice->remove_prefix(sizeof(double)); |
| 512 if (p >= limit) | 501 return true; |
| 513 return 0; | 502 } |
| 514 | 503 |
| 515 unsigned char type = *p++; | 504 bool DecodeIDBKeyPath(StringPiece* slice, IndexedDBKeyPath* value) { |
| 505 // May be typed, or may be a raw string. An invalid leading |
| 506 // byte sequence is used to identify typed coding. New records are |
| 507 // always written as typed. |
| 508 if (slice->size() < 3 || (*slice)[0] != kIndexedDBKeyPathTypeCodedByte1 || |
| 509 (*slice)[1] != kIndexedDBKeyPathTypeCodedByte2) { |
| 510 string16 s; |
| 511 if (!DecodeString(slice, &s)) |
| 512 return false; |
| 513 *value = IndexedDBKeyPath(s); |
| 514 return true; |
| 515 } |
| 516 |
| 517 slice->remove_prefix(2); |
| 518 DCHECK(!slice->empty()); |
| 519 WebIDBKeyPath::Type type = static_cast<WebIDBKeyPath::Type>((*slice)[0]); |
| 520 slice->remove_prefix(1); |
| 521 |
| 522 switch (type) { |
| 523 case WebIDBKeyPath::NullType: |
| 524 DCHECK(slice->empty()); |
| 525 *value = IndexedDBKeyPath(); |
| 526 return true; |
| 527 case WebIDBKeyPath::StringType: { |
| 528 string16 string; |
| 529 if (!DecodeStringWithLength(slice, &string)) |
| 530 return false; |
| 531 DCHECK(slice->empty()); |
| 532 *value = IndexedDBKeyPath(string); |
| 533 return true; |
| 534 } |
| 535 case WebIDBKeyPath::ArrayType: { |
| 536 std::vector<string16> array; |
| 537 int64 count; |
| 538 if (!DecodeVarInt(slice, &count)) |
| 539 return false; |
| 540 DCHECK_GE(count, 0); |
| 541 while (count--) { |
| 542 string16 string; |
| 543 if (!DecodeStringWithLength(slice, &string)) |
| 544 return false; |
| 545 array.push_back(string); |
| 546 } |
| 547 DCHECK(slice->empty()); |
| 548 *value = IndexedDBKeyPath(array); |
| 549 return true; |
| 550 } |
| 551 } |
| 552 NOTREACHED(); |
| 553 return false; |
| 554 } |
| 555 |
| 556 bool ExtractEncodedIDBKey(StringPiece* slice) { |
| 557 |
| 558 unsigned char type = (*slice)[0]; |
| 559 slice->remove_prefix(1); |
| 516 | 560 |
| 517 switch (type) { | 561 switch (type) { |
| 518 case kIndexedDBKeyNullTypeByte: | 562 case kIndexedDBKeyNullTypeByte: |
| 519 case kIndexedDBKeyMinKeyTypeByte: | 563 case kIndexedDBKeyMinKeyTypeByte: |
| 520 break; | 564 return true; |
| 521 case kIndexedDBKeyArrayTypeByte: { | 565 case kIndexedDBKeyArrayTypeByte: { |
| 522 int64 length; | 566 int64 length; |
| 523 p = DecodeVarInt(p, limit, length); | 567 if (!DecodeVarInt(slice, &length)) |
| 524 if (!p || length < 0) | 568 return false; |
| 525 return 0; | |
| 526 while (length--) { | 569 while (length--) { |
| 527 p = ExtractEncodedIDBKey(p, limit); | 570 if (!ExtractEncodedIDBKey(slice)) |
| 528 if (!p) | 571 return false; |
| 529 return 0; | 572 } |
| 530 } | 573 return true; |
| 531 break; | |
| 532 } | 574 } |
| 533 case kIndexedDBKeyStringTypeByte: { | 575 case kIndexedDBKeyStringTypeByte: { |
| 534 int64 length; | 576 int64 length; |
| 535 p = DecodeVarInt(p, limit, length); | 577 if (!DecodeVarInt(slice, &length) || length < 0) |
| 536 if (!p || length < 0 || p + length * 2 > limit) | 578 return false; |
| 537 return 0; | 579 if (slice->size() < static_cast<size_t>(length) * sizeof(char16)) |
| 538 p += length * 2; | 580 return false; |
| 539 break; | 581 slice->remove_prefix(length * sizeof(char16)); |
| 582 return true; |
| 540 } | 583 } |
| 541 case kIndexedDBKeyDateTypeByte: | 584 case kIndexedDBKeyDateTypeByte: |
| 542 case kIndexedDBKeyNumberTypeByte: | 585 case kIndexedDBKeyNumberTypeByte: |
| 543 if (p + sizeof(double) > limit) | 586 if (slice->size() < sizeof(double)) |
| 544 return 0; | 587 return false; |
| 545 p += sizeof(double); | 588 slice->remove_prefix(sizeof(double)); |
| 546 break; | 589 return true; |
| 547 } | 590 } |
| 548 | 591 NOTREACHED(); |
| 549 if (result) { | 592 return false; |
| 550 DCHECK(p); | 593 } |
| 551 DCHECK_LE(p, limit); | 594 |
| 552 result->assign(start, p); | 595 bool ExtractEncodedIDBKey(StringPiece* slice, std::vector<char>* result) { |
| 553 } | 596 const char* start = slice->begin(); |
| 554 | 597 if (!ExtractEncodedIDBKey(slice)) |
| 555 return p; | 598 return 0; |
| 599 |
| 600 if (result) |
| 601 result->assign(start, slice->begin()); |
| 602 return true; |
| 556 } | 603 } |
| 557 | 604 |
| 558 static WebIDBKey::Type KeyTypeByteToKeyType(unsigned char type) { | 605 static WebIDBKey::Type KeyTypeByteToKeyType(unsigned char type) { |
| 559 switch (type) { | 606 switch (type) { |
| 560 case kIndexedDBKeyNullTypeByte: | 607 case kIndexedDBKeyNullTypeByte: |
| 561 return WebIDBKey::InvalidType; | 608 return WebIDBKey::InvalidType; |
| 562 case kIndexedDBKeyArrayTypeByte: | 609 case kIndexedDBKeyArrayTypeByte: |
| 563 return WebIDBKey::ArrayType; | 610 return WebIDBKey::ArrayType; |
| 564 case kIndexedDBKeyStringTypeByte: | 611 case kIndexedDBKeyStringTypeByte: |
| 565 return WebIDBKey::StringType; | 612 return WebIDBKey::StringType; |
| 566 case kIndexedDBKeyDateTypeByte: | 613 case kIndexedDBKeyDateTypeByte: |
| 567 return WebIDBKey::DateType; | 614 return WebIDBKey::DateType; |
| 568 case kIndexedDBKeyNumberTypeByte: | 615 case kIndexedDBKeyNumberTypeByte: |
| 569 return WebIDBKey::NumberType; | 616 return WebIDBKey::NumberType; |
| 570 case kIndexedDBKeyMinKeyTypeByte: | 617 case kIndexedDBKeyMinKeyTypeByte: |
| 571 return WebIDBKey::MinType; | 618 return WebIDBKey::MinType; |
| 572 } | 619 } |
| 573 | 620 |
| 574 NOTREACHED(); | 621 NOTREACHED(); |
| 575 return WebIDBKey::InvalidType; | 622 return WebIDBKey::InvalidType; |
| 576 } | 623 } |
| 577 | 624 |
| 625 int CompareEncodedStringsWithLength(StringPiece* slice1, |
| 626 StringPiece* slice2, |
| 627 bool& ok) { |
| 628 int64 len1, len2; |
| 629 if (!DecodeVarInt(slice1, &len1) || !DecodeVarInt(slice2, &len2)) { |
| 630 ok = false; |
| 631 return 0; |
| 632 } |
| 633 DCHECK_GE(len1, 0); |
| 634 DCHECK_GE(len2, 0); |
| 635 if (len1 < 0 || len2 < 0) { |
| 636 ok = false; |
| 637 return 0; |
| 638 } |
| 639 DCHECK_GE(slice1->size(), len1 * sizeof(char16)); |
| 640 DCHECK_GE(slice2->size(), len2 * sizeof(char16)); |
| 641 if (slice1->size() < len1 * sizeof(char16) || |
| 642 slice2->size() < len2 * sizeof(char16)) { |
| 643 ok = false; |
| 644 return 0; |
| 645 } |
| 646 |
| 647 StringPiece string1(slice1->begin(), len1 * sizeof(char16)); |
| 648 StringPiece string2(slice2->begin(), len2 * sizeof(char16)); |
| 649 slice1->remove_prefix(len1 * sizeof(char16)); |
| 650 slice2->remove_prefix(len2 * sizeof(char16)); |
| 651 |
| 652 ok = true; |
| 653 // Strings are UTF-16BE encoded, so a simple memcmp is sufficient. |
| 654 return string1.compare(string2); |
| 655 } |
| 656 |
| 657 static int CompareInts(int64 a, int64 b) { |
| 658 #ifndef NDEBUG |
| 659 // Exercised by unit tests in debug only. |
| 660 DCHECK_GE(a, 0); |
| 661 DCHECK_GE(b, 0); |
| 662 #endif |
| 663 int64 diff = a - b; |
| 664 if (diff < 0) |
| 665 return -1; |
| 666 if (diff > 0) |
| 667 return 1; |
| 668 return 0; |
| 669 } |
| 670 |
| 578 static int CompareTypes(WebIDBKey::Type a, WebIDBKey::Type b) { return b - a; } | 671 static int CompareTypes(WebIDBKey::Type a, WebIDBKey::Type b) { return b - a; } |
| 579 | 672 |
| 580 int CompareEncodedIDBKeys(const char*& ptr_a, | 673 int CompareEncodedIDBKeys(StringPiece* slice_a, |
| 581 const char* limit_a, | 674 StringPiece* slice_b, |
| 582 const char*& ptr_b, | |
| 583 const char* limit_b, | |
| 584 bool& ok) { | 675 bool& ok) { |
| 585 ok = true; | 676 ok = true; |
| 586 DCHECK_NE(&ptr_a, &ptr_b); | 677 unsigned char type_a = (*slice_a)[0]; |
| 587 DCHECK_LT(ptr_a, limit_a); | 678 unsigned char type_b = (*slice_b)[0]; |
| 588 DCHECK_LT(ptr_b, limit_b); | 679 slice_a->remove_prefix(1); |
| 589 unsigned char type_a = *ptr_a++; | 680 slice_b->remove_prefix(1); |
| 590 unsigned char type_b = *ptr_b++; | |
| 591 | 681 |
| 592 if (int x = CompareTypes(KeyTypeByteToKeyType(type_a), | 682 if (int x = CompareTypes(KeyTypeByteToKeyType(type_a), |
| 593 KeyTypeByteToKeyType(type_b))) | 683 KeyTypeByteToKeyType(type_b))) |
| 594 return x; | 684 return x; |
| 595 | 685 |
| 596 switch (type_a) { | 686 switch (type_a) { |
| 597 case kIndexedDBKeyNullTypeByte: | 687 case kIndexedDBKeyNullTypeByte: |
| 598 case kIndexedDBKeyMinKeyTypeByte: | 688 case kIndexedDBKeyMinKeyTypeByte: |
| 599 // Null type or max type; no payload to compare. | 689 // Null type or max type; no payload to compare. |
| 600 return 0; | 690 return 0; |
| 601 case kIndexedDBKeyArrayTypeByte: { | 691 case kIndexedDBKeyArrayTypeByte: { |
| 602 int64 length_a, length_b; | 692 int64 length_a, length_b; |
| 603 ptr_a = DecodeVarInt(ptr_a, limit_a, length_a); | 693 if (!DecodeVarInt(slice_a, &length_a) || |
| 604 ptr_b = DecodeVarInt(ptr_b, limit_b, length_b); | 694 !DecodeVarInt(slice_b, &length_b)) { |
| 605 if (!ptr_a || !ptr_b || length_a < 0 || length_b < 0) { | |
| 606 ok = false; | 695 ok = false; |
| 607 return 0; | 696 return 0; |
| 608 } | 697 } |
| 609 for (int64 i = 0; i < length_a && i < length_b; ++i) { | 698 for (int64 i = 0; i < length_a && i < length_b; ++i) { |
| 610 int result = CompareEncodedIDBKeys(ptr_a, limit_a, ptr_b, limit_b, ok); | 699 int result = CompareEncodedIDBKeys(slice_a, slice_b, ok); |
| 611 if (!ok || result) | 700 if (!ok || result) |
| 612 return result; | 701 return result; |
| 613 } | 702 } |
| 614 if (length_a < length_b) | 703 return length_a - length_b; |
| 615 return -1; | |
| 616 if (length_a > length_b) | |
| 617 return 1; | |
| 618 return 0; | |
| 619 } | 704 } |
| 620 case kIndexedDBKeyStringTypeByte: | 705 case kIndexedDBKeyStringTypeByte: |
| 621 return CompareEncodedStringsWithLength( | 706 return CompareEncodedStringsWithLength(slice_a, slice_b, ok); |
| 622 ptr_a, limit_a, ptr_b, limit_b, ok); | |
| 623 case kIndexedDBKeyDateTypeByte: | 707 case kIndexedDBKeyDateTypeByte: |
| 624 case kIndexedDBKeyNumberTypeByte: { | 708 case kIndexedDBKeyNumberTypeByte: { |
| 625 double d, e; | 709 double d, e; |
| 626 ptr_a = DecodeDouble(ptr_a, limit_a, &d); | 710 if (!DecodeDouble(slice_a, &d) || !DecodeDouble(slice_b, &e)) { |
| 627 ptr_b = DecodeDouble(ptr_b, limit_b, &e); | |
| 628 DCHECK(ptr_a); | |
| 629 DCHECK(ptr_b); | |
| 630 if (!ptr_a || !ptr_b) { | |
| 631 ok = false; | 711 ok = false; |
| 632 return 0; | 712 return 0; |
| 633 } | 713 } |
| 634 if (d < e) | 714 if (d < e) |
| 635 return -1; | 715 return -1; |
| 636 if (d > e) | 716 if (d > e) |
| 637 return 1; | 717 return 1; |
| 638 return 0; | 718 return 0; |
| 639 } | 719 } |
| 640 } | 720 } |
| 641 | 721 |
| 642 NOTREACHED(); | 722 NOTREACHED(); |
| 643 return 0; | 723 return 0; |
| 644 } | 724 } |
| 645 | 725 |
| 646 int CompareEncodedIDBKeys(const std::vector<char>& key_a, | 726 int CompareEncodedIDBKeys(const std::vector<char>& key_a, |
| 647 const std::vector<char>& key_b, | 727 const std::vector<char>& key_b, |
| 648 bool& ok) { | 728 bool& ok) { |
| 649 DCHECK_GE(key_a.size(), static_cast<size_t>(1)); | 729 DCHECK(!key_a.empty()); |
| 650 DCHECK_GE(key_b.size(), static_cast<size_t>(1)); | 730 DCHECK(!key_b.empty()); |
| 651 | 731 |
| 652 const char* ptr_a = &*key_a.begin(); | 732 StringPiece slice_a(&*key_a.begin(), key_a.size()); |
| 653 const char* limit_a = &*key_a.rbegin() + 1; | 733 StringPiece slice_b(&*key_b.begin(), key_b.size()); |
| 654 const char* ptr_b = &*key_b.begin(); | 734 return CompareEncodedIDBKeys(&slice_a, &slice_b, ok); |
| 655 const char* limit_b = &*key_b.rbegin() + 1; | |
| 656 | |
| 657 return CompareEncodedIDBKeys(ptr_a, limit_a, ptr_b, limit_b, ok); | |
| 658 } | |
| 659 | |
| 660 void EncodeIDBKeyPath(const IndexedDBKeyPath& key_path, | |
| 661 std::vector<char>* into) { | |
| 662 // May be typed, or may be a raw string. An invalid leading | |
| 663 // byte is used to identify typed coding. New records are | |
| 664 // always written as typed. | |
| 665 EncodeByte(kIndexedDBKeyPathTypeCodedByte1, into); | |
| 666 EncodeByte(kIndexedDBKeyPathTypeCodedByte2, into); | |
| 667 EncodeByte(static_cast<char>(key_path.type()), into); | |
| 668 switch (key_path.type()) { | |
| 669 case WebIDBKeyPath::NullType: | |
| 670 break; | |
| 671 case WebIDBKeyPath::StringType: { | |
| 672 EncodeStringWithLength(key_path.string(), into); | |
| 673 break; | |
| 674 } | |
| 675 case WebIDBKeyPath::ArrayType: { | |
| 676 const std::vector<string16>& array = key_path.array(); | |
| 677 size_t count = array.size(); | |
| 678 EncodeVarInt(count, into); | |
| 679 for (size_t i = 0; i < count; ++i) { | |
| 680 EncodeStringWithLength(array[i], into); | |
| 681 } | |
| 682 break; | |
| 683 } | |
| 684 } | |
| 685 } | |
| 686 | |
| 687 IndexedDBKeyPath DecodeIDBKeyPath(const char* p, const char* limit) { | |
| 688 // May be typed, or may be a raw string. An invalid leading | |
| 689 // byte sequence is used to identify typed coding. New records are | |
| 690 // always written as typed. | |
| 691 if (p == limit || | |
| 692 (limit - p >= 2 && (*p != kIndexedDBKeyPathTypeCodedByte1 || | |
| 693 *(p + 1) != kIndexedDBKeyPathTypeCodedByte2))) | |
| 694 return IndexedDBKeyPath(DecodeString(p, limit)); | |
| 695 p += 2; | |
| 696 | |
| 697 DCHECK_NE(p, limit); | |
| 698 WebIDBKeyPath::Type type = static_cast<WebIDBKeyPath::Type>(*p++); | |
| 699 switch (type) { | |
| 700 case WebIDBKeyPath::NullType: | |
| 701 DCHECK_EQ(p, limit); | |
| 702 return IndexedDBKeyPath(); | |
| 703 case WebIDBKeyPath::StringType: { | |
| 704 string16 string; | |
| 705 p = DecodeStringWithLength(p, limit, string); | |
| 706 DCHECK_EQ(p, limit); | |
| 707 return IndexedDBKeyPath(string); | |
| 708 } | |
| 709 case WebIDBKeyPath::ArrayType: { | |
| 710 std::vector<string16> array; | |
| 711 int64 count; | |
| 712 p = DecodeVarInt(p, limit, count); | |
| 713 DCHECK(p); | |
| 714 DCHECK_GE(count, 0); | |
| 715 while (count--) { | |
| 716 string16 string; | |
| 717 p = DecodeStringWithLength(p, limit, string); | |
| 718 DCHECK(p); | |
| 719 array.push_back(string); | |
| 720 } | |
| 721 DCHECK_EQ(p, limit); | |
| 722 return IndexedDBKeyPath(array); | |
| 723 } | |
| 724 } | |
| 725 NOTREACHED(); | |
| 726 return IndexedDBKeyPath(); | |
| 727 } | 735 } |
| 728 | 736 |
| 729 namespace { | 737 namespace { |
| 730 | 738 |
| 731 template <typename KeyType> | 739 template <typename KeyType> |
| 732 int Compare(const LevelDBSlice& a, const LevelDBSlice& b, bool, bool& ok) { | 740 int Compare(const LevelDBSlice& a, const LevelDBSlice& b, bool, bool& ok) { |
| 733 KeyType key_a; | 741 KeyType key_a; |
| 734 KeyType key_b; | 742 KeyType key_b; |
| 735 | 743 |
| 736 const char* ptr_a = KeyType::Decode(a.begin(), a.end(), &key_a); | 744 const char* ptr_a = KeyType::Decode(a.begin(), a.end(), &key_a); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 765 DCHECK(prefix_a.object_store_id_); | 773 DCHECK(prefix_a.object_store_id_); |
| 766 DCHECK_EQ(prefix_a.index_id_, ExistsEntryKey::kSpecialIndexNumber); | 774 DCHECK_EQ(prefix_a.index_id_, ExistsEntryKey::kSpecialIndexNumber); |
| 767 DCHECK(prefix_b.database_id_); | 775 DCHECK(prefix_b.database_id_); |
| 768 DCHECK(prefix_b.object_store_id_); | 776 DCHECK(prefix_b.object_store_id_); |
| 769 DCHECK_EQ(prefix_b.index_id_, ExistsEntryKey::kSpecialIndexNumber); | 777 DCHECK_EQ(prefix_b.index_id_, ExistsEntryKey::kSpecialIndexNumber); |
| 770 DCHECK_NE(ptr_a, a.end()); | 778 DCHECK_NE(ptr_a, a.end()); |
| 771 DCHECK_NE(ptr_b, b.end()); | 779 DCHECK_NE(ptr_b, b.end()); |
| 772 // Prefixes are not compared - it is assumed this was already done. | 780 // Prefixes are not compared - it is assumed this was already done. |
| 773 DCHECK(!prefix_a.Compare(prefix_b)); | 781 DCHECK(!prefix_a.Compare(prefix_b)); |
| 774 | 782 |
| 775 return CompareEncodedIDBKeys(ptr_a, a.end(), ptr_b, b.end(), ok); | 783 StringPiece slice_a(ptr_a, a.end() - ptr_a); |
| 784 StringPiece slice_b(ptr_b, b.end() - ptr_b); |
| 785 return CompareEncodedIDBKeys(&slice_a, &slice_b, ok); |
| 776 } | 786 } |
| 777 | 787 |
| 778 template <> | 788 template <> |
| 779 int Compare<ObjectStoreDataKey>(const LevelDBSlice& a, | 789 int Compare<ObjectStoreDataKey>(const LevelDBSlice& a, |
| 780 const LevelDBSlice& b, | 790 const LevelDBSlice& b, |
| 781 bool, | 791 bool, |
| 782 bool& ok) { | 792 bool& ok) { |
| 783 KeyPrefix prefix_a; | 793 KeyPrefix prefix_a; |
| 784 KeyPrefix prefix_b; | 794 KeyPrefix prefix_b; |
| 785 const char* ptr_a = KeyPrefix::Decode(a.begin(), a.end(), &prefix_a); | 795 const char* ptr_a = KeyPrefix::Decode(a.begin(), a.end(), &prefix_a); |
| 786 const char* ptr_b = KeyPrefix::Decode(b.begin(), b.end(), &prefix_b); | 796 const char* ptr_b = KeyPrefix::Decode(b.begin(), b.end(), &prefix_b); |
| 787 DCHECK(ptr_a); | 797 DCHECK(ptr_a); |
| 788 DCHECK(ptr_b); | 798 DCHECK(ptr_b); |
| 789 DCHECK(prefix_a.database_id_); | 799 DCHECK(prefix_a.database_id_); |
| 790 DCHECK(prefix_a.object_store_id_); | 800 DCHECK(prefix_a.object_store_id_); |
| 791 DCHECK_EQ(prefix_a.index_id_, ObjectStoreDataKey::kSpecialIndexNumber); | 801 DCHECK_EQ(prefix_a.index_id_, ObjectStoreDataKey::kSpecialIndexNumber); |
| 792 DCHECK(prefix_b.database_id_); | 802 DCHECK(prefix_b.database_id_); |
| 793 DCHECK(prefix_b.object_store_id_); | 803 DCHECK(prefix_b.object_store_id_); |
| 794 DCHECK_EQ(prefix_b.index_id_, ObjectStoreDataKey::kSpecialIndexNumber); | 804 DCHECK_EQ(prefix_b.index_id_, ObjectStoreDataKey::kSpecialIndexNumber); |
| 795 DCHECK_NE(ptr_a, a.end()); | 805 DCHECK_NE(ptr_a, a.end()); |
| 796 DCHECK_NE(ptr_b, b.end()); | 806 DCHECK_NE(ptr_b, b.end()); |
| 797 // Prefixes are not compared - it is assumed this was already done. | 807 // Prefixes are not compared - it is assumed this was already done. |
| 798 DCHECK(!prefix_a.Compare(prefix_b)); | 808 DCHECK(!prefix_a.Compare(prefix_b)); |
| 799 | 809 |
| 800 return CompareEncodedIDBKeys(ptr_a, a.end(), ptr_b, b.end(), ok); | 810 StringPiece slice_a(ptr_a, a.end() - ptr_a); |
| 811 StringPiece slice_b(ptr_b, b.end() - ptr_b); |
| 812 return CompareEncodedIDBKeys(&slice_a, &slice_b, ok); |
| 801 } | 813 } |
| 802 | 814 |
| 803 template <> | 815 template <> |
| 804 int Compare<IndexDataKey>(const LevelDBSlice& a, | 816 int Compare<IndexDataKey>(const LevelDBSlice& a, |
| 805 const LevelDBSlice& b, | 817 const LevelDBSlice& b, |
| 806 bool ignore_duplicates, | 818 bool ignore_duplicates, |
| 807 bool& ok) { | 819 bool& ok) { |
| 808 KeyPrefix prefix_a; | 820 KeyPrefix prefix_a; |
| 809 KeyPrefix prefix_b; | 821 KeyPrefix prefix_b; |
| 810 const char* ptr_a = KeyPrefix::Decode(a.begin(), a.end(), &prefix_a); | 822 const char* ptr_a = KeyPrefix::Decode(a.begin(), a.end(), &prefix_a); |
| 811 const char* ptr_b = KeyPrefix::Decode(b.begin(), b.end(), &prefix_b); | 823 const char* ptr_b = KeyPrefix::Decode(b.begin(), b.end(), &prefix_b); |
| 812 DCHECK(ptr_a); | 824 DCHECK(ptr_a); |
| 813 DCHECK(ptr_b); | 825 DCHECK(ptr_b); |
| 814 DCHECK(prefix_a.database_id_); | 826 DCHECK(prefix_a.database_id_); |
| 815 DCHECK(prefix_a.object_store_id_); | 827 DCHECK(prefix_a.object_store_id_); |
| 816 DCHECK_GE(prefix_a.index_id_, kMinimumIndexId); | 828 DCHECK_GE(prefix_a.index_id_, kMinimumIndexId); |
| 817 DCHECK(prefix_b.database_id_); | 829 DCHECK(prefix_b.database_id_); |
| 818 DCHECK(prefix_b.object_store_id_); | 830 DCHECK(prefix_b.object_store_id_); |
| 819 DCHECK_GE(prefix_b.index_id_, kMinimumIndexId); | 831 DCHECK_GE(prefix_b.index_id_, kMinimumIndexId); |
| 820 DCHECK_NE(ptr_a, a.end()); | 832 DCHECK_NE(ptr_a, a.end()); |
| 821 DCHECK_NE(ptr_b, b.end()); | 833 DCHECK_NE(ptr_b, b.end()); |
| 822 // Prefixes are not compared - it is assumed this was already done. | 834 // Prefixes are not compared - it is assumed this was already done. |
| 823 DCHECK(!prefix_a.Compare(prefix_b)); | 835 DCHECK(!prefix_a.Compare(prefix_b)); |
| 824 | 836 |
| 825 // index key | 837 // index key |
| 826 int result = CompareEncodedIDBKeys(ptr_a, a.end(), ptr_b, b.end(), ok); | 838 |
| 839 StringPiece slice_a(ptr_a, a.end() - ptr_a); |
| 840 StringPiece slice_b(ptr_b, b.end() - ptr_b); |
| 841 int result = CompareEncodedIDBKeys(&slice_a, &slice_b, ok); |
| 827 if (!ok || result) | 842 if (!ok || result) |
| 828 return result; | 843 return result; |
| 829 if (ignore_duplicates) | 844 if (ignore_duplicates) |
| 830 return 0; | 845 return 0; |
| 831 | 846 |
| 832 // sequence number [optional] | 847 // sequence number [optional] |
| 833 int64 sequence_number_a = -1; | 848 int64 sequence_number_a = -1; |
| 834 int64 sequence_number_b = -1; | 849 int64 sequence_number_b = -1; |
| 835 if (ptr_a != a.end()) | 850 if (!slice_a.empty()) { |
| 836 ptr_a = DecodeVarInt(ptr_a, a.end(), sequence_number_a); | 851 if (!DecodeVarInt(&slice_a, &sequence_number_a)) |
| 837 if (ptr_b != b.end()) | 852 return 0; |
| 838 ptr_b = DecodeVarInt(ptr_b, b.end(), sequence_number_b); | 853 } |
| 854 if (!slice_b.empty()) { |
| 855 if (!DecodeVarInt(&slice_b, &sequence_number_b)) |
| 856 return 0; |
| 857 } |
| 839 | 858 |
| 840 // primary key [optional] | 859 // primary key [optional] |
| 841 if (!ptr_a || !ptr_b) | 860 if (slice_a.empty() && slice_b.empty()) |
| 842 return 0; | 861 return 0; |
| 843 if (ptr_a == a.end() && ptr_b == b.end()) | 862 if (slice_a.empty()) |
| 844 return 0; | |
| 845 if (ptr_a == a.end()) | |
| 846 return -1; | 863 return -1; |
| 847 if (ptr_b == b.end()) | 864 if (slice_b.empty()) |
| 848 return 1; | 865 return 1; |
| 849 | 866 |
| 850 result = CompareEncodedIDBKeys(ptr_a, a.end(), ptr_b, b.end(), ok); | 867 result = CompareEncodedIDBKeys(&slice_a, &slice_b, ok); |
| 851 if (!ok || result) | 868 if (!ok || result) |
| 852 return result; | 869 return result; |
| 853 | 870 |
| 854 return CompareInts(sequence_number_a, sequence_number_b); | 871 return CompareInts(sequence_number_a, sequence_number_b); |
| 855 } | 872 } |
| 856 | 873 |
| 857 int Compare(const LevelDBSlice& a, | 874 int Compare(const LevelDBSlice& a, |
| 858 const LevelDBSlice& b, | 875 const LevelDBSlice& b, |
| 859 bool index_keys, | 876 bool index_keys, |
| 860 bool& ok) { | 877 bool& ok) { |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1048 unsigned char first_byte = *start++; | 1065 unsigned char first_byte = *start++; |
| 1049 | 1066 |
| 1050 int database_id_bytes = ((first_byte >> 5) & 0x7) + 1; | 1067 int database_id_bytes = ((first_byte >> 5) & 0x7) + 1; |
| 1051 int object_store_id_bytes = ((first_byte >> 2) & 0x7) + 1; | 1068 int object_store_id_bytes = ((first_byte >> 2) & 0x7) + 1; |
| 1052 int index_id_bytes = (first_byte & 0x3) + 1; | 1069 int index_id_bytes = (first_byte & 0x3) + 1; |
| 1053 | 1070 |
| 1054 if (start + database_id_bytes + object_store_id_bytes + index_id_bytes > | 1071 if (start + database_id_bytes + object_store_id_bytes + index_id_bytes > |
| 1055 limit) | 1072 limit) |
| 1056 return 0; | 1073 return 0; |
| 1057 | 1074 |
| 1058 result->database_id_ = DecodeInt(start, start + database_id_bytes); | 1075 { |
| 1076 StringPiece slice(start, database_id_bytes); |
| 1077 if (!DecodeInt(&slice, &result->database_id_)) |
| 1078 return 0; |
| 1079 } |
| 1059 start += database_id_bytes; | 1080 start += database_id_bytes; |
| 1060 result->object_store_id_ = DecodeInt(start, start + object_store_id_bytes); | 1081 { |
| 1082 StringPiece slice(start, object_store_id_bytes); |
| 1083 if (!DecodeInt(&slice, &result->object_store_id_)) |
| 1084 return 0; |
| 1085 } |
| 1061 start += object_store_id_bytes; | 1086 start += object_store_id_bytes; |
| 1062 result->index_id_ = DecodeInt(start, start + index_id_bytes); | 1087 { |
| 1088 StringPiece slice(start, index_id_bytes); |
| 1089 if (!DecodeInt(&slice, &result->index_id_)) |
| 1090 return 0; |
| 1091 } |
| 1063 start += index_id_bytes; | 1092 start += index_id_bytes; |
| 1064 | 1093 |
| 1065 return start; | 1094 return start; |
| 1066 } | 1095 } |
| 1067 | 1096 |
| 1068 std::vector<char> KeyPrefix::EncodeEmpty() { | 1097 std::vector<char> KeyPrefix::EncodeEmpty() { |
| 1069 const std::vector<char> result(4, 0); | 1098 const std::vector<char> result(4, 0); |
| 1070 DCHECK(EncodeInternal(0, 0, 0) == std::vector<char>(4, 0)); | 1099 DCHECK(EncodeInternal(0, 0, 0) == std::vector<char>(4, 0)); |
| 1071 return result; | 1100 return result; |
| 1072 } | 1101 } |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1174 KeyPrefix prefix; | 1203 KeyPrefix prefix; |
| 1175 const char* p = KeyPrefix::Decode(start, limit, &prefix); | 1204 const char* p = KeyPrefix::Decode(start, limit, &prefix); |
| 1176 if (!p) | 1205 if (!p) |
| 1177 return 0; | 1206 return 0; |
| 1178 DCHECK(!prefix.database_id_); | 1207 DCHECK(!prefix.database_id_); |
| 1179 DCHECK(!prefix.object_store_id_); | 1208 DCHECK(!prefix.object_store_id_); |
| 1180 DCHECK(!prefix.index_id_); | 1209 DCHECK(!prefix.index_id_); |
| 1181 if (p == limit) | 1210 if (p == limit) |
| 1182 return 0; | 1211 return 0; |
| 1183 unsigned char type_byte = 0; | 1212 unsigned char type_byte = 0; |
| 1184 p = DecodeByte(p, limit, type_byte); | 1213 StringPiece slice(p, limit - p); |
| 1214 if (!DecodeByte(&slice, &type_byte)) |
| 1215 return 0; |
| 1185 DCHECK_EQ(type_byte, kDatabaseFreeListTypeByte); | 1216 DCHECK_EQ(type_byte, kDatabaseFreeListTypeByte); |
| 1186 if (p == limit) | 1217 if (slice.empty()) |
| 1187 return 0; | 1218 return 0; |
| 1188 return DecodeVarInt(p, limit, result->database_id_); | 1219 if (!DecodeVarInt(&slice, &result->database_id_)) |
| 1220 return 0; |
| 1221 return slice.begin(); |
| 1189 } | 1222 } |
| 1190 | 1223 |
| 1191 std::vector<char> DatabaseFreeListKey::Encode(int64 database_id) { | 1224 std::vector<char> DatabaseFreeListKey::Encode(int64 database_id) { |
| 1192 std::vector<char> ret = KeyPrefix::EncodeEmpty(); | 1225 std::vector<char> ret = KeyPrefix::EncodeEmpty(); |
| 1193 ret.push_back(kDatabaseFreeListTypeByte); | 1226 ret.push_back(kDatabaseFreeListTypeByte); |
| 1194 EncodeVarInt(database_id, &ret); | 1227 EncodeVarInt(database_id, &ret); |
| 1195 return ret; | 1228 return ret; |
| 1196 } | 1229 } |
| 1197 | 1230 |
| 1198 std::vector<char> DatabaseFreeListKey::EncodeMaxKey() { | 1231 std::vector<char> DatabaseFreeListKey::EncodeMaxKey() { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1215 KeyPrefix prefix; | 1248 KeyPrefix prefix; |
| 1216 const char* p = KeyPrefix::Decode(start, limit, &prefix); | 1249 const char* p = KeyPrefix::Decode(start, limit, &prefix); |
| 1217 if (!p) | 1250 if (!p) |
| 1218 return p; | 1251 return p; |
| 1219 DCHECK(!prefix.database_id_); | 1252 DCHECK(!prefix.database_id_); |
| 1220 DCHECK(!prefix.object_store_id_); | 1253 DCHECK(!prefix.object_store_id_); |
| 1221 DCHECK(!prefix.index_id_); | 1254 DCHECK(!prefix.index_id_); |
| 1222 if (p == limit) | 1255 if (p == limit) |
| 1223 return 0; | 1256 return 0; |
| 1224 unsigned char type_byte = 0; | 1257 unsigned char type_byte = 0; |
| 1225 p = DecodeByte(p, limit, type_byte); | 1258 StringPiece slice(p, limit - p); |
| 1259 if (!DecodeByte(&slice, &type_byte)) |
| 1260 return 0; |
| 1226 DCHECK_EQ(type_byte, kDatabaseNameTypeByte); | 1261 DCHECK_EQ(type_byte, kDatabaseNameTypeByte); |
| 1227 if (p == limit) | 1262 if (!DecodeStringWithLength(&slice, &result->origin_)) |
| 1228 return 0; | 1263 return 0; |
| 1229 p = DecodeStringWithLength(p, limit, result->origin_); | 1264 if (!DecodeStringWithLength(&slice, &result->database_name_)) |
| 1230 if (!p) | |
| 1231 return 0; | 1265 return 0; |
| 1232 return DecodeStringWithLength(p, limit, result->database_name_); | 1266 return slice.begin(); |
| 1233 } | 1267 } |
| 1234 | 1268 |
| 1235 std::vector<char> DatabaseNameKey::Encode(const string16& origin, | 1269 std::vector<char> DatabaseNameKey::Encode(const string16& origin, |
| 1236 const string16& database_name) { | 1270 const string16& database_name) { |
| 1237 std::vector<char> ret = KeyPrefix::EncodeEmpty(); | 1271 std::vector<char> ret = KeyPrefix::EncodeEmpty(); |
| 1238 ret.push_back(kDatabaseNameTypeByte); | 1272 ret.push_back(kDatabaseNameTypeByte); |
| 1239 EncodeStringWithLength(origin, &ret); | 1273 EncodeStringWithLength(origin, &ret); |
| 1240 EncodeStringWithLength(database_name, &ret); | 1274 EncodeStringWithLength(database_name, &ret); |
| 1241 return ret; | 1275 return ret; |
| 1242 } | 1276 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1275 KeyPrefix prefix; | 1309 KeyPrefix prefix; |
| 1276 const char* p = KeyPrefix::Decode(start, limit, &prefix); | 1310 const char* p = KeyPrefix::Decode(start, limit, &prefix); |
| 1277 if (!p) | 1311 if (!p) |
| 1278 return 0; | 1312 return 0; |
| 1279 DCHECK(prefix.database_id_); | 1313 DCHECK(prefix.database_id_); |
| 1280 DCHECK(!prefix.object_store_id_); | 1314 DCHECK(!prefix.object_store_id_); |
| 1281 DCHECK(!prefix.index_id_); | 1315 DCHECK(!prefix.index_id_); |
| 1282 if (p == limit) | 1316 if (p == limit) |
| 1283 return 0; | 1317 return 0; |
| 1284 unsigned char type_byte = 0; | 1318 unsigned char type_byte = 0; |
| 1285 p = DecodeByte(p, limit, type_byte); | 1319 StringPiece slice(p, limit - p); |
| 1320 if (!DecodeByte(&slice, &type_byte)) |
| 1321 return 0; |
| 1286 DCHECK_EQ(type_byte, kObjectStoreMetaDataTypeByte); | 1322 DCHECK_EQ(type_byte, kObjectStoreMetaDataTypeByte); |
| 1287 if (p == limit) | 1323 if (!DecodeVarInt(&slice, &result->object_store_id_)) |
| 1288 return 0; | |
| 1289 p = DecodeVarInt(p, limit, result->object_store_id_); | |
| 1290 if (!p) | |
| 1291 return 0; | 1324 return 0; |
| 1292 DCHECK(result->object_store_id_); | 1325 DCHECK(result->object_store_id_); |
| 1293 if (p == limit) | 1326 if (!DecodeByte(&slice, &result->meta_data_type_)) |
| 1294 return 0; | 1327 return 0; |
| 1295 return DecodeByte(p, limit, result->meta_data_type_); | 1328 return slice.begin(); |
| 1296 } | 1329 } |
| 1297 | 1330 |
| 1298 std::vector<char> ObjectStoreMetaDataKey::Encode(int64 database_id, | 1331 std::vector<char> ObjectStoreMetaDataKey::Encode(int64 database_id, |
| 1299 int64 object_store_id, | 1332 int64 object_store_id, |
| 1300 unsigned char meta_data_type) { | 1333 unsigned char meta_data_type) { |
| 1301 KeyPrefix prefix(database_id); | 1334 KeyPrefix prefix(database_id); |
| 1302 std::vector<char> ret = prefix.Encode(); | 1335 std::vector<char> ret = prefix.Encode(); |
| 1303 ret.push_back(kObjectStoreMetaDataTypeByte); | 1336 ret.push_back(kObjectStoreMetaDataTypeByte); |
| 1304 EncodeVarInt(object_store_id, &ret); | 1337 EncodeVarInt(object_store_id, &ret); |
| 1305 ret.push_back(meta_data_type); | 1338 ret.push_back(meta_data_type); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1344 KeyPrefix prefix; | 1377 KeyPrefix prefix; |
| 1345 const char* p = KeyPrefix::Decode(start, limit, &prefix); | 1378 const char* p = KeyPrefix::Decode(start, limit, &prefix); |
| 1346 if (!p) | 1379 if (!p) |
| 1347 return 0; | 1380 return 0; |
| 1348 DCHECK(prefix.database_id_); | 1381 DCHECK(prefix.database_id_); |
| 1349 DCHECK(!prefix.object_store_id_); | 1382 DCHECK(!prefix.object_store_id_); |
| 1350 DCHECK(!prefix.index_id_); | 1383 DCHECK(!prefix.index_id_); |
| 1351 if (p == limit) | 1384 if (p == limit) |
| 1352 return 0; | 1385 return 0; |
| 1353 unsigned char type_byte = 0; | 1386 unsigned char type_byte = 0; |
| 1354 p = DecodeByte(p, limit, type_byte); | 1387 StringPiece slice(p, limit - p); |
| 1388 if (!DecodeByte(&slice, &type_byte)) |
| 1389 return 0; |
| 1355 DCHECK_EQ(type_byte, kIndexMetaDataTypeByte); | 1390 DCHECK_EQ(type_byte, kIndexMetaDataTypeByte); |
| 1356 if (p == limit) | 1391 if (!DecodeVarInt(&slice, &result->object_store_id_)) |
| 1357 return 0; | 1392 return 0; |
| 1358 p = DecodeVarInt(p, limit, result->object_store_id_); | 1393 if (!DecodeVarInt(&slice, &result->index_id_)) |
| 1359 if (!p) | |
| 1360 return 0; | 1394 return 0; |
| 1361 p = DecodeVarInt(p, limit, result->index_id_); | 1395 if (!DecodeByte(&slice, &result->meta_data_type_)) |
| 1362 if (!p) | |
| 1363 return 0; | 1396 return 0; |
| 1364 if (p == limit) | 1397 return slice.begin(); |
| 1365 return 0; | |
| 1366 return DecodeByte(p, limit, result->meta_data_type_); | |
| 1367 } | 1398 } |
| 1368 | 1399 |
| 1369 std::vector<char> IndexMetaDataKey::Encode(int64 database_id, | 1400 std::vector<char> IndexMetaDataKey::Encode(int64 database_id, |
| 1370 int64 object_store_id, | 1401 int64 object_store_id, |
| 1371 int64 index_id, | 1402 int64 index_id, |
| 1372 unsigned char meta_data_type) { | 1403 unsigned char meta_data_type) { |
| 1373 KeyPrefix prefix(database_id); | 1404 KeyPrefix prefix(database_id); |
| 1374 std::vector<char> ret = prefix.Encode(); | 1405 std::vector<char> ret = prefix.Encode(); |
| 1375 ret.push_back(kIndexMetaDataTypeByte); | 1406 ret.push_back(kIndexMetaDataTypeByte); |
| 1376 EncodeVarInt(object_store_id, &ret); | 1407 EncodeVarInt(object_store_id, &ret); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1418 KeyPrefix prefix; | 1449 KeyPrefix prefix; |
| 1419 const char* p = KeyPrefix::Decode(start, limit, &prefix); | 1450 const char* p = KeyPrefix::Decode(start, limit, &prefix); |
| 1420 if (!p) | 1451 if (!p) |
| 1421 return 0; | 1452 return 0; |
| 1422 DCHECK(prefix.database_id_); | 1453 DCHECK(prefix.database_id_); |
| 1423 DCHECK(!prefix.object_store_id_); | 1454 DCHECK(!prefix.object_store_id_); |
| 1424 DCHECK(!prefix.index_id_); | 1455 DCHECK(!prefix.index_id_); |
| 1425 if (p == limit) | 1456 if (p == limit) |
| 1426 return 0; | 1457 return 0; |
| 1427 unsigned char type_byte = 0; | 1458 unsigned char type_byte = 0; |
| 1428 p = DecodeByte(p, limit, type_byte); | 1459 StringPiece slice(p, limit - p); |
| 1460 if (!DecodeByte(&slice, &type_byte)) |
| 1461 return 0; |
| 1429 DCHECK_EQ(type_byte, kObjectStoreFreeListTypeByte); | 1462 DCHECK_EQ(type_byte, kObjectStoreFreeListTypeByte); |
| 1430 if (p == limit) | 1463 if (!DecodeVarInt(&slice, &result->object_store_id_)) |
| 1431 return 0; | 1464 return 0; |
| 1432 return DecodeVarInt(p, limit, result->object_store_id_); | 1465 return slice.begin(); |
| 1433 } | 1466 } |
| 1434 | 1467 |
| 1435 std::vector<char> ObjectStoreFreeListKey::Encode(int64 database_id, | 1468 std::vector<char> ObjectStoreFreeListKey::Encode(int64 database_id, |
| 1436 int64 object_store_id) { | 1469 int64 object_store_id) { |
| 1437 KeyPrefix prefix(database_id); | 1470 KeyPrefix prefix(database_id); |
| 1438 std::vector<char> ret = prefix.Encode(); | 1471 std::vector<char> ret = prefix.Encode(); |
| 1439 ret.push_back(kObjectStoreFreeListTypeByte); | 1472 ret.push_back(kObjectStoreFreeListTypeByte); |
| 1440 EncodeVarInt(object_store_id, &ret); | 1473 EncodeVarInt(object_store_id, &ret); |
| 1441 return ret; | 1474 return ret; |
| 1442 } | 1475 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1466 KeyPrefix prefix; | 1499 KeyPrefix prefix; |
| 1467 const char* p = KeyPrefix::Decode(start, limit, &prefix); | 1500 const char* p = KeyPrefix::Decode(start, limit, &prefix); |
| 1468 if (!p) | 1501 if (!p) |
| 1469 return 0; | 1502 return 0; |
| 1470 DCHECK(prefix.database_id_); | 1503 DCHECK(prefix.database_id_); |
| 1471 DCHECK(!prefix.object_store_id_); | 1504 DCHECK(!prefix.object_store_id_); |
| 1472 DCHECK(!prefix.index_id_); | 1505 DCHECK(!prefix.index_id_); |
| 1473 if (p == limit) | 1506 if (p == limit) |
| 1474 return 0; | 1507 return 0; |
| 1475 unsigned char type_byte = 0; | 1508 unsigned char type_byte = 0; |
| 1476 p = DecodeByte(p, limit, type_byte); | 1509 StringPiece slice(p, limit - p); |
| 1510 if (!DecodeByte(&slice, &type_byte)) |
| 1511 return 0; |
| 1477 DCHECK_EQ(type_byte, kIndexFreeListTypeByte); | 1512 DCHECK_EQ(type_byte, kIndexFreeListTypeByte); |
| 1478 if (p == limit) | 1513 if (!DecodeVarInt(&slice, &result->object_store_id_)) |
| 1479 return 0; | 1514 return 0; |
| 1480 p = DecodeVarInt(p, limit, result->object_store_id_); | 1515 if (!DecodeVarInt(&slice, &result->index_id_)) |
| 1481 if (!p) | |
| 1482 return 0; | 1516 return 0; |
| 1483 return DecodeVarInt(p, limit, result->index_id_); | 1517 return slice.begin(); |
| 1484 } | 1518 } |
| 1485 | 1519 |
| 1486 std::vector<char> IndexFreeListKey::Encode(int64 database_id, | 1520 std::vector<char> IndexFreeListKey::Encode(int64 database_id, |
| 1487 int64 object_store_id, | 1521 int64 object_store_id, |
| 1488 int64 index_id) { | 1522 int64 index_id) { |
| 1489 KeyPrefix prefix(database_id); | 1523 KeyPrefix prefix(database_id); |
| 1490 std::vector<char> ret = prefix.Encode(); | 1524 std::vector<char> ret = prefix.Encode(); |
| 1491 ret.push_back(kIndexFreeListTypeByte); | 1525 ret.push_back(kIndexFreeListTypeByte); |
| 1492 EncodeVarInt(object_store_id, &ret); | 1526 EncodeVarInt(object_store_id, &ret); |
| 1493 EncodeVarInt(index_id, &ret); | 1527 EncodeVarInt(index_id, &ret); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1527 KeyPrefix prefix; | 1561 KeyPrefix prefix; |
| 1528 const char* p = KeyPrefix::Decode(start, limit, &prefix); | 1562 const char* p = KeyPrefix::Decode(start, limit, &prefix); |
| 1529 if (!p) | 1563 if (!p) |
| 1530 return 0; | 1564 return 0; |
| 1531 DCHECK(prefix.database_id_); | 1565 DCHECK(prefix.database_id_); |
| 1532 DCHECK(!prefix.object_store_id_); | 1566 DCHECK(!prefix.object_store_id_); |
| 1533 DCHECK(!prefix.index_id_); | 1567 DCHECK(!prefix.index_id_); |
| 1534 if (p == limit) | 1568 if (p == limit) |
| 1535 return 0; | 1569 return 0; |
| 1536 unsigned char type_byte = 0; | 1570 unsigned char type_byte = 0; |
| 1537 p = DecodeByte(p, limit, type_byte); | 1571 StringPiece slice(p, limit - p); |
| 1572 if (!DecodeByte(&slice, &type_byte)) |
| 1573 return 0; |
| 1538 DCHECK_EQ(type_byte, kObjectStoreNamesTypeByte); | 1574 DCHECK_EQ(type_byte, kObjectStoreNamesTypeByte); |
| 1539 return DecodeStringWithLength(p, limit, result->object_store_name_); | 1575 if (!DecodeStringWithLength(&slice, &result->object_store_name_)) |
| 1576 return 0; |
| 1577 return slice.begin(); |
| 1540 } | 1578 } |
| 1541 | 1579 |
| 1542 std::vector<char> ObjectStoreNamesKey::Encode( | 1580 std::vector<char> ObjectStoreNamesKey::Encode( |
| 1543 int64 database_id, | 1581 int64 database_id, |
| 1544 const string16& object_store_name) { | 1582 const string16& object_store_name) { |
| 1545 KeyPrefix prefix(database_id); | 1583 KeyPrefix prefix(database_id); |
| 1546 std::vector<char> ret = prefix.Encode(); | 1584 std::vector<char> ret = prefix.Encode(); |
| 1547 ret.push_back(kObjectStoreNamesTypeByte); | 1585 ret.push_back(kObjectStoreNamesTypeByte); |
| 1548 EncodeStringWithLength(object_store_name, &ret); | 1586 EncodeStringWithLength(object_store_name, &ret); |
| 1549 return ret; | 1587 return ret; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1563 KeyPrefix prefix; | 1601 KeyPrefix prefix; |
| 1564 const char* p = KeyPrefix::Decode(start, limit, &prefix); | 1602 const char* p = KeyPrefix::Decode(start, limit, &prefix); |
| 1565 if (!p) | 1603 if (!p) |
| 1566 return 0; | 1604 return 0; |
| 1567 DCHECK(prefix.database_id_); | 1605 DCHECK(prefix.database_id_); |
| 1568 DCHECK(!prefix.object_store_id_); | 1606 DCHECK(!prefix.object_store_id_); |
| 1569 DCHECK(!prefix.index_id_); | 1607 DCHECK(!prefix.index_id_); |
| 1570 if (p == limit) | 1608 if (p == limit) |
| 1571 return 0; | 1609 return 0; |
| 1572 unsigned char type_byte = 0; | 1610 unsigned char type_byte = 0; |
| 1573 p = DecodeByte(p, limit, type_byte); | 1611 StringPiece slice(p, limit - p); |
| 1612 if (!DecodeByte(&slice, &type_byte)) |
| 1613 return 0; |
| 1574 DCHECK_EQ(type_byte, kIndexNamesKeyTypeByte); | 1614 DCHECK_EQ(type_byte, kIndexNamesKeyTypeByte); |
| 1575 if (p == limit) | 1615 if (!DecodeVarInt(&slice, &result->object_store_id_)) |
| 1576 return 0; | 1616 return 0; |
| 1577 p = DecodeVarInt(p, limit, result->object_store_id_); | 1617 if (!DecodeStringWithLength(&slice, &result->index_name_)) |
| 1578 if (!p) | |
| 1579 return 0; | 1618 return 0; |
| 1580 return DecodeStringWithLength(p, limit, result->index_name_); | 1619 return slice.begin(); |
| 1581 } | 1620 } |
| 1582 | 1621 |
| 1583 std::vector<char> IndexNamesKey::Encode(int64 database_id, | 1622 std::vector<char> IndexNamesKey::Encode(int64 database_id, |
| 1584 int64 object_store_id, | 1623 int64 object_store_id, |
| 1585 const string16& index_name) { | 1624 const string16& index_name) { |
| 1586 KeyPrefix prefix(database_id); | 1625 KeyPrefix prefix(database_id); |
| 1587 std::vector<char> ret = prefix.Encode(); | 1626 std::vector<char> ret = prefix.Encode(); |
| 1588 ret.push_back(kIndexNamesKeyTypeByte); | 1627 ret.push_back(kIndexNamesKeyTypeByte); |
| 1589 EncodeVarInt(object_store_id, &ret); | 1628 EncodeVarInt(object_store_id, &ret); |
| 1590 EncodeStringWithLength(index_name, &ret); | 1629 EncodeStringWithLength(index_name, &ret); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1606 ObjectStoreDataKey* result) { | 1645 ObjectStoreDataKey* result) { |
| 1607 KeyPrefix prefix; | 1646 KeyPrefix prefix; |
| 1608 const char* p = KeyPrefix::Decode(start, end, &prefix); | 1647 const char* p = KeyPrefix::Decode(start, end, &prefix); |
| 1609 if (!p) | 1648 if (!p) |
| 1610 return 0; | 1649 return 0; |
| 1611 DCHECK(prefix.database_id_); | 1650 DCHECK(prefix.database_id_); |
| 1612 DCHECK(prefix.object_store_id_); | 1651 DCHECK(prefix.object_store_id_); |
| 1613 DCHECK_EQ(prefix.index_id_, kSpecialIndexNumber); | 1652 DCHECK_EQ(prefix.index_id_, kSpecialIndexNumber); |
| 1614 if (p == end) | 1653 if (p == end) |
| 1615 return 0; | 1654 return 0; |
| 1616 return ExtractEncodedIDBKey(p, end, &result->encoded_user_key_); | 1655 StringPiece slice(p, end - p); |
| 1656 if (!ExtractEncodedIDBKey(&slice, &result->encoded_user_key_)) |
| 1657 return 0; |
| 1658 return slice.begin(); |
| 1617 } | 1659 } |
| 1618 | 1660 |
| 1619 std::vector<char> ObjectStoreDataKey::Encode( | 1661 std::vector<char> ObjectStoreDataKey::Encode( |
| 1620 int64 database_id, | 1662 int64 database_id, |
| 1621 int64 object_store_id, | 1663 int64 object_store_id, |
| 1622 const std::vector<char> encoded_user_key) { | 1664 const std::vector<char> encoded_user_key) { |
| 1623 KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex( | 1665 KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex( |
| 1624 database_id, object_store_id, kSpecialIndexNumber)); | 1666 database_id, object_store_id, kSpecialIndexNumber)); |
| 1625 std::vector<char> ret = prefix.Encode(); | 1667 std::vector<char> ret = prefix.Encode(); |
| 1626 ret.insert(ret.end(), encoded_user_key.begin(), encoded_user_key.end()); | 1668 ret.insert(ret.end(), encoded_user_key.begin(), encoded_user_key.end()); |
| 1627 | 1669 |
| 1628 return ret; | 1670 return ret; |
| 1629 } | 1671 } |
| 1630 | 1672 |
| 1631 std::vector<char> ObjectStoreDataKey::Encode(int64 database_id, | 1673 std::vector<char> ObjectStoreDataKey::Encode(int64 database_id, |
| 1632 int64 object_store_id, | 1674 int64 object_store_id, |
| 1633 const IndexedDBKey& user_key) { | 1675 const IndexedDBKey& user_key) { |
| 1634 return Encode(database_id, object_store_id, EncodeIDBKey(user_key)); | 1676 std::vector<char> encoded_key; |
| 1677 EncodeIDBKey(user_key, &encoded_key); |
| 1678 return Encode(database_id, object_store_id, encoded_key); |
| 1635 } | 1679 } |
| 1636 | 1680 |
| 1637 int ObjectStoreDataKey::Compare(const ObjectStoreDataKey& other, bool& ok) { | 1681 int ObjectStoreDataKey::Compare(const ObjectStoreDataKey& other, bool& ok) { |
| 1638 return CompareEncodedIDBKeys(encoded_user_key_, other.encoded_user_key_, ok); | 1682 return CompareEncodedIDBKeys(encoded_user_key_, other.encoded_user_key_, ok); |
| 1639 } | 1683 } |
| 1640 | 1684 |
| 1641 scoped_ptr<IndexedDBKey> ObjectStoreDataKey::user_key() const { | 1685 scoped_ptr<IndexedDBKey> ObjectStoreDataKey::user_key() const { |
| 1642 scoped_ptr<IndexedDBKey> key; | 1686 scoped_ptr<IndexedDBKey> key; |
| 1643 DecodeIDBKey(&encoded_user_key_[0], | 1687 StringPiece slice(&encoded_user_key_[0], encoded_user_key_.size()); |
| 1644 &encoded_user_key_[0] + encoded_user_key_.size(), | 1688 if (!DecodeIDBKey(&slice, &key)) { |
| 1645 &key); | 1689 // TODO(jsbell): Return error. |
| 1690 } |
| 1646 return key.Pass(); | 1691 return key.Pass(); |
| 1647 } | 1692 } |
| 1648 | 1693 |
| 1649 const int64 ObjectStoreDataKey::kSpecialIndexNumber = kObjectStoreDataIndexId; | 1694 const int64 ObjectStoreDataKey::kSpecialIndexNumber = kObjectStoreDataIndexId; |
| 1650 | 1695 |
| 1651 ExistsEntryKey::ExistsEntryKey() {} | 1696 ExistsEntryKey::ExistsEntryKey() {} |
| 1652 ExistsEntryKey::~ExistsEntryKey() {} | 1697 ExistsEntryKey::~ExistsEntryKey() {} |
| 1653 | 1698 |
| 1654 const char* ExistsEntryKey::Decode(const char* start, | 1699 const char* ExistsEntryKey::Decode(const char* start, |
| 1655 const char* end, | 1700 const char* end, |
| 1656 ExistsEntryKey* result) { | 1701 ExistsEntryKey* result) { |
| 1657 KeyPrefix prefix; | 1702 KeyPrefix prefix; |
| 1658 const char* p = KeyPrefix::Decode(start, end, &prefix); | 1703 const char* p = KeyPrefix::Decode(start, end, &prefix); |
| 1659 if (!p) | 1704 if (!p) |
| 1660 return 0; | 1705 return 0; |
| 1661 DCHECK(prefix.database_id_); | 1706 DCHECK(prefix.database_id_); |
| 1662 DCHECK(prefix.object_store_id_); | 1707 DCHECK(prefix.object_store_id_); |
| 1663 DCHECK_EQ(prefix.index_id_, kSpecialIndexNumber); | 1708 DCHECK_EQ(prefix.index_id_, kSpecialIndexNumber); |
| 1664 if (p == end) | 1709 if (p == end) |
| 1665 return 0; | 1710 return 0; |
| 1666 return ExtractEncodedIDBKey(p, end, &result->encoded_user_key_); | 1711 StringPiece slice(p, end - p); |
| 1712 if (!ExtractEncodedIDBKey(&slice, &result->encoded_user_key_)) |
| 1713 return 0; |
| 1714 return slice.begin(); |
| 1667 } | 1715 } |
| 1668 | 1716 |
| 1669 std::vector<char> ExistsEntryKey::Encode(int64 database_id, | 1717 std::vector<char> ExistsEntryKey::Encode(int64 database_id, |
| 1670 int64 object_store_id, | 1718 int64 object_store_id, |
| 1671 const std::vector<char>& encoded_key) { | 1719 const std::vector<char>& encoded_key) { |
| 1672 KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex( | 1720 KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex( |
| 1673 database_id, object_store_id, kSpecialIndexNumber)); | 1721 database_id, object_store_id, kSpecialIndexNumber)); |
| 1674 std::vector<char> ret = prefix.Encode(); | 1722 std::vector<char> ret = prefix.Encode(); |
| 1675 ret.insert(ret.end(), encoded_key.begin(), encoded_key.end()); | 1723 ret.insert(ret.end(), encoded_key.begin(), encoded_key.end()); |
| 1676 return ret; | 1724 return ret; |
| 1677 } | 1725 } |
| 1678 | 1726 |
| 1679 std::vector<char> ExistsEntryKey::Encode(int64 database_id, | 1727 std::vector<char> ExistsEntryKey::Encode(int64 database_id, |
| 1680 int64 object_store_id, | 1728 int64 object_store_id, |
| 1681 const IndexedDBKey& user_key) { | 1729 const IndexedDBKey& user_key) { |
| 1682 return Encode(database_id, object_store_id, EncodeIDBKey(user_key)); | 1730 std::vector<char> encoded_key; |
| 1731 EncodeIDBKey(user_key, &encoded_key); |
| 1732 return Encode(database_id, object_store_id, encoded_key); |
| 1683 } | 1733 } |
| 1684 | 1734 |
| 1685 int ExistsEntryKey::Compare(const ExistsEntryKey& other, bool& ok) { | 1735 int ExistsEntryKey::Compare(const ExistsEntryKey& other, bool& ok) { |
| 1686 return CompareEncodedIDBKeys(encoded_user_key_, other.encoded_user_key_, ok); | 1736 return CompareEncodedIDBKeys(encoded_user_key_, other.encoded_user_key_, ok); |
| 1687 } | 1737 } |
| 1688 | 1738 |
| 1689 scoped_ptr<IndexedDBKey> ExistsEntryKey::user_key() const { | 1739 scoped_ptr<IndexedDBKey> ExistsEntryKey::user_key() const { |
| 1690 scoped_ptr<IndexedDBKey> key; | 1740 scoped_ptr<IndexedDBKey> key; |
| 1691 DecodeIDBKey(&encoded_user_key_[0], | 1741 StringPiece slice(&encoded_user_key_[0], encoded_user_key_.size()); |
| 1692 &encoded_user_key_[0] + encoded_user_key_.size(), | 1742 if (!DecodeIDBKey(&slice, &key)) { |
| 1693 &key); | 1743 // TODO(jsbell): Return error. |
| 1744 } |
| 1694 return key.Pass(); | 1745 return key.Pass(); |
| 1695 } | 1746 } |
| 1696 | 1747 |
| 1697 const int64 ExistsEntryKey::kSpecialIndexNumber = kExistsEntryIndexId; | 1748 const int64 ExistsEntryKey::kSpecialIndexNumber = kExistsEntryIndexId; |
| 1698 | 1749 |
| 1699 IndexDataKey::IndexDataKey() | 1750 IndexDataKey::IndexDataKey() |
| 1700 : database_id_(-1), | 1751 : database_id_(-1), |
| 1701 object_store_id_(-1), | 1752 object_store_id_(-1), |
| 1702 index_id_(-1), | 1753 index_id_(-1), |
| 1703 sequence_number_(-1) {} | 1754 sequence_number_(-1) {} |
| 1704 | 1755 |
| 1705 IndexDataKey::~IndexDataKey() {} | 1756 IndexDataKey::~IndexDataKey() {} |
| 1706 | 1757 |
| 1707 const char* IndexDataKey::Decode(const char* start, | 1758 const char* IndexDataKey::Decode(const char* start, |
| 1708 const char* limit, | 1759 const char* limit, |
| 1709 IndexDataKey* result) { | 1760 IndexDataKey* result) { |
| 1710 KeyPrefix prefix; | 1761 KeyPrefix prefix; |
| 1711 const char* p = KeyPrefix::Decode(start, limit, &prefix); | 1762 const char* p = KeyPrefix::Decode(start, limit, &prefix); |
| 1712 if (!p) | 1763 if (!p) |
| 1713 return 0; | 1764 return 0; |
| 1714 DCHECK(prefix.database_id_); | 1765 DCHECK(prefix.database_id_); |
| 1715 DCHECK(prefix.object_store_id_); | 1766 DCHECK(prefix.object_store_id_); |
| 1716 DCHECK_GE(prefix.index_id_, kMinimumIndexId); | 1767 DCHECK_GE(prefix.index_id_, kMinimumIndexId); |
| 1717 result->database_id_ = prefix.database_id_; | 1768 result->database_id_ = prefix.database_id_; |
| 1718 result->object_store_id_ = prefix.object_store_id_; | 1769 result->object_store_id_ = prefix.object_store_id_; |
| 1719 result->index_id_ = prefix.index_id_; | 1770 result->index_id_ = prefix.index_id_; |
| 1720 result->sequence_number_ = -1; | 1771 result->sequence_number_ = -1; |
| 1721 result->encoded_primary_key_ = MinIDBKey(); | 1772 result->encoded_primary_key_ = MinIDBKey(); |
| 1722 | 1773 |
| 1723 p = ExtractEncodedIDBKey(p, limit, &result->encoded_user_key_); | 1774 StringPiece slice(p, limit - p); |
| 1724 if (!p) | 1775 if (!ExtractEncodedIDBKey(&slice, &result->encoded_user_key_)) |
| 1725 return 0; | 1776 return 0; |
| 1726 | 1777 |
| 1727 // [optional] sequence number | 1778 // [optional] sequence number |
| 1728 if (p == limit) | 1779 if (slice.empty()) |
| 1729 return p; | 1780 return slice.begin(); |
| 1730 p = DecodeVarInt(p, limit, result->sequence_number_); | 1781 if (!DecodeVarInt(&slice, &result->sequence_number_)) |
| 1731 if (!p) | |
| 1732 return 0; | 1782 return 0; |
| 1733 | 1783 |
| 1734 // [optional] primary key | 1784 // [optional] primary key |
| 1735 if (p == limit) | 1785 if (slice.empty()) |
| 1736 return p; | 1786 return slice.begin(); |
| 1737 p = ExtractEncodedIDBKey(p, limit, &result->encoded_primary_key_); | 1787 if (!ExtractEncodedIDBKey(&slice, &result->encoded_primary_key_)) |
| 1738 if (!p) | |
| 1739 return 0; | 1788 return 0; |
| 1740 | 1789 |
| 1741 return p; | 1790 return slice.begin(); |
| 1742 } | 1791 } |
| 1743 | 1792 |
| 1744 std::vector<char> IndexDataKey::Encode( | 1793 std::vector<char> IndexDataKey::Encode( |
| 1745 int64 database_id, | 1794 int64 database_id, |
| 1746 int64 object_store_id, | 1795 int64 object_store_id, |
| 1747 int64 index_id, | 1796 int64 index_id, |
| 1748 const std::vector<char>& encoded_user_key, | 1797 const std::vector<char>& encoded_user_key, |
| 1749 const std::vector<char>& encoded_primary_key, | 1798 const std::vector<char>& encoded_primary_key, |
| 1750 int64 sequence_number) { | 1799 int64 sequence_number) { |
| 1751 KeyPrefix prefix(database_id, object_store_id, index_id); | 1800 KeyPrefix prefix(database_id, object_store_id, index_id); |
| 1752 std::vector<char> ret = prefix.Encode(); | 1801 std::vector<char> ret = prefix.Encode(); |
| 1753 ret.insert(ret.end(), encoded_user_key.begin(), encoded_user_key.end()); | 1802 ret.insert(ret.end(), encoded_user_key.begin(), encoded_user_key.end()); |
| 1754 EncodeVarInt(sequence_number, &ret); | 1803 EncodeVarInt(sequence_number, &ret); |
| 1755 ret.insert(ret.end(), encoded_primary_key.begin(), encoded_primary_key.end()); | 1804 ret.insert(ret.end(), encoded_primary_key.begin(), encoded_primary_key.end()); |
| 1756 return ret; | 1805 return ret; |
| 1757 } | 1806 } |
| 1758 | 1807 |
| 1759 std::vector<char> IndexDataKey::Encode(int64 database_id, | 1808 std::vector<char> IndexDataKey::Encode(int64 database_id, |
| 1760 int64 object_store_id, | 1809 int64 object_store_id, |
| 1761 int64 index_id, | 1810 int64 index_id, |
| 1762 const IndexedDBKey& user_key) { | 1811 const IndexedDBKey& user_key) { |
| 1763 return Encode(database_id, | 1812 std::vector<char> encoded_key; |
| 1764 object_store_id, | 1813 EncodeIDBKey(user_key, &encoded_key); |
| 1765 index_id, | 1814 return Encode( |
| 1766 EncodeIDBKey(user_key), | 1815 database_id, object_store_id, index_id, encoded_key, MinIDBKey()); |
| 1767 MinIDBKey()); | |
| 1768 } | 1816 } |
| 1769 | 1817 |
| 1770 std::vector<char> IndexDataKey::EncodeMinKey(int64 database_id, | 1818 std::vector<char> IndexDataKey::EncodeMinKey(int64 database_id, |
| 1771 int64 object_store_id, | 1819 int64 object_store_id, |
| 1772 int64 index_id) { | 1820 int64 index_id) { |
| 1773 return Encode( | 1821 return Encode( |
| 1774 database_id, object_store_id, index_id, MinIDBKey(), MinIDBKey()); | 1822 database_id, object_store_id, index_id, MinIDBKey(), MinIDBKey()); |
| 1775 } | 1823 } |
| 1776 | 1824 |
| 1777 std::vector<char> IndexDataKey::EncodeMaxKey(int64 database_id, | 1825 std::vector<char> IndexDataKey::EncodeMaxKey(int64 database_id, |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1814 return object_store_id_; | 1862 return object_store_id_; |
| 1815 } | 1863 } |
| 1816 | 1864 |
| 1817 int64 IndexDataKey::IndexId() const { | 1865 int64 IndexDataKey::IndexId() const { |
| 1818 DCHECK_GE(index_id_, 0); | 1866 DCHECK_GE(index_id_, 0); |
| 1819 return index_id_; | 1867 return index_id_; |
| 1820 } | 1868 } |
| 1821 | 1869 |
| 1822 scoped_ptr<IndexedDBKey> IndexDataKey::user_key() const { | 1870 scoped_ptr<IndexedDBKey> IndexDataKey::user_key() const { |
| 1823 scoped_ptr<IndexedDBKey> key; | 1871 scoped_ptr<IndexedDBKey> key; |
| 1824 DecodeIDBKey(&encoded_user_key_[0], | 1872 StringPiece slice(&encoded_user_key_[0], encoded_user_key_.size()); |
| 1825 &encoded_user_key_[0] + encoded_user_key_.size(), | 1873 if (!DecodeIDBKey(&slice, &key)) { |
| 1826 &key); | 1874 // TODO(jsbell): Return error. |
| 1875 } |
| 1827 return key.Pass(); | 1876 return key.Pass(); |
| 1828 } | 1877 } |
| 1829 | 1878 |
| 1830 scoped_ptr<IndexedDBKey> IndexDataKey::primary_key() const { | 1879 scoped_ptr<IndexedDBKey> IndexDataKey::primary_key() const { |
| 1831 scoped_ptr<IndexedDBKey> key; | 1880 scoped_ptr<IndexedDBKey> key; |
| 1832 DecodeIDBKey(&encoded_primary_key_[0], | 1881 StringPiece slice(&encoded_primary_key_[0], encoded_primary_key_.size()); |
| 1833 &encoded_primary_key_[0] + encoded_primary_key_.size(), | 1882 if (!DecodeIDBKey(&slice, &key)) { |
| 1834 &key); | 1883 // TODO(jsbell): Return error. |
| 1884 } |
| 1835 return key.Pass(); | 1885 return key.Pass(); |
| 1836 } | 1886 } |
| 1837 | 1887 |
| 1838 } // namespace content | 1888 } // namespace content |
| OLD | NEW |