123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- using System;
- using System.Collections.Generic;
- using System.IO;
- using SharpCompress.Compressors.LZMA;
- using SharpCompress.Compressors.LZMA.Utilites;
- namespace SharpCompress.Common.SevenZip
- {
- internal class ArchiveDatabase
- {
- internal byte _majorVersion;
- internal byte _minorVersion;
- internal long _startPositionAfterHeader;
- internal long _dataStartPosition;
- internal List<long> _packSizes = new List<long>();
- internal List<uint?> _packCrCs = new List<uint?>();
- internal List<CFolder> _folders = new List<CFolder>();
- internal List<int> _numUnpackStreamsVector;
- internal List<CFileItem> _files = new List<CFileItem>();
- internal List<long> _packStreamStartPositions = new List<long>();
- internal List<int> _folderStartFileIndex = new List<int>();
- internal List<int> _fileIndexToFolderIndexMap = new List<int>();
-
- internal IPasswordProvider PasswordProvider { get; }
- public ArchiveDatabase(IPasswordProvider passwordProvider)
- {
- PasswordProvider = passwordProvider;
- }
- internal void Clear()
- {
- _packSizes.Clear();
- _packCrCs.Clear();
- _folders.Clear();
- _numUnpackStreamsVector = null;
- _files.Clear();
- _packStreamStartPositions.Clear();
- _folderStartFileIndex.Clear();
- _fileIndexToFolderIndexMap.Clear();
- }
- internal bool IsEmpty()
- {
- return _packSizes.Count == 0
- && _packCrCs.Count == 0
- && _folders.Count == 0
- && _numUnpackStreamsVector.Count == 0
- && _files.Count == 0;
- }
- private void FillStartPos()
- {
- _packStreamStartPositions.Clear();
- long startPos = 0;
- for (int i = 0; i < _packSizes.Count; i++)
- {
- _packStreamStartPositions.Add(startPos);
- startPos += _packSizes[i];
- }
- }
- private void FillFolderStartFileIndex()
- {
- _folderStartFileIndex.Clear();
- _fileIndexToFolderIndexMap.Clear();
- int folderIndex = 0;
- int indexInFolder = 0;
- for (int i = 0; i < _files.Count; i++)
- {
- CFileItem file = _files[i];
- bool emptyStream = !file.HasStream;
- if (emptyStream && indexInFolder == 0)
- {
- _fileIndexToFolderIndexMap.Add(-1);
- continue;
- }
- if (indexInFolder == 0)
- {
- // v3.13 incorrectly worked with empty folders
- // v4.07: Loop for skipping empty folders
- for (;;)
- {
- if (folderIndex >= _folders.Count)
- {
- throw new InvalidOperationException();
- }
- _folderStartFileIndex.Add(i); // check it
- if (_numUnpackStreamsVector[folderIndex] != 0)
- {
- break;
- }
- folderIndex++;
- }
- }
- _fileIndexToFolderIndexMap.Add(folderIndex);
- if (emptyStream)
- {
- continue;
- }
- indexInFolder++;
- if (indexInFolder >= _numUnpackStreamsVector[folderIndex])
- {
- folderIndex++;
- indexInFolder = 0;
- }
- }
- }
- public void Fill()
- {
- FillStartPos();
- FillFolderStartFileIndex();
- }
- internal long GetFolderStreamPos(CFolder folder, int indexInFolder)
- {
- int index = folder._firstPackStreamId + indexInFolder;
- return _dataStartPosition + _packStreamStartPositions[index];
- }
- internal long GetFolderFullPackSize(int folderIndex)
- {
- int packStreamIndex = _folders[folderIndex]._firstPackStreamId;
- CFolder folder = _folders[folderIndex];
- long size = 0;
- for (int i = 0; i < folder._packStreams.Count; i++)
- {
- size += _packSizes[packStreamIndex + i];
- }
- return size;
- }
- internal Stream GetFolderStream(Stream stream, CFolder folder, IPasswordProvider pw)
- {
- int packStreamIndex = folder._firstPackStreamId;
- long folderStartPackPos = GetFolderStreamPos(folder, 0);
- List<long> packSizes = new List<long>();
- for (int j = 0; j < folder._packStreams.Count; j++)
- {
- packSizes.Add(_packSizes[packStreamIndex + j]);
- }
- return DecoderStreamHelper.CreateDecoderStream(stream, folderStartPackPos, packSizes.ToArray(), folder, pw);
- }
- private long GetFolderPackStreamSize(int folderIndex, int streamIndex)
- {
- return _packSizes[_folders[folderIndex]._firstPackStreamId + streamIndex];
- }
- private long GetFilePackSize(int fileIndex)
- {
- int folderIndex = _fileIndexToFolderIndexMap[fileIndex];
- if (folderIndex != -1)
- {
- if (_folderStartFileIndex[folderIndex] == fileIndex)
- {
- return GetFolderFullPackSize(folderIndex);
- }
- }
- return 0;
- }
- }
- }
|