You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

114 lines
3.7 KiB

namespace com.hitrust.util.GZip
{
using com.hitrust.util.Checksums;
using com.hitrust.util.Zip.Compression;
using com.hitrust.util.Zip.Compression.Streams;
using System;
using System.IO;
public class GZipOutputStream : DeflaterOutputStream
{
protected Crc32 crc;
private static int GZIP_MAGIC = 0x8b1f;
private OutputState state_;
public GZipOutputStream(Stream baseOutputStream) : this(baseOutputStream, 0x200)
{
}
public GZipOutputStream(Stream baseOutputStream, int size) : base(baseOutputStream, new Deflater(Deflater.DEFAULT_COMPRESSION, true), size)
{
this.crc = new Crc32();
this.state_ = OutputState.Header;
}
public override void Close()
{
try
{
this.Finish();
}
finally
{
if (this.state_ != OutputState.Closed)
{
this.state_ = OutputState.Closed;
if (base.IsStreamOwner)
{
base.baseOutputStream_.Close();
}
}
}
}
public override void Finish()
{
if (this.state_ == OutputState.Header)
{
this.WriteHeader();
}
if (this.state_ == OutputState.Footer)
{
this.state_ = OutputState.Finished;
base.Finish();
uint totalin = (uint) (base.deflater_.TotalIn & 0xffffffffL);
uint crcval = (uint) (((ulong) this.crc.Value) & 0xffffffffL);
byte[] gzipFooter = new byte[] { (byte) crcval, (byte) (crcval >> 8), (byte) (crcval >> 0x10), (byte) (crcval >> 0x18), (byte) totalin, (byte) (totalin >> 8), (byte) (totalin >> 0x10), (byte) (totalin >> 0x18) };
base.baseOutputStream_.Write(gzipFooter, 0, gzipFooter.Length);
}
}
public int GetLevel()
{
return base.deflater_.GetLevel();
}
public void SetLevel(int level)
{
if (level < Deflater.BEST_SPEED)
{
throw new ArgumentOutOfRangeException("level");
}
base.deflater_.SetLevel(level);
}
public override void Write(byte[] buffer, int offset, int count)
{
if (this.state_ == OutputState.Header)
{
this.WriteHeader();
}
if (this.state_ != OutputState.Footer)
{
throw new InvalidOperationException("Write not permitted in current state");
}
this.crc.Update(buffer, offset, count);
base.Write(buffer, offset, count);
}
private void WriteHeader()
{
if (this.state_ == OutputState.Header)
{
this.state_ = OutputState.Footer;
DateTime date = new DateTime(0x7b2, 1, 1);
int mod_time = (int) ((DateTime.Now.Ticks - date.Ticks) / 0x989680L);
byte[] bytes = new byte[10];
bytes[0] = (byte) GZIP_MAGIC;
bytes[1] = (byte) (GZIP_MAGIC >> 8);
bytes[2] = (byte) Deflater.DEFLATED;
byte[] gzipHeader = bytes;
base.baseOutputStream_.Write(gzipHeader, 0, gzipHeader.Length);
}
}
private enum OutputState
{
Header,
Footer,
Finished,
Closed
}
}
}