using System; using System.IO; namespace Oni.Metadata { internal abstract class MetaType { private string name; private int size; private bool isFixedSize; private bool? isLeaf; protected MetaType() { } protected MetaType(string name, int size) { this.size = size; this.name = name; } #region Primitive Types public static readonly MetaChar Char = new MetaChar(); public static readonly MetaByte Byte = new MetaByte(); public static readonly MetaInt16 Int16 = new MetaInt16(); public static readonly MetaUInt16 UInt16 = new MetaUInt16(); public static readonly MetaInt32 Int32 = new MetaInt32(); public static readonly MetaUInt32 UInt32 = new MetaUInt32(); public static readonly MetaInt64 Int64 = new MetaInt64(); public static readonly MetaUInt64 UInt64 = new MetaUInt64(); public static readonly MetaColor Color = new MetaColor(); public static readonly MetaFloat Float = new MetaFloat(); public static readonly MetaVector2 Vector2 = new MetaVector2(); public static readonly MetaVector3 Vector3 = new MetaVector3(); public static readonly MetaQuaternion Quaternion = new MetaQuaternion(); public static readonly MetaPlane Plane = new MetaPlane(); public static readonly MetaBoundingBox BoundingBox = new MetaBoundingBox(); public static readonly MetaBoundingSphere BoundingSphere = new MetaBoundingSphere(); public static readonly MetaMatrix4x3 Matrix4x3 = new MetaMatrix4x3(); public static readonly MetaRawOffset RawOffset = new MetaRawOffset(); public static readonly MetaSepOffset SepOffset = new MetaSepOffset(); public static readonly MetaString String16 = new MetaString(16); public static readonly MetaString String32 = new MetaString(32); public static readonly MetaString String48 = new MetaString(48); public static readonly MetaString String63 = new MetaString(63); public static readonly MetaString String64 = new MetaString(64); public static readonly MetaString String128 = new MetaString(128); public static readonly MetaString String256 = new MetaString(256); public static MetaPadding Padding(int length) => new MetaPadding(length); public static MetaPadding Padding(int length, byte fillByte) => new MetaPadding(length, fillByte); public static MetaArray Array(int length, MetaType elementType) => new MetaArray(elementType, length); public static MetaVarArray ShortVarArray(MetaType elementType) => new MetaVarArray(Int16, elementType); public static MetaVarArray VarArray(MetaType elementType) => new MetaVarArray(Int32, elementType); public static MetaString String(int length) { switch (length) { case 16: return String16; case 32: return String32; case 64: return String64; case 128: return String128; case 256: return String256; default: return new MetaString(length); } } public static MetaPointer Pointer(TemplateTag tag) => new MetaPointer(tag); public static MetaEnum Enum() { Type underlyingType = System.Enum.GetUnderlyingType(typeof(T)); if (underlyingType == typeof(Byte)) return new MetaEnum(MetaType.Byte, typeof(T)); if (underlyingType == typeof(Int16)) return new MetaEnum(MetaType.Int16, typeof(T)); if (underlyingType == typeof(UInt16)) return new MetaEnum(MetaType.UInt16, typeof(T)); if (underlyingType == typeof(Int32)) return new MetaEnum(MetaType.Int32, typeof(T)); if (underlyingType == typeof(UInt32)) return new MetaEnum(MetaType.UInt32, typeof(T)); if (underlyingType == typeof(Int64)) return new MetaEnum(MetaType.Int64, typeof(T)); if (underlyingType == typeof(UInt64)) return new MetaEnum(MetaType.UInt64, typeof(T)); throw new InvalidOperationException(System.String.Format("Unsupported enum type {0}", underlyingType)); } #endregion public string Name { get { return name; } protected set { name = value; } } public int Size { get { return size; } protected set { size = value; } } public bool IsFixedSize { get { return isFixedSize; } protected set { isFixedSize = value; } } public bool IsLeaf { get { if (!isLeaf.HasValue) isLeaf = IsLeafImpl(); return isLeaf.Value; } } protected abstract bool IsLeafImpl(); public bool IsBlittable { get { return (this == MetaType.Byte || this == MetaType.Int16 || this == MetaType.UInt16 || this == MetaType.Int32 || this == MetaType.UInt32 || this == MetaType.Int64 || this == MetaType.UInt64 || this == MetaType.Float || this == MetaType.Color || this == MetaType.Matrix4x3 || this == MetaType.Plane || this == MetaType.Quaternion || this == MetaType.Vector2 || this == MetaType.Vector3); } } public abstract void Accept(IMetaTypeVisitor visitor); internal int Copy(BinaryReader input, BinaryWriter output, Action callback) { var copyVisitor = new CopyVisitor(input, output, callback); Accept(copyVisitor); return copyVisitor.Position; } } }