private static bool ExtractEncodedIdbKey(StringPiece slice, out string result) { var start = slice.Fork(); if (!ConsumeEncodedIdbKey(slice)) { result = null; return(false); } result = start.Slice(start.Left - slice.Left).ToString(); return(true); }
// https://cs.chromium.org/chromium/src/content/browser/indexed_db/indexed_db_database_callbacks.cc private static int Compare(StringPiece a, StringPiece b, bool onlyCompareIndexKeys) { var sliceA = a.Fork(); var sliceB = b.Fork(); KeyPrefix prefixA, prefixB; if (!KeyPrefix.Decode(sliceA, out prefixA) || !KeyPrefix.Decode(sliceB, out prefixB)) { return(0); } { var x = prefixA.CompareTo(prefixB); if (x != 0) { return(x); } } switch (prefixA.Type) { case KeyType.GlobalMetadata: { if (sliceA.Empty || sliceB.Empty) { return(0); } var typeByteA = sliceA.Next(); var typeByteB = sliceB.Next(); { var x = typeByteA - typeByteB; if (x != 0) { return(x); } } if (typeByteA < KMaxSimpleGlobalMetaDataTypeByte) { return(0); } // Compare<> is used (which re-decodes the prefix) rather than an // specialized CompareSuffix<> because metadata is relatively uncommon // in the database. switch (typeByteA) { case KDatabaseFreeListTypeByte: return(DatabaseFreeListKey.Compare(a, b)); case KDatabaseNameTypeByte: return(DatabaseNameKey.Compare(a, b)); } break; } case KeyType.DatabaseMetadata: { if (sliceA.Empty || sliceB.Empty) { return(0); } var typeByteA = sliceA.Next(); var typeByteB = sliceB.Next(); { var x = typeByteA - typeByteB; if (x != 0) { return(x); } } if (typeByteA < (int)MetaDataType.MaxSimpleMetadataType) { return(0); } switch (typeByteA) { case KObjectStoreMetaDataTypeByte: return(ObjectStoreMetaDataKey.Compare(a, b)); case KIndexMetaDataTypeByte: return(IndexMetaDataKey.Compare(a, b)); case KObjectStoreNamesTypeByte: return(ObjectStoreNamesKey.Compare(a, b)); case KObjectStoreFreeListTypeByte: return(ObjectStoreFreeListKey.Compare(a, b)); case KIndexFreeListTypeByte: return(IndexFreeListKey.Compare(a, b)); case KIndexNamesKeyTypeByte: return(IndexNamesKey.Compare(a, b)); } break; } case KeyType.ObjectStoreData: return(sliceA.Empty || sliceB.Empty ? CompareSizes(sliceA.Left, sliceB.Left) : ObjectStoreDataKey.CompareSuffix(sliceA, sliceB)); case KeyType.ExistsEntry: return(sliceA.Empty || sliceB.Empty ? CompareSizes(sliceA.Left, sliceB.Left) : ExistsEntryKey.CompareSuffix(sliceA, sliceB)); case KeyType.BlobEntry: return(sliceA.Empty || sliceB.Empty ? CompareSizes(sliceA.Left, sliceB.Left) : BlobEntryKey.CompareSuffix(sliceA, sliceB)); case KeyType.IndexData: return(sliceA.Empty || sliceB.Empty ? CompareSizes(sliceA.Left, sliceB.Left) : IndexDataKey.CompareSuffix(sliceA, sliceB, onlyCompareIndexKeys)); case KeyType.InvalidType: break; } return(0); }