using System; //using System.Collections.Generic; using System.ComponentModel; using System.IO; namespace Gibbed.IO { public static partial class StreamHelpers { #region Cache private static class EnumTypeCache { /*private static Dictionary _Lookup; static EnumTypeCache() { _Lookup = new Dictionary(); }*/ private static TypeCode TranslateType(Type type) { if (type.IsEnum == true) { var underlyingType = Enum.GetUnderlyingType(type); var underlyingTypeCode = Type.GetTypeCode(underlyingType); switch (underlyingTypeCode) { case TypeCode.SByte: case TypeCode.Byte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: case TypeCode.UInt32: case TypeCode.Int64: case TypeCode.UInt64: { return underlyingTypeCode; } } } throw new ArgumentException("unknown enum type", "type"); } public static TypeCode Get(Type type) { /*if (Lookup.ContainsKey(type) == true) { return Lookup[type]; }*/ return /*Lookup[type] =*/ TranslateType(type); } } #endregion #region ReadValueEnum public static T ReadValueEnum(this Stream stream, Endian endian) { var type = typeof(T); object value; switch (EnumTypeCache.Get(type)) { case TypeCode.SByte: { value = stream.ReadValueS8(); break; } case TypeCode.Byte: { value = stream.ReadValueU8(); break; } case TypeCode.Int16: { value = stream.ReadValueS16(endian); break; } case TypeCode.UInt16: { value = stream.ReadValueU16(endian); break; } case TypeCode.Int32: { value = stream.ReadValueS32(endian); break; } case TypeCode.UInt32: { value = stream.ReadValueU32(endian); break; } case TypeCode.Int64: { value = stream.ReadValueS64(endian); break; } case TypeCode.UInt64: { value = stream.ReadValueU64(endian); break; } default: { throw new NotSupportedException(); } } return (T)Enum.ToObject(type, value); } public static T ReadValueEnum(this Stream stream) { return stream.ReadValueEnum(Endian.Little); } #endregion #region WriteValueEnum public static void WriteValueEnum(this Stream stream, object value, Endian endian) { var type = typeof(T); switch (EnumTypeCache.Get(type)) { case TypeCode.SByte: { stream.WriteValueS8((sbyte)value); break; } case TypeCode.Byte: { stream.WriteValueU8((byte)value); break; } case TypeCode.Int16: { stream.WriteValueS16((short)value, endian); break; } case TypeCode.UInt16: { stream.WriteValueU16((ushort)value, endian); break; } case TypeCode.Int32: { stream.WriteValueS32((int)value, endian); break; } case TypeCode.UInt32: { stream.WriteValueU32((uint)value, endian); break; } case TypeCode.Int64: { stream.WriteValueS64((long)value, endian); break; } case TypeCode.UInt64: { stream.WriteValueU64((ulong)value, endian); break; } default: { throw new NotSupportedException(); } } } public static void WriteValueEnum(this Stream stream, object value) { stream.WriteValueEnum(value, Endian.Little); } #endregion #region Obsolete [Obsolete("use Endian enum instead of boolean to represent endianness")] [EditorBrowsable(EditorBrowsableState.Never)] public static T ReadValueEnum(this Stream stream, bool littleEndian) { return stream.ReadValueEnum(littleEndian == true ? Endian.Little : Endian.Big); } [Obsolete("use Endian enum instead of boolean to represent endianness")] [EditorBrowsable(EditorBrowsableState.Never)] public static void WriteValueEnum(this Stream stream, object value, bool littleEndian) { stream.WriteValueEnum(value, littleEndian == true ? Endian.Little : Endian.Big); } #endregion } }