• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
6 
7 #include <iterator>
8 #include <limits>
9 
10 #include "base/logging.h"
11 #include "base/strings/string16.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/sys_byteorder.h"
14 #include "content/common/indexed_db/indexed_db_key.h"
15 #include "content/common/indexed_db/indexed_db_key_path.h"
16 
17 // LevelDB Coding Scheme
18 // =====================
19 //
20 // LevelDB stores key/value pairs. Keys and values are strings of bytes,
21 // normally of type std::string.
22 //
23 // The keys in the backing store are variable-length tuples with different
24 // types of fields. Each key in the backing store starts with a ternary
25 // prefix: (database id, object store id, index id). For each, 0 is reserved
26 // for metadata. See KeyPrefix::Decode() for details of the prefix coding.
27 //
28 // The prefix makes sure that data for a specific database, object store, and
29 // index are grouped together. The locality is important for performance:
30 // common operations should only need a minimal number of seek operations. For
31 // example, all the metadata for a database is grouped together so that
32 // reading that metadata only requires one seek.
33 //
34 // Each key type has a class (in square brackets below) which knows how to
35 // encode, decode, and compare that key type.
36 //
37 // Strings (origins, names, etc) are encoded as UTF-16BE.
38 //
39 //
40 // Global metadata
41 // ---------------
42 // The prefix is <0, 0, 0>, followed by a metadata type byte:
43 //
44 // <0, 0, 0, 0> => backing store schema version [SchemaVersionKey]
45 // <0, 0, 0, 1> => maximum allocated database [MaxDatabaseIdKey]
46 // <0, 0, 0, 2> => SerializedScriptValue version [DataVersionKey]
47 // <0, 0, 0, 3>
48 //   => Blob journal
49 //     The format of the journal is:
50 //         {database_id (var int), blobKey (var int)}*.
51 //     If the blobKey is kAllBlobsKey, the whole database should be deleted.
52 //     [BlobJournalKey]
53 // <0, 0, 0, 4> => Live blob journal; same format. [LiveBlobJournalKey]
54 // <0, 0, 0, 100, database id>
55 //   => Existence implies the database id is in the free list
56 //      [DatabaseFreeListKey]
57 // <0, 0, 0, 201, origin, database name> => Database id [DatabaseNameKey]
58 //
59 //
60 // Database metadata: [DatabaseMetaDataKey]
61 // ----------------------------------------
62 // The prefix is <database id, 0, 0> followed by a metadata type byte:
63 //
64 // <database id, 0, 0, 0> => origin name
65 // <database id, 0, 0, 1> => database name
66 // <database id, 0, 0, 2> => IDB string version data (obsolete)
67 // <database id, 0, 0, 3> => maximum allocated object store id
68 // <database id, 0, 0, 4> => IDB integer version (var int)
69 // <database id, 0, 0, 5> => blob key generator current number
70 //
71 //
72 // Object store metadata: [ObjectStoreMetaDataKey]
73 // -----------------------------------------------
74 // The prefix is <database id, 0, 0>, followed by a type byte (50), then the
75 // object store id (var int), then a metadata type byte.
76 //
77 // <database id, 0, 0, 50, object store id, 0> => object store name
78 // <database id, 0, 0, 50, object store id, 1> => key path
79 // <database id, 0, 0, 50, object store id, 2> => auto increment flag
80 // <database id, 0, 0, 50, object store id, 3> => is evictable
81 // <database id, 0, 0, 50, object store id, 4> => last "version" number
82 // <database id, 0, 0, 50, object store id, 5> => maximum allocated index id
83 // <database id, 0, 0, 50, object store id, 6> => has key path flag (obsolete)
84 // <database id, 0, 0, 50, object store id, 7> => key generator current number
85 //
86 // The key path was originally just a string (#1) or null (identified by flag,
87 // #6). To support null, string, or array the coding is now identified by the
88 // leading bytes in #1 - see EncodeIDBKeyPath.
89 //
90 // The "version" field is used to weed out stale index data. Whenever new
91 // object store data is inserted, it gets a new "version" number, and new
92 // index data is written with this number. When the index is used for
93 // look-ups, entries are validated against the "exists" entries, and records
94 // with old "version" numbers are deleted when they are encountered in
95 // GetPrimaryKeyViaIndex, IndexCursorImpl::LoadCurrentRow and
96 // IndexKeyCursorImpl::LoadCurrentRow.
97 //
98 //
99 // Index metadata: [IndexMetaDataKey]
100 // ----------------------------------
101 // The prefix is <database id, 0, 0>, followed by a type byte (100), then the
102 // object store id (var int), then the index id (var int), then a metadata
103 // type byte.
104 //
105 // <database id, 0, 0, 100, object store id, index id, 0> => index name
106 // <database id, 0, 0, 100, object store id, index id, 1> => unique flag
107 // <database id, 0, 0, 100, object store id, index id, 2> => key path
108 // <database id, 0, 0, 100, object store id, index id, 3> => multi-entry flag
109 //
110 //
111 // Other object store and index metadata
112 // -------------------------------------
113 // The prefix is <database id, 0, 0> followed by a type byte. The object
114 // store and index id are variable length integers, the names are variable
115 // length strings.
116 //
117 // <database id, 0, 0, 150, object store id>
118 //   => existence implies the object store id is in the free list
119 //      [ObjectStoreFreeListKey]
120 // <database id, 0, 0, 151, object store id, index id>
121 //   => existence implies the index id is in the free list [IndexFreeListKey]
122 // <database id, 0, 0, 200, object store name>
123 //   => object store id [ObjectStoreNamesKey]
124 // <database id, 0, 0, 201, object store id, index name>
125 //   => index id [IndexNamesKey]
126 //
127 //
128 // Object store data: [ObjectStoreDataKey]
129 // ---------------------------------------
130 // The prefix is followed by a type byte and the encoded IDB primary key. The
131 // data has a "version" prefix followed by the serialized script value.
132 //
133 // <database id, object store id, 1, user key>
134 //   => "version", serialized script value
135 //
136 //
137 // "Exists" entry: [ExistsEntryKey]
138 // --------------------------------
139 // The prefix is followed by a type byte and the encoded IDB primary key.
140 //
141 // <database id, object store id, 2, user key> => "version"
142 //
143 //
144 // Blob entry table: [BlobEntryKey]
145 // --------------------------------
146 //
147 // The prefix is followed by a type byte and the encoded IDB primary key.
148 //
149 // <database id, object store id, 3, user key> => array of IndexedDBBlobInfo
150 //
151 //
152 // Index data
153 // ----------
154 // The prefix is followed by a type byte, the encoded IDB index key, a
155 // "sequence" number (obsolete; var int), and the encoded IDB primary key.
156 //
157 // <database id, object store id, index id, index key, sequence number,
158 //   primary key> => "version", primary key [IndexDataKey]
159 //
160 // The sequence number is obsolete; it was used to allow two entries with the
161 // same user (index) key in non-unique indexes prior to the inclusion of the
162 // primary key in the data.
163 
164 using base::StringPiece;
165 using blink::WebIDBKeyType;
166 using blink::WebIDBKeyTypeArray;
167 using blink::WebIDBKeyTypeBinary;
168 using blink::WebIDBKeyTypeDate;
169 using blink::WebIDBKeyTypeInvalid;
170 using blink::WebIDBKeyTypeMin;
171 using blink::WebIDBKeyTypeNull;
172 using blink::WebIDBKeyTypeNumber;
173 using blink::WebIDBKeyTypeString;
174 using blink::WebIDBKeyPathType;
175 using blink::WebIDBKeyPathTypeArray;
176 using blink::WebIDBKeyPathTypeNull;
177 using blink::WebIDBKeyPathTypeString;
178 
179 namespace content {
180 
181 // As most of the IndexedDBKeys and encoded values are short, we
182 // initialize some std::vectors with a default inline buffer size to reduce
183 // the memory re-allocations when the std::vectors are appended.
184 static const size_t kDefaultInlineBufferSize = 32;
185 
186 static const unsigned char kIndexedDBKeyNullTypeByte = 0;
187 static const unsigned char kIndexedDBKeyStringTypeByte = 1;
188 static const unsigned char kIndexedDBKeyDateTypeByte = 2;
189 static const unsigned char kIndexedDBKeyNumberTypeByte = 3;
190 static const unsigned char kIndexedDBKeyArrayTypeByte = 4;
191 static const unsigned char kIndexedDBKeyMinKeyTypeByte = 5;
192 static const unsigned char kIndexedDBKeyBinaryTypeByte = 6;
193 
194 static const unsigned char kIndexedDBKeyPathTypeCodedByte1 = 0;
195 static const unsigned char kIndexedDBKeyPathTypeCodedByte2 = 0;
196 
197 static const unsigned char kObjectStoreDataIndexId = 1;
198 static const unsigned char kExistsEntryIndexId = 2;
199 static const unsigned char kBlobEntryIndexId = 3;
200 
201 static const unsigned char kSchemaVersionTypeByte = 0;
202 static const unsigned char kMaxDatabaseIdTypeByte = 1;
203 static const unsigned char kDataVersionTypeByte = 2;
204 static const unsigned char kBlobJournalTypeByte = 3;
205 static const unsigned char kLiveBlobJournalTypeByte = 4;
206 static const unsigned char kMaxSimpleGlobalMetaDataTypeByte =
207     5;  // Insert before this and increment.
208 static const unsigned char kDatabaseFreeListTypeByte = 100;
209 static const unsigned char kDatabaseNameTypeByte = 201;
210 
211 static const unsigned char kObjectStoreMetaDataTypeByte = 50;
212 static const unsigned char kIndexMetaDataTypeByte = 100;
213 static const unsigned char kObjectStoreFreeListTypeByte = 150;
214 static const unsigned char kIndexFreeListTypeByte = 151;
215 static const unsigned char kObjectStoreNamesTypeByte = 200;
216 static const unsigned char kIndexNamesKeyTypeByte = 201;
217 
218 static const unsigned char kObjectMetaDataTypeMaximum = 255;
219 static const unsigned char kIndexMetaDataTypeMaximum = 255;
220 
221 const unsigned char kMinimumIndexId = 30;
222 
EncodeIntSafely(int64 nParam,int64 max,std::string * into)223 inline void EncodeIntSafely(int64 nParam, int64 max, std::string* into) {
224   DCHECK_LE(nParam, max);
225   return EncodeInt(nParam, into);
226 }
227 
MaxIDBKey()228 std::string MaxIDBKey() {
229   std::string ret;
230   EncodeByte(kIndexedDBKeyNullTypeByte, &ret);
231   return ret;
232 }
233 
MinIDBKey()234 std::string MinIDBKey() {
235   std::string ret;
236   EncodeByte(kIndexedDBKeyMinKeyTypeByte, &ret);
237   return ret;
238 }
239 
EncodeByte(unsigned char value,std::string * into)240 void EncodeByte(unsigned char value, std::string* into) {
241   into->push_back(value);
242 }
243 
EncodeBool(bool value,std::string * into)244 void EncodeBool(bool value, std::string* into) {
245   into->push_back(value ? 1 : 0);
246 }
247 
EncodeInt(int64 value,std::string * into)248 void EncodeInt(int64 value, std::string* into) {
249 #ifndef NDEBUG
250   // Exercised by unit tests in debug only.
251   DCHECK_GE(value, 0);
252 #endif
253   uint64 n = static_cast<uint64>(value);
254 
255   do {
256     unsigned char c = n;
257     into->push_back(c);
258     n >>= 8;
259   } while (n);
260 }
261 
EncodeVarInt(int64 value,std::string * into)262 void EncodeVarInt(int64 value, std::string* into) {
263 #ifndef NDEBUG
264   // Exercised by unit tests in debug only.
265   DCHECK_GE(value, 0);
266 #endif
267   uint64 n = static_cast<uint64>(value);
268 
269   do {
270     unsigned char c = n & 0x7f;
271     n >>= 7;
272     if (n)
273       c |= 0x80;
274     into->push_back(c);
275   } while (n);
276 }
277 
EncodeString(const base::string16 & value,std::string * into)278 void EncodeString(const base::string16& value, std::string* into) {
279   if (value.empty())
280     return;
281   // Backing store is UTF-16BE, convert from host endianness.
282   size_t length = value.length();
283   size_t current = into->size();
284   into->resize(into->size() + length * sizeof(base::char16));
285 
286   const base::char16* src = value.c_str();
287   base::char16* dst =
288       reinterpret_cast<base::char16*>(&*into->begin() + current);
289   for (unsigned i = 0; i < length; ++i)
290     *dst++ = htons(*src++);
291 }
292 
EncodeBinary(const std::string & value,std::string * into)293 void EncodeBinary(const std::string& value, std::string* into) {
294   EncodeVarInt(value.length(), into);
295   into->append(value.begin(), value.end());
296   DCHECK(into->size() >= value.size());
297 }
298 
EncodeStringWithLength(const base::string16 & value,std::string * into)299 void EncodeStringWithLength(const base::string16& value, std::string* into) {
300   EncodeVarInt(value.length(), into);
301   EncodeString(value, into);
302 }
303 
EncodeDouble(double value,std::string * into)304 void EncodeDouble(double value, std::string* into) {
305   // This always has host endianness.
306   const char* p = reinterpret_cast<char*>(&value);
307   into->insert(into->end(), p, p + sizeof(value));
308 }
309 
EncodeIDBKey(const IndexedDBKey & value,std::string * into)310 void EncodeIDBKey(const IndexedDBKey& value, std::string* into) {
311   size_t previous_size = into->size();
312   DCHECK(value.IsValid());
313   switch (value.type()) {
314     case WebIDBKeyTypeArray: {
315       EncodeByte(kIndexedDBKeyArrayTypeByte, into);
316       size_t length = value.array().size();
317       EncodeVarInt(length, into);
318       for (size_t i = 0; i < length; ++i)
319         EncodeIDBKey(value.array()[i], into);
320       DCHECK_GT(into->size(), previous_size);
321       return;
322     }
323     case WebIDBKeyTypeBinary:
324       EncodeByte(kIndexedDBKeyBinaryTypeByte, into);
325       EncodeBinary(value.binary(), into);
326       DCHECK_GT(into->size(), previous_size);
327       return;
328     case WebIDBKeyTypeString:
329       EncodeByte(kIndexedDBKeyStringTypeByte, into);
330       EncodeStringWithLength(value.string(), into);
331       DCHECK_GT(into->size(), previous_size);
332       return;
333     case WebIDBKeyTypeDate:
334       EncodeByte(kIndexedDBKeyDateTypeByte, into);
335       EncodeDouble(value.date(), into);
336       DCHECK_EQ(9u, static_cast<size_t>(into->size() - previous_size));
337       return;
338     case WebIDBKeyTypeNumber:
339       EncodeByte(kIndexedDBKeyNumberTypeByte, into);
340       EncodeDouble(value.number(), into);
341       DCHECK_EQ(9u, static_cast<size_t>(into->size() - previous_size));
342       return;
343     case WebIDBKeyTypeNull:
344     case WebIDBKeyTypeInvalid:
345     case WebIDBKeyTypeMin:
346     default:
347       NOTREACHED();
348       EncodeByte(kIndexedDBKeyNullTypeByte, into);
349       return;
350   }
351 }
352 
EncodeIDBKeyPath(const IndexedDBKeyPath & value,std::string * into)353 void EncodeIDBKeyPath(const IndexedDBKeyPath& value, std::string* into) {
354   // May be typed, or may be a raw string. An invalid leading
355   // byte is used to identify typed coding. New records are
356   // always written as typed.
357   EncodeByte(kIndexedDBKeyPathTypeCodedByte1, into);
358   EncodeByte(kIndexedDBKeyPathTypeCodedByte2, into);
359   EncodeByte(static_cast<char>(value.type()), into);
360   switch (value.type()) {
361     case WebIDBKeyPathTypeNull:
362       break;
363     case WebIDBKeyPathTypeString: {
364       EncodeStringWithLength(value.string(), into);
365       break;
366     }
367     case WebIDBKeyPathTypeArray: {
368       const std::vector<base::string16>& array = value.array();
369       size_t count = array.size();
370       EncodeVarInt(count, into);
371       for (size_t i = 0; i < count; ++i) {
372         EncodeStringWithLength(array[i], into);
373       }
374       break;
375     }
376   }
377 }
378 
EncodeBlobJournal(const BlobJournalType & journal,std::string * into)379 void EncodeBlobJournal(const BlobJournalType& journal, std::string* into) {
380   BlobJournalType::const_iterator iter;
381   for (iter = journal.begin(); iter != journal.end(); ++iter) {
382     EncodeVarInt(iter->first, into);
383     EncodeVarInt(iter->second, into);
384   }
385 }
386 
DecodeByte(StringPiece * slice,unsigned char * value)387 bool DecodeByte(StringPiece* slice, unsigned char* value) {
388   if (slice->empty())
389     return false;
390 
391   *value = (*slice)[0];
392   slice->remove_prefix(1);
393   return true;
394 }
395 
DecodeBool(StringPiece * slice,bool * value)396 bool DecodeBool(StringPiece* slice, bool* value) {
397   if (slice->empty())
398     return false;
399 
400   *value = !!(*slice)[0];
401   slice->remove_prefix(1);
402   return true;
403 }
404 
DecodeInt(StringPiece * slice,int64 * value)405 bool DecodeInt(StringPiece* slice, int64* value) {
406   if (slice->empty())
407     return false;
408 
409   StringPiece::const_iterator it = slice->begin();
410   int shift = 0;
411   int64 ret = 0;
412   while (it != slice->end()) {
413     unsigned char c = *it++;
414     ret |= static_cast<int64>(c) << shift;
415     shift += 8;
416   }
417   *value = ret;
418   slice->remove_prefix(it - slice->begin());
419   return true;
420 }
421 
DecodeVarInt(StringPiece * slice,int64 * value)422 bool DecodeVarInt(StringPiece* slice, int64* value) {
423   if (slice->empty())
424     return false;
425 
426   StringPiece::const_iterator it = slice->begin();
427   int shift = 0;
428   int64 ret = 0;
429   do {
430     if (it == slice->end())
431       return false;
432 
433     unsigned char c = *it;
434     ret |= static_cast<int64>(c & 0x7f) << shift;
435     shift += 7;
436   } while (*it++ & 0x80);
437   *value = ret;
438   slice->remove_prefix(it - slice->begin());
439   return true;
440 }
441 
DecodeString(StringPiece * slice,base::string16 * value)442 bool DecodeString(StringPiece* slice, base::string16* value) {
443   if (slice->empty()) {
444     value->clear();
445     return true;
446   }
447 
448   // Backing store is UTF-16BE, convert to host endianness.
449   DCHECK(!(slice->size() % sizeof(base::char16)));
450   size_t length = slice->size() / sizeof(base::char16);
451   base::string16 decoded;
452   decoded.reserve(length);
453   const base::char16* encoded =
454       reinterpret_cast<const base::char16*>(slice->begin());
455   for (unsigned i = 0; i < length; ++i)
456     decoded.push_back(ntohs(*encoded++));
457 
458   *value = decoded;
459   slice->remove_prefix(length * sizeof(base::char16));
460   return true;
461 }
462 
DecodeStringWithLength(StringPiece * slice,base::string16 * value)463 bool DecodeStringWithLength(StringPiece* slice, base::string16* value) {
464   if (slice->empty())
465     return false;
466 
467   int64 length = 0;
468   if (!DecodeVarInt(slice, &length) || length < 0)
469     return false;
470   size_t bytes = length * sizeof(base::char16);
471   if (slice->size() < bytes)
472     return false;
473 
474   StringPiece subpiece(slice->begin(), bytes);
475   slice->remove_prefix(bytes);
476   if (!DecodeString(&subpiece, value))
477     return false;
478 
479   return true;
480 }
481 
DecodeBinary(StringPiece * slice,std::string * value)482 bool DecodeBinary(StringPiece* slice, std::string* value) {
483   if (slice->empty())
484     return false;
485 
486   int64 length = 0;
487   if (!DecodeVarInt(slice, &length) || length < 0)
488     return false;
489   size_t size = length;
490   if (slice->size() < size)
491     return false;
492 
493   value->assign(slice->begin(), size);
494   slice->remove_prefix(size);
495   return true;
496 }
497 
DecodeIDBKey(StringPiece * slice,scoped_ptr<IndexedDBKey> * value)498 bool DecodeIDBKey(StringPiece* slice, scoped_ptr<IndexedDBKey>* value) {
499   if (slice->empty())
500     return false;
501 
502   unsigned char type = (*slice)[0];
503   slice->remove_prefix(1);
504 
505   switch (type) {
506     case kIndexedDBKeyNullTypeByte:
507       *value = make_scoped_ptr(new IndexedDBKey());
508       return true;
509 
510     case kIndexedDBKeyArrayTypeByte: {
511       int64 length = 0;
512       if (!DecodeVarInt(slice, &length) || length < 0)
513         return false;
514       IndexedDBKey::KeyArray array;
515       while (length--) {
516         scoped_ptr<IndexedDBKey> key;
517         if (!DecodeIDBKey(slice, &key))
518           return false;
519         array.push_back(*key);
520       }
521       *value = make_scoped_ptr(new IndexedDBKey(array));
522       return true;
523     }
524     case kIndexedDBKeyBinaryTypeByte: {
525       std::string binary;
526       if (!DecodeBinary(slice, &binary))
527         return false;
528       *value = make_scoped_ptr(new IndexedDBKey(binary));
529       return true;
530     }
531     case kIndexedDBKeyStringTypeByte: {
532       base::string16 s;
533       if (!DecodeStringWithLength(slice, &s))
534         return false;
535       *value = make_scoped_ptr(new IndexedDBKey(s));
536       return true;
537     }
538     case kIndexedDBKeyDateTypeByte: {
539       double d;
540       if (!DecodeDouble(slice, &d))
541         return false;
542       *value = make_scoped_ptr(new IndexedDBKey(d, WebIDBKeyTypeDate));
543       return true;
544     }
545     case kIndexedDBKeyNumberTypeByte: {
546       double d;
547       if (!DecodeDouble(slice, &d))
548         return false;
549       *value = make_scoped_ptr(new IndexedDBKey(d, WebIDBKeyTypeNumber));
550       return true;
551     }
552   }
553 
554   NOTREACHED();
555   return false;
556 }
557 
DecodeDouble(StringPiece * slice,double * value)558 bool DecodeDouble(StringPiece* slice, double* value) {
559   if (slice->size() < sizeof(*value))
560     return false;
561 
562   memcpy(value, slice->begin(), sizeof(*value));
563   slice->remove_prefix(sizeof(*value));
564   return true;
565 }
566 
DecodeIDBKeyPath(StringPiece * slice,IndexedDBKeyPath * value)567 bool DecodeIDBKeyPath(StringPiece* slice, IndexedDBKeyPath* value) {
568   // May be typed, or may be a raw string. An invalid leading
569   // byte sequence is used to identify typed coding. New records are
570   // always written as typed.
571   if (slice->size() < 3 || (*slice)[0] != kIndexedDBKeyPathTypeCodedByte1 ||
572       (*slice)[1] != kIndexedDBKeyPathTypeCodedByte2) {
573     base::string16 s;
574     if (!DecodeString(slice, &s))
575       return false;
576     *value = IndexedDBKeyPath(s);
577     return true;
578   }
579 
580   slice->remove_prefix(2);
581   DCHECK(!slice->empty());
582   WebIDBKeyPathType type = static_cast<WebIDBKeyPathType>((*slice)[0]);
583   slice->remove_prefix(1);
584 
585   switch (type) {
586     case WebIDBKeyPathTypeNull:
587       DCHECK(slice->empty());
588       *value = IndexedDBKeyPath();
589       return true;
590     case WebIDBKeyPathTypeString: {
591       base::string16 string;
592       if (!DecodeStringWithLength(slice, &string))
593         return false;
594       DCHECK(slice->empty());
595       *value = IndexedDBKeyPath(string);
596       return true;
597     }
598     case WebIDBKeyPathTypeArray: {
599       std::vector<base::string16> array;
600       int64 count;
601       if (!DecodeVarInt(slice, &count))
602         return false;
603       DCHECK_GE(count, 0);
604       while (count--) {
605         base::string16 string;
606         if (!DecodeStringWithLength(slice, &string))
607           return false;
608         array.push_back(string);
609       }
610       DCHECK(slice->empty());
611       *value = IndexedDBKeyPath(array);
612       return true;
613     }
614   }
615   NOTREACHED();
616   return false;
617 }
618 
DecodeBlobJournal(StringPiece * slice,BlobJournalType * journal)619 bool DecodeBlobJournal(StringPiece* slice, BlobJournalType* journal) {
620   BlobJournalType output;
621   while (!slice->empty()) {
622     int64 database_id = -1;
623     int64 blob_key = -1;
624     if (!DecodeVarInt(slice, &database_id))
625       return false;
626     if (!KeyPrefix::IsValidDatabaseId(database_id))
627       return false;
628     if (!DecodeVarInt(slice, &blob_key))
629       return false;
630     if (!DatabaseMetaDataKey::IsValidBlobKey(blob_key) &&
631         (blob_key != DatabaseMetaDataKey::kAllBlobsKey)) {
632       return false;
633     }
634     output.push_back(std::make_pair(database_id, blob_key));
635   }
636   journal->swap(output);
637   return true;
638 }
639 
ConsumeEncodedIDBKey(StringPiece * slice)640 bool ConsumeEncodedIDBKey(StringPiece* slice) {
641   unsigned char type = (*slice)[0];
642   slice->remove_prefix(1);
643 
644   switch (type) {
645     case kIndexedDBKeyNullTypeByte:
646     case kIndexedDBKeyMinKeyTypeByte:
647       return true;
648     case kIndexedDBKeyArrayTypeByte: {
649       int64 length;
650       if (!DecodeVarInt(slice, &length))
651         return false;
652       while (length--) {
653         if (!ConsumeEncodedIDBKey(slice))
654           return false;
655       }
656       return true;
657     }
658     case kIndexedDBKeyBinaryTypeByte: {
659       int64 length = 0;
660       if (!DecodeVarInt(slice, &length) || length < 0)
661         return false;
662       if (slice->size() < static_cast<size_t>(length))
663         return false;
664       slice->remove_prefix(length);
665       return true;
666     }
667     case kIndexedDBKeyStringTypeByte: {
668       int64 length = 0;
669       if (!DecodeVarInt(slice, &length) || length < 0)
670         return false;
671       if (slice->size() < static_cast<size_t>(length) * sizeof(base::char16))
672         return false;
673       slice->remove_prefix(length * sizeof(base::char16));
674       return true;
675     }
676     case kIndexedDBKeyDateTypeByte:
677     case kIndexedDBKeyNumberTypeByte:
678       if (slice->size() < sizeof(double))
679         return false;
680       slice->remove_prefix(sizeof(double));
681       return true;
682   }
683   NOTREACHED();
684   return false;
685 }
686 
ExtractEncodedIDBKey(StringPiece * slice,std::string * result)687 bool ExtractEncodedIDBKey(StringPiece* slice, std::string* result) {
688   const char* start = slice->begin();
689   if (!ConsumeEncodedIDBKey(slice))
690     return false;
691 
692   if (result)
693     result->assign(start, slice->begin());
694   return true;
695 }
696 
KeyTypeByteToKeyType(unsigned char type)697 static WebIDBKeyType KeyTypeByteToKeyType(unsigned char type) {
698   switch (type) {
699     case kIndexedDBKeyNullTypeByte:
700       return WebIDBKeyTypeInvalid;
701     case kIndexedDBKeyArrayTypeByte:
702       return WebIDBKeyTypeArray;
703     case kIndexedDBKeyBinaryTypeByte:
704       return WebIDBKeyTypeBinary;
705     case kIndexedDBKeyStringTypeByte:
706       return WebIDBKeyTypeString;
707     case kIndexedDBKeyDateTypeByte:
708       return WebIDBKeyTypeDate;
709     case kIndexedDBKeyNumberTypeByte:
710       return WebIDBKeyTypeNumber;
711     case kIndexedDBKeyMinKeyTypeByte:
712       return WebIDBKeyTypeMin;
713   }
714 
715   NOTREACHED();
716   return WebIDBKeyTypeInvalid;
717 }
718 
CompareEncodedStringsWithLength(StringPiece * slice1,StringPiece * slice2,bool * ok)719 int CompareEncodedStringsWithLength(StringPiece* slice1,
720                                     StringPiece* slice2,
721                                     bool* ok) {
722   int64 len1, len2;
723   if (!DecodeVarInt(slice1, &len1) || !DecodeVarInt(slice2, &len2)) {
724     *ok = false;
725     return 0;
726   }
727   DCHECK_GE(len1, 0);
728   DCHECK_GE(len2, 0);
729   if (len1 < 0 || len2 < 0) {
730     *ok = false;
731     return 0;
732   }
733   DCHECK_GE(slice1->size(), len1 * sizeof(base::char16));
734   DCHECK_GE(slice2->size(), len2 * sizeof(base::char16));
735   if (slice1->size() < len1 * sizeof(base::char16) ||
736       slice2->size() < len2 * sizeof(base::char16)) {
737     *ok = false;
738     return 0;
739   }
740 
741   // Extract the string data, and advance the passed slices.
742   StringPiece string1(slice1->begin(), len1 * sizeof(base::char16));
743   StringPiece string2(slice2->begin(), len2 * sizeof(base::char16));
744   slice1->remove_prefix(len1 * sizeof(base::char16));
745   slice2->remove_prefix(len2 * sizeof(base::char16));
746 
747   *ok = true;
748   // Strings are UTF-16BE encoded, so a simple memcmp is sufficient.
749   return string1.compare(string2);
750 }
751 
CompareEncodedBinary(StringPiece * slice1,StringPiece * slice2,bool * ok)752 int CompareEncodedBinary(StringPiece* slice1,
753                          StringPiece* slice2,
754                          bool* ok) {
755   int64 len1, len2;
756   if (!DecodeVarInt(slice1, &len1) || !DecodeVarInt(slice2, &len2)) {
757     *ok = false;
758     return 0;
759   }
760   DCHECK_GE(len1, 0);
761   DCHECK_GE(len2, 0);
762   if (len1 < 0 || len2 < 0) {
763     *ok = false;
764     return 0;
765   }
766   size_t size1 = len1;
767   size_t size2 = len2;
768 
769   DCHECK_GE(slice1->size(), size1);
770   DCHECK_GE(slice2->size(), size2);
771   if (slice1->size() < size1 || slice2->size() < size2) {
772     *ok = false;
773     return 0;
774   }
775 
776   // Extract the binary data, and advance the passed slices.
777   StringPiece binary1(slice1->begin(), size1);
778   StringPiece binary2(slice2->begin(), size2);
779   slice1->remove_prefix(size1);
780   slice2->remove_prefix(size2);
781 
782   *ok = true;
783   // This is the same as a memcmp()
784   return binary1.compare(binary2);
785 }
786 
CompareInts(int64 a,int64 b)787 static int CompareInts(int64 a, int64 b) {
788 #ifndef NDEBUG
789   // Exercised by unit tests in debug only.
790   DCHECK_GE(a, 0);
791   DCHECK_GE(b, 0);
792 #endif
793   int64 diff = a - b;
794   if (diff < 0)
795     return -1;
796   if (diff > 0)
797     return 1;
798   return 0;
799 }
800 
CompareSizes(size_t a,size_t b)801 static inline int CompareSizes(size_t a, size_t b) {
802   if (a > b)
803     return 1;
804   if (b > a)
805     return -1;
806   return 0;
807 }
808 
CompareTypes(WebIDBKeyType a,WebIDBKeyType b)809 static int CompareTypes(WebIDBKeyType a, WebIDBKeyType b) { return b - a; }
810 
CompareEncodedIDBKeys(StringPiece * slice_a,StringPiece * slice_b,bool * ok)811 int CompareEncodedIDBKeys(StringPiece* slice_a,
812                           StringPiece* slice_b,
813                           bool* ok) {
814   DCHECK(!slice_a->empty());
815   DCHECK(!slice_b->empty());
816   *ok = true;
817   unsigned char type_a = (*slice_a)[0];
818   unsigned char type_b = (*slice_b)[0];
819   slice_a->remove_prefix(1);
820   slice_b->remove_prefix(1);
821 
822   if (int x = CompareTypes(KeyTypeByteToKeyType(type_a),
823                            KeyTypeByteToKeyType(type_b)))
824     return x;
825 
826   switch (type_a) {
827     case kIndexedDBKeyNullTypeByte:
828     case kIndexedDBKeyMinKeyTypeByte:
829       // Null type or max type; no payload to compare.
830       return 0;
831     case kIndexedDBKeyArrayTypeByte: {
832       int64 length_a, length_b;
833       if (!DecodeVarInt(slice_a, &length_a) ||
834           !DecodeVarInt(slice_b, &length_b)) {
835         *ok = false;
836         return 0;
837       }
838       for (int64 i = 0; i < length_a && i < length_b; ++i) {
839         int result = CompareEncodedIDBKeys(slice_a, slice_b, ok);
840         if (!*ok || result)
841           return result;
842       }
843       return length_a - length_b;
844     }
845     case kIndexedDBKeyBinaryTypeByte:
846       return CompareEncodedBinary(slice_a, slice_b, ok);
847     case kIndexedDBKeyStringTypeByte:
848       return CompareEncodedStringsWithLength(slice_a, slice_b, ok);
849     case kIndexedDBKeyDateTypeByte:
850     case kIndexedDBKeyNumberTypeByte: {
851       double d, e;
852       if (!DecodeDouble(slice_a, &d) || !DecodeDouble(slice_b, &e)) {
853         *ok = false;
854         return 0;
855       }
856       if (d < e)
857         return -1;
858       if (d > e)
859         return 1;
860       return 0;
861     }
862   }
863 
864   NOTREACHED();
865   return 0;
866 }
867 
868 namespace {
869 
870 template <typename KeyType>
Compare(const StringPiece & a,const StringPiece & b,bool only_compare_index_keys,bool * ok)871 int Compare(const StringPiece& a,
872             const StringPiece& b,
873             bool only_compare_index_keys,
874             bool* ok) {
875   KeyType key_a;
876   KeyType key_b;
877 
878   StringPiece slice_a(a);
879   if (!KeyType::Decode(&slice_a, &key_a)) {
880     *ok = false;
881     return 0;
882   }
883   StringPiece slice_b(b);
884   if (!KeyType::Decode(&slice_b, &key_b)) {
885     *ok = false;
886     return 0;
887   }
888 
889   *ok = true;
890   return key_a.Compare(key_b);
891 }
892 
893 template <typename KeyType>
CompareSuffix(StringPiece * a,StringPiece * b,bool only_compare_index_keys,bool * ok)894 int CompareSuffix(StringPiece* a,
895                   StringPiece* b,
896                   bool only_compare_index_keys,
897                   bool* ok) {
898   NOTREACHED();
899   return 0;
900 }
901 
902 template <>
CompareSuffix(StringPiece * slice_a,StringPiece * slice_b,bool only_compare_index_keys,bool * ok)903 int CompareSuffix<ExistsEntryKey>(StringPiece* slice_a,
904                                   StringPiece* slice_b,
905                                   bool only_compare_index_keys,
906                                   bool* ok) {
907   DCHECK(!slice_a->empty());
908   DCHECK(!slice_b->empty());
909   return CompareEncodedIDBKeys(slice_a, slice_b, ok);
910 }
911 
912 template <>
CompareSuffix(StringPiece * slice_a,StringPiece * slice_b,bool only_compare_index_keys,bool * ok)913 int CompareSuffix<ObjectStoreDataKey>(StringPiece* slice_a,
914                                       StringPiece* slice_b,
915                                       bool only_compare_index_keys,
916                                       bool* ok) {
917   return CompareEncodedIDBKeys(slice_a, slice_b, ok);
918 }
919 
920 template <>
CompareSuffix(StringPiece * slice_a,StringPiece * slice_b,bool only_compare_index_keys,bool * ok)921 int CompareSuffix<BlobEntryKey>(StringPiece* slice_a,
922                                 StringPiece* slice_b,
923                                 bool only_compare_index_keys,
924                                 bool* ok) {
925   return CompareEncodedIDBKeys(slice_a, slice_b, ok);
926 }
927 
928 template <>
CompareSuffix(StringPiece * slice_a,StringPiece * slice_b,bool only_compare_index_keys,bool * ok)929 int CompareSuffix<IndexDataKey>(StringPiece* slice_a,
930                                 StringPiece* slice_b,
931                                 bool only_compare_index_keys,
932                                 bool* ok) {
933   // index key
934   int result = CompareEncodedIDBKeys(slice_a, slice_b, ok);
935   if (!*ok || result)
936     return result;
937   if (only_compare_index_keys)
938     return 0;
939 
940   // sequence number [optional]
941   int64 sequence_number_a = -1;
942   int64 sequence_number_b = -1;
943   if (!slice_a->empty() && !DecodeVarInt(slice_a, &sequence_number_a))
944       return 0;
945   if (!slice_b->empty() && !DecodeVarInt(slice_b, &sequence_number_b))
946       return 0;
947 
948   if (slice_a->empty() || slice_b->empty())
949     return CompareSizes(slice_a->size(), slice_b->size());
950 
951   // primary key [optional]
952   result = CompareEncodedIDBKeys(slice_a, slice_b, ok);
953   if (!*ok || result)
954     return result;
955 
956   return CompareInts(sequence_number_a, sequence_number_b);
957 }
958 
Compare(const StringPiece & a,const StringPiece & b,bool only_compare_index_keys,bool * ok)959 int Compare(const StringPiece& a,
960             const StringPiece& b,
961             bool only_compare_index_keys,
962             bool* ok) {
963   StringPiece slice_a(a);
964   StringPiece slice_b(b);
965   KeyPrefix prefix_a;
966   KeyPrefix prefix_b;
967   bool ok_a = KeyPrefix::Decode(&slice_a, &prefix_a);
968   bool ok_b = KeyPrefix::Decode(&slice_b, &prefix_b);
969   DCHECK(ok_a);
970   DCHECK(ok_b);
971   if (!ok_a || !ok_b) {
972     *ok = false;
973     return 0;
974   }
975 
976   *ok = true;
977   if (int x = prefix_a.Compare(prefix_b))
978     return x;
979 
980   switch (prefix_a.type()) {
981     case KeyPrefix::GLOBAL_METADATA: {
982       DCHECK(!slice_a.empty());
983       DCHECK(!slice_b.empty());
984 
985       unsigned char type_byte_a;
986       if (!DecodeByte(&slice_a, &type_byte_a)) {
987         *ok = false;
988         return 0;
989       }
990 
991       unsigned char type_byte_b;
992       if (!DecodeByte(&slice_b, &type_byte_b)) {
993         *ok = false;
994         return 0;
995       }
996 
997       if (int x = type_byte_a - type_byte_b)
998         return x;
999       if (type_byte_a < kMaxSimpleGlobalMetaDataTypeByte)
1000         return 0;
1001 
1002       // Compare<> is used (which re-decodes the prefix) rather than an
1003       // specialized CompareSuffix<> because metadata is relatively uncommon
1004       // in the database.
1005 
1006       if (type_byte_a == kDatabaseFreeListTypeByte) {
1007         // TODO(jsbell): No need to pass only_compare_index_keys through here.
1008         return Compare<DatabaseFreeListKey>(a, b, only_compare_index_keys, ok);
1009       }
1010       if (type_byte_a == kDatabaseNameTypeByte) {
1011         return Compare<DatabaseNameKey>(
1012             a, b, /*only_compare_index_keys*/ false, ok);
1013       }
1014       break;
1015     }
1016 
1017     case KeyPrefix::DATABASE_METADATA: {
1018       DCHECK(!slice_a.empty());
1019       DCHECK(!slice_b.empty());
1020 
1021       unsigned char type_byte_a;
1022       if (!DecodeByte(&slice_a, &type_byte_a)) {
1023         *ok = false;
1024         return 0;
1025       }
1026 
1027       unsigned char type_byte_b;
1028       if (!DecodeByte(&slice_b, &type_byte_b)) {
1029         *ok = false;
1030         return 0;
1031       }
1032 
1033       if (int x = type_byte_a - type_byte_b)
1034         return x;
1035       if (type_byte_a < DatabaseMetaDataKey::MAX_SIMPLE_METADATA_TYPE)
1036         return 0;
1037 
1038       // Compare<> is used (which re-decodes the prefix) rather than an
1039       // specialized CompareSuffix<> because metadata is relatively uncommon
1040       // in the database.
1041 
1042       if (type_byte_a == kObjectStoreMetaDataTypeByte) {
1043         // TODO(jsbell): No need to pass only_compare_index_keys through here.
1044         return Compare<ObjectStoreMetaDataKey>(
1045             a, b, only_compare_index_keys, ok);
1046       }
1047       if (type_byte_a == kIndexMetaDataTypeByte) {
1048         return Compare<IndexMetaDataKey>(
1049             a, b, /*only_compare_index_keys*/ false, ok);
1050       }
1051       if (type_byte_a == kObjectStoreFreeListTypeByte) {
1052         return Compare<ObjectStoreFreeListKey>(
1053             a, b, only_compare_index_keys, ok);
1054       }
1055       if (type_byte_a == kIndexFreeListTypeByte) {
1056         return Compare<IndexFreeListKey>(
1057             a, b, /*only_compare_index_keys*/ false, ok);
1058       }
1059       if (type_byte_a == kObjectStoreNamesTypeByte) {
1060         // TODO(jsbell): No need to pass only_compare_index_keys through here.
1061         return Compare<ObjectStoreNamesKey>(
1062             a, b, only_compare_index_keys, ok);
1063       }
1064       if (type_byte_a == kIndexNamesKeyTypeByte) {
1065         return Compare<IndexNamesKey>(
1066             a, b, /*only_compare_index_keys*/ false, ok);
1067       }
1068       break;
1069     }
1070 
1071     case KeyPrefix::OBJECT_STORE_DATA: {
1072       // Provide a stable ordering for invalid data.
1073       if (slice_a.empty() || slice_b.empty())
1074         return CompareSizes(slice_a.size(), slice_b.size());
1075 
1076       return CompareSuffix<ObjectStoreDataKey>(
1077           &slice_a, &slice_b, /*only_compare_index_keys*/ false, ok);
1078     }
1079 
1080     case KeyPrefix::EXISTS_ENTRY: {
1081       // Provide a stable ordering for invalid data.
1082       if (slice_a.empty() || slice_b.empty())
1083         return CompareSizes(slice_a.size(), slice_b.size());
1084 
1085       return CompareSuffix<ExistsEntryKey>(
1086           &slice_a, &slice_b, /*only_compare_index_keys*/ false, ok);
1087     }
1088 
1089     case KeyPrefix::BLOB_ENTRY: {
1090       // Provide a stable ordering for invalid data.
1091       if (slice_a.empty() || slice_b.empty())
1092         return CompareSizes(slice_a.size(), slice_b.size());
1093 
1094       return CompareSuffix<BlobEntryKey>(
1095           &slice_a, &slice_b, /*only_compare_index_keys*/ false, ok);
1096     }
1097 
1098     case KeyPrefix::INDEX_DATA: {
1099       // Provide a stable ordering for invalid data.
1100       if (slice_a.empty() || slice_b.empty())
1101         return CompareSizes(slice_a.size(), slice_b.size());
1102 
1103       return CompareSuffix<IndexDataKey>(
1104           &slice_a, &slice_b, only_compare_index_keys, ok);
1105     }
1106 
1107     case KeyPrefix::INVALID_TYPE:
1108       break;
1109   }
1110 
1111   NOTREACHED();
1112   *ok = false;
1113   return 0;
1114 }
1115 
1116 }  // namespace
1117 
Compare(const StringPiece & a,const StringPiece & b,bool only_compare_index_keys)1118 int Compare(const StringPiece& a,
1119             const StringPiece& b,
1120             bool only_compare_index_keys) {
1121   bool ok;
1122   int result = Compare(a, b, only_compare_index_keys, &ok);
1123   DCHECK(ok);
1124   if (!ok)
1125     return 0;
1126   return result;
1127 }
1128 
KeyPrefix()1129 KeyPrefix::KeyPrefix()
1130     : database_id_(INVALID_TYPE),
1131       object_store_id_(INVALID_TYPE),
1132       index_id_(INVALID_TYPE) {}
1133 
KeyPrefix(int64 database_id)1134 KeyPrefix::KeyPrefix(int64 database_id)
1135     : database_id_(database_id), object_store_id_(0), index_id_(0) {
1136   DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
1137 }
1138 
KeyPrefix(int64 database_id,int64 object_store_id)1139 KeyPrefix::KeyPrefix(int64 database_id, int64 object_store_id)
1140     : database_id_(database_id),
1141       object_store_id_(object_store_id),
1142       index_id_(0) {
1143   DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
1144   DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id));
1145 }
1146 
KeyPrefix(int64 database_id,int64 object_store_id,int64 index_id)1147 KeyPrefix::KeyPrefix(int64 database_id, int64 object_store_id, int64 index_id)
1148     : database_id_(database_id),
1149       object_store_id_(object_store_id),
1150       index_id_(index_id) {
1151   DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
1152   DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id));
1153   DCHECK(KeyPrefix::IsValidIndexId(index_id));
1154 }
1155 
KeyPrefix(enum Type type,int64 database_id,int64 object_store_id,int64 index_id)1156 KeyPrefix::KeyPrefix(enum Type type,
1157                      int64 database_id,
1158                      int64 object_store_id,
1159                      int64 index_id)
1160     : database_id_(database_id),
1161       object_store_id_(object_store_id),
1162       index_id_(index_id) {
1163   DCHECK_EQ(type, INVALID_TYPE);
1164   DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
1165   DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id));
1166 }
1167 
CreateWithSpecialIndex(int64 database_id,int64 object_store_id,int64 index_id)1168 KeyPrefix KeyPrefix::CreateWithSpecialIndex(int64 database_id,
1169                                             int64 object_store_id,
1170                                             int64 index_id) {
1171   DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
1172   DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id));
1173   DCHECK(index_id);
1174   return KeyPrefix(INVALID_TYPE, database_id, object_store_id, index_id);
1175 }
1176 
IsValidDatabaseId(int64 database_id)1177 bool KeyPrefix::IsValidDatabaseId(int64 database_id) {
1178   return (database_id > 0) && (database_id < KeyPrefix::kMaxDatabaseId);
1179 }
1180 
IsValidObjectStoreId(int64 object_store_id)1181 bool KeyPrefix::IsValidObjectStoreId(int64 object_store_id) {
1182   return (object_store_id > 0) &&
1183          (object_store_id < KeyPrefix::kMaxObjectStoreId);
1184 }
1185 
IsValidIndexId(int64 index_id)1186 bool KeyPrefix::IsValidIndexId(int64 index_id) {
1187   return (index_id >= kMinimumIndexId) && (index_id < KeyPrefix::kMaxIndexId);
1188 }
1189 
Decode(StringPiece * slice,KeyPrefix * result)1190 bool KeyPrefix::Decode(StringPiece* slice, KeyPrefix* result) {
1191   unsigned char first_byte;
1192   if (!DecodeByte(slice, &first_byte))
1193     return false;
1194 
1195   size_t database_id_bytes = ((first_byte >> 5) & 0x7) + 1;
1196   size_t object_store_id_bytes = ((first_byte >> 2) & 0x7) + 1;
1197   size_t index_id_bytes = (first_byte & 0x3) + 1;
1198 
1199   if (database_id_bytes + object_store_id_bytes + index_id_bytes >
1200       slice->size())
1201     return false;
1202 
1203   {
1204     StringPiece tmp(slice->begin(), database_id_bytes);
1205     if (!DecodeInt(&tmp, &result->database_id_))
1206       return false;
1207   }
1208   slice->remove_prefix(database_id_bytes);
1209   {
1210     StringPiece tmp(slice->begin(), object_store_id_bytes);
1211     if (!DecodeInt(&tmp, &result->object_store_id_))
1212       return false;
1213   }
1214   slice->remove_prefix(object_store_id_bytes);
1215   {
1216     StringPiece tmp(slice->begin(), index_id_bytes);
1217     if (!DecodeInt(&tmp, &result->index_id_))
1218       return false;
1219   }
1220   slice->remove_prefix(index_id_bytes);
1221   return true;
1222 }
1223 
EncodeEmpty()1224 std::string KeyPrefix::EncodeEmpty() {
1225   const std::string result(4, 0);
1226   DCHECK(EncodeInternal(0, 0, 0) == std::string(4, 0));
1227   return result;
1228 }
1229 
Encode() const1230 std::string KeyPrefix::Encode() const {
1231   DCHECK(database_id_ != kInvalidId);
1232   DCHECK(object_store_id_ != kInvalidId);
1233   DCHECK(index_id_ != kInvalidId);
1234   return EncodeInternal(database_id_, object_store_id_, index_id_);
1235 }
1236 
EncodeInternal(int64 database_id,int64 object_store_id,int64 index_id)1237 std::string KeyPrefix::EncodeInternal(int64 database_id,
1238                                       int64 object_store_id,
1239                                       int64 index_id) {
1240   std::string database_id_string;
1241   std::string object_store_id_string;
1242   std::string index_id_string;
1243 
1244   EncodeIntSafely(database_id, kMaxDatabaseId, &database_id_string);
1245   EncodeIntSafely(object_store_id, kMaxObjectStoreId, &object_store_id_string);
1246   EncodeIntSafely(index_id, kMaxIndexId, &index_id_string);
1247 
1248   DCHECK(database_id_string.size() <= kMaxDatabaseIdSizeBytes);
1249   DCHECK(object_store_id_string.size() <= kMaxObjectStoreIdSizeBytes);
1250   DCHECK(index_id_string.size() <= kMaxIndexIdSizeBytes);
1251 
1252   unsigned char first_byte =
1253       (database_id_string.size() - 1) << (kMaxObjectStoreIdSizeBits +
1254                                           kMaxIndexIdSizeBits) |
1255       (object_store_id_string.size() - 1) << kMaxIndexIdSizeBits |
1256       (index_id_string.size() - 1);
1257   COMPILE_ASSERT(kMaxDatabaseIdSizeBits + kMaxObjectStoreIdSizeBits +
1258                          kMaxIndexIdSizeBits ==
1259                      sizeof(first_byte) * 8,
1260                  CANT_ENCODE_IDS);
1261   std::string ret;
1262   ret.reserve(kDefaultInlineBufferSize);
1263   ret.push_back(first_byte);
1264   ret.append(database_id_string);
1265   ret.append(object_store_id_string);
1266   ret.append(index_id_string);
1267 
1268   DCHECK_LE(ret.size(), kDefaultInlineBufferSize);
1269   return ret;
1270 }
1271 
Compare(const KeyPrefix & other) const1272 int KeyPrefix::Compare(const KeyPrefix& other) const {
1273   DCHECK(database_id_ != kInvalidId);
1274   DCHECK(object_store_id_ != kInvalidId);
1275   DCHECK(index_id_ != kInvalidId);
1276 
1277   if (database_id_ != other.database_id_)
1278     return CompareInts(database_id_, other.database_id_);
1279   if (object_store_id_ != other.object_store_id_)
1280     return CompareInts(object_store_id_, other.object_store_id_);
1281   if (index_id_ != other.index_id_)
1282     return CompareInts(index_id_, other.index_id_);
1283   return 0;
1284 }
1285 
type() const1286 KeyPrefix::Type KeyPrefix::type() const {
1287   DCHECK(database_id_ != kInvalidId);
1288   DCHECK(object_store_id_ != kInvalidId);
1289   DCHECK(index_id_ != kInvalidId);
1290 
1291   if (!database_id_)
1292     return GLOBAL_METADATA;
1293   if (!object_store_id_)
1294     return DATABASE_METADATA;
1295   if (index_id_ == kObjectStoreDataIndexId)
1296     return OBJECT_STORE_DATA;
1297   if (index_id_ == kExistsEntryIndexId)
1298     return EXISTS_ENTRY;
1299   if (index_id_ == kBlobEntryIndexId)
1300     return BLOB_ENTRY;
1301   if (index_id_ >= kMinimumIndexId)
1302     return INDEX_DATA;
1303 
1304   NOTREACHED();
1305   return INVALID_TYPE;
1306 }
1307 
Encode()1308 std::string SchemaVersionKey::Encode() {
1309   std::string ret = KeyPrefix::EncodeEmpty();
1310   ret.push_back(kSchemaVersionTypeByte);
1311   return ret;
1312 }
1313 
Encode()1314 std::string MaxDatabaseIdKey::Encode() {
1315   std::string ret = KeyPrefix::EncodeEmpty();
1316   ret.push_back(kMaxDatabaseIdTypeByte);
1317   return ret;
1318 }
1319 
Encode()1320 std::string DataVersionKey::Encode() {
1321   std::string ret = KeyPrefix::EncodeEmpty();
1322   ret.push_back(kDataVersionTypeByte);
1323   return ret;
1324 }
1325 
Encode()1326 std::string BlobJournalKey::Encode() {
1327   std::string ret = KeyPrefix::EncodeEmpty();
1328   ret.push_back(kBlobJournalTypeByte);
1329   return ret;
1330 }
1331 
Encode()1332 std::string LiveBlobJournalKey::Encode() {
1333   std::string ret = KeyPrefix::EncodeEmpty();
1334   ret.push_back(kLiveBlobJournalTypeByte);
1335   return ret;
1336 }
1337 
DatabaseFreeListKey()1338 DatabaseFreeListKey::DatabaseFreeListKey() : database_id_(-1) {}
1339 
Decode(StringPiece * slice,DatabaseFreeListKey * result)1340 bool DatabaseFreeListKey::Decode(StringPiece* slice,
1341                                  DatabaseFreeListKey* result) {
1342   KeyPrefix prefix;
1343   if (!KeyPrefix::Decode(slice, &prefix))
1344     return false;
1345   DCHECK(!prefix.database_id_);
1346   DCHECK(!prefix.object_store_id_);
1347   DCHECK(!prefix.index_id_);
1348   unsigned char type_byte = 0;
1349   if (!DecodeByte(slice, &type_byte))
1350     return false;
1351   DCHECK_EQ(type_byte, kDatabaseFreeListTypeByte);
1352   if (!DecodeVarInt(slice, &result->database_id_))
1353     return false;
1354   return true;
1355 }
1356 
Encode(int64 database_id)1357 std::string DatabaseFreeListKey::Encode(int64 database_id) {
1358   std::string ret = KeyPrefix::EncodeEmpty();
1359   ret.push_back(kDatabaseFreeListTypeByte);
1360   EncodeVarInt(database_id, &ret);
1361   return ret;
1362 }
1363 
EncodeMaxKey()1364 std::string DatabaseFreeListKey::EncodeMaxKey() {
1365   return Encode(std::numeric_limits<int64>::max());
1366 }
1367 
DatabaseId() const1368 int64 DatabaseFreeListKey::DatabaseId() const {
1369   DCHECK_GE(database_id_, 0);
1370   return database_id_;
1371 }
1372 
Compare(const DatabaseFreeListKey & other) const1373 int DatabaseFreeListKey::Compare(const DatabaseFreeListKey& other) const {
1374   DCHECK_GE(database_id_, 0);
1375   return CompareInts(database_id_, other.database_id_);
1376 }
1377 
Decode(StringPiece * slice,DatabaseNameKey * result)1378 bool DatabaseNameKey::Decode(StringPiece* slice, DatabaseNameKey* result) {
1379   KeyPrefix prefix;
1380   if (!KeyPrefix::Decode(slice, &prefix))
1381     return false;
1382   DCHECK(!prefix.database_id_);
1383   DCHECK(!prefix.object_store_id_);
1384   DCHECK(!prefix.index_id_);
1385   unsigned char type_byte = 0;
1386   if (!DecodeByte(slice, &type_byte))
1387     return false;
1388   DCHECK_EQ(type_byte, kDatabaseNameTypeByte);
1389   if (!DecodeStringWithLength(slice, &result->origin_))
1390     return false;
1391   if (!DecodeStringWithLength(slice, &result->database_name_))
1392     return false;
1393   return true;
1394 }
1395 
Encode(const std::string & origin_identifier,const base::string16 & database_name)1396 std::string DatabaseNameKey::Encode(const std::string& origin_identifier,
1397                                     const base::string16& database_name) {
1398   std::string ret = KeyPrefix::EncodeEmpty();
1399   ret.push_back(kDatabaseNameTypeByte);
1400   EncodeStringWithLength(base::ASCIIToUTF16(origin_identifier), &ret);
1401   EncodeStringWithLength(database_name, &ret);
1402   return ret;
1403 }
1404 
EncodeMinKeyForOrigin(const std::string & origin_identifier)1405 std::string DatabaseNameKey::EncodeMinKeyForOrigin(
1406     const std::string& origin_identifier) {
1407   return Encode(origin_identifier, base::string16());
1408 }
1409 
EncodeStopKeyForOrigin(const std::string & origin_identifier)1410 std::string DatabaseNameKey::EncodeStopKeyForOrigin(
1411     const std::string& origin_identifier) {
1412   // just after origin in collation order
1413   return EncodeMinKeyForOrigin(origin_identifier + '\x01');
1414 }
1415 
Compare(const DatabaseNameKey & other)1416 int DatabaseNameKey::Compare(const DatabaseNameKey& other) {
1417   if (int x = origin_.compare(other.origin_))
1418     return x;
1419   return database_name_.compare(other.database_name_);
1420 }
1421 
IsValidBlobKey(int64 blob_key)1422 bool DatabaseMetaDataKey::IsValidBlobKey(int64 blob_key) {
1423   return blob_key >= kBlobKeyGeneratorInitialNumber;
1424 }
1425 
1426 const int64 DatabaseMetaDataKey::kAllBlobsKey = 1;
1427 const int64 DatabaseMetaDataKey::kBlobKeyGeneratorInitialNumber = 2;
1428 const int64 DatabaseMetaDataKey::kInvalidBlobKey = -1;
1429 
Encode(int64 database_id,MetaDataType meta_data_type)1430 std::string DatabaseMetaDataKey::Encode(int64 database_id,
1431                                         MetaDataType meta_data_type) {
1432   KeyPrefix prefix(database_id);
1433   std::string ret = prefix.Encode();
1434   ret.push_back(meta_data_type);
1435   return ret;
1436 }
1437 
ObjectStoreMetaDataKey()1438 ObjectStoreMetaDataKey::ObjectStoreMetaDataKey()
1439     : object_store_id_(-1), meta_data_type_(-1) {}
1440 
Decode(StringPiece * slice,ObjectStoreMetaDataKey * result)1441 bool ObjectStoreMetaDataKey::Decode(StringPiece* slice,
1442                                     ObjectStoreMetaDataKey* result) {
1443   KeyPrefix prefix;
1444   if (!KeyPrefix::Decode(slice, &prefix))
1445     return false;
1446   DCHECK(prefix.database_id_);
1447   DCHECK(!prefix.object_store_id_);
1448   DCHECK(!prefix.index_id_);
1449   unsigned char type_byte = 0;
1450   if (!DecodeByte(slice, &type_byte))
1451     return false;
1452   DCHECK_EQ(type_byte, kObjectStoreMetaDataTypeByte);
1453   if (!DecodeVarInt(slice, &result->object_store_id_))
1454     return false;
1455   DCHECK(result->object_store_id_);
1456   if (!DecodeByte(slice, &result->meta_data_type_))
1457     return false;
1458   return true;
1459 }
1460 
Encode(int64 database_id,int64 object_store_id,unsigned char meta_data_type)1461 std::string ObjectStoreMetaDataKey::Encode(int64 database_id,
1462                                            int64 object_store_id,
1463                                            unsigned char meta_data_type) {
1464   KeyPrefix prefix(database_id);
1465   std::string ret = prefix.Encode();
1466   ret.push_back(kObjectStoreMetaDataTypeByte);
1467   EncodeVarInt(object_store_id, &ret);
1468   ret.push_back(meta_data_type);
1469   return ret;
1470 }
1471 
EncodeMaxKey(int64 database_id)1472 std::string ObjectStoreMetaDataKey::EncodeMaxKey(int64 database_id) {
1473   return Encode(database_id,
1474                 std::numeric_limits<int64>::max(),
1475                 kObjectMetaDataTypeMaximum);
1476 }
1477 
EncodeMaxKey(int64 database_id,int64 object_store_id)1478 std::string ObjectStoreMetaDataKey::EncodeMaxKey(int64 database_id,
1479                                                  int64 object_store_id) {
1480   return Encode(database_id, object_store_id, kObjectMetaDataTypeMaximum);
1481 }
1482 
ObjectStoreId() const1483 int64 ObjectStoreMetaDataKey::ObjectStoreId() const {
1484   DCHECK_GE(object_store_id_, 0);
1485   return object_store_id_;
1486 }
MetaDataType() const1487 unsigned char ObjectStoreMetaDataKey::MetaDataType() const {
1488   return meta_data_type_;
1489 }
1490 
Compare(const ObjectStoreMetaDataKey & other)1491 int ObjectStoreMetaDataKey::Compare(const ObjectStoreMetaDataKey& other) {
1492   DCHECK_GE(object_store_id_, 0);
1493   if (int x = CompareInts(object_store_id_, other.object_store_id_))
1494     return x;
1495   return meta_data_type_ - other.meta_data_type_;
1496 }
1497 
IndexMetaDataKey()1498 IndexMetaDataKey::IndexMetaDataKey()
1499     : object_store_id_(-1), index_id_(-1), meta_data_type_(0) {}
1500 
Decode(StringPiece * slice,IndexMetaDataKey * result)1501 bool IndexMetaDataKey::Decode(StringPiece* slice, IndexMetaDataKey* result) {
1502   KeyPrefix prefix;
1503   if (!KeyPrefix::Decode(slice, &prefix))
1504     return false;
1505   DCHECK(prefix.database_id_);
1506   DCHECK(!prefix.object_store_id_);
1507   DCHECK(!prefix.index_id_);
1508   unsigned char type_byte = 0;
1509   if (!DecodeByte(slice, &type_byte))
1510     return false;
1511   DCHECK_EQ(type_byte, kIndexMetaDataTypeByte);
1512   if (!DecodeVarInt(slice, &result->object_store_id_))
1513     return false;
1514   if (!DecodeVarInt(slice, &result->index_id_))
1515     return false;
1516   if (!DecodeByte(slice, &result->meta_data_type_))
1517     return false;
1518   return true;
1519 }
1520 
Encode(int64 database_id,int64 object_store_id,int64 index_id,unsigned char meta_data_type)1521 std::string IndexMetaDataKey::Encode(int64 database_id,
1522                                      int64 object_store_id,
1523                                      int64 index_id,
1524                                      unsigned char meta_data_type) {
1525   KeyPrefix prefix(database_id);
1526   std::string ret = prefix.Encode();
1527   ret.push_back(kIndexMetaDataTypeByte);
1528   EncodeVarInt(object_store_id, &ret);
1529   EncodeVarInt(index_id, &ret);
1530   EncodeByte(meta_data_type, &ret);
1531   return ret;
1532 }
1533 
EncodeMaxKey(int64 database_id,int64 object_store_id)1534 std::string IndexMetaDataKey::EncodeMaxKey(int64 database_id,
1535                                            int64 object_store_id) {
1536   return Encode(database_id,
1537                 object_store_id,
1538                 std::numeric_limits<int64>::max(),
1539                 kIndexMetaDataTypeMaximum);
1540 }
1541 
EncodeMaxKey(int64 database_id,int64 object_store_id,int64 index_id)1542 std::string IndexMetaDataKey::EncodeMaxKey(int64 database_id,
1543                                            int64 object_store_id,
1544                                            int64 index_id) {
1545   return Encode(
1546       database_id, object_store_id, index_id, kIndexMetaDataTypeMaximum);
1547 }
1548 
Compare(const IndexMetaDataKey & other)1549 int IndexMetaDataKey::Compare(const IndexMetaDataKey& other) {
1550   DCHECK_GE(object_store_id_, 0);
1551   DCHECK_GE(index_id_, 0);
1552 
1553   if (int x = CompareInts(object_store_id_, other.object_store_id_))
1554     return x;
1555   if (int x = CompareInts(index_id_, other.index_id_))
1556     return x;
1557   return meta_data_type_ - other.meta_data_type_;
1558 }
1559 
IndexId() const1560 int64 IndexMetaDataKey::IndexId() const {
1561   DCHECK_GE(index_id_, 0);
1562   return index_id_;
1563 }
1564 
ObjectStoreFreeListKey()1565 ObjectStoreFreeListKey::ObjectStoreFreeListKey() : object_store_id_(-1) {}
1566 
Decode(StringPiece * slice,ObjectStoreFreeListKey * result)1567 bool ObjectStoreFreeListKey::Decode(StringPiece* slice,
1568                                     ObjectStoreFreeListKey* result) {
1569   KeyPrefix prefix;
1570   if (!KeyPrefix::Decode(slice, &prefix))
1571     return false;
1572   DCHECK(prefix.database_id_);
1573   DCHECK(!prefix.object_store_id_);
1574   DCHECK(!prefix.index_id_);
1575   unsigned char type_byte = 0;
1576   if (!DecodeByte(slice, &type_byte))
1577     return false;
1578   DCHECK_EQ(type_byte, kObjectStoreFreeListTypeByte);
1579   if (!DecodeVarInt(slice, &result->object_store_id_))
1580     return false;
1581   return true;
1582 }
1583 
Encode(int64 database_id,int64 object_store_id)1584 std::string ObjectStoreFreeListKey::Encode(int64 database_id,
1585                                            int64 object_store_id) {
1586   KeyPrefix prefix(database_id);
1587   std::string ret = prefix.Encode();
1588   ret.push_back(kObjectStoreFreeListTypeByte);
1589   EncodeVarInt(object_store_id, &ret);
1590   return ret;
1591 }
1592 
EncodeMaxKey(int64 database_id)1593 std::string ObjectStoreFreeListKey::EncodeMaxKey(int64 database_id) {
1594   return Encode(database_id, std::numeric_limits<int64>::max());
1595 }
1596 
ObjectStoreId() const1597 int64 ObjectStoreFreeListKey::ObjectStoreId() const {
1598   DCHECK_GE(object_store_id_, 0);
1599   return object_store_id_;
1600 }
1601 
Compare(const ObjectStoreFreeListKey & other)1602 int ObjectStoreFreeListKey::Compare(const ObjectStoreFreeListKey& other) {
1603   // TODO(jsbell): It may seem strange that we're not comparing database id's,
1604   // but that comparison will have been made earlier.
1605   // We should probably make this more clear, though...
1606   DCHECK_GE(object_store_id_, 0);
1607   return CompareInts(object_store_id_, other.object_store_id_);
1608 }
1609 
IndexFreeListKey()1610 IndexFreeListKey::IndexFreeListKey() : object_store_id_(-1), index_id_(-1) {}
1611 
Decode(StringPiece * slice,IndexFreeListKey * result)1612 bool IndexFreeListKey::Decode(StringPiece* slice, IndexFreeListKey* result) {
1613   KeyPrefix prefix;
1614   if (!KeyPrefix::Decode(slice, &prefix))
1615     return false;
1616   DCHECK(prefix.database_id_);
1617   DCHECK(!prefix.object_store_id_);
1618   DCHECK(!prefix.index_id_);
1619   unsigned char type_byte = 0;
1620   if (!DecodeByte(slice, &type_byte))
1621     return false;
1622   DCHECK_EQ(type_byte, kIndexFreeListTypeByte);
1623   if (!DecodeVarInt(slice, &result->object_store_id_))
1624     return false;
1625   if (!DecodeVarInt(slice, &result->index_id_))
1626     return false;
1627   return true;
1628 }
1629 
Encode(int64 database_id,int64 object_store_id,int64 index_id)1630 std::string IndexFreeListKey::Encode(int64 database_id,
1631                                      int64 object_store_id,
1632                                      int64 index_id) {
1633   KeyPrefix prefix(database_id);
1634   std::string ret = prefix.Encode();
1635   ret.push_back(kIndexFreeListTypeByte);
1636   EncodeVarInt(object_store_id, &ret);
1637   EncodeVarInt(index_id, &ret);
1638   return ret;
1639 }
1640 
EncodeMaxKey(int64 database_id,int64 object_store_id)1641 std::string IndexFreeListKey::EncodeMaxKey(int64 database_id,
1642                                            int64 object_store_id) {
1643   return Encode(
1644       database_id, object_store_id, std::numeric_limits<int64>::max());
1645 }
1646 
Compare(const IndexFreeListKey & other)1647 int IndexFreeListKey::Compare(const IndexFreeListKey& other) {
1648   DCHECK_GE(object_store_id_, 0);
1649   DCHECK_GE(index_id_, 0);
1650   if (int x = CompareInts(object_store_id_, other.object_store_id_))
1651     return x;
1652   return CompareInts(index_id_, other.index_id_);
1653 }
1654 
ObjectStoreId() const1655 int64 IndexFreeListKey::ObjectStoreId() const {
1656   DCHECK_GE(object_store_id_, 0);
1657   return object_store_id_;
1658 }
1659 
IndexId() const1660 int64 IndexFreeListKey::IndexId() const {
1661   DCHECK_GE(index_id_, 0);
1662   return index_id_;
1663 }
1664 
1665 // TODO(jsbell): We never use this to look up object store ids,
1666 // because a mapping is kept in the IndexedDBDatabase. Can the
1667 // mapping become unreliable?  Can we remove this?
Decode(StringPiece * slice,ObjectStoreNamesKey * result)1668 bool ObjectStoreNamesKey::Decode(StringPiece* slice,
1669                                  ObjectStoreNamesKey* result) {
1670   KeyPrefix prefix;
1671   if (!KeyPrefix::Decode(slice, &prefix))
1672     return false;
1673   DCHECK(prefix.database_id_);
1674   DCHECK(!prefix.object_store_id_);
1675   DCHECK(!prefix.index_id_);
1676   unsigned char type_byte = 0;
1677   if (!DecodeByte(slice, &type_byte))
1678     return false;
1679   DCHECK_EQ(type_byte, kObjectStoreNamesTypeByte);
1680   if (!DecodeStringWithLength(slice, &result->object_store_name_))
1681     return false;
1682   return true;
1683 }
1684 
Encode(int64 database_id,const base::string16 & object_store_name)1685 std::string ObjectStoreNamesKey::Encode(
1686     int64 database_id,
1687     const base::string16& object_store_name) {
1688   KeyPrefix prefix(database_id);
1689   std::string ret = prefix.Encode();
1690   ret.push_back(kObjectStoreNamesTypeByte);
1691   EncodeStringWithLength(object_store_name, &ret);
1692   return ret;
1693 }
1694 
Compare(const ObjectStoreNamesKey & other)1695 int ObjectStoreNamesKey::Compare(const ObjectStoreNamesKey& other) {
1696   return object_store_name_.compare(other.object_store_name_);
1697 }
1698 
IndexNamesKey()1699 IndexNamesKey::IndexNamesKey() : object_store_id_(-1) {}
1700 
1701 // TODO(jsbell): We never use this to look up index ids, because a mapping
1702 // is kept at a higher level.
Decode(StringPiece * slice,IndexNamesKey * result)1703 bool IndexNamesKey::Decode(StringPiece* slice, IndexNamesKey* result) {
1704   KeyPrefix prefix;
1705   if (!KeyPrefix::Decode(slice, &prefix))
1706     return false;
1707   DCHECK(prefix.database_id_);
1708   DCHECK(!prefix.object_store_id_);
1709   DCHECK(!prefix.index_id_);
1710   unsigned char type_byte = 0;
1711   if (!DecodeByte(slice, &type_byte))
1712     return false;
1713   DCHECK_EQ(type_byte, kIndexNamesKeyTypeByte);
1714   if (!DecodeVarInt(slice, &result->object_store_id_))
1715     return false;
1716   if (!DecodeStringWithLength(slice, &result->index_name_))
1717     return false;
1718   return true;
1719 }
1720 
Encode(int64 database_id,int64 object_store_id,const base::string16 & index_name)1721 std::string IndexNamesKey::Encode(int64 database_id,
1722                                   int64 object_store_id,
1723                                   const base::string16& index_name) {
1724   KeyPrefix prefix(database_id);
1725   std::string ret = prefix.Encode();
1726   ret.push_back(kIndexNamesKeyTypeByte);
1727   EncodeVarInt(object_store_id, &ret);
1728   EncodeStringWithLength(index_name, &ret);
1729   return ret;
1730 }
1731 
Compare(const IndexNamesKey & other)1732 int IndexNamesKey::Compare(const IndexNamesKey& other) {
1733   DCHECK_GE(object_store_id_, 0);
1734   if (int x = CompareInts(object_store_id_, other.object_store_id_))
1735     return x;
1736   return index_name_.compare(other.index_name_);
1737 }
1738 
ObjectStoreDataKey()1739 ObjectStoreDataKey::ObjectStoreDataKey() {}
~ObjectStoreDataKey()1740 ObjectStoreDataKey::~ObjectStoreDataKey() {}
1741 
Decode(StringPiece * slice,ObjectStoreDataKey * result)1742 bool ObjectStoreDataKey::Decode(StringPiece* slice,
1743                                 ObjectStoreDataKey* result) {
1744   KeyPrefix prefix;
1745   if (!KeyPrefix::Decode(slice, &prefix))
1746     return false;
1747   DCHECK(prefix.database_id_);
1748   DCHECK(prefix.object_store_id_);
1749   DCHECK_EQ(prefix.index_id_, kSpecialIndexNumber);
1750   if (!ExtractEncodedIDBKey(slice, &result->encoded_user_key_))
1751     return false;
1752   return true;
1753 }
1754 
Encode(int64 database_id,int64 object_store_id,const std::string encoded_user_key)1755 std::string ObjectStoreDataKey::Encode(int64 database_id,
1756                                        int64 object_store_id,
1757                                        const std::string encoded_user_key) {
1758   KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex(
1759       database_id, object_store_id, kSpecialIndexNumber));
1760   std::string ret = prefix.Encode();
1761   ret.append(encoded_user_key);
1762 
1763   return ret;
1764 }
1765 
Encode(int64 database_id,int64 object_store_id,const IndexedDBKey & user_key)1766 std::string ObjectStoreDataKey::Encode(int64 database_id,
1767                                        int64 object_store_id,
1768                                        const IndexedDBKey& user_key) {
1769   std::string encoded_key;
1770   EncodeIDBKey(user_key, &encoded_key);
1771   return Encode(database_id, object_store_id, encoded_key);
1772 }
1773 
user_key() const1774 scoped_ptr<IndexedDBKey> ObjectStoreDataKey::user_key() const {
1775   scoped_ptr<IndexedDBKey> key;
1776   StringPiece slice(encoded_user_key_);
1777   if (!DecodeIDBKey(&slice, &key)) {
1778     // TODO(jsbell): Return error.
1779   }
1780   return key.Pass();
1781 }
1782 
1783 const int64 ObjectStoreDataKey::kSpecialIndexNumber = kObjectStoreDataIndexId;
1784 
ExistsEntryKey()1785 ExistsEntryKey::ExistsEntryKey() {}
~ExistsEntryKey()1786 ExistsEntryKey::~ExistsEntryKey() {}
1787 
Decode(StringPiece * slice,ExistsEntryKey * result)1788 bool ExistsEntryKey::Decode(StringPiece* slice, ExistsEntryKey* result) {
1789   KeyPrefix prefix;
1790   if (!KeyPrefix::Decode(slice, &prefix))
1791     return false;
1792   DCHECK(prefix.database_id_);
1793   DCHECK(prefix.object_store_id_);
1794   DCHECK_EQ(prefix.index_id_, kSpecialIndexNumber);
1795   if (!ExtractEncodedIDBKey(slice, &result->encoded_user_key_))
1796     return false;
1797   return true;
1798 }
1799 
Encode(int64 database_id,int64 object_store_id,const std::string & encoded_key)1800 std::string ExistsEntryKey::Encode(int64 database_id,
1801                                    int64 object_store_id,
1802                                    const std::string& encoded_key) {
1803   KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex(
1804       database_id, object_store_id, kSpecialIndexNumber));
1805   std::string ret = prefix.Encode();
1806   ret.append(encoded_key);
1807   return ret;
1808 }
1809 
Encode(int64 database_id,int64 object_store_id,const IndexedDBKey & user_key)1810 std::string ExistsEntryKey::Encode(int64 database_id,
1811                                    int64 object_store_id,
1812                                    const IndexedDBKey& user_key) {
1813   std::string encoded_key;
1814   EncodeIDBKey(user_key, &encoded_key);
1815   return Encode(database_id, object_store_id, encoded_key);
1816 }
1817 
user_key() const1818 scoped_ptr<IndexedDBKey> ExistsEntryKey::user_key() const {
1819   scoped_ptr<IndexedDBKey> key;
1820   StringPiece slice(encoded_user_key_);
1821   if (!DecodeIDBKey(&slice, &key)) {
1822     // TODO(jsbell): Return error.
1823   }
1824   return key.Pass();
1825 }
1826 
1827 const int64 ExistsEntryKey::kSpecialIndexNumber = kExistsEntryIndexId;
1828 
Decode(StringPiece * slice,BlobEntryKey * result)1829 bool BlobEntryKey::Decode(StringPiece* slice, BlobEntryKey* result) {
1830   KeyPrefix prefix;
1831   if (!KeyPrefix::Decode(slice, &prefix))
1832     return false;
1833   DCHECK(prefix.database_id_);
1834   DCHECK(prefix.object_store_id_);
1835   DCHECK_EQ(prefix.index_id_, kSpecialIndexNumber);
1836 
1837   if (!ExtractEncodedIDBKey(slice, &result->encoded_user_key_))
1838     return false;
1839   result->database_id_ = prefix.database_id_;
1840   result->object_store_id_ = prefix.object_store_id_;
1841 
1842   return true;
1843 }
1844 
FromObjectStoreDataKey(StringPiece * slice,BlobEntryKey * result)1845 bool BlobEntryKey::FromObjectStoreDataKey(StringPiece* slice,
1846                                           BlobEntryKey* result) {
1847   KeyPrefix prefix;
1848   if (!KeyPrefix::Decode(slice, &prefix))
1849     return false;
1850   DCHECK(prefix.database_id_);
1851   DCHECK(prefix.object_store_id_);
1852   DCHECK_EQ(prefix.index_id_, ObjectStoreDataKey::kSpecialIndexNumber);
1853 
1854   if (!ExtractEncodedIDBKey(slice, &result->encoded_user_key_))
1855     return false;
1856   result->database_id_ = prefix.database_id_;
1857   result->object_store_id_ = prefix.object_store_id_;
1858   return true;
1859 }
1860 
ReencodeToObjectStoreDataKey(StringPiece * slice)1861 std::string BlobEntryKey::ReencodeToObjectStoreDataKey(StringPiece* slice) {
1862   // TODO(ericu): We could be more efficient here, since the suffix is the same.
1863   BlobEntryKey key;
1864   if (!Decode(slice, &key))
1865     return std::string();
1866 
1867   return ObjectStoreDataKey::Encode(
1868       key.database_id_, key.object_store_id_, key.encoded_user_key_);
1869 }
1870 
EncodeMinKeyForObjectStore(int64 database_id,int64 object_store_id)1871 std::string BlobEntryKey::EncodeMinKeyForObjectStore(int64 database_id,
1872                                                      int64 object_store_id) {
1873   // Our implied encoded_user_key_ here is empty, the lowest possible key.
1874   return Encode(database_id, object_store_id, std::string());
1875 }
1876 
EncodeStopKeyForObjectStore(int64 database_id,int64 object_store_id)1877 std::string BlobEntryKey::EncodeStopKeyForObjectStore(int64 database_id,
1878                                                       int64 object_store_id) {
1879   DCHECK(KeyPrefix::ValidIds(database_id, object_store_id));
1880   KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex(
1881       database_id, object_store_id, kSpecialIndexNumber + 1));
1882   return prefix.Encode();
1883 }
1884 
Encode() const1885 std::string BlobEntryKey::Encode() const {
1886   DCHECK(!encoded_user_key_.empty());
1887   return Encode(database_id_, object_store_id_, encoded_user_key_);
1888 }
1889 
Encode(int64 database_id,int64 object_store_id,const IndexedDBKey & user_key)1890 std::string BlobEntryKey::Encode(int64 database_id,
1891                                  int64 object_store_id,
1892                                  const IndexedDBKey& user_key) {
1893   std::string encoded_key;
1894   EncodeIDBKey(user_key, &encoded_key);
1895   return Encode(database_id, object_store_id, encoded_key);
1896 }
1897 
Encode(int64 database_id,int64 object_store_id,const std::string & encoded_user_key)1898 std::string BlobEntryKey::Encode(int64 database_id,
1899                                  int64 object_store_id,
1900                                  const std::string& encoded_user_key) {
1901   DCHECK(KeyPrefix::ValidIds(database_id, object_store_id));
1902   KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex(
1903       database_id, object_store_id, kSpecialIndexNumber));
1904   return prefix.Encode() + encoded_user_key;
1905 }
1906 
1907 const int64 BlobEntryKey::kSpecialIndexNumber = kBlobEntryIndexId;
1908 
IndexDataKey()1909 IndexDataKey::IndexDataKey()
1910     : database_id_(-1),
1911       object_store_id_(-1),
1912       index_id_(-1),
1913       sequence_number_(-1) {}
1914 
~IndexDataKey()1915 IndexDataKey::~IndexDataKey() {}
1916 
Decode(StringPiece * slice,IndexDataKey * result)1917 bool IndexDataKey::Decode(StringPiece* slice, IndexDataKey* result) {
1918   KeyPrefix prefix;
1919   if (!KeyPrefix::Decode(slice, &prefix))
1920     return false;
1921   DCHECK(prefix.database_id_);
1922   DCHECK(prefix.object_store_id_);
1923   DCHECK_GE(prefix.index_id_, kMinimumIndexId);
1924   result->database_id_ = prefix.database_id_;
1925   result->object_store_id_ = prefix.object_store_id_;
1926   result->index_id_ = prefix.index_id_;
1927   result->sequence_number_ = -1;
1928   result->encoded_primary_key_ = MinIDBKey();
1929 
1930   if (!ExtractEncodedIDBKey(slice, &result->encoded_user_key_))
1931     return false;
1932 
1933   // [optional] sequence number
1934   if (slice->empty())
1935     return true;
1936   if (!DecodeVarInt(slice, &result->sequence_number_))
1937     return false;
1938 
1939   // [optional] primary key
1940   if (slice->empty())
1941     return true;
1942   if (!ExtractEncodedIDBKey(slice, &result->encoded_primary_key_))
1943     return false;
1944   return true;
1945 }
1946 
Encode(int64 database_id,int64 object_store_id,int64 index_id,const std::string & encoded_user_key,const std::string & encoded_primary_key,int64 sequence_number)1947 std::string IndexDataKey::Encode(int64 database_id,
1948                                  int64 object_store_id,
1949                                  int64 index_id,
1950                                  const std::string& encoded_user_key,
1951                                  const std::string& encoded_primary_key,
1952                                  int64 sequence_number) {
1953   KeyPrefix prefix(database_id, object_store_id, index_id);
1954   std::string ret = prefix.Encode();
1955   ret.append(encoded_user_key);
1956   EncodeVarInt(sequence_number, &ret);
1957   ret.append(encoded_primary_key);
1958   return ret;
1959 }
1960 
Encode(int64 database_id,int64 object_store_id,int64 index_id,const IndexedDBKey & user_key)1961 std::string IndexDataKey::Encode(int64 database_id,
1962                                  int64 object_store_id,
1963                                  int64 index_id,
1964                                  const IndexedDBKey& user_key) {
1965   std::string encoded_key;
1966   EncodeIDBKey(user_key, &encoded_key);
1967   return Encode(
1968       database_id, object_store_id, index_id, encoded_key, MinIDBKey(), 0);
1969 }
1970 
Encode(int64 database_id,int64 object_store_id,int64 index_id,const IndexedDBKey & user_key,const IndexedDBKey & user_primary_key)1971 std::string IndexDataKey::Encode(int64 database_id,
1972                                  int64 object_store_id,
1973                                  int64 index_id,
1974                                  const IndexedDBKey& user_key,
1975                                  const IndexedDBKey& user_primary_key) {
1976   std::string encoded_key;
1977   EncodeIDBKey(user_key, &encoded_key);
1978   std::string encoded_primary_key;
1979   EncodeIDBKey(user_primary_key, &encoded_primary_key);
1980   return Encode(database_id,
1981                 object_store_id,
1982                 index_id,
1983                 encoded_key,
1984                 encoded_primary_key,
1985                 0);
1986 }
1987 
EncodeMinKey(int64 database_id,int64 object_store_id,int64 index_id)1988 std::string IndexDataKey::EncodeMinKey(int64 database_id,
1989                                        int64 object_store_id,
1990                                        int64 index_id) {
1991   return Encode(
1992       database_id, object_store_id, index_id, MinIDBKey(), MinIDBKey(), 0);
1993 }
1994 
EncodeMaxKey(int64 database_id,int64 object_store_id,int64 index_id)1995 std::string IndexDataKey::EncodeMaxKey(int64 database_id,
1996                                        int64 object_store_id,
1997                                        int64 index_id) {
1998   return Encode(database_id,
1999                 object_store_id,
2000                 index_id,
2001                 MaxIDBKey(),
2002                 MaxIDBKey(),
2003                 std::numeric_limits<int64>::max());
2004 }
2005 
DatabaseId() const2006 int64 IndexDataKey::DatabaseId() const {
2007   DCHECK_GE(database_id_, 0);
2008   return database_id_;
2009 }
2010 
ObjectStoreId() const2011 int64 IndexDataKey::ObjectStoreId() const {
2012   DCHECK_GE(object_store_id_, 0);
2013   return object_store_id_;
2014 }
2015 
IndexId() const2016 int64 IndexDataKey::IndexId() const {
2017   DCHECK_GE(index_id_, 0);
2018   return index_id_;
2019 }
2020 
user_key() const2021 scoped_ptr<IndexedDBKey> IndexDataKey::user_key() const {
2022   scoped_ptr<IndexedDBKey> key;
2023   StringPiece slice(encoded_user_key_);
2024   if (!DecodeIDBKey(&slice, &key)) {
2025     // TODO(jsbell): Return error.
2026   }
2027   return key.Pass();
2028 }
2029 
primary_key() const2030 scoped_ptr<IndexedDBKey> IndexDataKey::primary_key() const {
2031   scoped_ptr<IndexedDBKey> key;
2032   StringPiece slice(encoded_primary_key_);
2033   if (!DecodeIDBKey(&slice, &key)) {
2034     // TODO(jsbell): Return error.
2035   }
2036   return key.Pass();
2037 }
2038 
2039 }  // namespace content
2040