const char* IndexDataKey::decode(const char* start, const char* limit, IndexDataKey* result) { KeyPrefix prefix; const char* p = KeyPrefix::decode(start, limit, &prefix); if (!p) return 0; ASSERT(prefix.m_databaseId); ASSERT(prefix.m_objectStoreId); ASSERT(prefix.m_indexId >= MinimumIndexId); result->m_databaseId = prefix.m_databaseId; result->m_objectStoreId = prefix.m_objectStoreId; result->m_indexId = prefix.m_indexId; result->m_sequenceNumber = -1; result->m_encodedPrimaryKey = minIDBKey(); p = extractEncodedIDBKey(p, limit, &result->m_encodedUserKey); if (!p) return 0; // [optional] sequence number if (p == limit) return p; p = decodeVarInt(p, limit, result->m_sequenceNumber); if (!p) return 0; // [optional] primary key if (p == limit) return p; p = extractEncodedIDBKey(p, limit, &result->m_encodedPrimaryKey); if (!p) return 0; return p; }
const char* extractEncodedIDBKey(const char* start, const char* limit, Vector<char>* result) { ASSERT(result); const char* p = start; if (p >= limit) return 0; unsigned char type = *p++; switch (type) { case kIDBKeyNullTypeByte: case kIDBKeyMinKeyTypeByte: *result = encodeByte(type); return p; case kIDBKeyArrayTypeByte: { int64_t length; p = decodeVarInt(p, limit, length); if (!p) return 0; if (length < 0) return 0; result->clear(); result->append(start, p - start); while (length--) { Vector<char> subkey; p = extractEncodedIDBKey(p, limit, &subkey); if (!p) return 0; result->append(subkey); } return p; } case kIDBKeyStringTypeByte: { int64_t length; p = decodeVarInt(p, limit, length); if (!p) return 0; if (p + length * 2 > limit) return 0; result->clear(); result->append(start, p - start + length * 2); return p + length * 2; } case kIDBKeyDateTypeByte: case kIDBKeyNumberTypeByte: if (p + sizeof(double) > limit) return 0; result->clear(); result->append(start, 1 + sizeof(double)); return p + sizeof(double); } ASSERT_NOT_REACHED(); return 0; }
const char* ExistsEntryKey::decode(const char* start, const char* end, ExistsEntryKey* result) { KeyPrefix prefix; const char* p = KeyPrefix::decode(start, end, &prefix); if (!p) return 0; ASSERT(prefix.m_databaseId); ASSERT(prefix.m_objectStoreId); ASSERT(prefix.m_indexId == SpecialIndexNumber); if (p == end) return 0; return extractEncodedIDBKey(p, end, &result->m_encodedUserKey); }