PageRenderTime 47ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/Json45r7/Source/Src/Newtonsoft.Json/Utilities/EnumUtils.cs

https://bitbucket.org/wantstudios/bitbucketclient
C# | 147 lines | 91 code | 25 blank | 31 comment | 15 complexity | c8f70cca3a4d3abb680fdef1ae720d70 MD5 | raw file
  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. using System;
  26. using System.Collections.Generic;
  27. using System.Globalization;
  28. #if NET20
  29. using Newtonsoft.Json.Utilities.LinqBridge;
  30. #else
  31. using System.Linq;
  32. #endif
  33. using System.Reflection;
  34. namespace Newtonsoft.Json.Utilities
  35. {
  36. internal static class EnumUtils
  37. {
  38. public static IList<T> GetFlagsValues<T>(T value) where T : struct
  39. {
  40. Type enumType = typeof(T);
  41. if (!enumType.IsDefined(typeof(FlagsAttribute), false))
  42. throw new ArgumentException("Enum type {0} is not a set of flags.".FormatWith(CultureInfo.InvariantCulture, enumType));
  43. Type underlyingType = Enum.GetUnderlyingType(value.GetType());
  44. ulong num = Convert.ToUInt64(value, CultureInfo.InvariantCulture);
  45. EnumValues<ulong> enumNameValues = GetNamesAndValues<T>();
  46. IList<T> selectedFlagsValues = new List<T>();
  47. foreach (EnumValue<ulong> enumNameValue in enumNameValues)
  48. {
  49. if ((num & enumNameValue.Value) == enumNameValue.Value && enumNameValue.Value != 0)
  50. selectedFlagsValues.Add((T)Convert.ChangeType(enumNameValue.Value, underlyingType, CultureInfo.CurrentCulture));
  51. }
  52. if (selectedFlagsValues.Count == 0 && enumNameValues.SingleOrDefault(v => v.Value == 0) != null)
  53. selectedFlagsValues.Add(default(T));
  54. return selectedFlagsValues;
  55. }
  56. /// <summary>
  57. /// Gets a dictionary of the names and values of an Enum type.
  58. /// </summary>
  59. /// <returns></returns>
  60. public static EnumValues<ulong> GetNamesAndValues<T>() where T : struct
  61. {
  62. return GetNamesAndValues<ulong>(typeof(T));
  63. }
  64. /// <summary>
  65. /// Gets a dictionary of the names and values of an Enum type.
  66. /// </summary>
  67. /// <param name="enumType">The enum type to get names and values for.</param>
  68. /// <returns></returns>
  69. public static EnumValues<TUnderlyingType> GetNamesAndValues<TUnderlyingType>(Type enumType) where TUnderlyingType : struct
  70. {
  71. if (enumType == null)
  72. throw new ArgumentNullException("enumType");
  73. ValidationUtils.ArgumentTypeIsEnum(enumType, "enumType");
  74. IList<object> enumValues = GetValues(enumType);
  75. IList<string> enumNames = GetNames(enumType);
  76. EnumValues<TUnderlyingType> nameValues = new EnumValues<TUnderlyingType>();
  77. for (int i = 0; i < enumValues.Count; i++)
  78. {
  79. try
  80. {
  81. nameValues.Add(new EnumValue<TUnderlyingType>(enumNames[i], (TUnderlyingType)Convert.ChangeType(enumValues[i], typeof(TUnderlyingType), CultureInfo.CurrentCulture)));
  82. }
  83. catch (OverflowException e)
  84. {
  85. throw new InvalidOperationException(
  86. 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}",
  87. Enum.GetUnderlyingType(enumType), typeof(TUnderlyingType), Convert.ToUInt64(enumValues[i], CultureInfo.InvariantCulture)), e);
  88. }
  89. }
  90. return nameValues;
  91. }
  92. public static IList<object> GetValues(Type enumType)
  93. {
  94. if (!enumType.IsEnum())
  95. throw new ArgumentException("Type '" + enumType.Name + "' is not an enum.");
  96. List<object> values = new List<object>();
  97. var fields = from field in enumType.GetFields()
  98. where field.IsLiteral
  99. select field;
  100. foreach (FieldInfo field in fields)
  101. {
  102. object value = field.GetValue(enumType);
  103. values.Add(value);
  104. }
  105. return values;
  106. }
  107. public static IList<string> GetNames(Type enumType)
  108. {
  109. if (!enumType.IsEnum())
  110. throw new ArgumentException("Type '" + enumType.Name + "' is not an enum.");
  111. List<string> values = new List<string>();
  112. var fields = from field in enumType.GetFields()
  113. where field.IsLiteral
  114. select field;
  115. foreach (FieldInfo field in fields)
  116. {
  117. values.Add(field.Name);
  118. }
  119. return values;
  120. }
  121. }
  122. }