示例#1
0
        internal void CompleteEncoderSession(EncoderSession session, int section, ArchiveDecoderSection definition, EncoderStorage[] storageList)
        {
            if (!mEncoderSessions.Remove(session))
            {
                throw new InternalFailureException();
            }

            System.Diagnostics.Debug.Assert(mDecoderSections[section] == null);
            mDecoderSections[section] = definition;

            // TODO: we can write storage lazily (just remember the streams in a list) and don't have to block the caller

            foreach (var storage in storageList)
            {
                var stream = storage.GetFinalStream();
                var offset = mAppendPosition;
                var length = stream.Length;
                mAppendPosition = checked (offset + length);
                var checksum = storage.GetFinalChecksum();
                mFileSections.Add(new ArchiveFileSection(offset, length, checksum));
                mArchiveStream.Position = offset;
                stream.Position         = 0;
                stream.CopyTo(mArchiveStream);
            }
        }
示例#2
0
        internal void CompleteEncoderSession(EncoderSession session, int section, ArchiveDecoderSection definition, EncoderStorage[] storageList)
        {
            if (!mEncoderSessions.Remove(session))
                throw new InternalFailureException();

            System.Diagnostics.Debug.Assert(mDecoderSections[section] == null);
            mDecoderSections[section] = definition;

            // TODO: we can write storage lazily (just remember the streams in a list) and don't have to block the caller

            foreach (var storage in storageList)
            {
                var stream = storage.GetFinalStream();
                var offset = mAppendPosition;
                var length = stream.Length;
                mAppendPosition = checked(offset + length);
                var checksum = storage.GetFinalChecksum();
                mFileSections.Add(new ArchiveFileSection(offset, length, checksum));
                mArchiveStream.Position = offset;
                stream.Position = 0;
                stream.CopyTo(mArchiveStream);
            }
        }
示例#3
0
 internal void Connect(EncoderSession session)
 {
     mSession = session;
 }
示例#4
0
        internal EncoderSession CreateEncoderSession(ArchiveWriter writer, int section, Stream[] storage, bool calculateStorageChecksums)
        {
            if (!mComplete)
            {
                throw new InvalidOperationException("Incomplete ArchiveEncoderDefinition.");
            }

            if (storage == null)
            {
                throw new ArgumentNullException(nameof(storage));
            }

            if (storage.Length != mStorage.Count)
            {
                throw new ArgumentException("Number of provided storage streams does not match number of declared storage streams.", nameof(storage));
            }

            var storageStreams = new EncoderStorage[storage.Length];

            for (int i = 0; i < storage.Length; i++)
            {
                storageStreams[i] = new EncoderStorage(storage[i], calculateStorageChecksums);
            }

            int totalInputCount  = 0;
            var firstInputOffset = new int[mEncoders.Count];

            for (int i = 0; i < mEncoders.Count; i++)
            {
                firstInputOffset[i] = totalInputCount;
                totalInputCount    += mEncoders[i].InputCount;
            }

            var contentTarget = mContent.Target;
            var contentIndex  = firstInputOffset[contentTarget.Node.Index] + contentTarget.Index;
            var contentStream = new EncoderInput(true); // TODO: make checksum calculation configurable? I think normal 7z archives skip this one, at least with copy-aes encoder graphs?

            var linkedStreams = new EncoderConnection[totalInputCount];

            for (int i = 0; i < totalInputCount; i++)
            {
                if (i != contentIndex)
                {
                    linkedStreams[i] = new EncoderConnection();
                }
            }

            var encoders = new EncoderNode[mEncoders.Count];

            for (int i = 0; i < mEncoders.Count; i++)
            {
                var settings = mEncoders[i].Settings;
                var encoder  = settings.CreateEncoder();
                encoders[i] = encoder;

                for (int n = settings.GetInputSlots(), j = 0; j < n; j++)
                {
                    var source = mEncoders[i].GetInput(j).Source;
                    if (source.IsContent)
                    {
                        contentStream.SetInputStream(encoder, j);
                    }
                    else
                    {
                        linkedStreams[firstInputOffset[i] + j].SetInputStream(encoder, j);
                    }
                }

                for (int n = settings.GetOutputSlots(), j = 0; j < n; j++)
                {
                    var target = mEncoders[i].GetOutput(j).Target;
                    if (target.IsStorage)
                    {
                        storageStreams[target.Index].SetOutputStream(encoder, j);
                    }
                    else
                    {
                        linkedStreams[firstInputOffset[target.Node.Index] + target.Index].SetOutputStream(encoder, j);
                    }
                }
            }

            var session = new EncoderSession(writer, section, this, contentStream, storageStreams, linkedStreams, encoders);

            contentStream.Start();

            foreach (var stream in storageStreams)
            {
                stream.Start();
            }

            foreach (var stream in linkedStreams)
            {
                stream?.Start();
            }

            foreach (var encoder in encoders)
            {
                encoder.Start();
            }

            return(session);
        }
