| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h" | 5 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h" |
| 6 | 6 |
| 7 #include <iterator> | 7 #include <iterator> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 // the primary key in the data. The "version" field is used to weed out | 143 // the primary key in the data. The "version" field is used to weed out |
| 144 // stale | 144 // stale |
| 145 // index data. Whenever new object store data is inserted, it gets a new | 145 // index data. Whenever new object store data is inserted, it gets a new |
| 146 // "version" number, and new index data is written with this number. When | 146 // "version" number, and new index data is written with this number. When |
| 147 // the index is used for look-ups, entries are validated against the | 147 // the index is used for look-ups, entries are validated against the |
| 148 // "exists" entries, and records with old "version" numbers are deleted | 148 // "exists" entries, and records with old "version" numbers are deleted |
| 149 // when they are encountered in get_primary_key_via_index, | 149 // when they are encountered in get_primary_key_via_index, |
| 150 // IndexCursorImpl::load_current_row, and | 150 // IndexCursorImpl::load_current_row, and |
| 151 // IndexKeyCursorImpl::load_current_row). | 151 // IndexKeyCursorImpl::load_current_row). |
| 152 | 152 |
| 153 using base::StringPiece; |
| 153 using WebKit::WebIDBKey; | 154 using WebKit::WebIDBKey; |
| 154 using WebKit::WebIDBKeyPath; | 155 using WebKit::WebIDBKeyPath; |
| 155 | 156 |
| 156 namespace content { | 157 namespace content { |
| 157 | 158 |
| 158 // As most of the IndexedDBKeys and encoded values are short, we | 159 // As most of the IndexedDBKeys and encoded values are short, we |
| 159 // initialize some Vectors with a default inline buffer size to reduce | 160 // initialize some Vectors with a default inline buffer size to reduce |
| 160 // the memory re-allocations when the Vectors are appended. | 161 // the memory re-allocations when the Vectors are appended. |
| 161 static const size_t kDefaultInlineBufferSize = 32; | 162 static const size_t kDefaultInlineBufferSize = 32; |
| 162 | 163 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 186 static const unsigned char kObjectStoreFreeListTypeByte = 150; | 187 static const unsigned char kObjectStoreFreeListTypeByte = 150; |
| 187 static const unsigned char kIndexFreeListTypeByte = 151; | 188 static const unsigned char kIndexFreeListTypeByte = 151; |
| 188 static const unsigned char kObjectStoreNamesTypeByte = 200; | 189 static const unsigned char kObjectStoreNamesTypeByte = 200; |
| 189 static const unsigned char kIndexNamesKeyTypeByte = 201; | 190 static const unsigned char kIndexNamesKeyTypeByte = 201; |
| 190 | 191 |
| 191 static const unsigned char kObjectMetaDataTypeMaximum = 255; | 192 static const unsigned char kObjectMetaDataTypeMaximum = 255; |
| 192 static const unsigned char kIndexMetaDataTypeMaximum = 255; | 193 static const unsigned char kIndexMetaDataTypeMaximum = 255; |
| 193 | 194 |
| 194 const unsigned char kMinimumIndexId = 30; | 195 const unsigned char kMinimumIndexId = 30; |
| 195 | 196 |
| 196 void EncodeByte(unsigned char c, std::vector<char>* into) { | 197 inline void EncodeIntSafely(int64 nParam, int64 max, std::vector<char>* into) { |
| 197 into->push_back(c); | 198 DCHECK_LE(nParam, max); |
| 198 } | 199 return EncodeInt(nParam, into); |
| 199 | |
| 200 const char* DecodeByte(const char* p, | |
| 201 const char* limit, | |
| 202 unsigned char& found_char) { | |
| 203 DCHECK_GE(limit, p); | |
| 204 if (p >= limit) | |
| 205 return 0; | |
| 206 | |
| 207 found_char = *p++; | |
| 208 return p; | |
| 209 } | 200 } |
| 210 | 201 |
| 211 std::vector<char> MaxIDBKey() { | 202 std::vector<char> MaxIDBKey() { |
| 212 std::vector<char> ret; | 203 std::vector<char> ret; |
| 213 EncodeByte(kIndexedDBKeyNullTypeByte, &ret); | 204 EncodeByte(kIndexedDBKeyNullTypeByte, &ret); |
| 214 return ret; | 205 return ret; |
| 215 } | 206 } |
| 216 | 207 |
| 217 std::vector<char> MinIDBKey() { | 208 std::vector<char> MinIDBKey() { |
| 218 std::vector<char> ret; | 209 std::vector<char> ret; |
| 219 EncodeByte(kIndexedDBKeyMinKeyTypeByte, &ret); | 210 EncodeByte(kIndexedDBKeyMinKeyTypeByte, &ret); |
| 220 return ret; | 211 return ret; |
| 221 } | 212 } |
| 222 | 213 |
| 223 bool DecodeBool(const char* p, const char* limit) { | 214 void EncodeByte(unsigned char value, std::vector<char>* into) { |
| 224 DCHECK_GT(limit, p); | 215 into->push_back(value); |
| 225 return !!*p; | |
| 226 } | 216 } |
| 227 | 217 |
| 228 void EncodeBool(bool b, std::vector<char>* into) { into->push_back(b ? 1 : 0); } | 218 void EncodeBool(bool value, std::vector<char>* into) { |
| 219 into->push_back(value ? 1 : 0); |
| 220 } |
| 229 | 221 |
| 230 void EncodeInt(int64 nParam, std::vector<char>* into) { | 222 void EncodeInt(int64 value, std::vector<char>* into) { |
| 231 #ifndef NDEBUG | 223 #ifndef NDEBUG |
| 232 // Exercised by unit tests in debug only. | 224 // Exercised by unit tests in debug only. |
| 233 DCHECK_GE(nParam, 0); | 225 DCHECK_GE(value, 0); |
| 234 #endif | 226 #endif |
| 235 uint64 n = static_cast<uint64>(nParam); | 227 uint64 n = static_cast<uint64>(value); |
| 236 | 228 |
| 237 do { | 229 do { |
| 238 unsigned char c = n; | 230 unsigned char c = n; |
| 239 into->push_back(c); | 231 into->push_back(c); |
| 240 n >>= 8; | 232 n >>= 8; |
| 241 } while (n); | 233 } while (n); |
| 242 } | 234 } |
| 243 | 235 |
| 244 static int CompareInts(int64 a, int64 b) { | 236 void EncodeVarInt(int64 value, std::vector<char>* into) { |
| 245 #ifndef NDEBUG | 237 #ifndef NDEBUG |
| 246 // Exercised by unit tests in debug only. | 238 // Exercised by unit tests in debug only. |
| 247 DCHECK_GE(a, 0); | 239 DCHECK_GE(value, 0); |
| 248 DCHECK_GE(b, 0); | |
| 249 #endif | 240 #endif |
| 250 int64 diff = a - b; | 241 uint64 n = static_cast<uint64>(value); |
| 251 if (diff < 0) | |
| 252 return -1; | |
| 253 if (diff > 0) | |
| 254 return 1; | |
| 255 return 0; | |
| 256 } | |
| 257 | |
| 258 void EncodeVarInt(int64 nParam, std::vector<char>* into) { | |
| 259 #ifndef NDEBUG | |
| 260 // Exercised by unit tests in debug only. | |
| 261 DCHECK_GE(nParam, 0); | |
| 262 #endif | |
| 263 uint64 n = static_cast<uint64>(nParam); | |
| 264 | 242 |
| 265 do { | 243 do { |
| 266 unsigned char c = n & 0x7f; | 244 unsigned char c = n & 0x7f; |
| 267 n >>= 7; | 245 n >>= 7; |
| 268 if (n) | 246 if (n) |
| 269 c |= 0x80; | 247 c |= 0x80; |
| 270 into->push_back(c); | 248 into->push_back(c); |
| 271 } while (n); | 249 } while (n); |
| 272 } | 250 } |
| 273 | 251 |
| 274 const char* DecodeVarInt(const char* p, const char* limit, int64& found_int) { | 252 void EncodeString(const string16& value, std::vector<char>* into) { |
| 275 DCHECK_GE(limit, p); | 253 if (value.empty()) |
| 276 found_int = 0; | |
| 277 int shift = 0; | |
| 278 | |
| 279 do { | |
| 280 if (p >= limit) | |
| 281 return 0; | |
| 282 | |
| 283 unsigned char c = *p; | |
| 284 found_int |= static_cast<int64>(c & 0x7f) << shift; | |
| 285 shift += 7; | |
| 286 } while (*p++ & 0x80); | |
| 287 return p; | |
| 288 } | |
| 289 | |
| 290 void EncodeString(const string16& s, std::vector<char>* into) { | |
| 291 if (s.empty()) | |
| 292 return; | 254 return; |
| 293 // Backing store is UTF-16BE, convert from host endianness. | 255 // Backing store is UTF-16BE, convert from host endianness. |
| 294 size_t length = s.length(); | 256 size_t length = value.length(); |
| 295 size_t current = into->size(); | 257 size_t current = into->size(); |
| 296 into->resize(into->size() + length * sizeof(char16)); | 258 into->resize(into->size() + length * sizeof(char16)); |
| 297 | 259 |
| 298 const char16* src = s.c_str(); | 260 const char16* src = value.c_str(); |
| 299 char16* dst = reinterpret_cast<char16*>(&*into->begin() + current); | 261 char16* dst = reinterpret_cast<char16*>(&*into->begin() + current); |
| 300 for (unsigned i = 0; i < length; ++i) | 262 for (unsigned i = 0; i < length; ++i) |
| 301 *dst++ = htons(*src++); | 263 *dst++ = htons(*src++); |
| 302 } | 264 } |
| 303 | 265 |
| 304 string16 DecodeString(const char* p, const char* limit) { | 266 void EncodeStringWithLength(const string16& value, std::vector<char>* into) { |
| 305 // Backing store is UTF-16BE, convert to host endianness. | 267 EncodeVarInt(value.length(), into); |
| 306 DCHECK_GE(limit, p); | 268 EncodeString(value, into); |
| 307 DCHECK(!((limit - p) % sizeof(char16))); | |
| 308 | |
| 309 size_t length = (limit - p) / sizeof(char16); | |
| 310 string16 decoded; | |
| 311 decoded.reserve(length); | |
| 312 const char16* encoded = reinterpret_cast<const char16*>(p); | |
| 313 for (unsigned i = 0; i < length; ++i) | |
| 314 decoded.push_back(ntohs(*encoded++)); | |
| 315 return decoded; | |
| 316 } | 269 } |
| 317 | 270 |
| 318 void EncodeStringWithLength(const string16& s, std::vector<char>* into) { | 271 void EncodeDouble(double value, std::vector<char>* into) { |
| 319 EncodeVarInt(s.length(), into); | 272 // This always has host endianness. |
| 320 EncodeString(s, into); | 273 const char* p = reinterpret_cast<char*>(&value); |
| 274 into->insert(into->end(), p, p + sizeof(value)); |
| 321 } | 275 } |
| 322 | 276 |
| 323 const char* DecodeStringWithLength(const char* p, | 277 void EncodeIDBKey(const IndexedDBKey& value, std::vector<char>* into) { |
| 324 const char* limit, | |
| 325 string16& found_string) { | |
| 326 DCHECK_GE(limit, p); | |
| 327 int64 len; | |
| 328 p = DecodeVarInt(p, limit, len); | |
| 329 if (!p || len < 0 || p + len * 2 > limit) | |
| 330 return 0; | |
| 331 | |
| 332 found_string = DecodeString(p, p + len * 2); | |
| 333 p += len * 2; | |
| 334 return p; | |
| 335 } | |
| 336 | |
| 337 int CompareEncodedStringsWithLength(const char*& p, | |
| 338 const char* limit_p, | |
| 339 const char*& q, | |
| 340 const char* limit_q, | |
| 341 bool& ok) { | |
| 342 DCHECK_NE(&p, &q); | |
| 343 DCHECK_GT(limit_p, p); | |
| 344 DCHECK_GT(limit_q, q); | |
| 345 int64 len_p, len_q; | |
| 346 p = DecodeVarInt(p, limit_p, len_p); | |
| 347 q = DecodeVarInt(q, limit_q, len_q); | |
| 348 if (!p || !q || len_p < 0 || len_q < 0) { | |
| 349 ok = false; | |
| 350 return 0; | |
| 351 } | |
| 352 DCHECK(p && q); | |
| 353 DCHECK_GE(len_p, 0); | |
| 354 DCHECK_GE(len_q, 0); | |
| 355 DCHECK_LE(p + len_p * 2, limit_p); | |
| 356 DCHECK_LE(q + len_q * 2, limit_q); | |
| 357 | |
| 358 const char* start_p = p; | |
| 359 const char* start_q = q; | |
| 360 p += len_p * 2; | |
| 361 q += len_q * 2; | |
| 362 | |
| 363 if (p > limit_p || q > limit_q) { | |
| 364 ok = false; | |
| 365 return 0; | |
| 366 } | |
| 367 | |
| 368 ok = true; | |
| 369 const size_t lmin = static_cast<size_t>(len_p < len_q ? len_p : len_q); | |
| 370 if (int x = memcmp(start_p, start_q, lmin * 2)) | |
| 371 return x; | |
| 372 | |
| 373 if (len_p == len_q) | |
| 374 return 0; | |
| 375 | |
| 376 return (len_p > len_q) ? 1 : -1; | |
| 377 } | |
| 378 | |
| 379 void EncodeDouble(double x, std::vector<char>* into) { | |
| 380 // TODO(jsbell): It would be nice if we could be byte order independent. | |
| 381 const char* p = reinterpret_cast<char*>(&x); | |
| 382 into->insert(into->end(), p, p + sizeof(x)); | |
| 383 } | |
| 384 | |
| 385 const char* DecodeDouble(const char* p, const char* limit, double* d) { | |
| 386 if (p + sizeof(*d) > limit) | |
| 387 return 0; | |
| 388 | |
| 389 char* x = reinterpret_cast<char*>(d); | |
| 390 for (size_t i = 0; i < sizeof(*d); ++i) | |
| 391 *x++ = *p++; | |
| 392 return p; | |
| 393 } | |
| 394 | |
| 395 std::vector<char> EncodeIDBKey(const IndexedDBKey& key) { | |
| 396 std::vector<char> buffer; | |
| 397 buffer.reserve(kDefaultInlineBufferSize); | |
| 398 EncodeIDBKey(key, &buffer); | |
| 399 return buffer; | |
| 400 } | |
| 401 | |
| 402 void EncodeIDBKey(const IndexedDBKey& key, std::vector<char>* into) { | |
| 403 size_t previous_size = into->size(); | 278 size_t previous_size = into->size(); |
| 404 DCHECK(key.IsValid()); | 279 DCHECK(value.IsValid()); |
| 405 switch (key.type()) { | 280 switch (value.type()) { |
| 406 case WebIDBKey::NullType: | 281 case WebIDBKey::NullType: |
| 407 case WebIDBKey::InvalidType: | 282 case WebIDBKey::InvalidType: |
| 408 case WebIDBKey::MinType: { | 283 case WebIDBKey::MinType: { |
| 409 NOTREACHED(); | 284 NOTREACHED(); |
| 410 EncodeByte(kIndexedDBKeyNullTypeByte, into); | 285 EncodeByte(kIndexedDBKeyNullTypeByte, into); |
| 411 return; | 286 return; |
| 412 } | 287 } |
| 413 case WebIDBKey::ArrayType: { | 288 case WebIDBKey::ArrayType: { |
| 414 EncodeByte(kIndexedDBKeyArrayTypeByte, into); | 289 EncodeByte(kIndexedDBKeyArrayTypeByte, into); |
| 415 size_t length = key.array().size(); | 290 size_t length = value.array().size(); |
| 416 EncodeVarInt(length, into); | 291 EncodeVarInt(length, into); |
| 417 for (size_t i = 0; i < length; ++i) | 292 for (size_t i = 0; i < length; ++i) |
| 418 EncodeIDBKey(key.array()[i], into); | 293 EncodeIDBKey(value.array()[i], into); |
| 419 DCHECK_GT(into->size(), previous_size); | 294 DCHECK_GT(into->size(), previous_size); |
| 420 return; | 295 return; |
| 421 } | 296 } |
| 422 case WebIDBKey::StringType: { | 297 case WebIDBKey::StringType: { |
| 423 EncodeByte(kIndexedDBKeyStringTypeByte, into); | 298 EncodeByte(kIndexedDBKeyStringTypeByte, into); |
| 424 EncodeStringWithLength(key.string(), into); | 299 EncodeStringWithLength(value.string(), into); |
| 425 DCHECK_GT(into->size(), previous_size); | 300 DCHECK_GT(into->size(), previous_size); |
| 426 return; | 301 return; |
| 427 } | 302 } |
| 428 case WebIDBKey::DateType: { | 303 case WebIDBKey::DateType: { |
| 429 EncodeByte(kIndexedDBKeyDateTypeByte, into); | 304 EncodeByte(kIndexedDBKeyDateTypeByte, into); |
| 430 EncodeDouble(key.date(), into); | 305 EncodeDouble(value.date(), into); |
| 431 DCHECK_EQ(static_cast<size_t>(9), | 306 DCHECK_EQ(static_cast<size_t>(9), |
| 432 static_cast<size_t>(into->size() - previous_size)); | 307 static_cast<size_t>(into->size() - previous_size)); |
| 433 return; | 308 return; |
| 434 } | 309 } |
| 435 case WebIDBKey::NumberType: { | 310 case WebIDBKey::NumberType: { |
| 436 EncodeByte(kIndexedDBKeyNumberTypeByte, into); | 311 EncodeByte(kIndexedDBKeyNumberTypeByte, into); |
| 437 EncodeDouble(key.number(), into); | 312 EncodeDouble(value.number(), into); |
| 438 DCHECK_EQ(static_cast<size_t>(9), | 313 DCHECK_EQ(static_cast<size_t>(9), |
| 439 static_cast<size_t>(into->size() - previous_size)); | 314 static_cast<size_t>(into->size() - previous_size)); |
| 440 return; | 315 return; |
| 441 } | 316 } |
| 442 } | 317 } |
| 443 | 318 |
| 444 NOTREACHED(); | 319 NOTREACHED(); |
| 445 } | 320 } |
| 446 | 321 |
| 447 const char* DecodeIDBKey(const char* p, | 322 void EncodeIDBKeyPath(const IndexedDBKeyPath& value, std::vector<char>* into) { |
| 448 const char* limit, | 323 // May be typed, or may be a raw string. An invalid leading |
| 449 scoped_ptr<IndexedDBKey>* found_key) { | 324 // byte is used to identify typed coding. New records are |
| 450 DCHECK_GE(limit, p); | 325 // always written as typed. |
| 451 if (p >= limit) | 326 EncodeByte(kIndexedDBKeyPathTypeCodedByte1, into); |
| 452 return 0; | 327 EncodeByte(kIndexedDBKeyPathTypeCodedByte2, into); |
| 453 | 328 EncodeByte(static_cast<char>(value.type()), into); |
| 454 unsigned char type = *p++; | 329 switch (value.type()) { |
| 330 case WebIDBKeyPath::NullType: |
| 331 break; |
| 332 case WebIDBKeyPath::StringType: { |
| 333 EncodeStringWithLength(value.string(), into); |
| 334 break; |
| 335 } |
| 336 case WebIDBKeyPath::ArrayType: { |
| 337 const std::vector<string16>& array = value.array(); |
| 338 size_t count = array.size(); |
| 339 EncodeVarInt(count, into); |
| 340 for (size_t i = 0; i < count; ++i) { |
| 341 EncodeStringWithLength(array[i], into); |
| 342 } |
| 343 break; |
| 344 } |
| 345 } |
| 346 } |
| 347 |
| 348 bool DecodeByte(StringPiece* slice, unsigned char* value) { |
| 349 if (slice->empty()) |
| 350 return false; |
| 351 |
| 352 *value = (*slice)[0]; |
| 353 slice->remove_prefix(1); |
| 354 return true; |
| 355 } |
| 356 |
| 357 bool DecodeBool(StringPiece* slice, bool* value) { |
| 358 if (slice->empty()) |
| 359 return false; |
| 360 |
| 361 *value = !!(*slice)[0]; |
| 362 slice->remove_prefix(1); |
| 363 return true; |
| 364 } |
| 365 |
| 366 bool DecodeInt(StringPiece* slice, int64* value) { |
| 367 if (slice->empty()) |
| 368 return false; |
| 369 |
| 370 StringPiece::const_iterator it = slice->begin(); |
| 371 int shift = 0; |
| 372 int64 ret = 0; |
| 373 while (it != slice->end()) { |
| 374 unsigned char c = *it++; |
| 375 ret |= static_cast<int64>(c) << shift; |
| 376 shift += 8; |
| 377 } |
| 378 *value = ret; |
| 379 slice->remove_prefix(it - slice->begin()); |
| 380 return true; |
| 381 } |
| 382 |
| 383 bool DecodeVarInt(StringPiece* slice, int64* value) { |
| 384 if (slice->empty()) |
| 385 return false; |
| 386 |
| 387 StringPiece::const_iterator it = slice->begin(); |
| 388 int shift = 0; |
| 389 int64 ret = 0; |
| 390 do { |
| 391 if (it == slice->end()) |
| 392 return 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 Loading... |
| 765 DCHECK(prefix_a.object_store_id_); | 773 DCHECK(prefix_a.object_store_id_); |
| 766 DCHECK_EQ(prefix_a.index_id_, ExistsEntryKey::kSpecialIndexNumber); | 774 DCHECK_EQ(prefix_a.index_id_, ExistsEntryKey::kSpecialIndexNumber); |
| 767 DCHECK(prefix_b.database_id_); | 775 DCHECK(prefix_b.database_id_); |
| 768 DCHECK(prefix_b.object_store_id_); | 776 DCHECK(prefix_b.object_store_id_); |
| 769 DCHECK_EQ(prefix_b.index_id_, ExistsEntryKey::kSpecialIndexNumber); | 777 DCHECK_EQ(prefix_b.index_id_, ExistsEntryKey::kSpecialIndexNumber); |
| 770 DCHECK_NE(ptr_a, a.end()); | 778 DCHECK_NE(ptr_a, a.end()); |
| 771 DCHECK_NE(ptr_b, b.end()); | 779 DCHECK_NE(ptr_b, b.end()); |
| 772 // Prefixes are not compared - it is assumed this was already done. | 780 // Prefixes are not compared - it is assumed this was already done. |
| 773 DCHECK(!prefix_a.Compare(prefix_b)); | 781 DCHECK(!prefix_a.Compare(prefix_b)); |
| 774 | 782 |
| 775 return CompareEncodedIDBKeys(ptr_a, a.end(), ptr_b, b.end(), ok); | 783 StringPiece slice_a(ptr_a, a.end() - ptr_a); |
| 784 StringPiece slice_b(ptr_b, b.end() - ptr_b); |
| 785 return CompareEncodedIDBKeys(&slice_a, &slice_b, ok); |
| 776 } | 786 } |
| 777 | 787 |
| 778 template <> | 788 template <> |
| 779 int Compare<ObjectStoreDataKey>(const LevelDBSlice& a, | 789 int Compare<ObjectStoreDataKey>(const LevelDBSlice& a, |
| 780 const LevelDBSlice& b, | 790 const LevelDBSlice& b, |
| 781 bool, | 791 bool, |
| 782 bool& ok) { | 792 bool& ok) { |
| 783 KeyPrefix prefix_a; | 793 KeyPrefix prefix_a; |
| 784 KeyPrefix prefix_b; | 794 KeyPrefix prefix_b; |
| 785 const char* ptr_a = KeyPrefix::Decode(a.begin(), a.end(), &prefix_a); | 795 const char* ptr_a = KeyPrefix::Decode(a.begin(), a.end(), &prefix_a); |
| 786 const char* ptr_b = KeyPrefix::Decode(b.begin(), b.end(), &prefix_b); | 796 const char* ptr_b = KeyPrefix::Decode(b.begin(), b.end(), &prefix_b); |
| 787 DCHECK(ptr_a); | 797 DCHECK(ptr_a); |
| 788 DCHECK(ptr_b); | 798 DCHECK(ptr_b); |
| 789 DCHECK(prefix_a.database_id_); | 799 DCHECK(prefix_a.database_id_); |
| 790 DCHECK(prefix_a.object_store_id_); | 800 DCHECK(prefix_a.object_store_id_); |
| 791 DCHECK_EQ(prefix_a.index_id_, ObjectStoreDataKey::kSpecialIndexNumber); | 801 DCHECK_EQ(prefix_a.index_id_, ObjectStoreDataKey::kSpecialIndexNumber); |
| 792 DCHECK(prefix_b.database_id_); | 802 DCHECK(prefix_b.database_id_); |
| 793 DCHECK(prefix_b.object_store_id_); | 803 DCHECK(prefix_b.object_store_id_); |
| 794 DCHECK_EQ(prefix_b.index_id_, ObjectStoreDataKey::kSpecialIndexNumber); | 804 DCHECK_EQ(prefix_b.index_id_, ObjectStoreDataKey::kSpecialIndexNumber); |
| 795 DCHECK_NE(ptr_a, a.end()); | 805 DCHECK_NE(ptr_a, a.end()); |
| 796 DCHECK_NE(ptr_b, b.end()); | 806 DCHECK_NE(ptr_b, b.end()); |
| 797 // Prefixes are not compared - it is assumed this was already done. | 807 // Prefixes are not compared - it is assumed this was already done. |
| 798 DCHECK(!prefix_a.Compare(prefix_b)); | 808 DCHECK(!prefix_a.Compare(prefix_b)); |
| 799 | 809 |
| 800 return CompareEncodedIDBKeys(ptr_a, a.end(), ptr_b, b.end(), ok); | 810 StringPiece slice_a(ptr_a, a.end() - ptr_a); |
| 811 StringPiece slice_b(ptr_b, b.end() - ptr_b); |
| 812 return CompareEncodedIDBKeys(&slice_a, &slice_b, ok); |
| 801 } | 813 } |
| 802 | 814 |
| 803 template <> | 815 template <> |
| 804 int Compare<IndexDataKey>(const LevelDBSlice& a, | 816 int Compare<IndexDataKey>(const LevelDBSlice& a, |
| 805 const LevelDBSlice& b, | 817 const LevelDBSlice& b, |
| 806 bool ignore_duplicates, | 818 bool ignore_duplicates, |
| 807 bool& ok) { | 819 bool& ok) { |
| 808 KeyPrefix prefix_a; | 820 KeyPrefix prefix_a; |
| 809 KeyPrefix prefix_b; | 821 KeyPrefix prefix_b; |
| 810 const char* ptr_a = KeyPrefix::Decode(a.begin(), a.end(), &prefix_a); | 822 const char* ptr_a = KeyPrefix::Decode(a.begin(), a.end(), &prefix_a); |
| 811 const char* ptr_b = KeyPrefix::Decode(b.begin(), b.end(), &prefix_b); | 823 const char* ptr_b = KeyPrefix::Decode(b.begin(), b.end(), &prefix_b); |
| 812 DCHECK(ptr_a); | 824 DCHECK(ptr_a); |
| 813 DCHECK(ptr_b); | 825 DCHECK(ptr_b); |
| 814 DCHECK(prefix_a.database_id_); | 826 DCHECK(prefix_a.database_id_); |
| 815 DCHECK(prefix_a.object_store_id_); | 827 DCHECK(prefix_a.object_store_id_); |
| 816 DCHECK_GE(prefix_a.index_id_, kMinimumIndexId); | 828 DCHECK_GE(prefix_a.index_id_, kMinimumIndexId); |
| 817 DCHECK(prefix_b.database_id_); | 829 DCHECK(prefix_b.database_id_); |
| 818 DCHECK(prefix_b.object_store_id_); | 830 DCHECK(prefix_b.object_store_id_); |
| 819 DCHECK_GE(prefix_b.index_id_, kMinimumIndexId); | 831 DCHECK_GE(prefix_b.index_id_, kMinimumIndexId); |
| 820 DCHECK_NE(ptr_a, a.end()); | 832 DCHECK_NE(ptr_a, a.end()); |
| 821 DCHECK_NE(ptr_b, b.end()); | 833 DCHECK_NE(ptr_b, b.end()); |
| 822 // Prefixes are not compared - it is assumed this was already done. | 834 // Prefixes are not compared - it is assumed this was already done. |
| 823 DCHECK(!prefix_a.Compare(prefix_b)); | 835 DCHECK(!prefix_a.Compare(prefix_b)); |
| 824 | 836 |
| 825 // index key | 837 // index key |
| 826 int result = CompareEncodedIDBKeys(ptr_a, a.end(), ptr_b, b.end(), ok); | 838 |
| 839 StringPiece slice_a(ptr_a, a.end() - ptr_a); |
| 840 StringPiece slice_b(ptr_b, b.end() - ptr_b); |
| 841 int result = CompareEncodedIDBKeys(&slice_a, &slice_b, ok); |
| 827 if (!ok || result) | 842 if (!ok || result) |
| 828 return result; | 843 return result; |
| 829 if (ignore_duplicates) | 844 if (ignore_duplicates) |
| 830 return 0; | 845 return 0; |
| 831 | 846 |
| 832 // sequence number [optional] | 847 // sequence number [optional] |
| 833 int64 sequence_number_a = -1; | 848 int64 sequence_number_a = -1; |
| 834 int64 sequence_number_b = -1; | 849 int64 sequence_number_b = -1; |
| 835 if (ptr_a != a.end()) | 850 if (!slice_a.empty()) { |
| 836 ptr_a = DecodeVarInt(ptr_a, a.end(), sequence_number_a); | 851 if (!DecodeVarInt(&slice_a, &sequence_number_a)) |
| 837 if (ptr_b != b.end()) | 852 return 0; |
| 838 ptr_b = DecodeVarInt(ptr_b, b.end(), sequence_number_b); | 853 } |
| 854 if (!slice_b.empty()) { |
| 855 if (!DecodeVarInt(&slice_b, &sequence_number_b)) |
| 856 return 0; |
| 857 } |
| 839 | 858 |
| 840 // primary key [optional] | 859 // primary key [optional] |
| 841 if (!ptr_a || !ptr_b) | 860 if (slice_a.empty() && slice_b.empty()) |
| 842 return 0; | 861 return 0; |
| 843 if (ptr_a == a.end() && ptr_b == b.end()) | 862 if (slice_a.empty()) |
| 844 return 0; | |
| 845 if (ptr_a == a.end()) | |
| 846 return -1; | 863 return -1; |
| 847 if (ptr_b == b.end()) | 864 if (slice_b.empty()) |
| 848 return 1; | 865 return 1; |
| 849 | 866 |
| 850 result = CompareEncodedIDBKeys(ptr_a, a.end(), ptr_b, b.end(), ok); | 867 result = CompareEncodedIDBKeys(&slice_a, &slice_b, ok); |
| 851 if (!ok || result) | 868 if (!ok || result) |
| 852 return result; | 869 return result; |
| 853 | 870 |
| 854 return CompareInts(sequence_number_a, sequence_number_b); | 871 return CompareInts(sequence_number_a, sequence_number_b); |
| 855 } | 872 } |
| 856 | 873 |
| 857 int Compare(const LevelDBSlice& a, | 874 int Compare(const LevelDBSlice& a, |
| 858 const LevelDBSlice& b, | 875 const LevelDBSlice& b, |
| 859 bool index_keys, | 876 bool index_keys, |
| 860 bool& ok) { | 877 bool& ok) { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |