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 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.º 4
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);
                }
        }