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); } }
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); } }
internal void Connect(EncoderSession session) { mSession = session; }
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); }
internal void Connect(EncoderSession session) { mSession = session; }
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; }