* collections.cs: In the indexer, return an empty group if the requested
[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 \r
9 using System;\r
10 \r
11 namespace System.Text.RegularExpressions {\r
12 \r
13         [Serializable]\r
14         public class Capture {\r
15                 public int Index {\r
16                         get { return index; }\r
17                 }\r
18 \r
19                 public int Length {\r
20                         get { return length; }\r
21                 }\r
22 \r
23                 public string Value {\r
24                         get { 
25                                 if (text!= null)
26                                         return text.Substring (index, length); 
27                                 else
28                                         return String.Empty;
29                         }\r
30                 }\r
31 \r
32                 public override string ToString () {\r
33                         return Value;\r
34                 }\r
35 \r
36                 // internal members\r
37 \r
38                 internal Capture (string text) : this (text, 0, 0) { }\r
39 \r
40                 internal Capture (string text, int index, int length) {\r
41                         this.text = text;\r
42                         this.index = index;\r
43                         this.length = length;\r
44                 }\r
45                 \r
46                 internal string Text {\r
47                         get { return text; }\r
48                 }\r
49 \r
50                 // private\r
51 \r
52                 internal int index, length;\r
53                 internal string text;\r
54         }\r
55 \r
56         [Serializable]\r
57         public class Group : Capture {\r
58                 public static Group Synchronized (Group inner) {\r
59                         return inner;   // is this enough?\r
60                 }\r
61 \r
62                 public CaptureCollection Captures {\r
63                         get { return captures; }\r
64                 }\r
65 \r
66                 public bool Success {\r
67                         get { return success; }\r
68                 }\r
69 \r
70                 // internal\r
71 \r
72                 internal Group (string text, int[] caps) : base (text) {\r
73                         this.captures = new CaptureCollection ();\r
74 \r
75                         if (caps == null || caps.Length == 0) {\r
76                                 this.success = false;\r
77                                 return;\r
78                         }\r
79 \r
80                         this.success = true;\r
81                         this.index = caps[0];\r
82                         this.length = caps[1];\r
83                         captures.Add (this);\r
84                         for (int i = 2; i < caps.Length; i += 2)\r
85                                 captures.Add (new Capture (text, caps[i], caps[i + 1]));\r
86                         captures.Reverse ();\r
87                 }\r
88                 \r
89                 internal Group (): base ("")\r
90                 {\r
91                         captures = new CaptureCollection ();\r
92                 }\r
93 \r
94                 private bool success;\r
95                 private CaptureCollection captures;\r
96         }\r
97 \r
98         [Serializable]\r
99         public class Match : Group {\r
100                 public static Match Empty {\r
101                         get { return empty; }\r
102                 }\r
103                 \r
104                 public static Match Synchronized (Match inner) {\r
105                         return inner;   // FIXME need to sync on machine access\r
106                 }\r
107                 \r
108                 public virtual GroupCollection Groups {\r
109                         get { return groups; }\r
110                 }\r
111 \r
112                 public Match NextMatch () {\r
113                         if (this == Empty)\r
114                                 return Empty;\r
115 \r
116                         int scan_ptr = regex.RightToLeft ? Index : Index + Length;\r
117 \r
118                         // next match after an empty match: make sure scan ptr makes progress\r
119                         \r
120                         if (Length == 0)\r
121                                 scan_ptr += regex.RightToLeft ? -1 : +1;\r
122 \r
123                         return machine.Scan (regex, Text, scan_ptr, text_length);\r
124                 }\r
125 \r
126                 public virtual string Result (string replacement) {\r
127                         return ReplacementEvaluator.Evaluate (replacement, this);\r
128                 }\r
129 \r
130                 // internal\r
131 \r
132                 internal Match () : base (null, null) {\r
133                         this.regex = null;\r
134                         this.machine = null;\r
135                         this.text_length = 0;\r
136                         this.groups = new GroupCollection ();\r
137 \r
138                         groups.Add (this);\r
139                 }\r
140                 \r
141                 internal Match (Regex regex, IMachine machine, string text, int text_length, int[][] grps) :\r
142                         base (text, grps[0])\r
143                 {\r
144                         this.regex = regex;\r
145                         this.machine = machine;\r
146                         this.text_length = text_length;\r
147 \r
148                         this.groups = new GroupCollection ();\r
149                         groups.Add (this);\r
150                         for (int i = 1; i < grps.Length; ++ i)\r
151                                 groups.Add (new Group (text, grps[i]));\r
152                 }\r
153 \r
154                 internal Regex Regex {\r
155                         get { return regex; }\r
156                 }\r
157 \r
158                 // private\r
159 \r
160                 private Regex regex;\r
161                 private IMachine machine;\r
162                 private int text_length;\r
163                 private GroupCollection groups;\r
164 \r
165                 private static Match empty = new Match ();\r
166         }\r
167 }\r