public FilePart GetNextPart(long requestedPartSize)
            {
                try
                {
                    int    partSize = Convert.ToInt32(Math.Min(requestedPartSize, fileLength - streamPosition));
                    byte[] content  = new byte[partSize];
                    stream.Read(content, 0, partSize);

                    bool   isLast = streamPosition + partSize >= fileLength;
                    string hash   = MD5HashProviderFactory.GetHashProvider().CreateHash().ComputeHash(content);
                    var    part   = new FilePart {
                        Bytes = content, Hash = hash, Index = partCount, Offset = streamPosition, IsLastPart = isLast
                    };

                    streamPosition += partSize;
                    partCount      += 1;
                    if (isLast)
                    {
                        HasMore = false;
                        fileHash.Finalize(content, 0, content.Length);
                    }
                    else
                    {
                        fileHash.Append(content, 0, content.Length);
                    }

                    return(part);
                }
                catch
                {
                    //improvement: return object to propagate this exception
                    HasMore = false;
                    return(null);
                }
            }
Exemplo n.º 2
0
            public async Task <FilePart> GetNextPart(long requestedPartSize)
            {
                try
                {
                    int            partSize    = Convert.ToInt32(Math.Min(requestedPartSize, fileLength - streamPosition));
                    ReadFileResult partContent = await ReadFile(partSize).ConfigureAwait(false);

                    bool isLast = streamPosition + partSize >= fileLength;
                    var  part   = new FilePart(partContent.Content, partCount, streamPosition, partSize, partContent.Hash, isLast);
                    if (isLast)
                    {
                        HasMore = false;
                        fileHash.Finalize(ArrayPool <byte> .Shared.Rent(0), 0, 0);
                    }
                    else
                    {
                        streamPosition += partSize;
                        partCount      += 1;
                    }
                    return(part);
                }
                catch
                {
                    HasMore = false;
                    throw;
                }
            }
Exemplo n.º 3
0
            private async Task <ReadFileResult> ReadFile(int length)
            {
                IBuffer          content   = bufferAllocator.Allocate(length);
                Stream           dest      = content.GetStream();
                IMD5HashProvider chunkHash = MD5HashProviderFactory.GetHashProvider().CreateHash();

                byte[] b = ArrayPool <byte> .Shared.Rent(Configuration.BufferSize);

                try
                {
                    int read   = 0;
                    int toRead = length;
                    do
                    {
                        read = await fileStream.ReadAsync(b, offset : 0, count : Math.Min(b.Length, toRead)).ConfigureAwait(false);

                        toRead -= read;

                        await dest.WriteAsync(b, offset : 0, count : read).ConfigureAwait(false);

                        chunkHash.Append(b, offset: 0, size: read);
                        fileHash.Append(b, offset: 0, size: read);
                    } while (read > 0 && toRead > 0);
                    if (toRead > 0)
                    {
                        throw new Exception($"Expected to read {length} bytes, actual read {length - toRead} bytes");
                    }

                    chunkHash.Finalize(ArrayPool <byte> .Shared.Rent(0), 0, 0);
                    return(new ReadFileResult {
                        Content = content, Hash = chunkHash.GetComputedHashAsString()
                    });
                }
                catch
                {
                    content.Dispose();
                    throw;
                }
                finally
                {
                    ArrayPool <byte> .Shared.Return(b);

                    dest.Dispose();
                }
            }
        public async Task <string> Append(Stream chunk, CancellationToken cancellationToken)
        {
            IMD5HashProvider chunkHash = NewHash();

            byte[] buffer    = new byte[bufferSize];
            int    bytesRead = 0;

            await fileHashLock.WaitAsync(cancellationToken);

            try
            {
                for (long position = 0; position < chunk.Length; position += bytesRead)
                {
                    bytesRead = await chunk.ReadAsync(buffer, 0, buffer.Length, cancellationToken);

                    fileHash.Append(buffer, 0, bytesRead);
                    chunkHash.Append(buffer, 0, bytesRead);
                }
            }
            finally { fileHashLock.Release(); }

            chunkHash.Finalize(zeroBuffer, 0, 0);
            return(chunkHash.GetComputedHashAsString());
        }