CustomAttribute.cs :  » Aspect-Oriented-Frameworks » Runtime-Assembly-Instrumentation-Library » rail » Reflect » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Aspect Oriented Frameworks » Runtime Assembly Instrumentation Library 
Runtime Assembly Instrumentation Library » rail » Reflect » CustomAttribute.cs
/*
  The contents of this file are subject to the Mozilla Public License Version 1.1 (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.mozilla.org/MPL/ 
  Software distributed under the License is distributed on an "AS IS" basis, 
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language 
  governing rights and limitations under the License. 

  The Original Code is RAIL(Runtime Assembly Instrumentation Library) Alpha Version.
  The Initial Developer of the Original Code is University of Coimbra,
  Computer Science Department, Dependable Systems Group. Copyright (C) University of Coimbra. 
  All Rights Reserved.  
*/
using System;
using System.Reflection;
using System.Collections;
using Mono.PEToolkit;
using Mono.PEToolkit.Metadata;
using System.Text;

namespace Rail.Reflect{
  /// <summary>
  /// Represents a custom attribute.
  /// </summary>
  /// <remarks>
  /// Elements of a C# program that support custom attributes:
  /// assembly, module, type, field, method, method parameter, 
  /// method return value, property, and event.
  /// 
  ///  The purpose of this class is to:
  ///   - Create new CustomAttributes instances
  ///   - Change existing instances (its fields, the arguments 
  ///   for the constructor, the arguments of the properties)
  ///   
  ///   Therefore, it must be possible to:
  ///   - Obtain RCustomAttrib objects from existing types
  ///   - Change its values.
  ///</remarks>  
  /// This class is not called RCustomAttrib because .Net conventions state
  /// that classes ending in Attribute should be custom attributes.
  public class RCustomAttrib
  {
    #region fields
    /// <summary>
    /// 
    /// </summary>
    protected RConstructor customAttributeCtor;
//    /// <summary>
//    /// 
//    /// </summary>
//    protected Object ctorArgs;
    /// <summary>
    /// 
    /// </summary>
    protected byte [] customAttributeData;
    /// <summary>
    /// 
    /// </summary>
    protected ArrayList customAttributeProp;
    /// <summary>
    /// 
    /// </summary>
    protected ArrayList propertyValues;
    /// <summary>
    /// 
    /// </summary>
    protected ArrayList customAttributeFields;
    /// <summary>
    /// 
    /// </summary>
    protected ArrayList fieldsValues;
    /// <summary>
    /// 
    /// </summary>
    protected Object[] constructorArguments;

    private RAssemblyDef rAssemblyDef;
    #endregion
    
