using System;
using System.IO;
using System.Threading;
using ICSharpCode.SharpZipLib.BZip2;
using ICSharpCode.SharpZipLib.Tests.TestSupport;
using NUnit.Framework;
namespace ICSharpCode.SharpZipLib.Tests.BZip2
{
///
/// This class contains test cases for Bzip2 compression
///
[TestFixture]
public class BZip2Suite
{
///
/// Basic compress/decompress test BZip2
///
[Test]
[Category("BZip2")]
public void BasicRoundTrip()
{
MemoryStream ms = new MemoryStream();
BZip2OutputStream outStream = new BZip2OutputStream(ms);
byte[] buf = new byte[10000];
System.Random rnd = new Random();
rnd.NextBytes(buf);
outStream.Write(buf, 0, buf.Length);
outStream.Close();
ms = new MemoryStream(ms.GetBuffer());
ms.Seek(0, SeekOrigin.Begin);
using (BZip2InputStream inStream = new BZip2InputStream(ms))
{
byte[] buf2 = new byte[buf.Length];
int pos = 0;
while (true)
{
int numRead = inStream.Read(buf2, pos, 4096);
if (numRead <= 0)
{
break;
}
pos += numRead;
}
for (int i = 0; i < buf.Length; ++i)
{
Assert.AreEqual(buf2[i], buf[i]);
}
}
}
///
/// Check that creating an empty archive is handled ok
///
[Test]
[Category("BZip2")]
public void CreateEmptyArchive()
{
MemoryStream ms = new MemoryStream();
BZip2OutputStream outStream = new BZip2OutputStream(ms);
outStream.Close();
ms = new MemoryStream(ms.GetBuffer());
ms.Seek(0, SeekOrigin.Begin);
using (BZip2InputStream inStream = new BZip2InputStream(ms))
{
byte[] buffer = new byte[1024];
int pos = 0;
while (true)
{
int numRead = inStream.Read(buffer, 0, buffer.Length);
if (numRead <= 0)
{
break;
}
pos += numRead;
}
Assert.AreEqual(pos, 0);
}
}
BZip2OutputStream outStream_;
BZip2InputStream inStream_;
WindowedStream window_;
long readTarget_;
long writeTarget_;
[Test]
[Category("BZip2")]
public void Performance()
{
window_ = new WindowedStream(0x150000);
outStream_ = new BZip2OutputStream(window_, 1);
const long Target = 0x10000000;
readTarget_ = writeTarget_ = Target;
Thread reader = new Thread(Reader);
reader.Name = "Reader";
Thread writer = new Thread(Writer);
writer.Name = "Writer";
DateTime startTime = DateTime.Now;
writer.Start();
inStream_ = new BZip2InputStream(window_);
reader.Start();
Assert.IsTrue(writer.Join(TimeSpan.FromMinutes(5.0D)));
Assert.IsTrue(reader.Join(TimeSpan.FromMinutes(5.0D)));
DateTime endTime = DateTime.Now;
TimeSpan span = endTime - startTime;
Console.WriteLine("Time {0} throughput {1} KB/Sec", span, (Target / 1024) / span.TotalSeconds);
}
void Reader()
{
const int Size = 8192;
int readBytes = 1;
byte[] buffer = new byte[Size];
long passifierLevel = readTarget_ - 0x10000000;
while ((readTarget_ > 0) && (readBytes > 0))
{
int count = Size;
if (count > readTarget_)
{
count = (int)readTarget_;
}
readBytes = inStream_.Read(buffer, 0, count);
readTarget_ -= readBytes;
if (readTarget_ <= passifierLevel)
{
Console.WriteLine("Reader {0} bytes remaining", readTarget_);
passifierLevel = readTarget_ - 0x10000000;
}
}
Assert.IsTrue(window_.IsClosed, "Window should be closed");
// This shouldnt read any data but should read the footer
readBytes = inStream_.Read(buffer, 0, 1);
Assert.AreEqual(0, readBytes, "Stream should be empty");
Assert.AreEqual(0, window_.Length, "Window should be closed");
inStream_.Close();
}
void WriteTargetBytes()
{
const int Size = 8192;
byte[] buffer = new byte[Size];
while (writeTarget_ > 0)
{
int thisTime = Size;
if (thisTime > writeTarget_)
{
thisTime = (int)writeTarget_;
}
outStream_.Write(buffer, 0, thisTime);
writeTarget_ -= thisTime;
}
}
void Writer()
{
WriteTargetBytes();
outStream_.Close();
}
}
}