using System; using System.IO; namespace NW4RTools { public class InputStream { public readonly byte[] Data; public readonly ByteEndian Endian; private readonly bool MustReverseArrays; public int Position { get; private set; } public InputStream(byte[] data) { Data = data; Endian = ByteEndian.BigEndian; Position = 0; MustReverseArrays = BitConverter.IsLittleEndian; } public InputStream(byte[] data, ByteEndian endian) { Data = data; Endian = endian; Position = 0; if (Endian == ByteEndian.BigEndian) MustReverseArrays = BitConverter.IsLittleEndian; else MustReverseArrays = !BitConverter.IsLittleEndian; } public bool AtEnd { get { return (Position == Data.Length); } } public void Seek(int pos) { if (pos < 0 || pos > Data.Length) throw new ArgumentOutOfRangeException(); Position = pos; } public void Skip(int count) { Seek(Position + count); } public byte[] ReadBytes(int count) { byte[] ret = new byte[count]; Array.Copy(Data, Position, ret, 0, count); Skip(count); return ret; } private byte[] ReadReversedBytes(int count) { byte[] buf = ReadBytes(count); if (MustReverseArrays) Array.Reverse(buf); return buf; } public byte ReadByte() { byte ret = Data[Position]; Skip(1); return ret; } public SByte ReadSByte() { return unchecked((sbyte)ReadByte()); } public Int16 ReadInt16() { return BitConverter.ToInt16(ReadReversedBytes(2), 0); } public UInt16 ReadUInt16() { return BitConverter.ToUInt16(ReadReversedBytes(2), 0); } public Int32 ReadInt32() { return BitConverter.ToInt32(ReadReversedBytes(4), 0); } public UInt32 ReadUInt32() { return BitConverter.ToUInt32(ReadReversedBytes(4), 0); } public float ReadFloat() { return BitConverter.ToSingle(ReadReversedBytes(4), 0); } public double ReadDouble() { return BitConverter.ToDouble(ReadReversedBytes(8), 0); } public Color ReadColor() { var ret = new Color(); ret.r = Data[Position]; ret.g = Data[Position + 1]; ret.b = Data[Position + 2]; ret.a = Data[Position + 3]; Skip(4); return ret; } public Vec2 ReadVec2() { float x = ReadFloat(); float y = ReadFloat(); return new Vec2 { x = x, y = y }; } public Vec3 ReadVec3() { float x = ReadFloat(); float y = ReadFloat(); float z = ReadFloat(); return new Vec3 { x = x, y = y, z = z }; } public Matrix ReadMatrix() { var ret = new Matrix(); ret.v00 = ReadFloat(); ret.v01 = ReadFloat(); ret.v02 = ReadFloat(); ret.v03 = ReadFloat(); ret.v10 = ReadFloat(); ret.v11 = ReadFloat(); ret.v12 = ReadFloat(); ret.v13 = ReadFloat(); ret.v20 = ReadFloat(); ret.v21 = ReadFloat(); ret.v22 = ReadFloat(); ret.v23 = ReadFloat(); return ret; } public string ReadName() { int length = ReadInt32(); string name = System.Text.Encoding.GetEncoding("Shift_JIS").GetString(ReadBytes(length)); if ((length & 3) != 0) { Skip(4 - (length & 3)); } return name; } public InputStream At(int pos) { var ret = new InputStream(Data, Endian); ret.Seek(pos); return ret; } public InputStream Copy() { return At(Position); } } }