    /// <summary>
    /// Initializes a new instance of the custom attribute. To build this object
    /// it is necessary to provide all the required information to instantiate
    /// a new instance of the underlying custom attribute class. So, if this
    /// object represents an instance of AssemblyCultureInformation it is
    /// necessary to provide its constructor and the arguments to be used to 
    /// initialize it. Use the other overloaded version of this constructor
    /// to initialize the properties and fields of the attribute instance.
    /// </summary>
    /// <param name="customAttributeCtor"></param>
    /// <param name="ctorArgs"></param>
//    public RCustomAttrib(RConstructor customAttributeCtor, Object ctorArgs)
//    {
//      this.customAttributeCtor = customAttributeCtor;
//      this.ctorArgs = ctorArgs;
//    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="customAttributeCtor"></param>
    /// <param name="customAttributeData"></param>
    public RCustomAttrib(RConstructor customAttributeCtor, byte [] customAttributeData, RAssemblyDef rAssemblyDef)
    {
      this.customAttributeCtor = customAttributeCtor;
      this.customAttributeData = customAttributeData;
      this.rAssemblyDef = rAssemblyDef;

      if (this.customAttributeCtor != null &&
        this.customAttributeCtor.ParametersCount > 0 &&
        this.customAttributeData != null &&
        this.customAttributeData.Length > 0)
      {
        int offset = 0;
        if (LEBitConverter.ToInt16(this.customAttributeData,offset) != 0x0001)
          throw new InvalidProgramException("Invalid Prolog in Custom attribute value blob");
        offset += 2;
        this.constructorArguments = new Object[this.customAttributeCtor.ParametersCount];
        for (int i = 1; i <= this.customAttributeCtor.ParametersCount; i++)
        {
          RParameter currParameter = this.customAttributeCtor.GetParameter(i) as RParameter;
          if (currParameter.ParameterType.IsArray)
          {
            int arraySize = LEBitConverter.ToInt32(this.customAttributeData,offset);
            offset += 4;
            object [] objectArray = new object[arraySize];
            for (int j=0; j<arraySize; j++)
            {
              objectArray[j] = GetElem(currParameter,this.customAttributeData,out offset,offset);
            }
            this.constructorArguments[i-1] = objectArray;

          }
          else
          {
            this.constructorArguments[i-1] = GetElem(currParameter,this.customAttributeData,out offset,offset);
          }
        }
        this.customAttributeFields = new ArrayList();
        this.customAttributeProp = new ArrayList();
        this.fieldsValues = new ArrayList();
        this.propertyValues = new ArrayList();
        int NumNamed = LEBitConverter.ToInt16(this.customAttributeData,offset);
        offset += 2;
        int stringSize = 0;
        byte [] data_array;
        string name;
        if (NumNamed>0)
        {
          for (int j=0; j<NumNamed; j++)
          {
            if (this.customAttributeData[offset]==0x53)
            {
              //Field
              ++offset;
              RFieldDef field = new RFieldDef();
              field.DeclaringType = this.AttributeConstructor.DeclaringType;
              ElementType FieldOrPropType = (ElementType)this.customAttributeData[offset];
              switch (FieldOrPropType)
              {
                case ElementType.Boolean:
                  field.FieldType = this.rAssemblyDef.GetRTypeRef(typeof(System.Boolean));
                  break;
                case ElementType.Char:
                  field.FieldType = this.rAssemblyDef.GetRTypeRef(typeof(System.Char));
                  break;
                case ElementType.I1:
                  field.FieldType = this.rAssemblyDef.GetRTypeRef(typeof(System.SByte));
                  break;
                case ElementType.I2:
                  field.FieldType = this.rAssemblyDef.GetRTypeRef(typeof(System.Int16));
                  break;
                case ElementType.I4:
                  field.FieldType = this.rAssemblyDef.GetRTypeRef(typeof(System.Int32));
                  break;
                case ElementType.I8:
                  field.FieldType = this.rAssemblyDef.GetRTypeRef(typeof(System.Int64));
                  break;
                case ElementType.U1:
                  field.FieldType = this.rAssemblyDef.GetRTypeRef(typeof(System.Byte));
                  break;
                case ElementType.U2:
                  field.FieldType = this.rAssemblyDef.GetRTypeRef(typeof(System.UInt16));
                  break;
                case ElementType.U4:
                  field.FieldType = this.rAssemblyDef.GetRTypeRef(typeof(System.UInt32));
                  break;
                case ElementType.U8:
                  field.FieldType = this.rAssemblyDef.GetRTypeRef(typeof(System.UInt64));
                  break;
                case ElementType.R4:
                  field.FieldType = this.rAssemblyDef.GetRTypeRef(typeof(System.Single));
                  break;
                case ElementType.R8:
                  field.FieldType = this.rAssemblyDef.GetRTypeRef(typeof(System.Double));
                  break;
                case ElementType.String:
                  field.FieldType = this.rAssemblyDef.GetRTypeRef(typeof(System.String));
                  break;
                case ElementType.Type:
                  field.FieldType = this.rAssemblyDef.GetRTypeRef(typeof(System.Type));
                  break;
                case ElementType.Enum:
                  ++offset;
                  stringSize = MetadataSignatures.ReadCompressedInt(this.customAttributeData, out offset,offset);
                  data_array = new byte[stringSize];
                  for (int x=offset; x< stringSize+offset ; x++)
                    data_array[x-offset] = this.customAttributeData[x];
                  name = Encoding.UTF8.GetString(data_array);
                  field.FieldType = this.rAssemblyDef.GetRTypeRef(name);
                  if (field.FieldType==null)
                    field.FieldType = this.rAssemblyDef.RModuleDef.GetType(name);
                  offset += stringSize - 1;
                  break;
              }
              ++offset;
              stringSize = MetadataSignatures.ReadCompressedInt(this.customAttributeData, out offset,offset);
              data_array = new byte[stringSize];
              for (int x=offset; x< stringSize+offset ; x++)
                data_array[x-offset] = this.customAttributeData[x];
              name = Encoding.UTF8.GetString(data_array);
              field.Name = name;
              offset += stringSize;

              if (field.FieldType.IsArray)
              {
                int arraySize = LEBitConverter.ToInt32(this.customAttributeData,offset);
                offset += 4;
                object [] objectArray = new object[arraySize];
                for (int x=0; x<arraySize; x++)
                {
                  objectArray[x] = GetElem(field.FieldType,this.customAttributeData,out offset,offset);
                }
                field.Value = objectArray;

              }
              else
              {
                field.Value = GetElem(field.FieldType,this.customAttributeData,out offset,offset);
              }
              this.fieldsValues.Add(field.Value);
              this.customAttributeFields.Add(field);
            }
            else if (this.customAttributeData[offset]==0x54)
            {
              //Property
              ++offset;
              RPropertyDef property = new RPropertyDef();
              property.DeclaringType = this.AttributeConstructor.DeclaringType;
              ElementType FieldOrPropType = (ElementType)this.customAttributeData[offset];
              switch (FieldOrPropType)
              {
                case ElementType.Boolean:
                  property.PropertyType = this.rAssemblyDef.GetRTypeRef(typeof(System.Boolean));
                  break;
                case ElementType.Char:
                  property.PropertyType = this.rAssemblyDef.GetRTypeRef(typeof(System.Char));
                  break;
                case ElementType.I1:
                  property.PropertyType = this.rAssemblyDef.GetRTypeRef(typeof(System.SByte));
                  break;
                case ElementType.I2:
                  property.PropertyType = this.rAssemblyDef.GetRTypeRef(typeof(System.Int16));
                  break;
                case ElementType.I4:
                  property.PropertyType = this.rAssemblyDef.GetRTypeRef(typeof(System.Int32));
                  break;
                case ElementType.I8:
                  property.PropertyType = this.rAssemblyDef.GetRTypeRef(typeof(System.Int64));
                  break;
                case ElementType.U1:
                  property.PropertyType = this.rAssemblyDef.GetRTypeRef(typeof(System.Byte));
                  break;
                case ElementType.U2:
                  property.PropertyType = this.rAssemblyDef.GetRTypeRef(typeof(System.UInt16));
                  break;
                case ElementType.U4:
                  property.PropertyType = this.rAssemblyDef.GetRTypeRef(typeof(System.UInt32));
                  break;
                case ElementType.U8:
                  property.PropertyType = this.rAssemblyDef.GetRTypeRef(typeof(System.UInt64));
                  break;
                case ElementType.R4:
                  property.PropertyType = this.rAssemblyDef.GetRTypeRef(typeof(System.Single));
                  break;
                case ElementType.R8:
                  property.PropertyType = this.rAssemblyDef.GetRTypeRef(typeof(System.Double));
                  break;
                case ElementType.String:
                  property.PropertyType = this.rAssemblyDef.GetRTypeRef(typeof(System.String));
                  break;
                case ElementType.Type:
                  property.PropertyType = this.rAssemblyDef.GetRTypeRef(typeof(System.Type));
                  break;
                case ElementType.Enum:
                  ++offset;
                  stringSize = MetadataSignatures.ReadCompressedInt(this.customAttributeData, out offset,offset);
                  data_array = new byte[stringSize];
                  for (int x=offset; x< stringSize+offset ; x++)
                    data_array[x-offset] = this.customAttributeData[x];
                  name = Encoding.UTF8.GetString(data_array);
                  property.PropertyType = this.rAssemblyDef.GetRTypeRef(name);
                  if (property.PropertyType==null)
                    property.PropertyType = this.rAssemblyDef.RModuleDef.GetType(name);
                  offset += stringSize - 1;
                  break;
              }
              ++offset;
              stringSize = MetadataSignatures.ReadCompressedInt(this.customAttributeData, out offset,offset);
              data_array = new byte[stringSize];
              for (int x=offset; x< stringSize+offset ; x++)
                data_array[x-offset] = this.customAttributeData[x];
              name = Encoding.UTF8.GetString(data_array);
              property.Name = name;
              offset += stringSize;

              if (property.PropertyType.IsArray)
              {
                int arraySize = LEBitConverter.ToInt32(this.customAttributeData,offset);
                offset += 4;
                object [] objectArray = new object[arraySize];
                for (int x=0; x<arraySize; x++)
                {
                  objectArray[x] = GetElem(property.PropertyType,this.customAttributeData,out offset,offset);
                }
                this.propertyValues.Add(objectArray);

              }
              else
              {
                this.propertyValues.Add(GetElem(property.PropertyType,this.customAttributeData,out offset,offset));
              }
              this.customAttributeProp.Add(property);
            }else
              throw new InvalidProgramException("Unknown NamedArg");
          }
        }
        
      }
    }
    
