123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- using System;
- using System.IO;
- using SharpCompress.Common.SevenZip;
- using SharpCompress.Compressors.LZMA.Utilites;
- using SharpCompress.IO;
- namespace SharpCompress.Compressors.LZMA
- {
- internal abstract class DecoderStream2 : Stream
- {
- public override bool CanRead => true;
- public override bool CanSeek => false;
- public override bool CanWrite => false;
- public override void Flush()
- {
- throw new NotSupportedException();
- }
- public override long Length => throw new NotSupportedException();
- public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }
- public override long Seek(long offset, SeekOrigin origin)
- {
- throw new NotSupportedException();
- }
- public override void SetLength(long value)
- {
- throw new NotSupportedException();
- }
- public override void Write(byte[] buffer, int offset, int count)
- {
- throw new NotSupportedException();
- }
- }
- internal static class DecoderStreamHelper
- {
- private static int FindCoderIndexForOutStreamIndex(CFolder folderInfo, int outStreamIndex)
- {
- for (int coderIndex = 0; coderIndex < folderInfo._coders.Count; coderIndex++)
- {
- var coderInfo = folderInfo._coders[coderIndex];
- outStreamIndex -= coderInfo._numOutStreams;
- if (outStreamIndex < 0)
- {
- return coderIndex;
- }
- }
- throw new InvalidOperationException("Could not link output stream to coder.");
- }
- private static void FindPrimaryOutStreamIndex(CFolder folderInfo, out int primaryCoderIndex,
- out int primaryOutStreamIndex)
- {
- bool foundPrimaryOutStream = false;
- primaryCoderIndex = -1;
- primaryOutStreamIndex = -1;
- for (int outStreamIndex = 0, coderIndex = 0;
- coderIndex < folderInfo._coders.Count;
- coderIndex++)
- {
- for (int coderOutStreamIndex = 0;
- coderOutStreamIndex < folderInfo._coders[coderIndex]._numOutStreams;
- coderOutStreamIndex++, outStreamIndex++)
- {
- if (folderInfo.FindBindPairForOutStream(outStreamIndex) < 0)
- {
- if (foundPrimaryOutStream)
- {
- throw new NotSupportedException("Multiple output streams.");
- }
- foundPrimaryOutStream = true;
- primaryCoderIndex = coderIndex;
- primaryOutStreamIndex = outStreamIndex;
- }
- }
- }
- if (!foundPrimaryOutStream)
- {
- throw new NotSupportedException("No output stream.");
- }
- }
- private static Stream CreateDecoderStream(Stream[] packStreams, long[] packSizes, Stream[] outStreams,
- CFolder folderInfo, int coderIndex, IPasswordProvider pass)
- {
- var coderInfo = folderInfo._coders[coderIndex];
- if (coderInfo._numOutStreams != 1)
- {
- throw new NotSupportedException("Multiple output streams are not supported.");
- }
- int inStreamId = 0;
- for (int i = 0; i < coderIndex; i++)
- {
- inStreamId += folderInfo._coders[i]._numInStreams;
- }
- int outStreamId = 0;
- for (int i = 0; i < coderIndex; i++)
- {
- outStreamId += folderInfo._coders[i]._numOutStreams;
- }
- Stream[] inStreams = new Stream[coderInfo._numInStreams];
- for (int i = 0; i < inStreams.Length; i++, inStreamId++)
- {
- int bindPairIndex = folderInfo.FindBindPairForInStream(inStreamId);
- if (bindPairIndex >= 0)
- {
- int pairedOutIndex = folderInfo._bindPairs[bindPairIndex]._outIndex;
- if (outStreams[pairedOutIndex] != null)
- {
- throw new NotSupportedException("Overlapping stream bindings are not supported.");
- }
- int otherCoderIndex = FindCoderIndexForOutStreamIndex(folderInfo, pairedOutIndex);
- inStreams[i] = CreateDecoderStream(packStreams, packSizes, outStreams, folderInfo, otherCoderIndex,
- pass);
- //inStreamSizes[i] = folderInfo.UnpackSizes[pairedOutIndex];
- if (outStreams[pairedOutIndex] != null)
- {
- throw new NotSupportedException("Overlapping stream bindings are not supported.");
- }
- outStreams[pairedOutIndex] = inStreams[i];
- }
- else
- {
- int index = folderInfo.FindPackStreamArrayIndex(inStreamId);
- if (index < 0)
- {
- throw new NotSupportedException("Could not find input stream binding.");
- }
- inStreams[i] = packStreams[index];
- //inStreamSizes[i] = packSizes[index];
- }
- }
- long unpackSize = folderInfo._unpackSizes[outStreamId];
- return DecoderRegistry.CreateDecoderStream(coderInfo._methodId, inStreams, coderInfo._props, pass, unpackSize);
- }
- internal static Stream CreateDecoderStream(Stream inStream, long startPos, long[] packSizes, CFolder folderInfo,
- IPasswordProvider pass)
- {
- if (!folderInfo.CheckStructure())
- {
- throw new NotSupportedException("Unsupported stream binding structure.");
- }
- Stream[] inStreams = new Stream[folderInfo._packStreams.Count];
- for (int j = 0; j < folderInfo._packStreams.Count; j++)
- {
- inStreams[j] = new BufferedSubStream(inStream, startPos, packSizes[j]);
- startPos += packSizes[j];
- }
- Stream[] outStreams = new Stream[folderInfo._unpackSizes.Count];
- int primaryCoderIndex, primaryOutStreamIndex;
- FindPrimaryOutStreamIndex(folderInfo, out primaryCoderIndex, out primaryOutStreamIndex);
- return CreateDecoderStream(inStreams, packSizes, outStreams, folderInfo, primaryCoderIndex, pass);
- }
- }
- }
|