/// <summary> /// For enum without flags, use a binary search /// </summary> /// <param name="enumType">edm enum type</param> /// <param name="value">input integer value</param> /// <returns>string</returns> private static string ToStringNoFlags(this IEdmEnumType enumType, Int64 value) { ulong[] values; string[] names; enumType.GetCachedValuesAndNames(out values, out names, true, true); ulong num = (ulong)value; int index = Array.BinarySearch(values, num); return(index >= 0 ? names[index] : value.ToString(CultureInfo.InvariantCulture)); }
/// <summary> /// For enum with flags, use a sequential search for bit masks, and then check if any residual /// </summary> /// <param name="enumType">edm enum type</param> /// <param name="value">input integer value</param> /// <returns>string separated by comma</returns> private static string ToStringWithFlags(this IEdmEnumType enumType, Int64 value) { string[] strArray; ulong[] numArray; ulong num = (ulong)value; enumType.GetCachedValuesAndNames(out numArray, out strArray, true, true); int index = numArray.Length - 1; StringBuilder builder = new StringBuilder(); bool flag = true; ulong num3 = num; const int Zero = 0; const ulong UlongZero = 0L; while (index >= Zero) { if ((index == Zero) && (numArray[index] == UlongZero)) { break; } if ((num & numArray[index]) == numArray[index]) { num -= numArray[index]; if (!flag) { builder.Insert(Zero, ", "); } builder.Insert(Zero, strArray[index]); flag = false; } index--; } if (num != UlongZero) { return(value.ToString(CultureInfo.InvariantCulture)); } if (num3 != UlongZero) { return(builder.ToString()); } if ((numArray.Length > Zero) && (numArray[Zero] == UlongZero)) { return(strArray[Zero]); } return(Zero.ToString(CultureInfo.InvariantCulture)); }
/// <summary> /// Parse an enum literal value to integer. The literal value can be Enum member name (e.g. "Red"), underlying value (e.g. "2"), or combined values (e.g. "Red, Green, Blue", "1,2,4"). /// </summary> /// <param name="enumType">edm enum type</param> /// <param name="value">input string value</param> /// <param name="ignoreCase">true if case insensitive, false if case sensitive</param> /// <param name="parseResult">parse result</param> /// <returns>true if parse succeeds, false if parse fails</returns> public static bool TryParseEnum(this IEdmEnumType enumType, string value, bool ignoreCase, out long parseResult) { char[] enumSeparatorCharArray = new[] { ',' }; string[] enumNames; ulong[] enumValues; IEdmEnumType type = enumType; parseResult = 0L; if (value == null) { return(false); } value = value.Trim(); if (value.Length == 0) { return(false); } ulong num = 0L; string[] values = value.Split(enumSeparatorCharArray); if ((!enumType.IsFlags) && values.Length > 1) { return(false); // nonflags can only have 1 value } type.GetCachedValuesAndNames(out enumValues, out enumNames, true, true); if ((char.IsDigit(value[0]) || (value[0] == '-')) || (value[0] == '+')) { // computed for later use. only meaningful for Enum types with IsFlags=true. ulong fullBits = 0; for (int j = 0; j < enumValues.Length; j++) { fullBits |= enumValues[j]; } // process each value for (int i = 0; i < values.Length; i++) { long itemValue; if (long.TryParse(values[i], out itemValue)) { // allow any number value, don't validate it against enum definition. num |= (ulong)itemValue; } else { return(false); } } } else { for (int i = 0; i < values.Length; i++) { values[i] = values[i].Trim(); bool flag = false; for (int j = 0; j < enumNames.Length; j++) { if (ignoreCase) { if (string.Compare(enumNames[j], values[i], StringComparison.OrdinalIgnoreCase) != 0) { continue; } } else { if (!enumNames[j].Equals(values[i])) { continue; } } ulong item = enumValues[j]; num |= item; flag = true; break; } if (!flag) { return(false); } } } parseResult = (long)num; return(true); }