NBTExplorer/SubstrateCS/Source/Core/NBTFile.cs
2011-11-09 21:46:19 -05:00

146 lines
4.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Ionic.Zlib;
using Substrate.Nbt;
namespace Substrate.Core
{
public enum CompressionType
{
None,
Zlib,
Deflate,
GZip,
}
public class NBTFile
{
private string _filename;
public NBTFile (string path)
{
_filename = path;
}
public string FileName
{
get { return _filename; }
protected set { _filename = value; }
}
public bool Exists ()
{
return File.Exists(_filename);
}
public void Delete ()
{
File.Delete(_filename);
}
public int GetModifiedTime ()
{
return Timestamp(File.GetLastWriteTime(_filename));
}
public Stream GetDataInputStream ()
{
return GetDataInputStream(CompressionType.GZip);
}
public virtual Stream GetDataInputStream (CompressionType compression)
{
try {
FileStream fstr = new FileStream(_filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
long length = fstr.Seek(0, SeekOrigin.End);
fstr.Seek(0, SeekOrigin.Begin);
byte[] data = new byte[length];
fstr.Read(data, 0, data.Length);
fstr.Close();
switch (compression) {
case CompressionType.None:
return new MemoryStream(data);
case CompressionType.GZip:
return new GZipStream(new MemoryStream(data), CompressionMode.Decompress);
case CompressionType.Zlib:
return new ZlibStream(new MemoryStream(data), CompressionMode.Decompress);
case CompressionType.Deflate:
return new DeflateStream(new MemoryStream(data), CompressionMode.Decompress);
default:
throw new ArgumentException("Invalid CompressionType specified", "compression");
}
}
catch (Exception ex) {
throw new NbtIOException("Failed to open compressed NBT data stream for input.", ex);
}
}
public Stream GetDataOutputStream ()
{
return GetDataOutputStream(CompressionType.GZip);
}
public virtual Stream GetDataOutputStream (CompressionType compression)
{
try {
switch (compression) {
case CompressionType.None:
return new NBTBuffer(this);
case CompressionType.GZip:
return new GZipStream(new NBTBuffer(this), CompressionMode.Compress);
case CompressionType.Zlib:
return new ZlibStream(new NBTBuffer(this), CompressionMode.Compress);
case CompressionType.Deflate:
return new DeflateStream(new NBTBuffer(this), CompressionMode.Compress);
default:
throw new ArgumentException("Invalid CompressionType specified", "compression");
}
}
catch (Exception ex) {
throw new NbtIOException("Failed to initialize compressed NBT data stream for output.", ex);
}
}
class NBTBuffer : MemoryStream
{
private NBTFile file;
public NBTBuffer (NBTFile c)
: base(8096)
{
this.file = c;
}
public override void Close ()
{
FileStream fstr;
try {
fstr = new FileStream(file._filename, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
}
catch (Exception ex) {
throw new NbtIOException("Failed to open NBT data stream for output.", ex);
}
try {
fstr.Write(this.GetBuffer(), 0, (int)this.Length);
fstr.Close();
}
catch (Exception ex) {
throw new NbtIOException("Failed to write out NBT data stream.", ex);
}
}
}
private int Timestamp (DateTime time)
{
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0);
return (int)((time - epoch).Ticks / (10000L * 1000L));
}
}
}