private RdcBufferPointer[] PrepareRdcBufferPointers() { var outputBuffers = PrepareOutputBuffers(); var result = new RdcBufferPointer[outputBuffers.Length]; for (var i = 0; i < outputBuffers.Length; i++) { result[i].Size = OutputBufferSize; result[i].Data = outputBuffers[i]; result[i].Used = 0; } return result; }
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; }
private static IntPtr[] PrepareOutputPointers(RdcBufferPointer[] rdcBufferPointers) { var result = new IntPtr[rdcBufferPointers.Length]; for (var i = 0; i < rdcBufferPointers.Length; i++) { result[i] = Marshal.AllocCoTaskMem(Marshal.SizeOf(rdcBufferPointers[i])); Marshal.StructureToPtr(rdcBufferPointers[i], result[i], false); } return result; }
private static void RdcBufferTranslate(IntPtr[] source, RdcBufferPointer[] dest) { if (source.Length != dest.Length) { throw new ArgumentException("source and dest should have the same length"); } // Marshal the native pointer back to the // managed structure. for (var i = 0; i < dest.Length; i++) { dest[i] = (RdcBufferPointer) Marshal.PtrToStructure(source[i], typeof (RdcBufferPointer)); Marshal.FreeCoTaskMem(source[i]); } }
private static void RdcBufferTranslate(RdcBufferPointer[] source, IntPtr[] dest) { if (source.Length != dest.Length) { throw new ArgumentException("source and dest should have the same length"); } // Marshal the managed structure to a native // pointer and add it to our array. for (var i = 0; i < dest.Length; i++) { dest[i] = Marshal.AllocCoTaskMem(Marshal.SizeOf(source[i])); Marshal.StructureToPtr(source[i], dest[i], false); } }
private static RdcBufferPointer GetInputBuffer(Stream source, int inputBufferSize, RdcBufferPointer inputBuffer, ref bool eof) { if (eof) { inputBuffer.Size = 0; inputBuffer.Used = 0; } else { var bytesRead = 0; try { bytesRead = RdcBufferTools.IntPtrCopy(source, inputBuffer.Data, inputBufferSize); } catch (Exception ex) { throw new RdcException("Failed to read from the source stream.", ex); } inputBuffer.Size = (uint) bytesRead; inputBuffer.Used = 0; if (bytesRead < inputBufferSize) { eof = true; } } return inputBuffer; }
public IList<RdcNeed> CreateNeedsList(SignatureInfo seedSignature, SignatureInfo sourceSignature, CancellationToken token) { var result = new List<RdcNeed>(); using (var seedStream = _seedSignatureRepository.GetContentForReading(seedSignature.Name)) using (var sourceStream = _sourceSignatureRepository.GetContentForReading(sourceSignature.Name)) { var fileReader = (IRdcFileReader) new RdcFileReader(seedStream); IRdcComparator comparator; if (_rdcLibrary.CreateComparator(fileReader, ComparatorBufferSize, out comparator) != 0) throw new RdcException("Cannot create comparator"); var inputBuffer = new RdcBufferPointer { Size = 0, Used = 0, Data = Marshal.AllocCoTaskMem(InputBufferSize + 16) }; var outputBuffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof (RdcNeed))*256); try { var eofInput = false; var eofOutput = false; var outputPointer = new RdcNeedPointer(); while (!eofOutput) { token.ThrowIfCancellationRequested(); if (inputBuffer.Size == inputBuffer.Used && !eofInput) { var bytesRead = 0; try { bytesRead = RdcBufferTools.IntPtrCopy(sourceStream, inputBuffer.Data, InputBufferSize); } catch (Exception ex) { throw new RdcException("Failed to read from the source stream.", ex); } inputBuffer.Size = (uint) bytesRead; inputBuffer.Used = 0; if (bytesRead < InputBufferSize) { eofInput = true; } } // Initialize our output needs array outputPointer.Size = 256; outputPointer.Used = 0; outputPointer.Data = outputBuffer; RdcError error; var hr = comparator.Process(eofInput, ref eofOutput, ref inputBuffer, ref outputPointer, out error); if (hr != 0) throw new RdcException("Failed to process the signature block!", hr, error); // Convert the stream to a Needs array. var needs = GetRdcNeedList(outputPointer); result.AddRange(needs); } } finally { // Free our resources if (outputBuffer != IntPtr.Zero) Marshal.FreeCoTaskMem(outputBuffer); if (inputBuffer.Data != IntPtr.Zero) Marshal.FreeCoTaskMem(inputBuffer.Data); } return result; } }