    private ElemType GetElemType(RParameter rParameter,byte [] stream, out int pos, int posValue)
    {
      return GetElemType(rParameter.ParameterType,stream,out pos,posValue);
    }

    private ElemType GetElemType(RType rParameterType,byte [] stream, out int pos, int posValue)
    {
      pos = posValue;
      if (rParameterType == null)
        throw new NullReferenceException();
      if (rParameterType.NameWithNameSpace.Equals("System.String") ||
        rParameterType.NameWithNameSpace.Equals("System.Type"))
        return ElemType.StringOrType;
//      ElementType FieldOrPropType = (ElementType)stream[pos];
//      switch (FieldOrPropType)
//      {
//        case ElementType.Boolean:
//        case ElementType.Char:
//        case ElementType.I1:
//        case ElementType.I2:
//        case ElementType.I4:
//        case ElementType.I8:
//        case ElementType.U1:
//        case ElementType.U2:
//        case ElementType.U4:
//        case ElementType.U8:
//        case ElementType.R4:
//        case ElementType.R8:
//        case ElementType.String:
//        case ElementType.Type:
//          return ElemType.BoxedValueType;
//      }
      return ElemType.SimpleOrEnum;    
    }

    private Object GetElem(RParameter parameter,byte [] stream, out int pos, int posValue)  
    {
      return GetElem(parameter.ParameterType,stream,out pos,posValue);
    }

