diff --git a/PInvoke/MsRdc/MsRdc.cs b/PInvoke/MsRdc/MsRdc.cs index 8e99c211..f980361f 100644 --- a/PInvoke/MsRdc/MsRdc.cs +++ b/PInvoke/MsRdc/MsRdc.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Runtime.InteropServices; using System.Security.Permissions; using Vanara.InteropServices; @@ -654,21 +655,21 @@ namespace Vanara.PInvoke /// The CreateComparator method creates a signature comparator. /// An IRdcFileReader interface pointer initialized to read the seed signatures. /// - /// Specifies the size of the comparator buffer. The range is from MSRDC_MINIMUM_COMPAREBUFFER to MSRDC_MAXIMUM_COMPAREBUFFER. - /// MSRDC_MINIMUM_COMPAREBUFFER (100000) - /// Minimum size of a comparator buffer. - /// MSRDC_DEFAULT_COMPAREBUFFER (3200000) - /// Default size of a comparator buffer. Used if zero (0) is passed for comparatorBufferSize. - /// MSRDC_MAXIMUM_COMPAREBUFFER (1073741824) - /// Maximum size of a comparator buffer. (1<<30) + /// Specifies the size of the comparator buffer. The range is from MSRDC_MINIMUM_COMPAREBUFFER to MSRDC_MAXIMUM_COMPAREBUFFER. + /// MSRDC_MINIMUM_COMPAREBUFFER (100000) + /// Minimum size of a comparator buffer. + /// MSRDC_DEFAULT_COMPAREBUFFER (3200000) + /// Default size of a comparator buffer. Used if zero (0) is passed for comparatorBufferSize. + /// MSRDC_MAXIMUM_COMPAREBUFFER (1073741824) + /// Maximum size of a comparator buffer. (1<<30) /// /// /// Pointer to a location that will receive an IRdcComparator interface pointer. On a successful return the interface will be /// initialized on return. Callers must release the interface. /// /// The caller must create a separate signature comparator for each level of recursion. - // https://docs.microsoft.com/en-us/windows/win32/api/msrdc/nf-msrdc-irdclibrary-createcomparator - // HRESULT CreateComparator( [in] IRdcFileReader *iSeedSignaturesFile, [in] ULONG comparatorBufferSize, [out] IRdcComparator **iComparator ); + // https://docs.microsoft.com/en-us/windows/win32/api/msrdc/nf-msrdc-irdclibrary-createcomparator HRESULT CreateComparator( [in] + // IRdcFileReader *iSeedSignaturesFile, [in] ULONG comparatorBufferSize, [out] IRdcComparator **iComparator ); [return: MarshalAs(UnmanagedType.Interface)] IRdcComparator CreateComparator([In, MarshalAs(UnmanagedType.Interface)] IRdcFileReader iSeedSignaturesFile, [Optional] uint comparatorBufferSize); @@ -1595,6 +1596,53 @@ namespace Vanara.PInvoke [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)] public class RdcSimilarityGenerator { } + /// An implementation of on top of a . + /// + [ComVisible(true), Guid("01EED492-3E92-4DF1-AC94-A7CDD0F23699"), ClassInterface(ClassInterfaceType.None)] + [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)] + public class RdcStreamReader : IRdcFileReader + { + private readonly Stream stream; + + /// Initializes a new instance of the class with stream to read. + /// The stream to read from. + public RdcStreamReader(Stream stream) => this.stream = stream; + + private RdcStreamReader() { } + + HRESULT IRdcFileReader.GetFilePosition(out ulong offsetFromStart) + { + offsetFromStart = (uint)stream.Position; + return HRESULT.S_OK; + } + + HRESULT IRdcFileReader.GetFileSize(out ulong fileSize) + { + fileSize = (ulong)stream.Length; + return HRESULT.S_OK; + } + + HRESULT IRdcFileReader.Read(ulong offsetFileStart, uint bytesToRead, out uint bytesActuallyRead, byte[] buffer, out bool eof) + { + if (stream.Position != (long)offsetFileStart) + { + stream.Seek((long)offsetFileStart, SeekOrigin.Begin); + } + + var intBuff = new byte[bytesToRead]; + int read = 0, lastRead; + do + { + lastRead = stream.Read(intBuff, read, ((int)bytesToRead - read)); + read += lastRead; + } while (lastRead != 0 && read < bytesToRead); + bytesActuallyRead = (uint)read; + Array.Copy(intBuff, buffer, (int)bytesToRead); + eof = read < bytesToRead; + return HRESULT.S_OK; + } + } + /// CLSID_Similarity [ComImport, Guid("96236A91-9DBC-11DA-9E3F-0011114AE311"), ClassInterface(ClassInterfaceType.None)] [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)] diff --git a/UnitTests/PInvoke/MsRdc/MsRdcTests.cs b/UnitTests/PInvoke/MsRdc/MsRdcTests.cs index 44c85609..43bfbfdd 100644 --- a/UnitTests/PInvoke/MsRdc/MsRdcTests.cs +++ b/UnitTests/PInvoke/MsRdc/MsRdcTests.cs @@ -36,7 +36,7 @@ public class MsRdcTests var gParamsCopy = gen.GetGeneratorParameters(MSRDC_MINIMUM_DEPTH); Assert.That(gParams.GetSerializeSize(), Is.EqualTo(gParamsCopy.GetSerializeSize())); - IRdcFileReader reader = new RdcFileReader(File.OpenRead(TestCaseSources.WordDoc)); + IRdcFileReader reader = new RdcStreamReader(File.OpenRead(TestCaseSources.WordDoc)); //var comp = lib.CreateComparator(reader, maxdepth); var sigRead = lib.CreateSignatureReader(reader); //TestContext.WriteLine($"SigHdrRes={sigRead.ReadHeader()}"); @@ -52,49 +52,4 @@ public class MsRdcTests public void SigGenTest() { } -} - -[ClassInterface(ClassInterfaceType.None)] -[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)] -[ComVisible(true)] -[Guid("01EED492-3E92-4DF1-AC94-A7CDD0F23699")] -public class RdcFileReader : IRdcFileReader -{ - private readonly Stream stream; - - private RdcFileReader() { } - - public RdcFileReader(Stream stream) => this.stream = stream; - - HRESULT IRdcFileReader.GetFileSize(out ulong fileSize) - { - fileSize = (ulong)stream.Length; - return HRESULT.S_OK; - } - - HRESULT IRdcFileReader.Read(ulong offsetFileStart, uint bytesToRead, out uint bytesActuallyRead, byte[] buffer, out bool eof) - { - if (stream.Position != (long)offsetFileStart) - { - stream.Seek((long)offsetFileStart, SeekOrigin.Begin); - } - - var intBuff = new byte[bytesToRead]; - int read = 0, lastRead; - do - { - lastRead = stream.Read(intBuff, read, ((int)bytesToRead - read)); - read += lastRead; - } while (lastRead != 0 && read < bytesToRead); - bytesActuallyRead = (uint)read; - Array.Copy(intBuff, buffer, (int)bytesToRead); - eof = read < bytesToRead; - return HRESULT.S_OK; - } - - HRESULT IRdcFileReader.GetFilePosition(out ulong offsetFromStart) - { - offsetFromStart = (uint)stream.Position; - return HRESULT.S_OK; - } } \ No newline at end of file