e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
105 lines
3.3 KiB
C#
105 lines
3.3 KiB
C#
//------------------------------------------------------------------------------
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//------------------------------------------------------------------------------
|
|
|
|
namespace System.ServiceModel.Configuration
|
|
{
|
|
using System;
|
|
using System.Configuration;
|
|
|
|
[AttributeUsage(AttributeTargets.Property)]
|
|
internal sealed class StandardRuntimeFlagEnumValidatorAttribute : ConfigurationValidatorAttribute
|
|
{
|
|
Type enumType;
|
|
Type validatorType;
|
|
|
|
public StandardRuntimeFlagEnumValidatorAttribute(Type enumType)
|
|
{
|
|
StandardRuntimeFlagEnumValidatorAttribute.ValidateFlagEnumType(enumType);
|
|
this.EnumType = enumType;
|
|
}
|
|
|
|
public Type EnumType
|
|
{
|
|
get { return this.enumType; }
|
|
set
|
|
{
|
|
StandardRuntimeFlagEnumValidatorAttribute.ValidateFlagEnumType(value);
|
|
this.enumType = value;
|
|
}
|
|
}
|
|
|
|
static bool IsPowerOfTwo(int value)
|
|
{
|
|
return value > 0 && (value & (value - 1)) == 0;
|
|
}
|
|
|
|
|
|
internal static void ValidateFlagEnumType(Type value)
|
|
{
|
|
if (value == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("EnumType");
|
|
}
|
|
|
|
bool hasFlags = value.GetCustomAttributes(typeof(FlagsAttribute), true).Length > 0;
|
|
if (!value.IsEnum || !hasFlags)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("EnumType", SR.GetString(SR.FlagEnumTypeExpected, value));
|
|
}
|
|
|
|
int[] values = (int[])Enum.GetValues(value);
|
|
|
|
if (values != null &&
|
|
values.Length > 0)
|
|
{
|
|
for (int i = 0; i < values.Length; i++)
|
|
{
|
|
if (values[i] != 0 && !IsPowerOfTwo(values[i]))
|
|
{
|
|
if (!StandardRuntimeFlagEnumValidatorAttribute.IsCombinedValue(values[i], values, i - 1))
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("EnumType", SR.GetString(SR.InvalidFlagEnumType));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
internal static bool IsCombinedValue(int combinedValue, int[] allowedValues, int startPosition)
|
|
{
|
|
int n = startPosition;
|
|
|
|
while (n >= 0 &&
|
|
combinedValue > 0)
|
|
{
|
|
if ((combinedValue & allowedValues[n]) == allowedValues[n])
|
|
{
|
|
combinedValue -= allowedValues[n];
|
|
}
|
|
|
|
n--;
|
|
}
|
|
|
|
return combinedValue == 0;
|
|
}
|
|
|
|
private void EnsureValidatorType()
|
|
{
|
|
if (this.validatorType == null)
|
|
{
|
|
validatorType = typeof(StandardRuntimeFlagEnumValidator<>).MakeGenericType(new System.Type[] { this.enumType });
|
|
}
|
|
}
|
|
|
|
public override ConfigurationValidatorBase ValidatorInstance
|
|
{
|
|
get
|
|
{
|
|
this.EnsureValidatorType();
|
|
return (ConfigurationValidatorBase)Activator.CreateInstance(validatorType, null);
|
|
}
|
|
}
|
|
}
|
|
}
|