    private Object GetElem(RType parameterType,byte [] stream, out int pos, int posValue)
    {
      pos = posValue;
      int inc = 0;
      int stringSize = 0;
      byte[] data_array;
      Type t;
      switch (GetElemType(parameterType,stream, out pos,pos))
      {
        case ElemType.SimpleOrEnum:
          #region SimpleOrEnum
          if (parameterType.NameWithNameSpace.Equals("System.Boolean"))
          {
            if (stream[pos]==0x00)
            {
              ++pos;
              return false;
            }
            else if (stream[pos]==0x01)
            {
              ++pos;
              return true;
            }
            else 
              throw new InvalidOperationException("Not a bool values");
          }
          else if (parameterType.NameWithNameSpace.Equals("System.Char"))
          {
            ++pos;
            return (char)stream[pos-1];
          }
          else if (parameterType.NameWithNameSpace.Equals("System.Single"))
          {
            Single s = BitConverter.ToSingle(stream,pos);
            pos += 4;
            return s;
          }
          else if (parameterType.NameWithNameSpace.Equals("System.Double"))
          {
            Double d = BitConverter.ToDouble(stream,pos);
            pos += 8;
            return d;
          }
          else if (parameterType.NameWithNameSpace.Equals("System.Int16"))
          {
            inc = 2;
            pos += inc;
            return LEBitConverter.ToInt16(stream,pos - inc);
          }
          else if (parameterType.NameWithNameSpace.Equals("System.Int32"))
          {
            inc = 4;
            pos += inc;
            return LEBitConverter.ToInt32(stream,pos - inc);
          }
          else if (parameterType.NameWithNameSpace.Equals("System.Int64"))
          {
            inc = 8;
            pos += inc;
            return LEBitConverter.ToInt64(stream,pos - inc);
          }
          else if (parameterType.NameWithNameSpace.Equals("System.UInt16"))
          {
            inc = 2;
            pos += inc;
            return LEBitConverter.ToUInt16(stream,pos - inc);
          }
          else if (parameterType.NameWithNameSpace.Equals("System.UInt32"))
          {
            inc = 4;
            pos += inc;
            return LEBitConverter.ToUInt32(stream,pos - inc);
          }
          else if (parameterType.NameWithNameSpace.Equals("System.UInt64"))
          {
            inc = 8;
            pos += inc;
            return LEBitConverter.ToUInt64(stream,pos - inc);
          }
          else 
          {
            RType rt = rAssemblyDef.RModuleDef.GetType(parameterType.NameWithNameSpace);
            RField f;
            if (rt==null)
            {
              //Type enumType = Type.GetType(parameterType.NameWithNameSpace);
              //rt = new RTypeRef(enumType.Name,enumType.Namespace,this.rAssemblyDef);
              //((RTypeRef)rt).CompleteRTypeRef(enumType,this.rAssemblyDef);

              rt = this.rAssemblyDef.GetRTypeRef(parameterType.NameWithNameSpace);
              f = ((RTypeRef)rt).GetField("value__");
            }else
              f = rt.GetField("value__");
            RType fieldType = f.FieldType;
            if (fieldType.NameWithNameSpace.Equals("System.Boolean"))
            {
              if (stream[pos]==0x00)
              {
                ++pos;
                return false;
              }
              else if (stream[pos]==0x01)
              {
                ++pos;
                return true;
              }
              else 
                throw new InvalidOperationException("Not a bool values");
            }
            else if (fieldType.NameWithNameSpace.Equals("System.Char"))
            {
              ++pos;
              return (char)stream[pos-1];
            }
            else if (fieldType.NameWithNameSpace.Equals("System.Single"))
            {
              Single s = BitConverter.ToSingle(stream,pos);
              pos += 4;
              return s;
            }
            else if (fieldType.NameWithNameSpace.Equals("System.Double"))
            {
              Double d = BitConverter.ToDouble(stream,pos);
              pos += 8;
              return d;
            }
            else if (fieldType.NameWithNameSpace.Equals("System.Int16"))
            {
              inc = 2;
              pos += inc;
              return LEBitConverter.ToInt16(stream,pos - inc);
            }
            else if (fieldType.NameWithNameSpace.Equals("System.Int32"))
            {
              inc = 4;
              pos += inc;
              return LEBitConverter.ToInt32(stream,pos - inc);
            }
            else if (fieldType.NameWithNameSpace.Equals("System.Int64"))
            {
              inc = 8;
              pos += inc;
              return LEBitConverter.ToInt64(stream,pos - inc);
            }
            else if (fieldType.NameWithNameSpace.Equals("System.UInt16"))
            {
              inc = 2;
              pos += inc;
              return LEBitConverter.ToUInt16(stream,pos - inc);
            }
            else if (fieldType.NameWithNameSpace.Equals("System.UInt32"))
            {
              inc = 4;
              pos += inc;
              return LEBitConverter.ToUInt32(stream,pos - inc);
            }
            else if (fieldType.NameWithNameSpace.Equals("System.UInt64"))
            {
              inc = 8;
              pos += inc;
              return LEBitConverter.ToUInt64(stream,pos - inc);
            }
            else
              throw new InvalidProgramException("Not a valid type");
          }
          #endregion
        case ElemType.StringOrType:
          #region StringOrType
          if (parameterType.NameWithNameSpace.Equals("System.String"))
          {
            stringSize = MetadataSignatures.ReadCompressedInt(this.customAttributeData, out pos,pos);
            data_array = new byte[stringSize];
            for (int j=pos; j< stringSize+pos ; j++)
              data_array[j-pos] = stream[j];
            pos += stringSize;
            return Encoding.UTF8.GetString(data_array);
          }
          else if (parameterType.NameWithNameSpace.Equals("System.Type"))
          {
            stringSize = MetadataSignatures.ReadCompressedInt(this.customAttributeData, out pos,pos);
            data_array = new byte[stringSize];
            for (int j=pos; j< stringSize+pos ; j++)
              data_array[j-pos] = stream[j];
            string typeName = Encoding.UTF8.GetString(data_array);
            pos += stringSize;
            RType rt;
            if (typeName.IndexOf(",")>=0)
            {
              t = Type.GetType(typeName);
              rt = this.rAssemblyDef.GetRTypeRef(t);
              return rt;
            }
            t = Type.GetType(typeName);
            if (t == null)
              rt = this.rAssemblyDef.RModuleDef.GetType(typeName);
            else 
              rt = this.rAssemblyDef.GetRTypeRef(t);
            //pos += stringSize;
            return rt;    
          }
          #endregion
          break;
        case ElemType.BoxedValueType:
          #region boxedValueType
          ElementType FieldOrPropType = (ElementType)stream[pos];
          ++pos;
        switch (FieldOrPropType)
        {
          case ElementType.Boolean:
            if (stream[pos]==0x00)
            {
              ++pos;
              return false;
            }
            else if (stream[pos]==0x01)
            {
              ++pos;
              return true;
            }
            else 
              throw new InvalidOperationException("Not a bool values");
          case ElementType.Char:
            ++pos;
            return (char)stream[pos-1];
          case ElementType.I1:
            pos += 1;
            return (int)stream[pos - 1];
          case ElementType.I2:
            pos += 2;
            return LEBitConverter.ToInt16(stream, pos - 2);
          case ElementType.I4:
            pos += 4;
            return LEBitConverter.ToInt32(stream, pos - 4);
          case ElementType.I8:
            pos += 8;
            return LEBitConverter.ToInt64(stream, pos - 8);
          case ElementType.U1:
            pos += 1;
            return (int)stream[pos - 1];
          case ElementType.U2:
            pos += 2;
            return LEBitConverter.ToUInt16(stream, pos - 2);
          case ElementType.U4:
            pos += 4;
            return LEBitConverter.ToUInt32(stream, pos - 4);
          case ElementType.U8:
            pos += 8;
            return LEBitConverter.ToUInt64(stream, pos - 8);
          case ElementType.R4:
            pos += 4;
            return BitConverter.ToSingle(stream,pos - 4);
          case ElementType.R8:
            pos += 8;
            return BitConverter.ToSingle(stream,pos - 8);
          case ElementType.String:
            stringSize = MetadataSignatures.ReadCompressedInt(this.customAttributeData, out pos,pos);
            data_array = new byte[stringSize];
            for (int j=pos; j< stringSize+pos ; j++)
              data_array[j-pos] =stream[j];
            pos += stringSize;
            return Encoding.UTF8.GetString(data_array);
          case ElementType.Type:
            stringSize = MetadataSignatures.ReadCompressedInt(this.customAttributeData, out pos,pos);
            data_array = new byte[stringSize];
            for (int j=pos; j< stringSize+pos ; j++)
              data_array[j-pos] = stream[j];
            string typeName = Encoding.UTF8.GetString(data_array);
            pos += stringSize;
            RType rt;
            if (typeName.IndexOf(",")>=0)
            {
              t = Type.GetType(typeName);
              rt = this.rAssemblyDef.GetRTypeRef(t);
              return rt;
            }
            t = Type.GetType(typeName);
            if (t == null)
              rt = this.rAssemblyDef.RModuleDef.GetType(typeName);
            else 
              rt = this.rAssemblyDef.GetRTypeRef(t);
            return rt;
        }
          #endregion
          break;
      }
      throw new NullReferenceException("Argument not found");
    }

