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;
         }
     }
 }