Esempio n. 1
0
        private static BlobIdentifier ComputeIdentifierBasedOnBlocks(IEnumerable <BlobBlockHash> blocks)
        {
            var rollingId = new VsoHash.RollingBlobIdentifier();

            // ReSharper disable once GenericEnumeratorNotDisposed
            IEnumerator <BlobBlockHash> enumerator = blocks.GetEnumerator();

            bool isLast = !enumerator.MoveNext();

            if (isLast)
            {
                throw new InvalidDataException("Blob must have at least one block.");
            }

            BlobBlockHash current = enumerator.Current;

            isLast = !enumerator.MoveNext();
            while (!isLast)
            {
                rollingId.Update(current);
                current = enumerator.Current;
                isLast  = !enumerator.MoveNext();
            }

            return(rollingId.Finalize(current));
        }
Esempio n. 2
0
        private byte[]? TryHashAllBytesWithNoCopy(ReadOnlySpan <byte> source)
        {
            int startIndex = 0;

            byte[]? finalizedBytes = null;

            // If we know the size of the input upfront, we can hash all the data
            // without copying them into a temporary buffer.
            if (source.Length == _expectedInputLength && _currentOffset == 0)
            {
                // The span still maybe bigger than 2Mb buffer the hash algorithm uses to compute hash blocks.
                // Need to split the input source into the 2Mb pieces.
                int remaining = source.Length;
                int blockSize = GlobalObjectPools.TwoMbByteArrayPool.ArraySize;

                while (remaining > 0)
                {
                    int bytesToCopy  = Math.Min(blockSize, source.Length - startIndex);
                    var currentBatch = source.Slice(startIndex, bytesToCopy);
                    startIndex += bytesToCopy;
                    remaining  -= bytesToCopy;

                    var blockHash = HashBlock(currentBatch);

                    if (remaining == 0)
                    {
                        // Finalizing the hash. We're done.
                        finalizedBytes = _rollingId.Finalize(blockHash).Bytes;
                    }
                    else
                    {
                        // Not done yet.
                        _rollingId.Update(blockHash);
                    }
                }
            }

            return(finalizedBytes);
        }
Esempio n. 3
0
        /// <inheritdoc />
        protected override void HashCore(byte[] array, int ibStart, int cbSize)
        {
            Contract.AssertDebug(_buffer != null);

            while (cbSize > 0)
            {
                if (_currentOffset == _buffer.Length)
                {
                    var blockHash = HashBlock(_buffer, _buffer.Length);
                    _rollingId.Update(blockHash);
                    _currentOffset = 0;
                }

                int bytesToCopy = Math.Min(cbSize, _buffer.Length - _currentOffset);
                Buffer.BlockCopy(array, ibStart, _buffer, _currentOffset, bytesToCopy);
                _currentOffset += bytesToCopy;
                ibStart        += bytesToCopy;
                cbSize         -= bytesToCopy;
            }
        }
Esempio n. 4
0
        /// <inheritdoc />
        protected override byte[] HashFinal()
        {
            var rollingId = new VsoHash.RollingBlobIdentifier();

            // Flush out buffer
            if (_currentOffset != 0)
            {
                _blockHashes.Add(VsoHash.HashBlock(_buffer, _currentOffset));
            }

            // if there are no blocks add an empty block
            if (_blockHashes.Count == 0)
            {
                _blockHashes.Add(VsoHash.HashBlock(new byte[] { }, 0));
            }

            for (int i = 0; i < _blockHashes.Count - 1; i++)
            {
                rollingId.Update(_blockHashes[i]);
            }

            return(rollingId.Finalize(_blockHashes[_blockHashes.Count - 1]).Bytes);
        }