2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / System / System.Text.RegularExpressions / match.cs
1 //\r
2 // assembly:    System\r
3 // namespace:   System.Text.RegularExpressions\r
4 // file:        match.cs\r
5 //\r
6 // author:      Dan Lewis (dlewis@gmx.co.uk)\r
7 //              (c) 2002\r
8
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29 \r
30 using System;\r
31 \r
32 namespace System.Text.RegularExpressions {\r
33 \r
34         [Serializable]\r
35         public class Capture {\r
36                 public int Index {\r
37                         get { return index; }\r
38                 }\r
39 \r
40                 public int Length {\r
41                         get { return length; }\r
42                 }\r
43 \r
44                 public string Value {\r
45                         get { 
46                                 if (text!= null)
47                                         return text.Substring (index, length); 
48                                 else
49                                         return String.Empty;
50                         }\r
51                 }\r
52 \r
53                 public override string ToString () {\r
54                         return Value;\r
55                 }\r
56 \r
57                 // internal members\r
58 \r
59                 internal Capture (string text) : this (text, 0, 0) { }\r
60 \r
61                 internal Capture (string text, int index, int length) {\r
62                         this.text = text;\r
63                         this.index = index;\r
64                         this.length = length;\r
65                 }\r
66                 \r
67                 internal string Text {\r
68                         get { return text; }\r
69                 }\r
70 \r
71                 // private\r
72 \r
73                 internal int index, length;\r
74                 internal string text;\r
75         }\r
76 \r
77         [Serializable]\r
78         public class Group : Capture {\r
79                 public static Group Synchronized (Group inner) {\r
80                         return inner;   // is this enough?\r
81                 }\r
82 \r
83                 public CaptureCollection Captures {\r
84                         get { return captures; }\r
85                 }\r
86 \r
87                 public bool Success {\r
88                         get { return success; }\r
89                 }\r
90 \r
91                 // internal\r
92 \r
93                 internal Group (string text, int[] caps) : base (text) {\r
94                         this.captures = new CaptureCollection ();\r
95 \r
96                         if (caps == null || caps.Length == 0) {\r
97                                 this.success = false;\r
98                                 return;\r
99                         }\r
100 \r
101                         this.success = true;\r
102                         this.index = caps[0];\r
103                         this.length = caps[1];\r
104                         captures.Add (this);\r
105                         for (int i = 2; i < caps.Length; i += 2)\r
106                                 captures.Add (new Capture (text, caps[i], caps[i + 1]));\r
107                         captures.Reverse ();\r
108                 }\r
109                 \r
110                 internal Group (): base ("")\r
111                 {\r
112                         captures = new CaptureCollection ();\r
113                 }\r
114 \r
115                 private bool success;\r
116                 private CaptureCollection captures;\r
117         }\r
118 \r
119         [Serializable]\r
120         public class Match : Group {\r
121                 public static Match Empty {\r
122                         get { return empty; }\r
123                 }\r
124                 \r
125                 public static Match Synchronized (Match inner) {\r
126                         return inner;   // FIXME need to sync on machine access\r
127                 }\r
128                 \r
129                 public virtual GroupCollection Groups {\r
130                         get { return groups; }\r
131                 }\r
132 \r
133                 public Match NextMatch () {\r
134                         if (this == Empty)\r
135                                 return Empty;\r
136 \r
137                         int scan_ptr = regex.RightToLeft ? Index : Index + Length;\r
138 \r
139                         // next match after an empty match: make sure scan ptr makes progress\r
140                         \r
141                         if (Length == 0)\r
142                                 scan_ptr += regex.RightToLeft ? -1 : +1;\r
143 \r
144                         return machine.Scan (regex, Text, scan_ptr, text_length);\r
145                 }\r
146 \r
147                 public virtual string Result (string replacement) {\r
148                         return ReplacementEvaluator.Evaluate (replacement, this);\r
149                 }\r
150 \r
151                 // internal\r
152 \r
153                 internal Match () : base (null, null) {\r
154                         this.regex = null;\r
155                         this.machine = null;\r
156                         this.text_length = 0;\r
157                         this.groups = new GroupCollection ();\r
158 \r
159                         groups.Add (this);\r
160                 }\r
161                 \r
162                 internal Match (Regex regex, IMachine machine, string text, int text_length, int[][] grps) :\r
163                         base (text, grps[0])\r
164                 {\r
165                         this.regex = regex;\r
166                         this.machine = machine;\r
167                         this.text_length = text_length;\r
168 \r
169                         this.groups = new GroupCollection ();\r
170                         groups.Add (this);\r
171                         for (int i = 1; i < grps.Length; ++ i)\r
172                                 groups.Add (new Group (text, grps[i]));\r
173                 }\r
174 \r
175                 internal Regex Regex {\r
176                         get { return regex; }\r
177                 }\r
178 \r
179                 // private\r
180 \r
181                 private Regex regex;\r
182                 private IMachine machine;\r
183                 private int text_length;\r
184                 private GroupCollection groups;\r
185 \r
186                 private static Match empty = new Match ();\r
187         }\r
188 }\r