/// <summary> /// Reads a byte from the stream and advances the position within the stream by one byte, /// or returns -1 if at the end of the stream. /// </summary> /// /// <returns> /// The unsigned byte cast to an <see cref="int"/>, or -1 if at the end of the stream. /// </returns> /// /// <exception cref="NotSupportedException"> /// If the stream does not support reading. /// </exception> /// /// <exception cref="ObjectDisposedException"> /// Methods were called after the stream was closed. /// </exception> /// /// <exception cref="HealthServiceException"> /// If there was a failure reading the data from HealthVault. /// </exception> /// public override int ReadByte() { if (!CanRead) { throw new NotSupportedException(); } if (_disposed) { throw new ObjectDisposedException(nameof(BlobStream)); } int result = -1; // Check to see if there is still something in the buffer if (_bufferList.Count > 0) { BufferRequest buffer = _bufferList[0]; result = buffer.Buffer[buffer.Offset]; buffer.Count--; buffer.Offset++; if (buffer.Count == 0) { _bufferList.RemoveAt(0); } } else { // Get a new chunk int bufferSize = (int)(_length ?? DefaultStreamBufferSize); byte[] newBuffer = new byte[bufferSize]; int count = Read(newBuffer, 0, bufferSize); if (count > 0) { result = newBuffer[0]; // Note, this makes a copy of the buffer. _bufferList.Add( new BufferRequest(newBuffer, 1, count - 1)); } } return(result); }
private async Task WriteChunkAsync(int chunkSizeToWrite, bool uploadComplete) { int bytesInWebRequest = 0; long start = 0; byte[] webRequestBuffer = null; if (chunkSizeToWrite > 0) { int writeBufferOffset = 0; while (writeBufferOffset < chunkSizeToWrite) { BufferRequest curRequestBuffer = _bufferList[_currentBufferRequestIndex]; // Get the number of bytes in the current request buffer up to a chunk. int numBytesToCopy = Math.Min(curRequestBuffer.Count, chunkSizeToWrite); // Ensure we don't write past the end of the chunk buffer. numBytesToCopy = Math.Min( numBytesToCopy, _chunkBuffer.Length - writeBufferOffset); // Copy the bytes to be sent over in to the chunk buffer; Array.Copy( curRequestBuffer.Buffer, curRequestBuffer.Offset, _chunkBuffer, writeBufferOffset, numBytesToCopy); writeBufferOffset += numBytesToCopy; curRequestBuffer.Offset += numBytesToCopy; curRequestBuffer.Count -= numBytesToCopy; if (curRequestBuffer.Count < 1) { _currentBufferRequestIndex++; } } if (_currentBufferRequestIndex > 0) { _bufferList.RemoveRange(0, _currentBufferRequestIndex); _currentBufferRequestIndex = 0; } IList <byte[]> blockHashes = _blobHasher.CalculateBlockHashes(_chunkBuffer, 0, chunkSizeToWrite); _blockHashes.AddRange(blockHashes); bytesInWebRequest = chunkSizeToWrite; start = _position; webRequestBuffer = _chunkBuffer; } if (webRequestBuffer != null) { HttpResponseMessage request = await ExecutePutRequestAsync(start, bytesInWebRequest, uploadComplete, webRequestBuffer).ConfigureAwait(false); if (!request.IsSuccessStatusCode) { ThrowRequestFailedException(request); } _bytesInBuffer -= chunkSizeToWrite; } _position += chunkSizeToWrite; }
private void AugmentBufferList(BufferRequest buffer) { _bufferList.Add(buffer); _bytesInBuffer += buffer.Count; }