| 1 | using System; | 
 
 
 
 
 | 2 | using System.Xml; | 
 
 
 
 
 | 3 |  | 
 
 
 
 
 | 4 | namespace Oni.Metadata | 
 
 
 
 
 | 5 | { | 
 
 
 
 
 | 6 | internal class MetaEnum : MetaType | 
 
 
 
 
 | 7 | { | 
 
 
 
 
 | 8 | private MetaType baseType; | 
 
 
 
 
 | 9 | private Type enumType; | 
 
 
 
 
 | 10 |  | 
 
 
 
 
 | 11 | public MetaEnum(MetaType baseType, Type enumType) : base("Enum", baseType.Size) | 
 
 
 
 
 | 12 | { | 
 
 
 
 
 | 13 | if (baseType != MetaType.Byte | 
 
 
 
 
 | 14 | && baseType != MetaType.Int16 | 
 
 
 
 
 | 15 | && baseType != MetaType.UInt16 | 
 
 
 
 
 | 16 | && baseType != MetaType.Int32 | 
 
 
 
 
 | 17 | && baseType != MetaType.UInt32 | 
 
 
 
 
 | 18 | && baseType != MetaType.Int64 | 
 
 
 
 
 | 19 | && baseType != MetaType.UInt64) | 
 
 
 
 
 | 20 | { | 
 
 
 
 
 | 21 | throw new ArgumentException("Invalid enum base type", "baseType"); | 
 
 
 
 
 | 22 | } | 
 
 
 
 
 | 23 |  | 
 
 
 
 
 | 24 | this.baseType = baseType; | 
 
 
 
 
 | 25 | this.enumType = enumType; | 
 
 
 
 
 | 26 | } | 
 
 
 
 
 | 27 |  | 
 
 
 
 
 | 28 | public MetaType BaseType => baseType; | 
 
 
 
 
 | 29 |  | 
 
 
 
 
 | 30 | public Type EnumType => enumType; | 
 
 
 
 
 | 31 |  | 
 
 
 
 
 | 32 | public bool IsFlags => Utils.IsFlagsEnum(enumType); | 
 
 
 
 
 | 33 |  | 
 
 
 
 
 | 34 | protected override bool IsLeafImpl() => true; | 
 
 
 
 
 | 35 |  | 
 
 
 
 
 | 36 | public override void Accept(IMetaTypeVisitor visitor) => visitor.VisitEnum(this); | 
 
 
 
 
 | 37 |  | 
 
 
 
 
 | 38 | public void BinaryToXml(BinaryReader reader, XmlWriter writer) | 
 
 
 
 
 | 39 | { | 
 
 
 
 
 | 40 | object value; | 
 
 
 
 
 | 41 |  | 
 
 
 
 
 | 42 | if (baseType == MetaType.Byte) | 
 
 
 
 
 | 43 | value = System.Enum.ToObject(enumType, reader.ReadByte()); | 
 
 
 
 
 | 44 | else if (baseType == MetaType.Int16) | 
 
 
 
 
 | 45 | value = System.Enum.ToObject(enumType, reader.ReadInt16()); | 
 
 
 
 
 | 46 | else if (baseType == MetaType.UInt16) | 
 
 
 
 
 | 47 | value = System.Enum.ToObject(enumType, reader.ReadUInt16()); | 
 
 
 
 
 | 48 | else if (baseType == MetaType.Int32) | 
 
 
 
 
 | 49 | value = System.Enum.ToObject(enumType, reader.ReadInt32()); | 
 
 
 
 
 | 50 | else if (baseType == MetaType.UInt32) | 
 
 
 
 
 | 51 | value = System.Enum.ToObject(enumType, reader.ReadUInt32()); | 
 
 
 
 
 | 52 | else if (baseType == MetaType.Int64) | 
 
 
 
 
 | 53 | value = System.Enum.ToObject(enumType, reader.ReadInt64()); | 
 
 
 
 
 | 54 | else | 
 
 
 
 
 | 55 | value = System.Enum.ToObject(enumType, reader.ReadUInt64()); | 
 
 
 
 
 | 56 |  | 
 
 
 
 
 | 57 | string text = value.ToString().Replace(",", string.Empty); | 
 
 
 
 
 | 58 |  | 
 
 
 
 
 | 59 | if (text == "None" && IsFlags) | 
 
 
 
 
 | 60 | text = string.Empty; | 
 
 
 
 
 | 61 |  | 
 
 
 
 
 | 62 | writer.WriteValue(text); | 
 
 
 
 
 | 63 | } | 
 
 
 
 
 | 64 |  | 
 
 
 
 
 | 65 | public void XmlToBinary(XmlReader reader, BinaryWriter writer) | 
 
 
 
 
 | 66 | { | 
 
 
 
 
 | 67 | string text = reader.ReadElementContentAsString(); | 
 
 
 
 
 | 68 |  | 
 
 
 
 
 | 69 | if (string.IsNullOrEmpty(text) && IsFlags) | 
 
 
 
 
 | 70 | { | 
 
 
 
 
 | 71 | if (baseType == MetaType.Byte) | 
 
 
 
 
 | 72 | writer.WriteByte(0); | 
 
 
 
 
 | 73 | else if (baseType == MetaType.Int16 || baseType == MetaType.UInt16) | 
 
 
 
 
 | 74 | writer.WriteUInt16(0); | 
 
 
 
 
 | 75 | else if (baseType == MetaType.Int32 || baseType == MetaType.UInt32) | 
 
 
 
 
 | 76 | writer.Write(0); | 
 
 
 
 
 | 77 | else | 
 
 
 
 
 | 78 | writer.Write(0L); | 
 
 
 
 
 | 79 |  | 
 
 
 
 
 | 80 | return; | 
 
 
 
 
 | 81 | } | 
 
 
 
 
 | 82 |  | 
 
 
 
 
 | 83 | object value = null; | 
 
 
 
 
 | 84 |  | 
 
 
 
 
 | 85 | try | 
 
 
 
 
 | 86 | { | 
 
 
 
 
 | 87 | value = System.Enum.Parse(enumType, text.Trim().Replace(' ', ',')); | 
 
 
 
 
 | 88 | } | 
 
 
 
 
 | 89 | catch | 
 
 
 
 
 | 90 | { | 
 
 
 
 
 | 91 | } | 
 
 
 
 
 | 92 |  | 
 
 
 
 
 | 93 | if (value == null) | 
 
 
 
 
 | 94 | throw new FormatException(string.Format("{0} is not a valid value name. Run onisplit -help enums to see a list of possible names.", text)); | 
 
 
 
 
 | 95 |  | 
 
 
 
 
 | 96 | if (baseType == MetaType.Byte) | 
 
 
 
 
 | 97 | writer.WriteByte(Convert.ToByte(value)); | 
 
 
 
 
 | 98 | else if (baseType == MetaType.Int16) | 
 
 
 
 
 | 99 | writer.Write(Convert.ToInt16(value)); | 
 
 
 
 
 | 100 | else if (baseType == MetaType.UInt16) | 
 
 
 
 
 | 101 | writer.Write(Convert.ToUInt16(value)); | 
 
 
 
 
 | 102 | else if (baseType == MetaType.Int32) | 
 
 
 
 
 | 103 | writer.Write(Convert.ToInt32(value)); | 
 
 
 
 
 | 104 | else if (baseType == MetaType.UInt32) | 
 
 
 
 
 | 105 | writer.Write(Convert.ToUInt32(value)); | 
 
 
 
 
 | 106 | else if (baseType == MetaType.Int64) | 
 
 
 
 
 | 107 | writer.Write(Convert.ToInt64(value)); | 
 
 
 
 
 | 108 | else | 
 
 
 
 
 | 109 | writer.Write(Convert.ToUInt64(value)); | 
 
 
 
 
 | 110 | } | 
 
 
 
 
 | 111 |  | 
 
 
 
 
 | 112 | public static T Parse<T>(string text) where T : struct | 
 
 
 
 
 | 113 | { | 
 
 
 
 
 | 114 | object value = null; | 
 
 
 
 
 | 115 |  | 
 
 
 
 
 | 116 | if (string.IsNullOrEmpty(text) && Utils.IsFlagsEnum(typeof(T))) | 
 
 
 
 
 | 117 | { | 
 
 
 
 
 | 118 | value = System.Enum.Parse(typeof(T), "None"); | 
 
 
 
 
 | 119 | } | 
 
 
 
 
 | 120 | else | 
 
 
 
 
 | 121 | { | 
 
 
 
 
 | 122 | try | 
 
 
 
 
 | 123 | { | 
 
 
 
 
 | 124 | string[] values = text.Split(new char[0], StringSplitOptions.RemoveEmptyEntries); | 
 
 
 
 
 | 125 | text = string.Join(", ", values); | 
 
 
 
 
 | 126 | value = System.Enum.Parse(typeof(T), text, true); | 
 
 
 
 
 | 127 | } | 
 
 
 
 
 | 128 | catch | 
 
 
 
 
 | 129 | { | 
 
 
 
 
 | 130 | } | 
 
 
 
 
 | 131 | } | 
 
 
 
 
 | 132 |  | 
 
 
 
 
 | 133 | if (value == null) | 
 
 
 
 
 | 134 | throw new FormatException(string.Format("{0} is not a valid value name. Run onisplit -help enums to see a list of possible names.", text)); | 
 
 
 
 
 | 135 |  | 
 
 
 
 
 | 136 | return (T)value; | 
 
 
 
 
 | 137 | } | 
 
 
 
 
 | 138 |  | 
 
 
 
 
 | 139 | public static string ToString<T>(T value) where T : struct | 
 
 
 
 
 | 140 | { | 
 
 
 
 
 | 141 | string text = value.ToString().Replace(",", string.Empty); | 
 
 
 
 
 | 142 |  | 
 
 
 
 
 | 143 | if (text == "None" && Utils.IsFlagsEnum(typeof(T))) | 
 
 
 
 
 | 144 | text = string.Empty; | 
 
 
 
 
 | 145 |  | 
 
 
 
 
 | 146 | return text; | 
 
 
 
 
 | 147 | } | 
 
 
 
 
 | 148 | } | 
 
 
 
 
 | 149 | } |