    private enum ElemType
    {
      SimpleOrEnum,
      StringOrType,
      BoxedValueType
    }


    /// <summary>
    /// 
    /// </summary>
    /// <param name="customAttributeCtor"></param>
    /// <param name="ctorArgs"></param>
    /// <param name="customAttributeProp"></param>
    /// <param name="propertyValues"></param>
    /// <param name="customAttributeFields"></param>
    /// <param name="fieldsValues"></param>
//    public RCustomAttrib(RConstructor customAttributeCtor, Object ctorArgs,
//      RProperty[] customAttributeProp, Object[] propertyValues,
//      RField[] customAttributeFields, Object[] fieldsValues) 
//    {
//      this.customAttributeCtor = customAttributeCtor;
//      this.ctorArgs = ctorArgs;
//      this.customAttributeProp = customAttributeProp;
//      this.propertyValues = propertyValues;
//      this.customAttributeFields = customAttributeFields;
//      this.fieldsValues = fieldsValues;
//    }

    /// <summary>
    /// Gets or sets the constructor used to create the custom attribute.
    /// </summary>
    public RConstructor AttributeConstructor 
    {
      get 
      {
        return this.customAttributeCtor;
      }
      set 
      {
        this.customAttributeCtor = value;
      }
    }

    /// <summary>
    /// Gets or sets the data used to create the custom attribute.
    /// </summary>
    public byte [] AttributeData
    {
      get 
      {
        return this.customAttributeData;
      }
      set 
      {
        this.customAttributeData = value;
      }
    }

