public void Extract(ArchiveDatabase _db, int[] indices, IPasswordProvider pw) { int numItems; bool allFilesMode = (indices == null); if (allFilesMode) numItems = _db.Files.Count; else numItems = indices.Length; if (numItems == 0) return; List<CExtractFolderInfo> extractFolderInfoVector = new List<CExtractFolderInfo>(); for (int i = 0; i < numItems; i++) { int fileIndex = allFilesMode ? i : indices[i]; int folderIndex = _db.FileIndexToFolderIndexMap[fileIndex]; if (folderIndex == -1) { extractFolderInfoVector.Add(new CExtractFolderInfo(fileIndex, -1)); continue; } if (extractFolderInfoVector.Count == 0 || folderIndex != extractFolderInfoVector.Last().FolderIndex) extractFolderInfoVector.Add(new CExtractFolderInfo(-1, folderIndex)); CExtractFolderInfo efi = extractFolderInfoVector.Last(); int startIndex = _db.FolderStartFileIndex[folderIndex]; for (int index = efi.ExtractStatuses.Count; index <= fileIndex - startIndex; index++) efi.ExtractStatuses.Add(index == fileIndex - startIndex); } foreach (CExtractFolderInfo efi in extractFolderInfoVector) { int startIndex; if (efi.FileIndex != -1) startIndex = efi.FileIndex; else startIndex = _db.FolderStartFileIndex[efi.FolderIndex]; var outStream = new FolderUnpackStream(_db, 0, startIndex, efi.ExtractStatuses); if (efi.FileIndex != -1) continue; int folderIndex = efi.FolderIndex; CFolder folderInfo = _db.Folders[folderIndex]; int packStreamIndex = _db.Folders[folderIndex].FirstPackStreamId; long folderStartPackPos = _db.GetFolderStreamPos(folderInfo, 0); List<long> packSizes = new List<long>(); for (int j = 0; j < folderInfo.PackStreams.Count; j++) packSizes.Add(_db.PackSizes[packStreamIndex + j]); // TODO: If the decoding fails the last file may be extracted incompletely. Delete it? Stream s = DecoderStreamHelper.CreateDecoderStream(_stream, folderStartPackPos, packSizes.ToArray(), folderInfo, pw); byte[] buffer = new byte[4 << 10]; for (; ; ) { int processed = s.Read(buffer, 0, buffer.Length); if (processed == 0) break; outStream.Write(buffer, 0, processed); } } }
public void Extract(ArchiveDatabase _db, int[] indices, IPasswordProvider pw) { int count; bool flag = indices == null; if (flag) { count = _db.Files.Count; } else { count = indices.Length; } if (count != 0) { int folderIndex; int num5; List<CExtractFolderInfo> source = new List<CExtractFolderInfo>(); for (int i = 0; i < count; i++) { int fileIndex = flag ? i : indices[i]; folderIndex = _db.FileIndexToFolderIndexMap[fileIndex]; if (folderIndex == -1) { source.Add(new CExtractFolderInfo(fileIndex, -1)); } else { if ((source.Count == 0) || (folderIndex != Enumerable.Last<CExtractFolderInfo>(source).FolderIndex)) { source.Add(new CExtractFolderInfo(-1, folderIndex)); } CExtractFolderInfo info = Enumerable.Last<CExtractFolderInfo>(source); num5 = _db.FolderStartFileIndex[folderIndex]; for (int j = info.ExtractStatuses.Count; j <= (fileIndex - num5); j++) { info.ExtractStatuses.Add(j == (fileIndex - num5)); } } } foreach (CExtractFolderInfo info in source) { int num10; bool flag2; if (info.FileIndex != -1) { num5 = info.FileIndex; } else { num5 = _db.FolderStartFileIndex[info.FolderIndex]; } FolderUnpackStream stream = new FolderUnpackStream(_db, 0, num5, info.ExtractStatuses); if (info.FileIndex != -1) { continue; } folderIndex = info.FolderIndex; CFolder folder = _db.Folders[folderIndex]; int firstPackStreamId = _db.Folders[folderIndex].FirstPackStreamId; long folderStreamPos = _db.GetFolderStreamPos(folder, 0); List<long> list2 = new List<long>(); for (int k = 0; k < folder.PackStreams.Count; k++) { list2.Add(_db.PackSizes[firstPackStreamId + k]); } Stream stream2 = DecoderStreamHelper.CreateDecoderStream(this._stream, folderStreamPos, list2.ToArray(), folder, pw); byte[] buffer = new byte[0x1000]; goto Label_0252; Label_0223: num10 = stream2.Read(buffer, 0, buffer.Length); if (num10 == 0) { continue; } stream.Write(buffer, 0, num10); Label_0252: flag2 = true; goto Label_0223; } } }