public override void Write(byte[] buffer, int offset, int count) { CheckDisposed(); var done = false; long left = count; long current = offset; if (_needsRead) { SeekInternal(_lastPosition, SeekOrigin.Begin); NativeFile.Read(_handle, _writeBuffer, 0, (int)_blockSize); SeekInternal(_lastPosition, SeekOrigin.Begin); _needsRead = false; } while (!done) { _needsFlush = true; if (_bufferedCount + left < _writeBufferSize) { CopyBuffer(buffer, current, left); done = true; current += left; } else { var toFill = _writeBufferSize - _bufferedCount; CopyBuffer(buffer, current, toFill); Flush(); left -= toFill; current += toFill; done = left == 0; } } }
public override int Read(byte[] buffer, int offset, int count) { CheckDisposed(); if (offset < 0 || buffer.Length < offset) { throw new ArgumentException("offset"); } if (count < 0 || buffer.Length < count) { throw new ArgumentException("offset"); } if (offset + count > buffer.Length) { throw new ArgumentException("offset + count must be less than size of array"); } var position = GetLowestAlignment(Position); var roffset = (int)(Position - position); var bytesRead = _readBufferSize; if (_readLocation + _readBufferSize <= position || _readLocation > position || _readLocation == 0) { SeekInternal(position); bytesRead = NativeFile.Read(_handle, _readBuffer, 0, _readBufferSize); _readLocation = position; } else if (_readLocation != position) { roffset += (int)(position - _readLocation); } var bytesAvailable = bytesRead - roffset; if (bytesAvailable <= 0) { return(0); } var toCopy = count > bytesAvailable ? bytesAvailable : count; MemCopy(_readBuffer, roffset, buffer, offset, toCopy); _bufferedCount += toCopy; if (count - toCopy == 0) { return(toCopy); } return(toCopy + Read(buffer, offset + toCopy, count - toCopy)); }
public override long Seek(long offset, SeekOrigin origin) { CheckDisposed(); if (origin == SeekOrigin.Current) { throw new NotImplementedException("only supports seek origin begin/end"); } if (origin == SeekOrigin.End) { offset = Length + offset; } var aligned = GetLowestAlignment(offset); var left = (int)(offset - aligned); Flush(); _bufferedCount = left; _aligned = aligned == left; _lastPosition = aligned; SeekInternal(aligned); NativeFile.Read(_handle, _writeBuffer, 0, (int)_blockSize); SeekInternal(aligned); return(offset); }