SocketTest.ConnectMultiple() for Mac OS.
[mono.git] / mcs / class / System / System.Text.RegularExpressions / BaseMachine.cs
1 //\r
2 // BaseMachine.cs\r
3 //\r
4 // Author:\r
5 // author:      Dan Lewis (dlewis@gmx.co.uk)\r
6 //              (c) 2002\r
7 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)\r
8 //\r
9 \r
10 //\r
11 // Permission is hereby granted, free of charge, to any person obtaining\r
12 // a copy of this software and associated documentation files (the\r
13 // "Software"), to deal in the Software without restriction, including\r
14 // without limitation the rights to use, copy, modify, merge, publish,\r
15 // distribute, sublicense, and/or sell copies of the Software, and to\r
16 // permit persons to whom the Software is furnished to do so, subject to\r
17 // the following conditions:\r
18 //\r
19 // The above copyright notice and this permission notice shall be\r
20 // included in all copies or substantial portions of the Software.\r
21 //\r
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
29 //\r
30 \r
31 using System;\r
32 using System.Collections;\r
33 using System.Collections.Specialized;\r
34 using System.Collections.Generic;\r
35 \r
36 namespace System.Text.RegularExpressions\r
37 {\r
38         abstract class BaseMachine : IMachine\r
39         {\r
40                 internal delegate void MatchAppendEvaluator (Match match, StringBuilder sb);\r
41 \r
42                 public virtual string Replace (Regex regex, string input, string replacement, int count, int startat)\r
43                 {\r
44                         ReplacementEvaluator ev = new ReplacementEvaluator (regex, replacement);\r
45                         if (regex.RightToLeft)\r
46                                 return RTLReplace (regex, input, new MatchEvaluator (ev.Evaluate), count, startat);\r
47                         else\r
48                                 return LTRReplace (regex, input, new MatchAppendEvaluator (ev.EvaluateAppend), count, startat, ev.NeedsGroupsOrCaptures);\r
49                 }\r
50 \r
51                 virtual public string [] Split (Regex regex, string input, int count, int startat)\r
52                 {\r
53                         var splits = new List<string> ();\r
54                         if (count == 0)\r
55                                 count = Int32.MaxValue;\r
56 \r
57                         int ptr = startat;\r
58                         Match m = null;\r
59                         while (--count > 0) {\r
60                                 if (m != null)\r
61                                         m = m.NextMatch ();\r
62                                 else\r
63                                         m = regex.Match (input, ptr);\r
64 \r
65                                 if (!m.Success)\r
66                                         break;\r
67 \r
68                                 if (regex.RightToLeft)\r
69                                         splits.Add (input.Substring (m.Index + m.Length, ptr - m.Index - m.Length));\r
70                                 else\r
71                                         splits.Add (input.Substring (ptr, m.Index - ptr));\r
72 \r
73                                 int gcount = m.Groups.Count;\r
74                                 for (int gindex = 1; gindex < gcount; gindex++) {\r
75                                         Group grp = m.Groups [gindex];\r
76                                         if (grp.Length > 0)\r
77                                                 splits.Add (input.Substring (grp.Index, grp.Length));\r
78                                 }\r
79 \r
80                                 if (regex.RightToLeft)\r
81                                         ptr = m.Index;\r
82                                 else\r
83                                         ptr = m.Index + m.Length;\r
84 \r
85                         }\r
86 \r
87                         if (regex.RightToLeft && ptr >= 0)\r
88                                 splits.Add (input.Substring (0, ptr));\r
89                         if (!regex.RightToLeft && ptr <= input.Length)\r
90                                 splits.Add (input.Substring (ptr));\r
91 \r
92                         return splits.ToArray ();
93                 }\r
94 \r
95                 virtual public Match Scan (Regex regex, string text, int start, int end)\r
96                 {\r
97                         throw new NotImplementedException ("Scan method must be implemented in derived classes");\r
98                 }\r
99 \r
100                 virtual public string Result (string replacement, Match match)\r
101                 {\r
102                         return ReplacementEvaluator.Evaluate (replacement, match);\r
103                 }\r
104 \r
105                 internal string LTRReplace (Regex regex, string input, MatchAppendEvaluator evaluator, int count, int startat) {\r
106                         return LTRReplace (regex, input, evaluator, count, startat, true);\r
107                 }\r
108 \r
109                 internal string LTRReplace (Regex regex, string input, MatchAppendEvaluator evaluator, int count, int startat, bool needs_groups_or_captures)\r
110                 {\r
111                         this.needs_groups_or_captures = needs_groups_or_captures;\r
112                         \r
113                         Match m = Scan (regex, input, startat, input.Length);\r
114                         if (!m.Success)\r
115                                 return input;\r
116 \r
117                         StringBuilder result = new StringBuilder (input.Length);\r
118                         int ptr = startat;\r
119                         int counter = count;\r
120 \r
121                         result.Append (input, 0, ptr);\r
122 \r
123                         do {\r
124                                 if (count != -1)\r
125                                         if (counter-- <= 0)\r
126                                                 break;\r
127                                 if (m.Index < ptr)\r
128                                         throw new SystemException ("how");\r
129                                 result.Append (input, ptr, m.Index - ptr);\r
130                                 evaluator (m, result);\r
131 \r
132                                 ptr = m.Index + m.Length;\r
133                                 m = m.NextMatch ();\r
134                         } while (m.Success);\r
135 \r
136                         result.Append (input, ptr, input.Length - ptr);\r
137 \r
138                         return result.ToString ();\r
139                 }\r
140 \r
141                 internal string RTLReplace (Regex regex, string input, MatchEvaluator evaluator, int count, int startat)\r
142                 {\r
143                         Match m = Scan (regex, input, startat, input.Length);\r
144                         if (!m.Success)\r
145                                 return input;\r
146 \r
147                         int ptr = startat;\r
148                         int counter = count;\r
149 #if NET_2_1\r
150                         var pieces = new System.Collections.Generic.List<string> ();\r
151 #else\r
152                         StringCollection pieces = new StringCollection ();\r
153 #endif\r
154                         \r
155                         pieces.Add (input.Substring (ptr));\r
156 \r
157                         do {\r
158                                 if (count != -1)\r
159                                         if (counter-- <= 0)\r
160                                                 break;\r
161                                 if (m.Index + m.Length > ptr)\r
162                                         throw new SystemException ("how");\r
163                                 pieces.Add (input.Substring (m.Index + m.Length, ptr - m.Index - m.Length));\r
164                                 pieces.Add (evaluator (m));\r
165 \r
166                                 ptr = m.Index;\r
167                                 m = m.NextMatch ();\r
168                         } while (m.Success);\r
169 \r
170                         StringBuilder result = new StringBuilder ();\r
171 \r
172                         result.Append (input, 0, ptr);\r
173                         for (int i = pieces.Count; i > 0; )\r
174                                 result.Append (pieces [--i]);\r
175 \r
176                         pieces.Clear ();\r
177 \r
178                         return result.ToString ();\r
179                 }\r
180 \r
181                 // Specify whenever Match objects created by this machine need to be fully\r
182                 // built. If false, these can be omitted, avoiding some memory allocations and\r
183                 // processing time.\r
184                 protected bool needs_groups_or_captures = true; \r
185         }\r
186 }\r