1 #region License 2 // Copyright (c) 2007 James Newton-King 3 // 4 // Permission is hereby granted, free of charge, to any person 5 // obtaining a copy of this software and associated documentation 6 // files (the "Software"), to deal in the Software without 7 // restriction, including without limitation the rights to use, 8 // copy, modify, merge, publish, distribute, sublicense, and/or sell 9 // copies of the Software, and to permit persons to whom the 10 // Software is furnished to do so, subject to the following 11 // conditions: 12 // 13 // The above copyright notice and this permission notice shall be 14 // included in all copies or substantial portions of the Software. 15 // 16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 // OTHER DEALINGS IN THE SOFTWARE. 24 #endregion 25 26 using System; 27 using System.Collections.Generic; 28 using System.Globalization; 29 #if NET20 30 using Newtonsoft.Json.Utilities.LinqBridge; 31 #else 32 using System.Linq; 33 #endif 34 using System.Reflection; 35 36 namespace Newtonsoft.Json.Utilities 37 { 38 internal static class EnumUtils 39 { 40 public static IList<T> GetFlagsValues<T>(T value) where T : struct 41 { 42 Type enumType = typeof(T); 43 44 if (!enumType.IsDefined(typeof(FlagsAttribute), false)) 45 throw new Exception("Enum type {0} is not a set of flags.".FormatWith(CultureInfo.InvariantCulture, enumType)); 46 47 Type underlyingType = Enum.GetUnderlyingType(value.GetType()); 48 49 ulong num = Convert.ToUInt64(value, CultureInfo.InvariantCulture); 50 EnumValues<ulong> enumNameValues = GetNamesAndValues<T>(); 51 IList<T> selectedFlagsValues = new List<T>(); 52 53 foreach (EnumValue<ulong> enumNameValue in enumNameValues) 54 { 55 if ((num & enumNameValue.Value) == enumNameValue.Value && enumNameValue.Value != 0) 56 selectedFlagsValues.Add((T)Convert.ChangeType(enumNameValue.Value, underlyingType, CultureInfo.CurrentCulture)); 57 } 58 59 if (selectedFlagsValues.Count == 0 && enumNameValues.SingleOrDefault(v => v.Value == 0) != null) selectedFlagsValues.AddNewtonsoft.Json.Utilities.EnumUtils.__anon160 selectedFlagsValues.Add(default(T)); 61 62 return selectedFlagsValues; 63 } 64 65 /// <summary> 66 /// Gets a dictionary of the names and values of an Enum type. 67 /// </summary> 68 /// <returns></returns> 69 public static EnumValues<ulong> GetNamesAndValues<T>() where T : struct 70 { 71 return GetNamesAndValues<ulong>(typeof(T)); 72 } 73 74 /// <summary> 75 /// Gets a dictionary of the names and values of an Enum type. 76 /// </summary> 77 /// <param name="enumType">The enum type to get names and values for.</param> 78 /// <returns></returns> 79 public static EnumValues<TUnderlyingType> GetNamesAndValues<TUnderlyingType>(Type enumType) where TUnderlyingType : struct 80 { 81 if (enumType == null) 82 throw new ArgumentNullException("enumType"); 83 ValidationUtils.ArgumentTypeIsEnumNewtonsoft.Json.Utilities.EnumUtils.__anon384 ValidationUtils.ArgumentTypeIsEnum(enumType, "enumType"); 85 86 IList<object> enumValues = GetValues(enumType); 87 IList<string> enumNames = GetNames(enumType); 88 89 EnumValues<TUnderlyingType> nameValues = new EnumValues<TUnderlyingType>(); 90 91 for (int i = 0; i < enumValues.Count; i++) 92 { 93 try 94 { 95 nameValues.Add(new EnumValue<TUnderlyingType>(enumNames[i], (TUnderlyingType)Convert.ChangeType(enumValues[i], typeof(TUnderlyingType), CultureInfo.CurrentCulture))); 96 } 97 catch (OverflowException e) 98 { 99 throw new Exception( 100 string.Format(CultureInfo.InvariantCulture, "Value from enum with the underlying type of {0} cannot be added to dictionary with a value type of {1}. Value was too large: {2}", 101 Enum.GetUnderlyingType(enumType), typeof(TUnderlyingType), Convert.ToUInt64(enumValues[i], CultureInfo.InvariantCulture)), e); 102 } 103 } 104 105 return nameValues; 106 } 107 GetValues(Type enumType)108 public static IList<object> GetValues(Type enumType) 109 { 110 if (!enumType.IsEnum()) 111 throw new ArgumentException("Type '" + enumType.Name + "' is not an enum."); 112 113 List<object> values = new List<object>(); 114 115 var fields = from field in enumType.GetFields() 116 where field.IsLiteral 117 select field; 118 119 foreach (FieldInfo field in fields) 120 { 121 object value = field.GetValue(enumType); 122 values.Add(value); 123 } 124 125 return values; 126 } 127 GetNames(Type enumType)128 public static IList<string> GetNames(Type enumType) 129 { 130 if (!enumType.IsEnum()) 131 throw new ArgumentException("Type '" + enumType.Name + "' is not an enum."); 132 133 List<string> values = new List<string>(); 134 135 var fields = from field in enumType.GetFields() 136 where field.IsLiteral 137 select field; 138 139 foreach (FieldInfo field in fields) 140 { 141 values.Add(field.Name); 142 } 143 144 return values; 145 } 146 } 147 }