private void CacheFilePositions() { // get list of all files List <EmbeddedFileEntry> files = new List <EmbeddedFileEntry>(); FileIDMatcher matcher = delegate { return(true); }; ListFiles(m_rootPointer, files, matcher, null); // construct dictionary foreach (EmbeddedFileEntry file in files) { m_filePosCache[file.FileID] = file; } }
private void ListFiles(uint filePointer, List <EmbeddedFileEntry> destinationList, FileIDMatcher matcher, object stateObject) { byte[] directory = new byte[m_sectorsPerDirectory * m_sectorSize * sizeof(uint)]; // read the directory Util.UIntToBArr(directory, 0, filePointer); for (int i = 0; i < m_sectorsPerDirectory && BitConverter.ToUInt32(directory, 0) != 0x00; i++) { // always read the next sector pointer into the first position // of the data array. Then read the rest of the sector to the back // of the array filePointer = BitConverter.ToUInt32(directory, 0); m_inputStream.Seek(filePointer, SeekOrigin.Begin); m_inputStream.Read(directory, 0, sizeof(uint)); m_inputStream.Read(directory, (i * (m_sectorSize - 1) + 1) * sizeof(uint), (m_sectorSize - 1) * sizeof(uint)); } // find the amount of files int fileCount = BitConverter.ToInt32(directory, m_fileCountOffset * sizeof(uint)); Debug.Assert(fileCount < m_filesPerDirectory); // add the file numbers to the list for (int index = 0; index < fileCount; index++) { uint fileId = BitConverter.ToUInt32(directory, (index * m_entrySize + m_filesPerDirectory + 1 + m_entryDataOffset) * sizeof(uint)); if (fileId != 0x00) { if (matcher(fileId, stateObject)) { uint fileSize = BitConverter.ToUInt32(directory, (index * m_entrySize + m_filesPerDirectory + 3 + m_entryDataOffset) * sizeof(uint)); EmbeddedFileEntry newEntry = new EmbeddedFileEntry(fileSize, fileId); if (!destinationList.Contains(newEntry)) { destinationList.Add(newEntry); } } } } // recurse into subdirs, if needed bool hasSubDirs = (BitConverter.ToUInt32(directory, sizeof(uint)) != 0); if (hasSubDirs) { int max = fileCount; if (m_canHaveMoreSubDirsThanFiles) { max = 62; } for (int index = 0; index < max; index++) { uint subDirPointer = BitConverter.ToUInt32(directory, index * sizeof(uint) + sizeof(uint)); if (subDirPointer != 0x00) { ListFiles(subDirPointer, destinationList, matcher, stateObject); } } } }