    /// <summary>
    /// Returns the type of the custom attribute represented by this object. 
    /// This is obtained from the constructor and is changed only when the
    /// constructor is changed.
    /// </summary>
    public RType CustomAttributeType 
    {
      get 
      {
        return this.customAttributeCtor.DeclaringType;
      }
    }

    /// <summary>
    /// Gets the constructor arguments. The constructor will be called with
    /// these arguments when the assembly containing this attribute is
    /// created.
    /// </summary>
    /// <returns></returns>
    public Object[] GetAttributeConstructorArguments() 
    {
      return this.constructorArguments;
    }

    /// <summary>
    /// Sets the constructor arguments.
    /// </summary>
    /// <param name="args"></param>
    public void SetAttributeConstructorArguments(Object[] args) 
    {
      this.constructorArguments = args;
    }

  
    /// <summary>
    /// Get the properties array
    /// </summary>
    /// <returns></returns>
    public RProperty [] GetProperties()
    {
      if (this.customAttributeProp==null)
        return null;
      RProperty [] rp = new RProperty[this.customAttributeProp.Count];
      int i = 0;
      while (i<this.customAttributeProp.Count)
      {
        rp[i] = this.customAttributeProp[i] as RProperty;
        ++i;
      }
      return rp;
    }
    
    /// <summary>
    /// Get the fields array
    /// </summary>
    /// <returns></returns>
    public RField [] GetFields()
    {
      if (this.customAttributeFields==null)
        return null;
      RField [] rf = new RField[this.customAttributeFields.Count];
      int i = 0;
      while (i<this.customAttributeFields.Count)
      {
        rf[i] = this.customAttributeFields[i] as RField;
        ++i;
      }
      return rf;
    }

    /// <summary>
    /// Get values for the properties
    /// </summary>
    /// <returns></returns>
    public Object [] GetPropertiesValues()
    {
      if (this.propertyValues==null)
        return null;
      Object [] obj = new Object[this.propertyValues.Count];
      int i = 0;
      while (i<this.propertyValues.Count)
      {
        obj[i] = this.propertyValues[i] as Object;
        ++i;
      }
      return obj;
    }
    

    /// <summary>
    /// Get values for the fields
    /// </summary>
    /// <returns></returns>
    public Object [] GetFieldsValues()
    {
      if (this.fieldsValues==null)
        return null;
      Object [] obj = new Object[this.fieldsValues.Count];
      int i = 0;
      while (i<this.fieldsValues.Count)
      {
        obj[i] = this.fieldsValues[i] as Object;
        ++i;
      }
      return obj;
    }

    /// <summary>
    /// Set the Properties list
    /// </summary>
    /// <param name="props"></param>
    public void SetProperties(RProperty [] props)
    {
      if (props!=null)
      {
        int i = 0;
        while(i<props.Length)
        {
          this.customAttributeProp.Add(props[i]);
          ++i;
        }
      }
    }

    /// <summary>
    /// Set the fields list
    /// </summary>
    /// <param name="props"></param>
    public void SetProperties(RField [] fields)
    {
      if (fields!=null)
      {
        int i = 0;
        while(i<fields.Length)
        {
          this.customAttributeFields.Add(fields[i]);
          ++i;
        }
      }
    }

    public void SetPropertiesValues(Object [] values)
    {
      if (values!=null)
      {
        int i = 0;
        while(i<values.Length)
        {
          this.propertyValues.Add(values[i]);
          ++i;
        }
      }
    }

    public void SetFieldsValues(Object [] values)
    {
      if (values!=null)
      {
        int i = 0;
        while(i<values.Length)
        {
          this.fieldsValues.Add(values[i]);
          ++i;
        }
      }
    }
    /// <summary>
    /// Obtains the value used to initialize of the given field. The field
    /// must belong to the underlying attribute
    /// </summary>
    /// <param name="cAttrField"></param>
    /// <returns></returns>
//    public Object GetFieldValue(RField customAttrField) 
//    {
//      if (this.customAttributeFields==null) return null;
//      if (this.fieldsValues==null) return null;
//      RField r = null;
//      for (int i = 0; i < this.customAttributeFields.Count;i++)
//      {
//        r = (RField)this.customAttributeFields[i];
//        if (r.Equals(customAttrField))
//        {
//          if (this.fieldsValues.Count>i)
//            return this.fieldsValues[i];
//          else 
//            return null;
//        }
//      }
//      return null;
//    }

