コード例 #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;
		}
コード例 #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);
				}
			}
			result.Reverse();
			signatureRepository.Flush(result);
			return result;
		}
コード例 #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;
		}
コード例 #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]);
			}
		}
コード例 #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);
			}
		}
コード例 #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;
		}
コード例 #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;
			}
		}