Пример #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
        private static RdcNeed[] GetRdcNeedList(RdcNeedPointer pointer)
        {
            var result = new RdcNeed[pointer.Used];

            var ptr = pointer.Data;
            var needSize = Marshal.SizeOf(typeof(RdcNeed));

            // Get our native needs pointer 
            // and deserialize to our managed 
            // RdcNeed array.
            for (var i = 0; i < result.Length; i++)
            {
                result[i] = (RdcNeed)Marshal.PtrToStructure(ptr, typeof(RdcNeed));

                // Advance the intermediate pointer
                // to our next RdcNeed struct.
                ptr = new IntPtr(ptr.ToInt64() + needSize);
            }
            return result;
        }