forked from mirrors/NBTExplorer
146 lines
4.7 KiB
C#
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));
|
|
}
|
|
}
|
|
}
|