// $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(); } } }