public bool SearchEntry(byte[] input, int inputLen, out int result) { result = 0; SpanReader sr = new SpanReader(BlockBuffer); sr.Position = 2; int entryCount = sr.ReadInt16() / 2; ushort blockSize = ParentVolume.GetBlockSize(); // Check first sr.Position = blockSize - 0x08; short entryOffset = sr.ReadInt16(); short entryLength = sr.ReadInt16(); sr.Position = entryOffset; byte[] entryIndexer = sr.ReadBytes(entryLength); int diff = DebugReader.CompareEntries(input, inputLen, entryIndexer, entryLength); if (diff < 0) { result = 0; return(false); } // Check last sr.Position = blockSize - (entryCount * 0x08); entryOffset = sr.ReadInt16(); entryLength = sr.ReadInt16(); sr.Position = entryOffset; entryIndexer = sr.ReadBytes(entryLength); diff = DebugReader.CompareEntries(input, inputLen, entryIndexer, entryLength); if (diff > 0) { result = -entryCount; return(false); } int min = 0; int max = entryCount; int mid = (min + max) / 2; while (min < max) { if (max - min < 8) { mid = min; int baseOffset = blockSize - (mid * 0x08); int entryitorOffset = baseOffset; if (max < min) { return(false); } while (min <= max) { entryitorOffset -= 0x08; sr.Position = entryitorOffset; entryOffset = sr.ReadInt16(); sr.Position = (mid * 0x08 - blockSize) + baseOffset + entryitorOffset; sr.Position += 2; entryLength = sr.ReadInt16(); sr.Position = entryOffset; entryIndexer = sr.ReadBytes(entryLength); diff = DebugReader.CompareEntries(input, inputLen, entryIndexer, entryLength); if (diff < 1) { result = min; return(diff == 0); } min++; } return(false); } sr.Position = blockSize - (mid * 0x08); entryOffset = sr.ReadInt16(); entryLength = sr.ReadInt16(); sr.Position = entryOffset; entryIndexer = sr.ReadBytes(entryLength); diff = DebugReader.CompareEntries(input, inputLen, entryIndexer, entryLength); if (diff == 0) { result = mid - 1; return(true); } else if (diff > 0) { min = mid; } else { max = mid; } mid = (min + max) / 2; } throw new Exception("Failed to bsearch the entry."); }
public int SearchBlockIndex(byte[] input, int inputLen) { SpanReader sr = new SpanReader(BlockBuffer); sr.Position = 2; int indexEntryCount = sr.ReadInt16(); int realEntryCount = (((indexEntryCount - 1) / 2) - 1); ushort blockSize = ParentVolume.GetBlockSize(); if (indexEntryCount == 1) { // return the first sr.Position = blockSize - 4; return(sr.ReadInt32()); } // First sr.Position = blockSize - 0x08; short entryOffset = sr.ReadInt16(); short entryLength = sr.ReadInt16(); sr.Position = entryOffset; byte[] entryIndexer = sr.ReadBytes(entryLength); int diff = DebugReader.CompareEntries(input, inputLen, entryIndexer, entryLength); if (diff < 0) { // return the first block index sr.Position = (blockSize - 0x08) + 4; return(sr.ReadInt32()); } // Last sr.Position = blockSize - (realEntryCount * 0x08); entryOffset = sr.ReadInt16(); entryLength = sr.ReadInt16(); sr.Position = entryOffset; entryIndexer = sr.ReadBytes(entryLength); diff = DebugReader.CompareEntries(input, inputLen, entryIndexer, entryLength); if (diff > 0) { // return the last block index sr.Position = blockSize - (realEntryCount * 0x08) + 4; return(sr.ReadInt32()); } int min = 0; int max = realEntryCount; int mid = (min + max) / 2; while (min < max) { if (max - min < 8) { mid = min; int baseOffset = blockSize - (mid * 0x08); int entryitorOffset = baseOffset; if (max < min) { return(-1); } while (min <= max) { entryitorOffset -= 0x08; sr.Position = entryitorOffset; entryOffset = sr.ReadInt16(); int entryIndexOffset = (mid * 0x08 - blockSize) + baseOffset + entryitorOffset; sr.Position = entryIndexOffset + 2; entryLength = sr.ReadInt16(); sr.Position = entryOffset; entryIndexer = sr.ReadBytes(entryLength); diff = DebugReader.CompareEntries(input, inputLen, entryIndexer, entryLength); if (diff == 0) { sr.Position = entryIndexOffset - 4; return(sr.ReadInt32()); } else if (diff < 0) { sr.Position = entryIndexOffset + 4; return(sr.ReadInt32()); } min++; } return(-1); } sr.Position = blockSize - (mid * 0x08); entryOffset = sr.ReadInt16(); entryLength = sr.ReadInt16(); sr.Position = entryOffset; entryIndexer = sr.ReadBytes(entryLength); diff = DebugReader.CompareEntries(input, inputLen, entryIndexer, entryLength); if (diff == 0) { // return the matching index sr.Position = blockSize - (mid * 0x08) + 4; return(sr.ReadInt32()); } else if (diff > 0) { min = mid; } else { max = mid; } mid = (min + max) / 2; } throw new Exception("Failed to bsearch for the block entry."); }