protected override void ExecuteOperation() { Debug.Assert(ItemCompletionRegister[Index] == false); PayloadItem item = PayloadItems[Index]; Guid itemIdentifier = item.Identifier; bool skip = ItemSkipRegister != null && ItemSkipRegister.Contains(itemIdentifier); MuxItemResourceContainer itemContainer; bool activeResource = _activeItemResources.ContainsKey(itemIdentifier); if (activeResource) { itemContainer = _activeItemResources[itemIdentifier]; } else { if (skip == false) { itemContainer = CreateEtMSchemeResources(item); if (Writing) { EmitHeader(itemContainer.Authenticator); } else { ConsumeHeader(itemContainer.Authenticator); } } else { itemContainer = new MuxItemResourceContainer(null, null, null); } _activeItemResources.Add(itemIdentifier, itemContainer); } int opLength = NextOperationLength(); if (skip == false) { CipherStream itemEncryptor = itemContainer.Encryptor; MacStream itemAuthenticator = itemContainer.Authenticator; if (Writing) { // Writing/multiplexing if (itemEncryptor.BytesIn + opLength < item.ExternalLength) { // Normal operation itemEncryptor.WriteExactly(item.StreamBinding, opLength); } else { // Final operation, or just prior to if (itemContainer.Buffer.IsValueCreated == false) { // Redirect final ciphertext to buffer to account for possible expansion itemAuthenticator.ReassignBinding(itemContainer.Buffer.Value, false, finish: false); } var remaining = (int)(item.ExternalLength - itemEncryptor.BytesIn); if (remaining > 0) { while (remaining > 0) { int toRead = Math.Min(remaining, BufferSize); int iterIn = item.StreamBinding.Read(Buffer, 0, toRead); if (iterIn < toRead) { throw new EndOfStreamException(); } itemEncryptor.Write(Buffer, 0, iterIn); // Writing into recently-lazy-inited buffer remaining -= iterIn; } itemEncryptor.Close(); } var toWrite = (int)Math.Min(opLength, itemContainer.Buffer.Value.Length); Debug.Print(DebugUtility.CreateReportString("FabricPayloadMux", "ExecuteOperation", "Multiplexing item: final stripe length", toWrite)); itemContainer.Buffer.Value.ReadTo(PayloadStream, toWrite); } } else { // Reading/demultiplexing long readRemaining = item.InternalLength - itemEncryptor.BytesIn; bool finalOp = false; if (readRemaining <= opLength) { // Final operation opLength = (int)readRemaining; finalOp = true; Debug.Print(DebugUtility.CreateReportString("FabricPayloadMux", "ExecuteOperation", "Demultiplexing item: final stripe length", opLength)); } itemEncryptor.ReadExactly(item.StreamBinding, opLength, finalOp); } if ((Writing && itemEncryptor.BytesIn >= item.ExternalLength && itemContainer.Buffer.Value.Length == 0) || (Writing == false && itemEncryptor.BytesIn >= item.InternalLength)) { // Now that we're finished we need to do some extra things, then clean up FinishItem(item, itemEncryptor, itemAuthenticator); } } else { // Skipping Debug.Assert(Writing == false, "Should not be skipping when writing!"); if (itemContainer.SkippedLength == 0) { // Start of item PayloadStream.Seek(opLength, SeekOrigin.Current); itemContainer.SkippedLength += opLength; } else if (itemContainer.SkippedLength + opLength >= item.InternalLength) { int remainingToSkip = (int)(item.InternalLength - itemContainer.SkippedLength); itemContainer.SkippedLength += remainingToSkip; PayloadStream.Seek(remainingToSkip + GetTrailerLength(), SeekOrigin.Current); // "Finish" item _activeItemResources.Remove(item.Identifier); // Mark the item as completed in the register ItemCompletionRegister[Index] = true; ItemsCompleted++; Debug.Print(DebugUtility.CreateReportString("FabricPayloadMux", "ExecuteOperation", "[*** SKIPPED ITEM", Index + " ***]")); } else { PayloadStream.Seek(opLength, SeekOrigin.Current); itemContainer.SkippedLength += opLength; } } }