private IList<SignatureInfo> Process(Stream source, IRdcGenerator rdcGenerator, string fileName,
ISignatureRepository signatureRepository)
{
var result = Enumerable.Range(0, _recursionDepth).Reverse().Select(i => new SignatureInfo(i, fileName)).ToList();
var eof = false;
var eofOutput = false;
// prepare streams
var sigStreams = result.Select(item => signatureRepository.CreateContent(item.Name)).ToList();
var inputBuffer = new RdcBufferPointer
{
Size = 0,
Used = 0,
Data = Marshal.AllocCoTaskMem(InputBufferSize + 16)
};
var rdcBufferPointers = PrepareRdcBufferPointers();
var outputPointers = PrepareOutputPointers(rdcBufferPointers);
try
{
while (!eofOutput)
{
if (inputBuffer.Size == inputBuffer.Used)
inputBuffer = GetInputBuffer(source, InputBufferSize, inputBuffer, ref eof);
RdcError rdcErrorCode;
var hr = rdcGenerator.Process(
eof,
ref eofOutput,
ref inputBuffer,
(uint) _recursionDepth,
outputPointers,
out rdcErrorCode);
if (hr != 0)
throw new RdcException("RdcGenerator failed to process the signature block.", hr, rdcErrorCode);
RdcBufferTranslate(outputPointers, rdcBufferPointers);
for (var i = 0; i < _recursionDepth; i++)
{
var resultStream = sigStreams[i];
// Write the signature block to the file.
var bytesWritten = RdcBufferTools.IntPtrCopy(
rdcBufferPointers[i].Data,
resultStream,
(int) rdcBufferPointers[i].Used);
result[i].Length += bytesWritten;
if (rdcBufferPointers[i].Used != bytesWritten)
{
throw new RdcException("Failed to write to the signature file.");
}
rdcBufferPointers[i].Used = 0;
}
RdcBufferTranslate(rdcBufferPointers, outputPointers);
}
}
finally
{
if (inputBuffer.Data != IntPtr.Zero)
Marshal.FreeCoTaskMem(inputBuffer.Data);
foreach (var item in outputPointers)
{
Marshal.FreeCoTaskMem(item);
}
}
result.Reverse();
signatureRepository.Flush(result);
return result;
}