public static string GetName(Type enumType, object value) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (value == null) { throw new ArgumentNullException("value"); } if (!enumType.IsEnum) { throw new ArgumentException("enumType is not an Enum type.", "enumType"); } MonoEnumInfo info; value = ToObject(enumType, value); MonoEnumInfo.GetInfo(enumType, out info); int i = FindPosition(enumType, value, info.values); return((i >= 0) ? info.names [i] : null); }
private MonoEnumInfo(MonoEnumInfo other) { utype = other.utype; values = other.values; names = other.names; name_hash = other.name_hash; }
private MonoEnumInfo(MonoEnumInfo other) { this.utype = other.utype; this.values = other.values; this.names = other.names; this.name_hash = other.name_hash; }
public static bool IsDefined (Type enumType, object value) { if (enumType == null) throw new ArgumentNullException ("enumType"); if (value == null) throw new ArgumentNullException ("value"); if (!enumType.IsEnum) throw new ArgumentException ("enumType is not an Enum type.", "enumType"); MonoEnumInfo info; MonoEnumInfo.GetInfo (enumType, out info); Type vType = value.GetType (); if (vType == typeof(String)) { return ((IList)(info.names)).Contains (value); } else if ((vType == info.utype) || (vType == enumType)) { value = ToObject (enumType, value); MonoEnumInfo.GetInfo (enumType, out info); return FindPosition (value, info.values) >= 0; } else { throw new ArgumentException("The value parameter is not the correct type." + "It must be type String or the same type as the underlying type" + "of the Enum."); } }
internal static void GetInfo(Type enumType, out MonoEnumInfo info) { if (MonoEnumInfo.Cache.ContainsKey(enumType)) { info = (MonoEnumInfo)MonoEnumInfo.cache[enumType]; return; } object obj = MonoEnumInfo.global_cache_monitor; lock (obj) { if (MonoEnumInfo.global_cache.ContainsKey(enumType)) { object obj2 = MonoEnumInfo.global_cache[enumType]; MonoEnumInfo.cache[enumType] = obj2; info = (MonoEnumInfo)obj2; return; } } MonoEnumInfo.get_enum_info(enumType, out info); IComparer comparer = null; if (!(info.values is byte[]) && !(info.values is ushort[]) && !(info.values is uint[]) && !(info.values is ulong[])) { if (info.values is int[]) { comparer = MonoEnumInfo.int_comparer; } else if (info.values is short[]) { comparer = MonoEnumInfo.short_comparer; } else if (info.values is sbyte[]) { comparer = MonoEnumInfo.sbyte_comparer; } else if (info.values is long[]) { comparer = MonoEnumInfo.long_comparer; } } Array.Sort(info.values, info.names, comparer); if (info.names.Length > 50) { info.name_hash = new Hashtable(info.names.Length); for (int i = 0; i < info.names.Length; i++) { info.name_hash[info.names[i]] = i; } } MonoEnumInfo monoEnumInfo = new MonoEnumInfo(info); object obj3 = MonoEnumInfo.global_cache_monitor; lock (obj3) { MonoEnumInfo.global_cache[enumType] = monoEnumInfo; } }
internal static void GetInfo(Type enumType, out MonoEnumInfo info) { /* First check the thread-local cache without locking */ if (Cache.ContainsKey(enumType)) { info = (MonoEnumInfo)cache [enumType]; return; } /* Threads could die, so keep a global cache too */ lock (global_cache_monitor) { if (global_cache.ContainsKey(enumType)) { object boxedInfo = global_cache [enumType]; cache [enumType] = boxedInfo; info = (MonoEnumInfo)boxedInfo; return; } } get_enum_info(enumType, out info); IComparer ic = null; Type et = Enum.GetUnderlyingType(enumType); if (et == typeof(int)) { ic = int_comparer; } else if (et == typeof(short)) { ic = short_comparer; } else if (et == typeof(sbyte)) { ic = sbyte_comparer; } else if (et == typeof(long)) { ic = long_comparer; } Array.Sort(info.values, info.names, ic); if (info.names.Length > 50) { info.name_hash = new Hashtable(info.names.Length); for (int i = 0; i < info.names.Length; ++i) { info.name_hash [info.names [i]] = i; } } MonoEnumInfo cached = new MonoEnumInfo(info); lock (global_cache_monitor) { global_cache [enumType] = cached; } }
internal static void GetInfo(Type enumType, out MonoEnumInfo info) { var user_type = !(enumType is MonoType); if (user_type) { GetUserEnumInfo(enumType, out info); } else { /* First check the thread-local cache without locking */ if (cache != null && cache.TryGetValue(enumType, out info)) { return; } /* Threads could die, so keep a global cache too */ lock (global_cache_monitor) { if (global_cache.TryGetValue(enumType, out info)) { if (cache == null) { cache = new Dictionary <Type, MonoEnumInfo> (); } cache [enumType] = info; return; } } // TODO: return info with ulong values only to avoid all sorts of // Array trick and slow paths get_enum_info(enumType, out info); } SortEnums(info.utype, info.values, info.names); // User types can have unreliable/not-implemented GetHashCode if (user_type) { return; } if (info.names.Length > 50) { info.name_hash = new Dictionary <string, int> (info.names.Length); for (int i = 0; i < info.names.Length; ++i) { info.name_hash [info.names [i]] = i; } } MonoEnumInfo cached = new MonoEnumInfo(info); lock (global_cache_monitor) { global_cache [enumType] = cached; } }
public static Array GetValues (Type enumType) { if (enumType == null) throw new ArgumentNullException ("enumType"); if (!enumType.IsEnum) throw new ArgumentException ("enumType is not an Enum type.", "enumType"); MonoEnumInfo info; MonoEnumInfo.GetInfo (enumType, out info); return (Array) info.values.Clone (); }
public static string[] GetNames (Type enumType) { if (enumType == null) throw new ArgumentNullException ("enumType"); if (!enumType.IsEnum) throw new ArgumentException ("enumType is not an Enum type."); MonoEnumInfo info; MonoEnumInfo.GetInfo (enumType, out info); return (string []) info.names.Clone (); }
static void GetUserEnumInfo(Type type, out MonoEnumInfo mei) { mei = new MonoEnumInfo(); mei.utype = typeof(UInt64); var fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); mei.names = new string [fields.Length]; var values = new UInt64 [fields.Length]; mei.values = values; for (int i = 0; i < fields.Length; ++i) { mei.names [i] = fields [i].Name; values [i] = ToUInt64(fields [i].GetRawConstantValue()); } }
internal static void GetInfo(Type enumType, out MonoEnumInfo info) { /* First check the thread-local cache without locking */ if (cache != null && cache.TryGetValue(enumType, out info)) { return; } /* Threads could die, so keep a global cache too */ lock (global_cache_monitor) { if (global_cache.TryGetValue(enumType, out info)) { if (cache == null) { cache = new Dictionary <Type, MonoEnumInfo> (); } cache [enumType] = info; return; } } get_enum_info(enumType, out info); Type et = Enum.GetUnderlyingType(enumType); SortEnums(et, info.values, info.names); if (info.names.Length > 50) { info.name_hash = new Dictionary <string, int> (info.names.Length); for (int i = 0; i < info.names.Length; ++i) { info.name_hash [info.names [i]] = i; } } MonoEnumInfo cached = new MonoEnumInfo(info); lock (global_cache_monitor) { global_cache [enumType] = cached; } }
internal static void GetInfo(Type enumType, out MonoEnumInfo info) { /* First check the thread-local cache without locking */ if (Cache.ContainsKey(enumType)) { info = (MonoEnumInfo)cache [enumType]; return; } /* Threads could die, so keep a global cache too */ lock (global_cache_monitor) { if (global_cache.ContainsKey(enumType)) { object boxedInfo = global_cache [enumType]; cache [enumType] = boxedInfo; info = (MonoEnumInfo)boxedInfo; return; } } get_enum_info(enumType, out info); Type et = Enum.GetUnderlyingType(enumType); SortEnums(et, info.values, info.names); if (info.names.Length > 50) { info.name_hash = new Hashtable(info.names.Length); for (int i = 0; i < info.names.Length; ++i) { info.name_hash [info.names [i]] = i; } } MonoEnumInfo cached = new MonoEnumInfo(info); lock (global_cache_monitor) { global_cache [enumType] = cached; } }
static string FormatFlags(Type enumType, object value) { string retVal = String.Empty; MonoEnumInfo info; MonoEnumInfo.GetInfo(enumType, out info); string asString = value.ToString(); if (asString == "0") { retVal = GetName(enumType, value); if (retVal == null) { retVal = asString; } return(retVal); } // This is ugly, yes. We need to handle the different integer // types for enums. If someone else has a better idea, be my guest. switch (((Enum)info.values.GetValue(0)).GetTypeCode()) { case TypeCode.SByte: { sbyte flags = (sbyte)value; sbyte enumValue; for (int i = info.values.Length - 1; i >= 0; i--) { enumValue = (sbyte)info.values.GetValue(i); if (enumValue == 0) { continue; } if ((flags & enumValue) == enumValue) { retVal = info.names[i] + (retVal == String.Empty ? String.Empty : ", ") + retVal; flags -= enumValue; } } if (flags != 0) { return(asString); } } break; case TypeCode.Byte: { byte flags = (byte)value; byte enumValue; for (int i = info.values.Length - 1; i >= 0; i--) { enumValue = (byte)info.values.GetValue(i); if (enumValue == 0) { continue; } if ((flags & enumValue) == enumValue) { retVal = info.names[i] + (retVal == String.Empty ? String.Empty : ", ") + retVal; flags -= enumValue; } } if (flags != 0) { return(asString); } } break; case TypeCode.Int16: { short flags = (short)value; short enumValue; for (int i = info.values.Length - 1; i >= 0; i--) { enumValue = (short)info.values.GetValue(i); if (enumValue == 0) { continue; } if ((flags & enumValue) == enumValue) { retVal = info.names[i] + (retVal == String.Empty ? String.Empty : ", ") + retVal; flags -= enumValue; } } if (flags != 0) { return(asString); } } break; case TypeCode.Int32: { int flags = (int)value; int enumValue; for (int i = info.values.Length - 1; i >= 0; i--) { enumValue = (int)info.values.GetValue(i); if (enumValue == 0) { continue; } if ((flags & enumValue) == enumValue) { retVal = info.names[i] + (retVal == String.Empty ? String.Empty : ", ") + retVal; flags -= enumValue; } } if (flags != 0) { return(asString); } } break; case TypeCode.UInt16: { ushort flags = (ushort)value; ushort enumValue; for (int i = info.values.Length - 1; i >= 0; i--) { enumValue = (ushort)info.values.GetValue(i); if (enumValue == 0) { continue; } if ((flags & enumValue) == enumValue) { retVal = info.names[i] + (retVal == String.Empty ? String.Empty : ", ") + retVal; flags -= enumValue; } } if (flags != 0) { return(asString); } } break; case TypeCode.UInt32: { uint flags = (uint)value; uint enumValue; for (int i = info.values.Length - 1; i >= 0; i--) { enumValue = (uint)info.values.GetValue(i); if (enumValue == 0) { continue; } if ((flags & enumValue) == enumValue) { retVal = info.names[i] + (retVal == String.Empty ? String.Empty : ", ") + retVal; flags -= enumValue; } } if (flags != 0) { return(asString); } } break; case TypeCode.Int64: { long flags = (long)value; long enumValue; for (int i = info.values.Length - 1; i >= 0; i--) { enumValue = (long)info.values.GetValue(i); if (enumValue == 0) { continue; } if ((flags & enumValue) == enumValue) { retVal = info.names[i] + (retVal == String.Empty ? String.Empty : ", ") + retVal; flags -= enumValue; } } if (flags != 0) { return(asString); } } break; case TypeCode.UInt64: { ulong flags = (ulong)value; ulong enumValue; for (int i = info.values.Length - 1; i >= 0; i--) { enumValue = (ulong)info.values.GetValue(i); if (enumValue == 0) { continue; } if ((flags & enumValue) == enumValue) { retVal = info.names[i] + (retVal == String.Empty ? String.Empty : ", ") + retVal; flags -= enumValue; } } if (flags != 0) { return(asString); } } break; } if (retVal == String.Empty) { return(asString); } return(retVal); }
static bool Parse <TEnum> (Type enumType, string value, bool ignoreCase, out TEnum result) { result = default(TEnum); MonoEnumInfo info; MonoEnumInfo.GetInfo(enumType, out info); // is 'value' a named constant? int loc = FindName(info.name_hash, info.names, value, ignoreCase); if (loc >= 0) { result = (TEnum)info.values.GetValue(loc); return(true); } TypeCode typeCode = ((Enum)info.values.GetValue(0)).GetTypeCode(); // is 'value' a list of named constants? if (value.IndexOf(',') != -1) { string [] names = value.Split(split_char); ulong retVal = 0; for (int i = 0; i < names.Length; ++i) { loc = FindName(info.name_hash, info.names, names [i].Trim(), ignoreCase); if (loc < 0) { return(false); } retVal |= GetValue(info.values.GetValue(loc), typeCode); } result = (TEnum)ToObject(enumType, retVal); return(true); } // is 'value' a number? switch (typeCode) { case TypeCode.SByte: sbyte sb; if (!SByte.TryParse(value, out sb)) { return(false); } result = (TEnum)ToObject(enumType, sb); break; case TypeCode.Byte: byte b; if (!Byte.TryParse(value, out b)) { return(false); } result = (TEnum)ToObject(enumType, b); break; case TypeCode.Int16: short i16; if (!Int16.TryParse(value, out i16)) { return(false); } result = (TEnum)ToObject(enumType, i16); break; case TypeCode.UInt16: ushort u16; if (!UInt16.TryParse(value, out u16)) { return(false); } result = (TEnum)ToObject(enumType, u16); break; case TypeCode.Int32: int i32; if (!Int32.TryParse(value, out i32)) { return(false); } result = (TEnum)ToObject(enumType, i32); break; case TypeCode.UInt32: uint u32; if (!UInt32.TryParse(value, out u32)) { return(false); } result = (TEnum)ToObject(enumType, u32); break; case TypeCode.Int64: long i64; if (!Int64.TryParse(value, out i64)) { return(false); } result = (TEnum)ToObject(enumType, i64); break; case TypeCode.UInt64: ulong u64; if (!UInt64.TryParse(value, out u64)) { return(false); } result = (TEnum)ToObject(enumType, u64); break; default: break; } return(true); }
public static object Parse(Type enumType, string value, bool ignoreCase) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (value == null) { throw new ArgumentNullException("value"); } if (!enumType.IsEnum) { throw new ArgumentException("enumType is not an Enum type.", "enumType"); } value = value.Trim(); if (value.Length == 0) { throw new ArgumentException("An empty string is not considered a valid value."); } MonoEnumInfo info; MonoEnumInfo.GetInfo(enumType, out info); // is 'value' a named constant? int loc = FindName(info.name_hash, info.names, value, ignoreCase); if (loc >= 0) { return(info.values.GetValue(loc)); } TypeCode typeCode = ((Enum)info.values.GetValue(0)).GetTypeCode(); // is 'value' a list of named constants? if (value.IndexOf(',') != -1) { string [] names = value.Split(split_char); ulong retVal = 0; for (int i = 0; i < names.Length; ++i) { loc = FindName(info.name_hash, info.names, names [i].Trim(), ignoreCase); if (loc < 0) { throw new ArgumentException("The requested value was not found."); } retVal |= GetValue(info.values.GetValue(loc), typeCode); } return(ToObject(enumType, retVal)); } // is 'value' a number? #if !NET_2_0 try { return(ToObject(enumType, Convert.ChangeType(value, typeCode))); } catch (FormatException) { throw new ArgumentException(String.Format("The requested value '{0}' was not found.", value)); } #else switch (typeCode) { case TypeCode.SByte: sbyte sb; if (SByte.TryParse(value, out sb)) { return(ToObject(enumType, sb)); } break; case TypeCode.Byte: byte b; if (Byte.TryParse(value, out b)) { return(ToObject(enumType, b)); } break; case TypeCode.Int16: short i16; if (Int16.TryParse(value, out i16)) { return(ToObject(enumType, i16)); } break; case TypeCode.UInt16: ushort u16; if (UInt16.TryParse(value, out u16)) { return(ToObject(enumType, u16)); } break; case TypeCode.Int32: int i32; if (Int32.TryParse(value, out i32)) { return(ToObject(enumType, i32)); } break; case TypeCode.UInt32: uint u32; if (UInt32.TryParse(value, out u32)) { return(ToObject(enumType, u32)); } break; case TypeCode.Int64: long i64; if (Int64.TryParse(value, out i64)) { return(ToObject(enumType, i64)); } break; case TypeCode.UInt64: ulong u64; if (UInt64.TryParse(value, out u64)) { return(ToObject(enumType, u64)); } break; default: break; } throw new ArgumentException(String.Format("The requested value '{0}' was not found.", value)); #endif }
private static void get_enum_info (Type enumType, out MonoEnumInfo info) { throw new System.NotImplementedException(); }
private static extern void get_enum_info(Type enumType, out MonoEnumInfo info);
private static extern void get_enum_info (Type enumType, out MonoEnumInfo info);
private static void get_enum_info(Type enumType, out MonoEnumInfo info) { throw new System.NotImplementedException(); }