} // end function Clone public unsafe void Read(ref byte[] a_Destination, UInt64 a_DestinationOffset, UInt64 a_OutputLength) { UInt64 LRemainder, LBlockOffset, LDiff; Int32 LCount; UInt32[] LWords = new UInt32[16]; if (Offset == MaxDigestLengthInBytes) { throw new ArgumentOutOfRangeHashLibException(MaximumOutputLengthExceeded); } else { LRemainder = MaxDigestLengthInBytes - Offset; if (a_OutputLength > LRemainder) { a_OutputLength = LRemainder; } } // end else fixed(UInt32 *LPtrCardinal = LWords) { fixed(byte *LPtrByte = Block) { while (a_OutputLength > 0) { if ((Offset & (BlockSizeInBytes - 1)) == 0) { N.Counter = Offset / (UInt64)BlockSizeInBytes; N.Compress(ref LWords); Converters.le32_copy((IntPtr)LPtrCardinal, 0, (IntPtr)LPtrByte, 0, BlockSizeInBytes); } LBlockOffset = Offset & (BlockSizeInBytes - 1); LDiff = (UInt64)Block.Length - LBlockOffset; LCount = (Int32)Math.Min(a_OutputLength, LDiff); Utils.Utils.Memmove(ref a_Destination, Block, LCount, (Int32)LBlockOffset, (Int32)a_DestinationOffset); a_OutputLength -= (UInt64)LCount; a_DestinationOffset += (UInt64)LCount; Offset += (UInt64)LCount; } } } } // end function Read
public unsafe void Read(byte[] dest, ulong destOffset, ulong outputLength) { var words = new uint[16]; if (Offset == MaxDigestLengthInBytes) { throw new ArgumentException(MaximumOutputLengthExceeded); } var remainder = MaxDigestLengthInBytes - Offset; outputLength = Math.Min(outputLength, remainder); fixed(uint *wordsPtr = words) { fixed(byte *blockPtr = _block, destPtr = dest) { while (outputLength > 0) { if ((Offset & (BlockSizeInBytes - 1)) == 0) { N.Counter = Offset / BlockSizeInBytes; N.Compress(wordsPtr); Converters.le32_copy(wordsPtr, 0, blockPtr, 0, BlockSizeInBytes); } var blockOffset = Offset & (BlockSizeInBytes - 1); var diff = (ulong)_block.Length - blockOffset; var count = (int)Math.Min(outputLength, diff); PointerUtils.MemMove(destPtr + destOffset, blockPtr + blockOffset, count); outputLength -= (ulong)count; destOffset += (ulong)count; Offset += (ulong)count; } } } }