Ejemplo n.º 1
0
        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;
        }
Ejemplo n.º 2
0
        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);

                foreach (var item in rdcBufferPointers)
                    Marshal.FreeCoTaskMem(item.Data);
            }
            result.Reverse();
            signatureRepository.Flush(result);
            return result;
        }
Ejemplo n.º 3
0
 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;
 }
Ejemplo n.º 4
0
 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]);
     }
 }
Ejemplo n.º 5
0
 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);
     }
 }
Ejemplo n.º 6
0
        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;
        }
Ejemplo n.º 7
0
        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;
            }
        }