Ejemplo 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));
        }
Ejemplo n.º 2
0
        /// <inheritdoc />
        protected override byte[] HashFinal()
        {
            Contract.AssertDebug(_buffer != null);

            // Here, either the buffer has data, or there were no blocks.

            // Flush out buffer
            if (_currentOffset != 0)
            {
                var blockHash = HashBlock(_buffer, _currentOffset);
                return(_rollingId.Finalize(blockHash).Bytes);
            }

            // if there are no blocks add an empty block
            var emptyBlockHash = HashBlock(new byte[] { }, 0);

            return(_rollingId.Finalize(emptyBlockHash).Bytes);
        }
Ejemplo n.º 3
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);
        }
Ejemplo 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);
        }