//called when data for any output pin is requested public void Evaluate(int spreadMax) { //ResizeAndDispose will adjust the spread length and thereby call //the given constructor function for new slices and Dispose on old //slices. FStreamOut.ResizeAndDispose(spreadMax, () => new MemoryStream()); Tasks.SliceCount = spreadMax; IOs.SliceCount = spreadMax; FWorking.SliceCount = spreadMax; FError.SliceCount = spreadMax; for (int i = 0; i < spreadMax; i++) { if (!FAsync[i]) { FWorking[i] = false; } if (FCompress[i]) { IOs[i] = new CompressorIO(); IOs[i].InBytes = new byte[FStreamIn[i].Length]; FStreamIn[i].Position = 0; FStreamIn[i].Read(IOs[i].InBytes, 0, (int)FStreamIn[i].Length); if (FAsync[i]) { Tasks[i] = new Task(CompressAsync, IOs[i]); Tasks[i].Start(); } else { CompressAsync(IOs[i]); FWorking[i] = true; FStreamOut[i].Position = 0; FStreamOut[i].Write(IOs[i].OutBytes, 0, IOs[i].OutBytes.Length); } } if (Tasks[i] != null) { if (FAsync[i]) { if ((IOs[i].OutBytes != null) && FWorking[i]) { FStreamOut[i].Position = 0; FStreamOut[i].Write(IOs[i].OutBytes, 0, IOs[i].OutBytes.Length); } FWorking[i] = (!Tasks[i].IsCompleted) && (!Tasks[i].IsFaulted); } if (Tasks[i].Exception != null) { FError[i] = Tasks[i].Exception.Message; } } } //this will force the changed flag of the output pin to be set FStreamOut.Flush(true); }
//when dealing with byte streams (what we call Raw in the GUI) it's always //good to have a byte buffer around. we'll use it when copying the data. //readonly byte[] FBuffer = new byte[1024]; private void CompressAsync(object io) { CompressorIO IO = (CompressorIO)io; IO.OutBytes = SevenZipHelper.Compress(IO.InBytes); }