示例#5
0
 internal void Connect(EncoderSession session)
 {
     mSession = session;
 }
示例#6
0
        internal EncoderSession CreateEncoderSession(ArchiveWriter writer, int section, Stream[] storage, bool calculateStorageChecksums)
        {
            if (!mComplete)
                throw new InvalidOperationException("Incomplete ArchiveEncoderDefinition.");

            if (storage == null)
                throw new ArgumentNullException(nameof(storage));

            if (storage.Length != mStorage.Count)
                throw new ArgumentException("Number of provided storage streams does not match number of declared storage streams.", nameof(storage));

            var storageStreams = new EncoderStorage[storage.Length];
            for (int i = 0; i < storage.Length; i++)
                storageStreams[i] = new EncoderStorage(storage[i], calculateStorageChecksums);

            int totalInputCount = 0;
            var firstInputOffset = new int[mEncoders.Count];
            for (int i = 0; i < mEncoders.Count; i++)
            {
                firstInputOffset[i] = totalInputCount;
                totalInputCount += mEncoders[i].InputCount;
            }

            var contentTarget = mContent.Target;
            var contentIndex = firstInputOffset[contentTarget.Node.Index] + contentTarget.Index;
            var contentStream = new EncoderInput(true); // TODO: make checksum calculation configurable? I think normal 7z archives skip this one, at least with copy-aes encoder graphs?

            var linkedStreams = new EncoderConnection[totalInputCount];
            for (int i = 0; i < totalInputCount; i++)
                if (i != contentIndex)
                    linkedStreams[i] = new EncoderConnection();

            var encoders = new EncoderNode[mEncoders.Count];

            for (int i = 0; i < mEncoders.Count; i++)
            {
                var settings = mEncoders[i].Settings;
                var encoder = settings.CreateEncoder();
                encoders[i] = encoder;

                for (int n = settings.GetInputSlots(), j = 0; j < n; j++)
                {
                    var source = mEncoders[i].GetInput(j).Source;
                    if (source.IsContent)
                        contentStream.SetInputStream(encoder, j);
                    else
                        linkedStreams[firstInputOffset[i] + j].SetInputStream(encoder, j);
                }

                for (int n = settings.GetOutputSlots(), j = 0; j < n; j++)
                {
                    var target = mEncoders[i].GetOutput(j).Target;
                    if (target.IsStorage)
                        storageStreams[target.Index].SetOutputStream(encoder, j);
                    else
                        linkedStreams[firstInputOffset[target.Node.Index] + target.Index].SetOutputStream(encoder, j);
                }
            }

            var session = new EncoderSession(writer, section, this, contentStream, storageStreams, linkedStreams, encoders);

            contentStream.Start();

            foreach (var stream in storageStreams)
                stream.Start();

            foreach (var stream in linkedStreams)
                stream?.Start();

            foreach (var encoder in encoders)
                encoder.Start();

            return session;
        }