[bcl] Rename aot_hybrid profile to testing_aot_hybrid
[mono.git] / mcs / class / System.Web.Services / System.Web.Services.Protocols / PatternMatcher.cs
1 // 
2 // System.Web.Services.Protocols.PatternMatcher.cs
3 //
4 // Author:
5 //   Tim Coleman (tim@timcoleman.com)
6 //
7 // Copyright (C) Tim Coleman, 2002
8 //
9
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31 using System.Web.Services;
32 using System.Reflection;
33 using System.Text.RegularExpressions;
34 using System.Collections;
35
36 namespace System.Web.Services.Protocols 
37 {
38         public sealed class PatternMatcher 
39         {
40                 Type _returnType;
41                 MatchInfo[] _matchInfos;
42                 
43                 public PatternMatcher (Type type) 
44                 {
45                         _returnType = type;
46                         
47                         FieldInfo[] fields = type.GetFields ();
48                         ArrayList matchInfos = new ArrayList ();
49                         
50                         foreach (FieldInfo field in fields)
51                         {
52                                 object[] ats = field.GetCustomAttributes (typeof(MatchAttribute), true);
53                                 if (ats.Length == 0) continue;
54                                 
55                                 MatchInfo mi = new MatchInfo ();
56                                 mi.Field = field;
57                                 mi.Match = (MatchAttribute) ats[0];
58                                 
59                                 RegexOptions opts = RegexOptions.Multiline;
60                                 if (mi.Match.IgnoreCase) opts |= RegexOptions.IgnoreCase;
61                                 mi.Regex = new Regex (mi.Match.Pattern, opts);
62                                 
63                                 matchInfos.Add (mi);
64                         }
65                         _matchInfos = (MatchInfo[]) matchInfos.ToArray (typeof(MatchInfo));
66                 }
67                 
68                 public object Match (string text)
69                 {
70                         object ob = Activator.CreateInstance (_returnType);
71                         
72                         foreach (MatchInfo mi in _matchInfos)
73                         {
74                                 MatchCollection matches = mi.Regex.Matches (text);
75                                 
76                                 object res = null;
77                                 
78                                 if (mi.Field.FieldType.IsArray)
79                                 {
80                                         int max = mi.Match.MaxRepeats;
81                                         if (max == -1) max = matches.Count;
82                                         
83                                         Type elemType = mi.Field.FieldType.GetElementType();
84                                         Array array = Array.CreateInstance (elemType, max);
85                                         for (int n=0; n<max; n++)
86                                                 array.SetValue (mi.GetMatchValue (matches[n], elemType), n);
87                                         res = array;
88                                 }
89                                 else if (matches.Count > 0)
90                                         res = mi.GetMatchValue (matches[0], mi.Field.FieldType);
91                                         
92                                 mi.Field.SetValue (ob, res);
93                         }
94                         return ob;
95                 }
96
97         }
98
99         class MatchInfo
100         {
101                 public FieldInfo Field;
102                 public MatchAttribute Match;
103                 public Regex Regex;
104                 
105                 const string GroupError = "{0} is not a valid group index for match '{1}'. The highest valid group index for this match is {2}";
106                 const string CaptureError = "{0} is not a valid capture index for match '{1}'. The highest valid capture index for this match is {2}";
107                 
108                 public object GetMatchValue (Match match, Type castType)
109                 {
110                         if (Match.Group >= match.Groups.Count)
111                                 throw new Exception (string.Format (GroupError, Match.Group, Field.Name, match.Groups.Count-1));
112                                 
113                         Group group = match.Groups [Match.Group];
114                         if (Match.Capture >= group.Captures.Count)
115                                 throw new Exception (string.Format (CaptureError, Match.Capture, Field.Name, group.Captures.Count-1));
116                                 
117                         string val = group.Captures [Match.Capture].Value;
118                         return Convert.ChangeType (val, castType);
119                 }
120         }
121
122 }