private void DoOperation(ModifyStream modifyStream, ModifyBuffer modifyBuffer, int count)
{
int startOffset = (int)(_position % _blockSize);
if (startOffset == 0 && (count % _blockSize == 0 || _position + count == Length))
{
WrappedStream.Position = _position;
modifyStream(WrappedStream, 0, count);
_position += count;
return;
}
long unalignedEnd = _position + count;
long alignedPos = MathUtilities.RoundDown(_position, _blockSize);
if (startOffset != 0)
{
WrappedStream.Position = alignedPos;
WrappedStream.Read(_alignmentBuffer, 0, _blockSize);
modifyBuffer(_alignmentBuffer, startOffset, 0, Math.Min(count, _blockSize - startOffset));
WrappedStream.Position = alignedPos;
WrappedStream.Write(_alignmentBuffer, 0, _blockSize);
}
alignedPos = MathUtilities.RoundUp(_position, _blockSize);
if (alignedPos >= unalignedEnd)
{
_position = unalignedEnd;
return;
}
int passthroughLength = (int)MathUtilities.RoundDown(_position + count - alignedPos, _blockSize);
if (passthroughLength > 0)
{
WrappedStream.Position = alignedPos;
modifyStream(WrappedStream, (int)(alignedPos - _position), passthroughLength);
}
alignedPos += passthroughLength;
if (alignedPos >= unalignedEnd)
{
_position = unalignedEnd;
return;
}
WrappedStream.Position = alignedPos;
WrappedStream.Read(_alignmentBuffer, 0, _blockSize);
modifyBuffer(_alignmentBuffer, 0, (int)(alignedPos - _position), (int)Math.Min(count - (alignedPos - _position), unalignedEnd - alignedPos));
WrappedStream.Position = alignedPos;
WrappedStream.Write(_alignmentBuffer, 0, _blockSize);
_position = unalignedEnd;
}