private static void TransformAllTest(
			int inBlockSize,
			int outBlockSize,
			int inputCacheBlocks,
			int dataSize,
			int bufSize,
			bool canTransformMultipleBlocks,
			int transformBufferSize)
        {
            var src = new BigBufferedSourceMock (dataSize, bufSize, FillFunction);
            var mock = new CryptoTransformMock (inBlockSize, outBlockSize, inputCacheBlocks, canTransformMultipleBlocks);
            var transform = new CryptoTransformingBufferedSource (src, mock, new byte[transformBufferSize]);

            var fullBlocks = dataSize / inBlockSize;
            var inReminder = dataSize - fullBlocks * inBlockSize;
            var outReminder = Math.Min (inReminder, outBlockSize);
            var resultSize = fullBlocks * outBlockSize + outReminder;

            // считываем весь результат преобразования
            int len = 0;
            var result = new byte[resultSize];
            int available;
            while ((available = transform.FillBuffer ()) > 0)
            {
                Array.Copy (transform.Buffer, transform.Offset, result, len, available);
                len += available;
                transform.SkipBuffer (available);
            }
            Assert.IsTrue (transform.IsExhausted);
            Assert.AreEqual (resultSize, len);

            // проверяем что результат преобразования совпадает с тестовым массивом
            for (var i = 0; i < fullBlocks; i++)
            {
                for (int j = 0; j < outBlockSize; j++)
                {
                    var inIndex = i * inBlockSize + (j % inBlockSize);
                    var outIndex = i * outBlockSize + j;
                    Assert.AreEqual (FillFunction (inIndex), (byte)~result[outIndex]);
                }
            }
            for (int j = 0; j < outReminder; j++)
            {
                var inIndex = fullBlocks * inBlockSize + (j % inBlockSize);
                var outIndex = fullBlocks * outBlockSize + j;
                Assert.AreEqual (FillFunction (inIndex), (byte)~result[outIndex]);
            }
        }
        private static void SkipTransformChunkTest(
			int inBlockSize,
			int outBlockSize,
			int inputCacheBlocks,
			long dataSize,
			int bufSize,
			bool canTransformMultipleBlocks,
			int transformBufferSize,
			long totalSkip,
			int bufferSkip)
        {
            var src = new BigBufferedSourceMock (dataSize, bufSize, FillFunction);
            var mock = new CryptoTransformMock (inBlockSize, outBlockSize, inputCacheBlocks, canTransformMultipleBlocks);
            var transform = new CryptoTransformingBufferedSource (src, mock, new byte[transformBufferSize]);

            Assert.AreEqual (totalSkip, transform.TrySkip (totalSkip));
            transform.EnsureBuffer (3);
            Assert.AreEqual ((byte)~FillFunction (MapTransformIndexBackToOriginal (totalSkip, mock)), transform.Buffer[transform.Offset]);
            Assert.AreEqual ((byte)~FillFunction (MapTransformIndexBackToOriginal (totalSkip + 1, mock)), transform.Buffer[transform.Offset + 1]);
            Assert.AreEqual ((byte)~FillFunction (MapTransformIndexBackToOriginal (totalSkip + 2, mock)), transform.Buffer[transform.Offset + 2]);
            transform.EnsureBuffer (bufferSkip);
            transform.SkipBuffer (bufferSkip);
            transform.EnsureBuffer (3);
            Assert.AreEqual ((byte)~FillFunction (MapTransformIndexBackToOriginal (totalSkip + bufferSkip, mock)), transform.Buffer[transform.Offset]);
            Assert.AreEqual ((byte)~FillFunction (MapTransformIndexBackToOriginal (totalSkip + bufferSkip + 1, mock)), transform.Buffer[transform.Offset + 1]);
            Assert.AreEqual ((byte)~FillFunction (MapTransformIndexBackToOriginal (totalSkip + bufferSkip + 2, mock)), transform.Buffer[transform.Offset + 2]);
        }