// $Id$
//
// Copyright 2007-2008 Cisco Systems Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
using System;
using Etch.Msg;
namespace Etch.Support
{
///
/// Base class of validators which validate based on exact type.
///
abstract public class TypeValidator : Validator
{
///
/// Constructs the TypeValidator.
///
/// class to use if nDims == 0
/// class to use if nDims > 0
/// the number of dimensions. 0 for a scalar.
///
public TypeValidator( Type scalarClass, Type arrayClass, int nDims,
String descr)
: this(scalarClass, arrayClass, nDims, descr, false)
{
}
///
/// Constructs the TypeValidator.
///
/// class to use if nDims == 0
/// class to use if nDims > 0
/// the number of dimensions. 0 for a scalar.
///
/// true of a subclass of the expected class is ok
public TypeValidator(Type scalarClass, Type arrayClass, int nDims,
String descr, bool subclassOk)
{
CheckDims(nDims);
this.expectedClass = MkExpectedClass(scalarClass, arrayClass, nDims);
this.nDims = nDims;
this.descr = descr;
this.subclassOk = subclassOk;
}
///
/// Checks the number of dimensions for standard validators.
///
///
public static void CheckDims( int nDims )
{
if ( nDims < 0 || nDims > MAX_NDIMS )
throw new ArgumentOutOfRangeException( "nDims < 0 || nDims > MAX_NDIMS" );
}
private Type expectedClass;
///
/// number of dimensions if this is an array
///
protected int nDims;
protected bool subclassOk;
public int GetNDims()
{
return nDims;
}
private String descr;
public Type GetExpectedClass()
{
return expectedClass;
}
public override string ToString()
{
return descr;
}
public override bool Validate( object value )
{
if (value == null)
return false;
Type clss = value.GetType();
if (clss == expectedClass)
return true;
return subclassOk && expectedClass.IsAssignableFrom(clss);
}
public override object ValidateValue(object value)
{
if (Validate(value))
return value;
throw new Exception("value not appropriate for " + descr + ": " + value);
}
///
///
///
/// class to use if nDims == 0
/// class to use if nDims > 0
/// number of dimensions, 0 for scalar
/// an appropriate class given nDims.
///
private static Type MkExpectedClass( Type scalarClass, Type arrayClass, int nDims )
{
if ( nDims == 0 )
return scalarClass;
Array tempArray = Array.CreateInstance( arrayClass, 1 );
// Note: About C# jagged arrays
//
for ( int i = 0; i < ( nDims - 1 ); i++ )
tempArray = Array.CreateInstance( tempArray.GetType(), 1 );
return tempArray.GetType();
}
}
}