summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/__Filters.cs
blob: aabb52d8036332adb970de2ab006b75fce7e73cd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

//
// This class defines the delegate methods for the COM+ implemented filters.
//
// 
//

namespace System {
    using System;
    using System.Reflection;
    using System.Globalization;
    [Serializable]
    internal class __Filters {
        
        // Filters...
        // The following are the built in filters defined for this class.  These
        //  should really be defined as static methods.  They are used in as delegates
        //  which currently doesn't support static methods.  We will change this 
        //  once the compiler supports delegates.
        //
        // Note that it is not possible to make this class static as suggested by 
        // the above comment anymore because of it got marked serializable.

        internal static readonly __Filters Instance = new __Filters();
        
        // FilterAttribute
        //  This method will search for a member based upon the attribute passed in.
        //  filterCriteria -- an Int32 representing the attribute
        internal virtual bool FilterAttribute(MemberInfo m,Object filterCriteria)
        {
            // Check that the criteria object is an Integer object
            if (filterCriteria == null)
                throw new InvalidFilterCriteriaException(Environment.GetResourceString("RFLCT.FltCritInt"));
    
            switch (m.MemberType) 
            {
            case MemberTypes.Constructor:
            case MemberTypes.Method: {

                MethodAttributes criteria = 0;
                try {
                    int i = (int) filterCriteria;
                    criteria = (MethodAttributes) i;
                }
                catch {
                    throw new InvalidFilterCriteriaException(Environment.GetResourceString("RFLCT.FltCritInt"));
                }

                
                MethodAttributes attr;
                if (m.MemberType == MemberTypes.Method)
                    attr = ((MethodInfo) m).Attributes;
                else
                    attr = ((ConstructorInfo) m).Attributes;
                    
                if (((criteria & MethodAttributes.MemberAccessMask) != 0) && (attr & MethodAttributes.MemberAccessMask) != (criteria & MethodAttributes.MemberAccessMask))
                    return false;
                if (((criteria & MethodAttributes.Static) != 0) && (attr & MethodAttributes.Static) == 0)
                    return false;
                if (((criteria & MethodAttributes.Final) != 0) && (attr & MethodAttributes.Final) == 0)
                    return false;
                if (((criteria & MethodAttributes.Virtual) != 0) && (attr & MethodAttributes.Virtual) == 0)
                    return false;
                if (((criteria & MethodAttributes.Abstract) != 0) && (attr & MethodAttributes.Abstract) == 0)
                    return false;
                if (((criteria & MethodAttributes.SpecialName)  != 0) && (attr & MethodAttributes.SpecialName) == 0)
                    return false;
                return true;
            }
            case MemberTypes.Field: 
            {
                FieldAttributes criteria = 0;
                try {
                    int i = (int) filterCriteria;
                    criteria = (FieldAttributes) i;
                }
                catch {
                    throw new InvalidFilterCriteriaException(Environment.GetResourceString("RFLCT.FltCritInt"));
                }

                FieldAttributes attr = ((FieldInfo) m).Attributes;
                if (((criteria & FieldAttributes.FieldAccessMask) != 0) && (attr & FieldAttributes.FieldAccessMask) != (criteria & FieldAttributes.FieldAccessMask))
                    return false;
                if (((criteria & FieldAttributes.Static) != 0) && (attr & FieldAttributes.Static) == 0)
                    return false;
                if (((criteria & FieldAttributes.InitOnly) != 0) && (attr & FieldAttributes.InitOnly) == 0)
                    return false;
                if (((criteria & FieldAttributes.Literal) != 0) && (attr & FieldAttributes.Literal) == 0)
                    return false;
                if (((criteria & FieldAttributes.NotSerialized) != 0) && (attr & FieldAttributes.NotSerialized) == 0)
                    return false;
                if (((criteria & FieldAttributes.PinvokeImpl) != 0) && (attr & FieldAttributes.PinvokeImpl) == 0)
                    return false;
                return true;
            }
            }
    
            return false;
        }
        // FilterName
        // This method will filter based upon the name.  A partial wildcard
        //  at the end of the string is supported.
        //  filterCriteria -- This is the string name
        internal virtual bool FilterName(MemberInfo m,Object filterCriteria)
        {
            // Check that the criteria object is a String object
            if(filterCriteria == null || !(filterCriteria is String))
                throw new InvalidFilterCriteriaException(Environment.GetResourceString("RFLCT.FltCritString"));
    
            // At the moment this fails if its done on a single line....
            String str = ((String) filterCriteria);
            str = str.Trim();
    
            String name = m.Name;
            // Get the nested class name only, as opposed to the mangled one
            if (m.MemberType == MemberTypes.NestedType) 
                name = name.Substring(name.LastIndexOf('+') + 1);
            // Check to see if this is a prefix or exact match requirement
            if (str.Length > 0 && str[str.Length - 1] == '*') {
                str = str.Substring(0, str.Length - 1);
                return (name.StartsWith(str, StringComparison.Ordinal));
            }
    
            return (name.Equals(str));
        }
        
        // FilterIgnoreCase
        // This delegate will do a name search but does it with the
        //  ignore case specified.
        internal virtual bool FilterIgnoreCase(MemberInfo m,Object filterCriteria)
        {
            // Check that the criteria object is a String object
            if(filterCriteria == null || !(filterCriteria is String))
                throw new InvalidFilterCriteriaException(Environment.GetResourceString("RFLCT.FltCritString"));
    
            String str = (String) filterCriteria;
            str = str.Trim();
    
            String name = m.Name;
            // Get the nested class name only, as opposed to the mangled one
            if (m.MemberType == MemberTypes.NestedType) 
                name = name.Substring(name.LastIndexOf('+') + 1);
            // Check to see if this is a prefix or exact match requirement
            if (str.Length > 0 && str[str.Length - 1] == '*') {
                str = str.Substring(0, str.Length - 1);
                return (String.Compare(name,0,str,0,str.Length,StringComparison.OrdinalIgnoreCase)==0);
            }
    
            return (String.Compare(str,name, StringComparison.OrdinalIgnoreCase) == 0);
        }
    }
}