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

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

Issue 16256014: IndexedDB: Convert decoding functions to pass StringPieces vs. pointers (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Correct bogus iterator dereference in unit test Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 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
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
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 false;
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->clear();
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(*value))
508 const char* limit, 497 return false;
509 std::vector<char>* result = 0) { 498
510 DCHECK_GT(limit, start); 499 memcpy(value, slice->begin(), sizeof(*value));
511 const char* p = start; 500 slice->remove_prefix(sizeof(*value));
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
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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 return 0; 947 return 0;
931 if (ptr_a == end_a) 948 if (ptr_a == end_a)
932 return -1; 949 return -1;
933 if (ptr_b == end_b) 950 if (ptr_b == end_b)
934 return 1; // TODO(jsbell): This case of non-existing user keys should not 951 return 1; // TODO(jsbell): This case of non-existing user keys should not
935 // have to be handled this way. 952 // have to be handled this way.
936 953
937 const bool ignore_duplicates = false; 954 const bool ignore_duplicates = false;
938 return Compare<ObjectStoreDataKey>(a, b, ignore_duplicates, ok); 955 return Compare<ObjectStoreDataKey>(a, b, ignore_duplicates, ok);
939 } 956 }
957
940 if (prefix_a.type() == KeyPrefix::EXISTS_ENTRY) { 958 if (prefix_a.type() == KeyPrefix::EXISTS_ENTRY) {
941 if (ptr_a == end_a && ptr_b == end_b) 959 if (ptr_a == end_a && ptr_b == end_b)
942 return 0; 960 return 0;
943 if (ptr_a == end_a) 961 if (ptr_a == end_a)
944 return -1; 962 return -1;
945 if (ptr_b == end_b) 963 if (ptr_b == end_b)
946 return 1; // TODO(jsbell): This case of non-existing user keys should not 964 return 1; // TODO(jsbell): This case of non-existing user keys should not
947 // have to be handled this way. 965 // have to be handled this way.
948 966
949 const bool ignore_duplicates = false; 967 const bool ignore_duplicates = false;
950 return Compare<ExistsEntryKey>(a, b, ignore_duplicates, ok); 968 return Compare<ExistsEntryKey>(a, b, ignore_duplicates, ok);
951 } 969 }
970
952 if (prefix_a.type() == KeyPrefix::INDEX_DATA) { 971 if (prefix_a.type() == KeyPrefix::INDEX_DATA) {
953 if (ptr_a == end_a && ptr_b == end_b) 972 if (ptr_a == end_a && ptr_b == end_b)
954 return 0; 973 return 0;
955 if (ptr_a == end_a) 974 if (ptr_a == end_a)
956 return -1; 975 return -1;
957 if (ptr_b == end_b) 976 if (ptr_b == end_b)
958 return 1; // TODO(jsbell): This case of non-existing user keys should not 977 return 1; // TODO(jsbell): This case of non-existing user keys should not
959 // have to be handled this way. 978 // have to be handled this way.
960 979
961 bool ignore_duplicates = index_keys; 980 bool ignore_duplicates = index_keys;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1048 unsigned char first_byte = *start++; 1067 unsigned char first_byte = *start++;
1049 1068
1050 int database_id_bytes = ((first_byte >> 5) & 0x7) + 1; 1069 int database_id_bytes = ((first_byte >> 5) & 0x7) + 1;
1051 int object_store_id_bytes = ((first_byte >> 2) & 0x7) + 1; 1070 int object_store_id_bytes = ((first_byte >> 2) & 0x7) + 1;
1052 int index_id_bytes = (first_byte & 0x3) + 1; 1071 int index_id_bytes = (first_byte & 0x3) + 1;
1053 1072
1054 if (start + database_id_bytes + object_store_id_bytes + index_id_bytes > 1073 if (start + database_id_bytes + object_store_id_bytes + index_id_bytes >
1055 limit) 1074 limit)
1056 return 0; 1075 return 0;
1057 1076
1058 result->database_id_ = DecodeInt(start, start + database_id_bytes); 1077 {
1078 StringPiece slice(start, database_id_bytes);
1079 if (!DecodeInt(&slice, &result->database_id_))
1080 return 0;
1081 }
1059 start += database_id_bytes; 1082 start += database_id_bytes;
1060 result->object_store_id_ = DecodeInt(start, start + object_store_id_bytes); 1083 {
1084 StringPiece slice(start, object_store_id_bytes);
1085 if (!DecodeInt(&slice, &result->object_store_id_))
1086 return 0;
1087 }
1061 start += object_store_id_bytes; 1088 start += object_store_id_bytes;
1062 result->index_id_ = DecodeInt(start, start + index_id_bytes); 1089 {
1090 StringPiece slice(start, index_id_bytes);
1091 if (!DecodeInt(&slice, &result->index_id_))
1092 return 0;
1093 }
1063 start += index_id_bytes; 1094 start += index_id_bytes;
1064 1095
1065 return start; 1096 return start;
1066 } 1097 }
1067 1098
1068 std::vector<char> KeyPrefix::EncodeEmpty() { 1099 std::vector<char> KeyPrefix::EncodeEmpty() {
1069 const std::vector<char> result(4, 0); 1100 const std::vector<char> result(4, 0);
1070 DCHECK(EncodeInternal(0, 0, 0) == std::vector<char>(4, 0)); 1101 DCHECK(EncodeInternal(0, 0, 0) == std::vector<char>(4, 0));
1071 return result; 1102 return result;
1072 } 1103 }
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 KeyPrefix prefix; 1205 KeyPrefix prefix;
1175 const char* p = KeyPrefix::Decode(start, limit, &prefix); 1206 const char* p = KeyPrefix::Decode(start, limit, &prefix);
1176 if (!p) 1207 if (!p)
1177 return 0; 1208 return 0;
1178 DCHECK(!prefix.database_id_); 1209 DCHECK(!prefix.database_id_);
1179 DCHECK(!prefix.object_store_id_); 1210 DCHECK(!prefix.object_store_id_);
1180 DCHECK(!prefix.index_id_); 1211 DCHECK(!prefix.index_id_);
1181 if (p == limit) 1212 if (p == limit)
1182 return 0; 1213 return 0;
1183 unsigned char type_byte = 0; 1214 unsigned char type_byte = 0;
1184 p = DecodeByte(p, limit, type_byte); 1215 StringPiece slice(p, limit - p);
1216 if (!DecodeByte(&slice, &type_byte))
1217 return 0;
1185 DCHECK_EQ(type_byte, kDatabaseFreeListTypeByte); 1218 DCHECK_EQ(type_byte, kDatabaseFreeListTypeByte);
1186 if (p == limit) 1219 if (slice.empty())
1187 return 0; 1220 return 0;
1188 return DecodeVarInt(p, limit, result->database_id_); 1221 if (!DecodeVarInt(&slice, &result->database_id_))
1222 return 0;
1223 return slice.begin();
1189 } 1224 }
1190 1225
1191 std::vector<char> DatabaseFreeListKey::Encode(int64 database_id) { 1226 std::vector<char> DatabaseFreeListKey::Encode(int64 database_id) {
1192 std::vector<char> ret = KeyPrefix::EncodeEmpty(); 1227 std::vector<char> ret = KeyPrefix::EncodeEmpty();
1193 ret.push_back(kDatabaseFreeListTypeByte); 1228 ret.push_back(kDatabaseFreeListTypeByte);
1194 EncodeVarInt(database_id, &ret); 1229 EncodeVarInt(database_id, &ret);
1195 return ret; 1230 return ret;
1196 } 1231 }
1197 1232
1198 std::vector<char> DatabaseFreeListKey::EncodeMaxKey() { 1233 std::vector<char> DatabaseFreeListKey::EncodeMaxKey() {
(...skipping 16 matching lines...) Expand all
1215 KeyPrefix prefix; 1250 KeyPrefix prefix;
1216 const char* p = KeyPrefix::Decode(start, limit, &prefix); 1251 const char* p = KeyPrefix::Decode(start, limit, &prefix);
1217 if (!p) 1252 if (!p)
1218 return p; 1253 return p;
1219 DCHECK(!prefix.database_id_); 1254 DCHECK(!prefix.database_id_);
1220 DCHECK(!prefix.object_store_id_); 1255 DCHECK(!prefix.object_store_id_);
1221 DCHECK(!prefix.index_id_); 1256 DCHECK(!prefix.index_id_);
1222 if (p == limit) 1257 if (p == limit)
1223 return 0; 1258 return 0;
1224 unsigned char type_byte = 0; 1259 unsigned char type_byte = 0;
1225 p = DecodeByte(p, limit, type_byte); 1260 StringPiece slice(p, limit - p);
1261 if (!DecodeByte(&slice, &type_byte))
1262 return 0;
1226 DCHECK_EQ(type_byte, kDatabaseNameTypeByte); 1263 DCHECK_EQ(type_byte, kDatabaseNameTypeByte);
1227 if (p == limit) 1264 if (!DecodeStringWithLength(&slice, &result->origin_))
1228 return 0; 1265 return 0;
1229 p = DecodeStringWithLength(p, limit, result->origin_); 1266 if (!DecodeStringWithLength(&slice, &result->database_name_))
1230 if (!p)
1231 return 0; 1267 return 0;
1232 return DecodeStringWithLength(p, limit, result->database_name_); 1268 return slice.begin();
1233 } 1269 }
1234 1270
1235 std::vector<char> DatabaseNameKey::Encode(const string16& origin, 1271 std::vector<char> DatabaseNameKey::Encode(const string16& origin,
1236 const string16& database_name) { 1272 const string16& database_name) {
1237 std::vector<char> ret = KeyPrefix::EncodeEmpty(); 1273 std::vector<char> ret = KeyPrefix::EncodeEmpty();
1238 ret.push_back(kDatabaseNameTypeByte); 1274 ret.push_back(kDatabaseNameTypeByte);
1239 EncodeStringWithLength(origin, &ret); 1275 EncodeStringWithLength(origin, &ret);
1240 EncodeStringWithLength(database_name, &ret); 1276 EncodeStringWithLength(database_name, &ret);
1241 return ret; 1277 return ret;
1242 } 1278 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1275 KeyPrefix prefix; 1311 KeyPrefix prefix;
1276 const char* p = KeyPrefix::Decode(start, limit, &prefix); 1312 const char* p = KeyPrefix::Decode(start, limit, &prefix);
1277 if (!p) 1313 if (!p)
1278 return 0; 1314 return 0;
1279 DCHECK(prefix.database_id_); 1315 DCHECK(prefix.database_id_);
1280 DCHECK(!prefix.object_store_id_); 1316 DCHECK(!prefix.object_store_id_);
1281 DCHECK(!prefix.index_id_); 1317 DCHECK(!prefix.index_id_);
1282 if (p == limit) 1318 if (p == limit)
1283 return 0; 1319 return 0;
1284 unsigned char type_byte = 0; 1320 unsigned char type_byte = 0;
1285 p = DecodeByte(p, limit, type_byte); 1321 StringPiece slice(p, limit - p);
1322 if (!DecodeByte(&slice, &type_byte))
1323 return 0;
1286 DCHECK_EQ(type_byte, kObjectStoreMetaDataTypeByte); 1324 DCHECK_EQ(type_byte, kObjectStoreMetaDataTypeByte);
1287 if (p == limit) 1325 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; 1326 return 0;
1292 DCHECK(result->object_store_id_); 1327 DCHECK(result->object_store_id_);
1293 if (p == limit) 1328 if (!DecodeByte(&slice, &result->meta_data_type_))
1294 return 0; 1329 return 0;
1295 return DecodeByte(p, limit, result->meta_data_type_); 1330 return slice.begin();
1296 } 1331 }
1297 1332
1298 std::vector<char> ObjectStoreMetaDataKey::Encode(int64 database_id, 1333 std::vector<char> ObjectStoreMetaDataKey::Encode(int64 database_id,
1299 int64 object_store_id, 1334 int64 object_store_id,
1300 unsigned char meta_data_type) { 1335 unsigned char meta_data_type) {
1301 KeyPrefix prefix(database_id); 1336 KeyPrefix prefix(database_id);
1302 std::vector<char> ret = prefix.Encode(); 1337 std::vector<char> ret = prefix.Encode();
1303 ret.push_back(kObjectStoreMetaDataTypeByte); 1338 ret.push_back(kObjectStoreMetaDataTypeByte);
1304 EncodeVarInt(object_store_id, &ret); 1339 EncodeVarInt(object_store_id, &ret);
1305 ret.push_back(meta_data_type); 1340 ret.push_back(meta_data_type);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1344 KeyPrefix prefix; 1379 KeyPrefix prefix;
1345 const char* p = KeyPrefix::Decode(start, limit, &prefix); 1380 const char* p = KeyPrefix::Decode(start, limit, &prefix);
1346 if (!p) 1381 if (!p)
1347 return 0; 1382 return 0;
1348 DCHECK(prefix.database_id_); 1383 DCHECK(prefix.database_id_);
1349 DCHECK(!prefix.object_store_id_); 1384 DCHECK(!prefix.object_store_id_);
1350 DCHECK(!prefix.index_id_); 1385 DCHECK(!prefix.index_id_);
1351 if (p == limit) 1386 if (p == limit)
1352 return 0; 1387 return 0;
1353 unsigned char type_byte = 0; 1388 unsigned char type_byte = 0;
1354 p = DecodeByte(p, limit, type_byte); 1389 StringPiece slice(p, limit - p);
1390 if (!DecodeByte(&slice, &type_byte))
1391 return 0;
1355 DCHECK_EQ(type_byte, kIndexMetaDataTypeByte); 1392 DCHECK_EQ(type_byte, kIndexMetaDataTypeByte);
1356 if (p == limit) 1393 if (!DecodeVarInt(&slice, &result->object_store_id_))
1357 return 0; 1394 return 0;
1358 p = DecodeVarInt(p, limit, result->object_store_id_); 1395 if (!DecodeVarInt(&slice, &result->index_id_))
1359 if (!p)
1360 return 0; 1396 return 0;
1361 p = DecodeVarInt(p, limit, result->index_id_); 1397 if (!DecodeByte(&slice, &result->meta_data_type_))
1362 if (!p)
1363 return 0; 1398 return 0;
1364 if (p == limit) 1399 return slice.begin();
1365 return 0;
1366 return DecodeByte(p, limit, result->meta_data_type_);
1367 } 1400 }
1368 1401
1369 std::vector<char> IndexMetaDataKey::Encode(int64 database_id, 1402 std::vector<char> IndexMetaDataKey::Encode(int64 database_id,
1370 int64 object_store_id, 1403 int64 object_store_id,
1371 int64 index_id, 1404 int64 index_id,
1372 unsigned char meta_data_type) { 1405 unsigned char meta_data_type) {
1373 KeyPrefix prefix(database_id); 1406 KeyPrefix prefix(database_id);
1374 std::vector<char> ret = prefix.Encode(); 1407 std::vector<char> ret = prefix.Encode();
1375 ret.push_back(kIndexMetaDataTypeByte); 1408 ret.push_back(kIndexMetaDataTypeByte);
1376 EncodeVarInt(object_store_id, &ret); 1409 EncodeVarInt(object_store_id, &ret);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1418 KeyPrefix prefix; 1451 KeyPrefix prefix;
1419 const char* p = KeyPrefix::Decode(start, limit, &prefix); 1452 const char* p = KeyPrefix::Decode(start, limit, &prefix);
1420 if (!p) 1453 if (!p)
1421 return 0; 1454 return 0;
1422 DCHECK(prefix.database_id_); 1455 DCHECK(prefix.database_id_);
1423 DCHECK(!prefix.object_store_id_); 1456 DCHECK(!prefix.object_store_id_);
1424 DCHECK(!prefix.index_id_); 1457 DCHECK(!prefix.index_id_);
1425 if (p == limit) 1458 if (p == limit)
1426 return 0; 1459 return 0;
1427 unsigned char type_byte = 0; 1460 unsigned char type_byte = 0;
1428 p = DecodeByte(p, limit, type_byte); 1461 StringPiece slice(p, limit - p);
1462 if (!DecodeByte(&slice, &type_byte))
1463 return 0;
1429 DCHECK_EQ(type_byte, kObjectStoreFreeListTypeByte); 1464 DCHECK_EQ(type_byte, kObjectStoreFreeListTypeByte);
1430 if (p == limit) 1465 if (!DecodeVarInt(&slice, &result->object_store_id_))
1431 return 0; 1466 return 0;
1432 return DecodeVarInt(p, limit, result->object_store_id_); 1467 return slice.begin();
1433 } 1468 }
1434 1469
1435 std::vector<char> ObjectStoreFreeListKey::Encode(int64 database_id, 1470 std::vector<char> ObjectStoreFreeListKey::Encode(int64 database_id,
1436 int64 object_store_id) { 1471 int64 object_store_id) {
1437 KeyPrefix prefix(database_id); 1472 KeyPrefix prefix(database_id);
1438 std::vector<char> ret = prefix.Encode(); 1473 std::vector<char> ret = prefix.Encode();
1439 ret.push_back(kObjectStoreFreeListTypeByte); 1474 ret.push_back(kObjectStoreFreeListTypeByte);
1440 EncodeVarInt(object_store_id, &ret); 1475 EncodeVarInt(object_store_id, &ret);
1441 return ret; 1476 return ret;
1442 } 1477 }
(...skipping 23 matching lines...) Expand all
1466 KeyPrefix prefix; 1501 KeyPrefix prefix;
1467 const char* p = KeyPrefix::Decode(start, limit, &prefix); 1502 const char* p = KeyPrefix::Decode(start, limit, &prefix);
1468 if (!p) 1503 if (!p)
1469 return 0; 1504 return 0;
1470 DCHECK(prefix.database_id_); 1505 DCHECK(prefix.database_id_);
1471 DCHECK(!prefix.object_store_id_); 1506 DCHECK(!prefix.object_store_id_);
1472 DCHECK(!prefix.index_id_); 1507 DCHECK(!prefix.index_id_);
1473 if (p == limit) 1508 if (p == limit)
1474 return 0; 1509 return 0;
1475 unsigned char type_byte = 0; 1510 unsigned char type_byte = 0;
1476 p = DecodeByte(p, limit, type_byte); 1511 StringPiece slice(p, limit - p);
1512 if (!DecodeByte(&slice, &type_byte))
1513 return 0;
1477 DCHECK_EQ(type_byte, kIndexFreeListTypeByte); 1514 DCHECK_EQ(type_byte, kIndexFreeListTypeByte);
1478 if (p == limit) 1515 if (!DecodeVarInt(&slice, &result->object_store_id_))
1479 return 0; 1516 return 0;
1480 p = DecodeVarInt(p, limit, result->object_store_id_); 1517 if (!DecodeVarInt(&slice, &result->index_id_))
1481 if (!p)
1482 return 0; 1518 return 0;
1483 return DecodeVarInt(p, limit, result->index_id_); 1519 return slice.begin();
1484 } 1520 }
1485 1521
1486 std::vector<char> IndexFreeListKey::Encode(int64 database_id, 1522 std::vector<char> IndexFreeListKey::Encode(int64 database_id,
1487 int64 object_store_id, 1523 int64 object_store_id,
1488 int64 index_id) { 1524 int64 index_id) {
1489 KeyPrefix prefix(database_id); 1525 KeyPrefix prefix(database_id);
1490 std::vector<char> ret = prefix.Encode(); 1526 std::vector<char> ret = prefix.Encode();
1491 ret.push_back(kIndexFreeListTypeByte); 1527 ret.push_back(kIndexFreeListTypeByte);
1492 EncodeVarInt(object_store_id, &ret); 1528 EncodeVarInt(object_store_id, &ret);
1493 EncodeVarInt(index_id, &ret); 1529 EncodeVarInt(index_id, &ret);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1527 KeyPrefix prefix; 1563 KeyPrefix prefix;
1528 const char* p = KeyPrefix::Decode(start, limit, &prefix); 1564 const char* p = KeyPrefix::Decode(start, limit, &prefix);
1529 if (!p) 1565 if (!p)
1530 return 0; 1566 return 0;
1531 DCHECK(prefix.database_id_); 1567 DCHECK(prefix.database_id_);
1532 DCHECK(!prefix.object_store_id_); 1568 DCHECK(!prefix.object_store_id_);
1533 DCHECK(!prefix.index_id_); 1569 DCHECK(!prefix.index_id_);
1534 if (p == limit) 1570 if (p == limit)
1535 return 0; 1571 return 0;
1536 unsigned char type_byte = 0; 1572 unsigned char type_byte = 0;
1537 p = DecodeByte(p, limit, type_byte); 1573 StringPiece slice(p, limit - p);
1574 if (!DecodeByte(&slice, &type_byte))
1575 return 0;
1538 DCHECK_EQ(type_byte, kObjectStoreNamesTypeByte); 1576 DCHECK_EQ(type_byte, kObjectStoreNamesTypeByte);
1539 return DecodeStringWithLength(p, limit, result->object_store_name_); 1577 if (!DecodeStringWithLength(&slice, &result->object_store_name_))
1578 return 0;
1579 return slice.begin();
1540 } 1580 }
1541 1581
1542 std::vector<char> ObjectStoreNamesKey::Encode( 1582 std::vector<char> ObjectStoreNamesKey::Encode(
1543 int64 database_id, 1583 int64 database_id,
1544 const string16& object_store_name) { 1584 const string16& object_store_name) {
1545 KeyPrefix prefix(database_id); 1585 KeyPrefix prefix(database_id);
1546 std::vector<char> ret = prefix.Encode(); 1586 std::vector<char> ret = prefix.Encode();
1547 ret.push_back(kObjectStoreNamesTypeByte); 1587 ret.push_back(kObjectStoreNamesTypeByte);
1548 EncodeStringWithLength(object_store_name, &ret); 1588 EncodeStringWithLength(object_store_name, &ret);
1549 return ret; 1589 return ret;
(...skipping 13 matching lines...) Expand all
1563 KeyPrefix prefix; 1603 KeyPrefix prefix;
1564 const char* p = KeyPrefix::Decode(start, limit, &prefix); 1604 const char* p = KeyPrefix::Decode(start, limit, &prefix);
1565 if (!p) 1605 if (!p)
1566 return 0; 1606 return 0;
1567 DCHECK(prefix.database_id_); 1607 DCHECK(prefix.database_id_);
1568 DCHECK(!prefix.object_store_id_); 1608 DCHECK(!prefix.object_store_id_);
1569 DCHECK(!prefix.index_id_); 1609 DCHECK(!prefix.index_id_);
1570 if (p == limit) 1610 if (p == limit)
1571 return 0; 1611 return 0;
1572 unsigned char type_byte = 0; 1612 unsigned char type_byte = 0;
1573 p = DecodeByte(p, limit, type_byte); 1613 StringPiece slice(p, limit - p);
1614 if (!DecodeByte(&slice, &type_byte))
1615 return 0;
1574 DCHECK_EQ(type_byte, kIndexNamesKeyTypeByte); 1616 DCHECK_EQ(type_byte, kIndexNamesKeyTypeByte);
1575 if (p == limit) 1617 if (!DecodeVarInt(&slice, &result->object_store_id_))
1576 return 0; 1618 return 0;
1577 p = DecodeVarInt(p, limit, result->object_store_id_); 1619 if (!DecodeStringWithLength(&slice, &result->index_name_))
1578 if (!p)
1579 return 0; 1620 return 0;
1580 return DecodeStringWithLength(p, limit, result->index_name_); 1621 return slice.begin();
1581 } 1622 }
1582 1623
1583 std::vector<char> IndexNamesKey::Encode(int64 database_id, 1624 std::vector<char> IndexNamesKey::Encode(int64 database_id,
1584 int64 object_store_id, 1625 int64 object_store_id,
1585 const string16& index_name) { 1626 const string16& index_name) {
1586 KeyPrefix prefix(database_id); 1627 KeyPrefix prefix(database_id);
1587 std::vector<char> ret = prefix.Encode(); 1628 std::vector<char> ret = prefix.Encode();
1588 ret.push_back(kIndexNamesKeyTypeByte); 1629 ret.push_back(kIndexNamesKeyTypeByte);
1589 EncodeVarInt(object_store_id, &ret); 1630 EncodeVarInt(object_store_id, &ret);
1590 EncodeStringWithLength(index_name, &ret); 1631 EncodeStringWithLength(index_name, &ret);
(...skipping 15 matching lines...) Expand all
1606 ObjectStoreDataKey* result) { 1647 ObjectStoreDataKey* result) {
1607 KeyPrefix prefix; 1648 KeyPrefix prefix;
1608 const char* p = KeyPrefix::Decode(start, end, &prefix); 1649 const char* p = KeyPrefix::Decode(start, end, &prefix);
1609 if (!p) 1650 if (!p)
1610 return 0; 1651 return 0;
1611 DCHECK(prefix.database_id_); 1652 DCHECK(prefix.database_id_);
1612 DCHECK(prefix.object_store_id_); 1653 DCHECK(prefix.object_store_id_);
1613 DCHECK_EQ(prefix.index_id_, kSpecialIndexNumber); 1654 DCHECK_EQ(prefix.index_id_, kSpecialIndexNumber);
1614 if (p == end) 1655 if (p == end)
1615 return 0; 1656 return 0;
1616 return ExtractEncodedIDBKey(p, end, &result->encoded_user_key_); 1657 StringPiece slice(p, end - p);
1658 if (!ExtractEncodedIDBKey(&slice, &result->encoded_user_key_))
1659 return 0;
1660 return slice.begin();
1617 } 1661 }
1618 1662
1619 std::vector<char> ObjectStoreDataKey::Encode( 1663 std::vector<char> ObjectStoreDataKey::Encode(
1620 int64 database_id, 1664 int64 database_id,
1621 int64 object_store_id, 1665 int64 object_store_id,
1622 const std::vector<char> encoded_user_key) { 1666 const std::vector<char> encoded_user_key) {
1623 KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex( 1667 KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex(
1624 database_id, object_store_id, kSpecialIndexNumber)); 1668 database_id, object_store_id, kSpecialIndexNumber));
1625 std::vector<char> ret = prefix.Encode(); 1669 std::vector<char> ret = prefix.Encode();
1626 ret.insert(ret.end(), encoded_user_key.begin(), encoded_user_key.end()); 1670 ret.insert(ret.end(), encoded_user_key.begin(), encoded_user_key.end());
1627 1671
1628 return ret; 1672 return ret;
1629 } 1673 }
1630 1674
1631 std::vector<char> ObjectStoreDataKey::Encode(int64 database_id, 1675 std::vector<char> ObjectStoreDataKey::Encode(int64 database_id,
1632 int64 object_store_id, 1676 int64 object_store_id,
1633 const IndexedDBKey& user_key) { 1677 const IndexedDBKey& user_key) {
1634 return Encode(database_id, object_store_id, EncodeIDBKey(user_key)); 1678 std::vector<char> encoded_key;
1679 EncodeIDBKey(user_key, &encoded_key);
1680 return Encode(database_id, object_store_id, encoded_key);
1635 } 1681 }
1636 1682
1637 int ObjectStoreDataKey::Compare(const ObjectStoreDataKey& other, bool& ok) { 1683 int ObjectStoreDataKey::Compare(const ObjectStoreDataKey& other, bool& ok) {
1638 return CompareEncodedIDBKeys(encoded_user_key_, other.encoded_user_key_, ok); 1684 return CompareEncodedIDBKeys(encoded_user_key_, other.encoded_user_key_, ok);
1639 } 1685 }
1640 1686
1641 scoped_ptr<IndexedDBKey> ObjectStoreDataKey::user_key() const { 1687 scoped_ptr<IndexedDBKey> ObjectStoreDataKey::user_key() const {
1642 scoped_ptr<IndexedDBKey> key; 1688 scoped_ptr<IndexedDBKey> key;
1643 DecodeIDBKey(&encoded_user_key_[0], 1689 StringPiece slice(&encoded_user_key_[0], encoded_user_key_.size());
1644 &encoded_user_key_[0] + encoded_user_key_.size(), 1690 if (!DecodeIDBKey(&slice, &key)) {
1645 &key); 1691 // TODO(jsbell): Return error.
1692 }
1646 return key.Pass(); 1693 return key.Pass();
1647 } 1694 }
1648 1695
1649 const int64 ObjectStoreDataKey::kSpecialIndexNumber = kObjectStoreDataIndexId; 1696 const int64 ObjectStoreDataKey::kSpecialIndexNumber = kObjectStoreDataIndexId;
1650 1697
1651 ExistsEntryKey::ExistsEntryKey() {} 1698 ExistsEntryKey::ExistsEntryKey() {}
1652 ExistsEntryKey::~ExistsEntryKey() {} 1699 ExistsEntryKey::~ExistsEntryKey() {}
1653 1700
1654 const char* ExistsEntryKey::Decode(const char* start, 1701 const char* ExistsEntryKey::Decode(const char* start,
1655 const char* end, 1702 const char* end,
1656 ExistsEntryKey* result) { 1703 ExistsEntryKey* result) {
1657 KeyPrefix prefix; 1704 KeyPrefix prefix;
1658 const char* p = KeyPrefix::Decode(start, end, &prefix); 1705 const char* p = KeyPrefix::Decode(start, end, &prefix);
1659 if (!p) 1706 if (!p)
1660 return 0; 1707 return 0;
1661 DCHECK(prefix.database_id_); 1708 DCHECK(prefix.database_id_);
1662 DCHECK(prefix.object_store_id_); 1709 DCHECK(prefix.object_store_id_);
1663 DCHECK_EQ(prefix.index_id_, kSpecialIndexNumber); 1710 DCHECK_EQ(prefix.index_id_, kSpecialIndexNumber);
1664 if (p == end) 1711 if (p == end)
1665 return 0; 1712 return 0;
1666 return ExtractEncodedIDBKey(p, end, &result->encoded_user_key_); 1713 StringPiece slice(p, end - p);
1714 if (!ExtractEncodedIDBKey(&slice, &result->encoded_user_key_))
1715 return 0;
1716 return slice.begin();
1667 } 1717 }
1668 1718
1669 std::vector<char> ExistsEntryKey::Encode(int64 database_id, 1719 std::vector<char> ExistsEntryKey::Encode(int64 database_id,
1670 int64 object_store_id, 1720 int64 object_store_id,
1671 const std::vector<char>& encoded_key) { 1721 const std::vector<char>& encoded_key) {
1672 KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex( 1722 KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex(
1673 database_id, object_store_id, kSpecialIndexNumber)); 1723 database_id, object_store_id, kSpecialIndexNumber));
1674 std::vector<char> ret = prefix.Encode(); 1724 std::vector<char> ret = prefix.Encode();
1675 ret.insert(ret.end(), encoded_key.begin(), encoded_key.end()); 1725 ret.insert(ret.end(), encoded_key.begin(), encoded_key.end());
1676 return ret; 1726 return ret;
1677 } 1727 }
1678 1728
1679 std::vector<char> ExistsEntryKey::Encode(int64 database_id, 1729 std::vector<char> ExistsEntryKey::Encode(int64 database_id,
1680 int64 object_store_id, 1730 int64 object_store_id,
1681 const IndexedDBKey& user_key) { 1731 const IndexedDBKey& user_key) {
1682 return Encode(database_id, object_store_id, EncodeIDBKey(user_key)); 1732 std::vector<char> encoded_key;
1733 EncodeIDBKey(user_key, &encoded_key);
1734 return Encode(database_id, object_store_id, encoded_key);
1683 } 1735 }
1684 1736
1685 int ExistsEntryKey::Compare(const ExistsEntryKey& other, bool& ok) { 1737 int ExistsEntryKey::Compare(const ExistsEntryKey& other, bool& ok) {
1686 return CompareEncodedIDBKeys(encoded_user_key_, other.encoded_user_key_, ok); 1738 return CompareEncodedIDBKeys(encoded_user_key_, other.encoded_user_key_, ok);
1687 } 1739 }
1688 1740
1689 scoped_ptr<IndexedDBKey> ExistsEntryKey::user_key() const { 1741 scoped_ptr<IndexedDBKey> ExistsEntryKey::user_key() const {
1690 scoped_ptr<IndexedDBKey> key; 1742 scoped_ptr<IndexedDBKey> key;
1691 DecodeIDBKey(&encoded_user_key_[0], 1743 StringPiece slice(&encoded_user_key_[0], encoded_user_key_.size());
1692 &encoded_user_key_[0] + encoded_user_key_.size(), 1744 if (!DecodeIDBKey(&slice, &key)) {
1693 &key); 1745 // TODO(jsbell): Return error.
1746 }
1694 return key.Pass(); 1747 return key.Pass();
1695 } 1748 }
1696 1749
1697 const int64 ExistsEntryKey::kSpecialIndexNumber = kExistsEntryIndexId; 1750 const int64 ExistsEntryKey::kSpecialIndexNumber = kExistsEntryIndexId;
1698 1751
1699 IndexDataKey::IndexDataKey() 1752 IndexDataKey::IndexDataKey()
1700 : database_id_(-1), 1753 : database_id_(-1),
1701 object_store_id_(-1), 1754 object_store_id_(-1),
1702 index_id_(-1), 1755 index_id_(-1),
1703 sequence_number_(-1) {} 1756 sequence_number_(-1) {}
1704 1757
1705 IndexDataKey::~IndexDataKey() {} 1758 IndexDataKey::~IndexDataKey() {}
1706 1759
1707 const char* IndexDataKey::Decode(const char* start, 1760 const char* IndexDataKey::Decode(const char* start,
1708 const char* limit, 1761 const char* limit,
1709 IndexDataKey* result) { 1762 IndexDataKey* result) {
1710 KeyPrefix prefix; 1763 KeyPrefix prefix;
1711 const char* p = KeyPrefix::Decode(start, limit, &prefix); 1764 const char* p = KeyPrefix::Decode(start, limit, &prefix);
1712 if (!p) 1765 if (!p)
1713 return 0; 1766 return 0;
1714 DCHECK(prefix.database_id_); 1767 DCHECK(prefix.database_id_);
1715 DCHECK(prefix.object_store_id_); 1768 DCHECK(prefix.object_store_id_);
1716 DCHECK_GE(prefix.index_id_, kMinimumIndexId); 1769 DCHECK_GE(prefix.index_id_, kMinimumIndexId);
1717 result->database_id_ = prefix.database_id_; 1770 result->database_id_ = prefix.database_id_;
1718 result->object_store_id_ = prefix.object_store_id_; 1771 result->object_store_id_ = prefix.object_store_id_;
1719 result->index_id_ = prefix.index_id_; 1772 result->index_id_ = prefix.index_id_;
1720 result->sequence_number_ = -1; 1773 result->sequence_number_ = -1;
1721 result->encoded_primary_key_ = MinIDBKey(); 1774 result->encoded_primary_key_ = MinIDBKey();
1722 1775
1723 p = ExtractEncodedIDBKey(p, limit, &result->encoded_user_key_); 1776 StringPiece slice(p, limit - p);
1724 if (!p) 1777 if (!ExtractEncodedIDBKey(&slice, &result->encoded_user_key_))
1725 return 0; 1778 return 0;
1726 1779
1727 // [optional] sequence number 1780 // [optional] sequence number
1728 if (p == limit) 1781 if (slice.empty())
1729 return p; 1782 return slice.begin();
1730 p = DecodeVarInt(p, limit, result->sequence_number_); 1783 if (!DecodeVarInt(&slice, &result->sequence_number_))
1731 if (!p)
1732 return 0; 1784 return 0;
1733 1785
1734 // [optional] primary key 1786 // [optional] primary key
1735 if (p == limit) 1787 if (slice.empty())
1736 return p; 1788 return slice.begin();
1737 p = ExtractEncodedIDBKey(p, limit, &result->encoded_primary_key_); 1789 if (!ExtractEncodedIDBKey(&slice, &result->encoded_primary_key_))
1738 if (!p)
1739 return 0; 1790 return 0;
1740 1791
1741 return p; 1792 return slice.begin();
1742 } 1793 }
1743 1794
1744 std::vector<char> IndexDataKey::Encode( 1795 std::vector<char> IndexDataKey::Encode(
1745 int64 database_id, 1796 int64 database_id,
1746 int64 object_store_id, 1797 int64 object_store_id,
1747 int64 index_id, 1798 int64 index_id,
1748 const std::vector<char>& encoded_user_key, 1799 const std::vector<char>& encoded_user_key,
1749 const std::vector<char>& encoded_primary_key, 1800 const std::vector<char>& encoded_primary_key,
1750 int64 sequence_number) { 1801 int64 sequence_number) {
1751 KeyPrefix prefix(database_id, object_store_id, index_id); 1802 KeyPrefix prefix(database_id, object_store_id, index_id);
1752 std::vector<char> ret = prefix.Encode(); 1803 std::vector<char> ret = prefix.Encode();
1753 ret.insert(ret.end(), encoded_user_key.begin(), encoded_user_key.end()); 1804 ret.insert(ret.end(), encoded_user_key.begin(), encoded_user_key.end());
1754 EncodeVarInt(sequence_number, &ret); 1805 EncodeVarInt(sequence_number, &ret);
1755 ret.insert(ret.end(), encoded_primary_key.begin(), encoded_primary_key.end()); 1806 ret.insert(ret.end(), encoded_primary_key.begin(), encoded_primary_key.end());
1756 return ret; 1807 return ret;
1757 } 1808 }
1758 1809
1759 std::vector<char> IndexDataKey::Encode(int64 database_id, 1810 std::vector<char> IndexDataKey::Encode(int64 database_id,
1760 int64 object_store_id, 1811 int64 object_store_id,
1761 int64 index_id, 1812 int64 index_id,
1762 const IndexedDBKey& user_key) { 1813 const IndexedDBKey& user_key) {
1763 return Encode(database_id, 1814 std::vector<char> encoded_key;
1764 object_store_id, 1815 EncodeIDBKey(user_key, &encoded_key);
1765 index_id, 1816 return Encode(
1766 EncodeIDBKey(user_key), 1817 database_id, object_store_id, index_id, encoded_key, MinIDBKey());
1767 MinIDBKey());
1768 } 1818 }
1769 1819
1770 std::vector<char> IndexDataKey::EncodeMinKey(int64 database_id, 1820 std::vector<char> IndexDataKey::EncodeMinKey(int64 database_id,
1771 int64 object_store_id, 1821 int64 object_store_id,
1772 int64 index_id) { 1822 int64 index_id) {
1773 return Encode( 1823 return Encode(
1774 database_id, object_store_id, index_id, MinIDBKey(), MinIDBKey()); 1824 database_id, object_store_id, index_id, MinIDBKey(), MinIDBKey());
1775 } 1825 }
1776 1826
1777 std::vector<char> IndexDataKey::EncodeMaxKey(int64 database_id, 1827 std::vector<char> IndexDataKey::EncodeMaxKey(int64 database_id,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1814 return object_store_id_; 1864 return object_store_id_;
1815 } 1865 }
1816 1866
1817 int64 IndexDataKey::IndexId() const { 1867 int64 IndexDataKey::IndexId() const {
1818 DCHECK_GE(index_id_, 0); 1868 DCHECK_GE(index_id_, 0);
1819 return index_id_; 1869 return index_id_;
1820 } 1870 }
1821 1871
1822 scoped_ptr<IndexedDBKey> IndexDataKey::user_key() const { 1872 scoped_ptr<IndexedDBKey> IndexDataKey::user_key() const {
1823 scoped_ptr<IndexedDBKey> key; 1873 scoped_ptr<IndexedDBKey> key;
1824 DecodeIDBKey(&encoded_user_key_[0], 1874 StringPiece slice(&encoded_user_key_[0], encoded_user_key_.size());
1825 &encoded_user_key_[0] + encoded_user_key_.size(), 1875 if (!DecodeIDBKey(&slice, &key)) {
1826 &key); 1876 // TODO(jsbell): Return error.
1877 }
1827 return key.Pass(); 1878 return key.Pass();
1828 } 1879 }
1829 1880
1830 scoped_ptr<IndexedDBKey> IndexDataKey::primary_key() const { 1881 scoped_ptr<IndexedDBKey> IndexDataKey::primary_key() const {
1831 scoped_ptr<IndexedDBKey> key; 1882 scoped_ptr<IndexedDBKey> key;
1832 DecodeIDBKey(&encoded_primary_key_[0], 1883 StringPiece slice(&encoded_primary_key_[0], encoded_primary_key_.size());
1833 &encoded_primary_key_[0] + encoded_primary_key_.size(), 1884 if (!DecodeIDBKey(&slice, &key)) {
1834 &key); 1885 // TODO(jsbell): Return error.
1886 }
1835 return key.Pass(); 1887 return key.Pass();
1836 } 1888 }
1837 1889
1838 } // namespace content 1890 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698