    /// <summary>
    /// Sets the value used to initialize the given field.
    /// </summary>
    /// <param name="cAttrField"></param>
    /// <param name="fieldValue"></param>
//    public void SetFieldValue(RField customAttrField, Object fieldValue) 
//    {
//      if (this.customAttributeFields==null) return;
//      RField r = null;
//      for (int i = 0; i < this.customAttributeFields.Count;i++)
//      {
//        r = (RField)this.customAttributeFields[i];
//        if (r.Equals(customAttrField))
//        {
//          if (this.fieldsValues==null)
//            this.fieldsValues = new Object[this.customAttributeFields.Count];
//          if (this.fieldsValues.Count<this.customAttributeFields.Length)
//          {
//            Object [] temp = new Object[this.customAttributeFields.Count];
//            for (int j = 0; j< this.fieldsValues.Count;j++)
//              temp[j] = this.fieldsValues[j];
//            this.fieldsValues = temp;
//          }
//          this.fieldsValues[i] = fieldValue;
//        }
//      }
//      
//    }

    /// <summary>
    ///  Gets the value used to initialize a certain property of the custom attribute.
    /// </summary>
    /// <param name="cAttrProperty"></param>
    /// <returns></returns>
//    public Object GetPropertyValue(RProperty customAttrProperty) 
//    {
//      if (this.customAttributeProp==null) return null;
//      if (this.propertyValues==null) return null;
//      RProperty r = null;
//      for (int i = 0; i < this.customAttributeProp.Length;i++)
//      {
//        r = this.customAttributeProp[i];
//        if (r.Equals(customAttrProperty))
//        {
//          if (this.propertyValues.Length>i)
//            return this.propertyValues[i];
//          else 
//            return null;
//        }
//      }
//      return null;
//    }

    /// <summary>
    /// Sets the value used to initialize a certain property of the custom attribute.
    /// </summary>
    /// <param name="cAttrProperty"></param>
    /// <param name="propertyValue"></param>
//    public void SetPropertyValue(RProperty customAttrProperty, Object propertyValue) 
//    {
//      if (this.customAttributeProp==null) return;
//      RProperty r = null;
//      for (int i = 0; i < this.customAttributeProp.Length;i++)
//      {
//        r = this.customAttributeProp[i];
//        if (r.Equals(customAttrProperty))
//        {
//          if (this.propertyValues==null)
//            this.propertyValues = new Object[this.customAttributeProp.Length];
//          if (this.propertyValues.Length<this.customAttributeProp.Length)
//          {
//            Object [] temp = new Object[this.customAttributeProp.Length];
//            for (int j = 0; j< this.propertyValues.Length;j++)
//              temp[j] = this.propertyValues[j];
//            this.propertyValues = temp;
//          }
//          this.propertyValues[i] = propertyValue;
//        }
//      }
//    }
  }

  /// <summary>
  /// Represents an element that can have custom attributes.
  /// </summary>
  /// <remarks>
  /// </remarks>
  public interface ICustomAttributeOwner 
  {    
    #region ICustomAttributeProvider Methods
    /// <summary>
    /// Gets an array with all custom attributes of defined on this member.
    /// </summary>
    /// <param name="inherit">Whether the hierarchy chain should be searched for
    /// custom attributes</param>
    /// <returns>An array with all the custom attributes defined on this 
    /// member.</returns>
    RCustomAttrib[] GetCustomAttributes(bool inherit);

    /// <summary>
    /// Gets an array with all custom attributes of <i>attributeType</i> defined 
    /// on this member.
    /// </summary>
    /// <param name="attributeType">The type of the custom attribute</param>
    /// <param name="inherit">Whether the hierarchy chain should be searched for the 
    /// custom attribute</param>
    /// <returns>An array with all the custom attributes defined on this member.</returns>
    RCustomAttrib[] GetCustomAttributes(RType attributeType, bool inherit);
    
    /// <summary>
    /// Indicates whether one or more instance of attribute type is defined
    /// on this member.
    /// </summary>
    /// <param name="attributeType">The type of the custom attribute</param>
    /// <param name="inherit">Whether the attribute should be searched in the 
    /// hierarchy chain</param>
    /// <returns><i>True</i> if the attribute is defined on this member.</returns>
    bool IsDefined(RType attributeType,bool inherit);
    #endregion
  }


  /// <summary>
  /// To be implemented by the Ref classes.
  /// </summary>
  public interface ICustomAttributeOwnerDef : ICustomAttributeOwner 
  {
    /// <summary>
    /// Adds a custom attribute to this element
    /// </summary>
    /// <param name="attribute">The attribute to be added.</param>
    void AddCustomAttributtes(RCustomAttrib attribute);

    /// <summary>
    /// Removes the given custom attribute instance from this member.
    /// </summary>
    /// <param name="attribute">The instance of the custom attribute to 
    /// be removed.</param>
    /// <remarks>If the given attribute is not found, this method returns
    /// silently.</remarks>
    void RemoveCustomAttribute(RCustomAttrib attribute);
  }

