コード例 #1
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);
                }
        }
コード例 #2
0
ファイル: RdcServices.cs プロジェクト: lethek/rdc.net
        /// <summary>
        /// Builds a comparator and perform the RDC comparison logic against the provided signatures to generate a needs list.
        /// </summary>
        /// <param name="seedSignature">Seed signature to compare</param>
        /// <param name="sourceSignature">Source signature to compare</param>
        /// <returns>RDC Needs list</returns>
        public ArrayList CreateNeedsList(SignatureInfo seedSignature, SignatureInfo sourceSignature)
        {
            int hr = 0;

            IRdcFileReader fileReader = (IRdcFileReader) new RdcFileReader(seedSignature.InnerStream);
            IRdcComparator comparator;

            GC.Collect();
            GC.WaitForPendingFinalizers();

            hr = rdcLibrary.CreateComparator(fileReader, 1000000, out comparator);

            // Create and allocate memory for our input buffer.
            IntPtr           inputBuffer  = Marshal.AllocCoTaskMem((int)inputBufferSize + 16);
            RdcBufferPointer inputPointer = new RdcBufferPointer();

            inputPointer.size = 0;
            inputPointer.used = 0;
            inputPointer.data = inputBuffer;

            ArrayList needsList = new ArrayList();

            IntPtr outputBuffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(RdcNeed)) * 256);

            RdcNeedPointer outputPointer = new RdcNeedPointer();

            long totalBytesRead = 0;
            bool eof            = false;
            bool eofOutput      = false;

            while (hr == 0 && !eofOutput)
            {
                if (inputPointer.size == inputPointer.used && !eof)
                {
                    // Fill our input buffer with the signature
                    // data from the source.
                    // When the input buffer is completely empty
                    // refill it.
                    int bytesRead = 0;
                    try
                    {
                        bytesRead = IntPtrCopy(sourceSignature.InnerStream, inputBuffer, 0, (int)inputBufferSize);
                    }
                    catch (Exception ex)
                    {
                        // TODO: Cleanup
                        throw new RdcException("Failed to read from the source stream.", ex);
                    }

                    totalBytesRead   += bytesRead;
                    inputPointer.size = (uint)bytesRead;
                    inputPointer.used = 0;

                    if (bytesRead < inputBufferSize)
                    {
                        eof = true;
                    }
                }

                // Initialize our output needs array
                outputPointer.size = 256;
                outputPointer.used = 0;
                outputPointer.data = outputBuffer;

                RdcError error = RdcError.NoError;

                // Perform the signature comparison.
                // This function may not produce needs output every time.
                // Also, it may not use all available input each time either.
                // You may call it with any number of input bytes
                // and output needs array entries. Obviously, it is more
                // efficient to give it reasonably sized buffers for each.
                // This sample waits until Process() consumes an entire input
                // buffer before reading more data from the source signatures file.
                // Continue calling this function until it sets "eofOutput" to true.
                hr = comparator.Process(
                    eof,
                    ref eofOutput,
                    ref inputPointer,
                    ref outputPointer,
                    out error);

                if (hr != 0)
                {
                    throw new RdcException("Failed to process the signature block!");
                }

                if (error != RdcError.NoError)
                {
                    throw new RdcException("Failed!");
                }

                // Convert the stream to a Needs array.
                RdcNeed[] needs = GetRdcNeedList(outputPointer);

                foreach (RdcNeed need in needs)
                {
                    // assign the needs to our arraylist.
                    needsList.Add(need);
                }
            }

            if (hr != 0)
            {
                throw new RdcException("Failed!");
            }

            // Free our resources
            if (outputBuffer != IntPtr.Zero)
            {
                Marshal.FreeCoTaskMem(outputBuffer);
            }

            if (inputBuffer != IntPtr.Zero)
            {
                Marshal.FreeCoTaskMem(inputBuffer);
            }

            return(needsList);
        }