  /// <summary>
  /// 
  /// </summary>
  public abstract class CustomAttributeOwner : ICustomAttributeOwner 
  {
    #region fields
    /// <summary>
    /// 
    /// </summary>
    private ArrayList customAttributes;
    /// <summary>
    /// 
    /// </summary>
    private IEnumerator iEnum;

    #endregion
    
    /// <summary>
    /// 
    /// </summary>
    /// <param name="inherit"></param>
    /// <returns></returns>
    public virtual RCustomAttrib[] GetCustomAttributes(bool inherit) 
    {
      if (inherit)
        throw new NotImplementedException();
      if (customAttributes==null)
        return new RCustomAttrib[0];
      RCustomAttrib [] rCAttribs = new RCustomAttrib[customAttributes.Count];
      int i = 0;
      foreach (RCustomAttrib r in customAttributes)
      {
        rCAttribs[i] = r;
        ++i;
      }
      return rCAttribs;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="attributeType"></param>
    /// <param name="inherit"></param>
    /// <returns></returns>
    public virtual RCustomAttrib[] GetCustomAttributes(String attributeType, bool inherit) 
    {
      if (inherit)
        throw new NotImplementedException();
      if (customAttributes==null)
        return new RCustomAttrib[0];
      RCustomAttrib [] rCAttribs = new RCustomAttrib[customAttributes.Count];
      int i = 0;
      foreach (RCustomAttrib r in customAttributes)
      {
        if (r.CustomAttributeType.NameWithNameSpace.Equals(attributeType))
        {
          rCAttribs[i] = r;
          ++i;
        }
      }
      RCustomAttrib [] temp = new RCustomAttrib[i];
      for(int j = 0; j < i; j++)
      {
        temp[j] = rCAttribs[j];
      }
      return temp;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="attributeType"></param>
    /// <param name="inherit"></param>
    /// <returns></returns>
    public virtual RCustomAttrib[] GetCustomAttributes(RType attributeType, bool inherit) 
    {
      if (inherit)
        throw new NotImplementedException();
      if (customAttributes==null)
        return new RCustomAttrib[0];
      RCustomAttrib [] rCAttribs = new RCustomAttrib[customAttributes.Count];
      int i = 0;
      foreach (RCustomAttrib r in customAttributes)
      {
        if (r.CustomAttributeType.NameWithNameSpace.Equals(attributeType.NameWithNameSpace))
        {
          rCAttribs[i] = r;
          ++i;
        }
      }
      RCustomAttrib [] temp = new RCustomAttrib[i];
      for(int j = 0; j < i; j++)
      {
        temp[j] = rCAttribs[j];
      }
      return temp;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="attributeType"></param>
    /// <param name="inherit"></param>
    /// <returns></returns>
    public virtual bool IsDefined(RType attributeType,bool inherit) 
    {
      if (inherit)
        throw new NotImplementedException();
      bool retVal = false;
      foreach (RCustomAttrib r in customAttributes)
      {
        if (r.CustomAttributeType.Equals(attributeType))
        {
          retVal = true;
          break;
        }
      }
      return retVal;
    }
    /// <summary>
    /// Adds a custom attribute to this element
    /// </summary>
    /// <param name="attribute">The attribute to be added.</param>
    protected internal void InternalAddCustomAttributtes(RCustomAttrib attribute) 
    {
      if (this.customAttributes==null)
        this.customAttributes = new ArrayList();
      this.customAttributes.Add(attribute);
      this.iEnum = this.customAttributes.GetEnumerator();
    }

    /// <summary>
    /// Removes the given custom attribute instance from this member.
    /// </summary>
    /// <param name="attribute">The instance of the custom attribute to 
    /// be removed.</param>
    /// <remarks>If the given attribute is not found, this method returns
    /// silently.</remarks>
    protected internal void InternalRemoveCustomAttribute(RCustomAttrib attribute) 
    {
      if (this.customAttributes!=null)
        if (this.customAttributes.Contains(attribute))
          this.customAttributes.Remove(attribute);
      this.iEnum = this.customAttributes.GetEnumerator();
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    protected internal bool MoveToNextCustomAttribute()
    {
      if (this.customAttributes==null) return false;
      if (this.iEnum == null)
        this.iEnum = this.customAttributes.GetEnumerator();
      return this.iEnum.MoveNext();
    }

    /// <summary>
    /// 
    /// </summary>
    protected internal RCustomAttrib CurrentCustomAttribute
    {
      get
      {
        if (this.customAttributes==null) return null;
        if (this.iEnum == null) {
          this.iEnum = this.customAttributes.GetEnumerator();
          this.iEnum.MoveNext();
        }
        return (RCustomAttrib)this.iEnum.Current;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    protected internal int CustomAttributeCount
    {
      get
      {
        if (this.customAttributes==null) return 0;
        return this.customAttributes.Count;
      }
    }
  }
}
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.