* MonoTouch/MonoPInvokeCallbackAttribute.cs: Added.
[mono.git] / mcs / class / System / System.Text.RegularExpressions / BaseMachine.cs
index 934cffe756ae9f155d6b556a027e36d5dffe65bd..24a16a19bd6977e479985d5177cb0707cc6768e3 100644 (file)
-//
-// BaseMachine.jvm.cs
-//
-// Author:
-// author:     Dan Lewis (dlewis@gmx.co.uk)
-//             (c) 2002
-// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
-//
-
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System;
-using System.Collections;
-using System.Collections.Specialized;
-
-namespace System.Text.RegularExpressions
-{
-       abstract class BaseMachine : IMachine
-       {
-               internal delegate void MatchAppendEvaluator (Match match, StringBuilder sb);
-
-               public virtual string Replace (Regex regex, string input, string replacement, int count, int startat)
-               {
-                       ReplacementEvaluator ev = new ReplacementEvaluator (regex, replacement);
-                       if (regex.RightToLeft)
-                               return RTLReplace (regex, input, new MatchEvaluator (ev.Evaluate), count, startat);
-                       else
-                               return LTRReplace (regex, input, new MatchAppendEvaluator (ev.EvaluateAppend), count, startat);
-               }
-
-               virtual public string [] Split (Regex regex, string input, int count, int startat)
-               {
-                       ArrayList splits = new ArrayList ();
-                       if (count == 0)
-                               count = Int32.MaxValue;
-
-                       int ptr = startat;
-                       Match m = null;
-                       while (--count > 0) {
-                               if (m != null)
-                                       m = m.NextMatch ();
-                               else
-                                       m = regex.Match (input, ptr);
-
-                               if (!m.Success)
-                                       break;
-
-                               if (regex.RightToLeft)
-                                       splits.Add (input.Substring (m.Index + m.Length, ptr - m.Index - m.Length));
-                               else
-                                       splits.Add (input.Substring (ptr, m.Index - ptr));
-
-                               int gcount = m.Groups.Count;
-                               for (int gindex = 1; gindex < gcount; gindex++) {
-                                       Group grp = m.Groups [gindex];
-                                       splits.Add (input.Substring (grp.Index, grp.Length));
-                               }
-
-                               if (regex.RightToLeft)
-                                       ptr = m.Index;
-                               else
-                                       ptr = m.Index + m.Length;
-
-                       }
-
-                       if (regex.RightToLeft && ptr >= 0)
-                               splits.Add (input.Substring (0, ptr));
-                       if (!regex.RightToLeft && ptr <= input.Length)
-                               splits.Add (input.Substring (ptr));
-
-                       return (string []) splits.ToArray (typeof (string));
-               }
-
-               virtual public Match Scan (Regex regex, string text, int start, int end)
-               {
-                       throw new NotImplementedException ("Scan method must be implemented in derived classes");
-               }
-
-               virtual public string Result (string replacement, Match match)
-               {
-                       return ReplacementEvaluator.Evaluate (replacement, match);
-               }
-
-               internal static string LTRReplace (Regex regex, string input, MatchAppendEvaluator evaluator, int count, int startat)
-               {
-                       StringBuilder result = new StringBuilder ();
-                       int ptr = startat;
-                       int counter = count;
-
-                       result.Append (input, 0, ptr);
-
-                       Match m = regex.Match (input, startat);
-                       while (m.Success) {
-                               if (count != -1)
-                                       if (counter-- <= 0)
-                                               break;
-                               if (m.Index < ptr)
-                                       throw new SystemException ("how");
-                               result.Append (input, ptr, m.Index - ptr);
-                               evaluator (m, result);
-
-                               ptr = m.Index + m.Length;
-                               m = m.NextMatch ();
-                       }
-
-                       if (ptr == startat)
-                               return input;
-
-                       result.Append (input, ptr, input.Length - ptr);
-
-                       return result.ToString ();
-               }
-
-               internal static string RTLReplace (Regex regex, string input, MatchEvaluator evaluator, int count, int startat)
-               {
-                       int ptr = startat;
-                       int counter = count;
-
-                       StringCollection pieces = new StringCollection ();
-                       pieces.Add (input.Substring (ptr));
-
-                       Match m = regex.Match (input, startat);
-                       while (m.Success) {
-                               if (count != -1)
-                                       if (counter-- <= 0)
-                                               break;
-                               if (m.Index + m.Length > ptr)
-                                       throw new SystemException ("how");
-                               pieces.Add (input.Substring (m.Index + m.Length, ptr - m.Index - m.Length));
-                               pieces.Add (evaluator (m));
-
-                               ptr = m.Index;
-                               m = m.NextMatch ();
-                       }
-
-                       if (ptr == startat)
-                               return input;
-
-                       StringBuilder result = new StringBuilder ();
-
-                       result.Append (input, 0, ptr);
-                       for (int i = pieces.Count; i > 0; )
-                               result.Append (pieces [--i]);
-
-                       pieces.Clear ();
-
-                       return result.ToString ();
-               }
-       }
-}
+//\r
+// BaseMachine.cs\r
+//\r
+// Author:\r
+// author:     Dan Lewis (dlewis@gmx.co.uk)\r
+//             (c) 2002\r
+// Copyright (C) 2005 Novell, Inc (http://www.novell.com)\r
+//\r
+\r
+//\r
+// Permission is hereby granted, free of charge, to any person obtaining\r
+// a copy of this software and associated documentation files (the\r
+// "Software"), to deal in the Software without restriction, including\r
+// without limitation the rights to use, copy, modify, merge, publish,\r
+// distribute, sublicense, and/or sell copies of the Software, and to\r
+// permit persons to whom the Software is furnished to do so, subject to\r
+// the following conditions:\r
+//\r
+// The above copyright notice and this permission notice shall be\r
+// included in all copies or substantial portions of the Software.\r
+//\r
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+//\r
+\r
+using System;\r
+using System.Collections;\r
+using System.Collections.Specialized;\r
+\r
+namespace System.Text.RegularExpressions\r
+{\r
+       abstract class BaseMachine : IMachine\r
+       {\r
+               internal delegate void MatchAppendEvaluator (Match match, StringBuilder sb);\r
+\r
+               public virtual string Replace (Regex regex, string input, string replacement, int count, int startat)\r
+               {\r
+                       ReplacementEvaluator ev = new ReplacementEvaluator (regex, replacement);\r
+                       if (regex.RightToLeft)\r
+                               return RTLReplace (regex, input, new MatchEvaluator (ev.Evaluate), count, startat);\r
+                       else\r
+                               return LTRReplace (regex, input, new MatchAppendEvaluator (ev.EvaluateAppend), count, startat, ev.NeedsGroupsOrCaptures);\r
+               }\r
+\r
+               virtual public string [] Split (Regex regex, string input, int count, int startat)\r
+               {\r
+                       ArrayList splits = new ArrayList ();\r
+                       if (count == 0)\r
+                               count = Int32.MaxValue;\r
+\r
+                       int ptr = startat;\r
+                       Match m = null;\r
+                       while (--count > 0) {\r
+                               if (m != null)\r
+                                       m = m.NextMatch ();\r
+                               else\r
+                                       m = regex.Match (input, ptr);\r
+\r
+                               if (!m.Success)\r
+                                       break;\r
+\r
+                               if (regex.RightToLeft)\r
+                                       splits.Add (input.Substring (m.Index + m.Length, ptr - m.Index - m.Length));\r
+                               else\r
+                                       splits.Add (input.Substring (ptr, m.Index - ptr));\r
+\r
+                               int gcount = m.Groups.Count;\r
+                               for (int gindex = 1; gindex < gcount; gindex++) {\r
+                                       Group grp = m.Groups [gindex];\r
+                                       splits.Add (input.Substring (grp.Index, grp.Length));\r
+                               }\r
+\r
+                               if (regex.RightToLeft)\r
+                                       ptr = m.Index;\r
+                               else\r
+                                       ptr = m.Index + m.Length;\r
+\r
+                       }\r
+\r
+                       if (regex.RightToLeft && ptr >= 0)\r
+                               splits.Add (input.Substring (0, ptr));\r
+                       if (!regex.RightToLeft && ptr <= input.Length)\r
+                               splits.Add (input.Substring (ptr));\r
+\r
+                       return (string []) splits.ToArray (typeof (string));\r
+               }\r
+\r
+               virtual public Match Scan (Regex regex, string text, int start, int end)\r
+               {\r
+                       throw new NotImplementedException ("Scan method must be implemented in derived classes");\r
+               }\r
+\r
+               virtual public string Result (string replacement, Match match)\r
+               {\r
+                       return ReplacementEvaluator.Evaluate (replacement, match);\r
+               }\r
+\r
+               internal string LTRReplace (Regex regex, string input, MatchAppendEvaluator evaluator, int count, int startat) {\r
+                       return LTRReplace (regex, input, evaluator, count, startat, true);\r
+               }\r
+\r
+               internal string LTRReplace (Regex regex, string input, MatchAppendEvaluator evaluator, int count, int startat, bool needs_groups_or_captures)\r
+               {\r
+                       this.needs_groups_or_captures = needs_groups_or_captures;\r
+                       \r
+                       Match m = Scan (regex, input, startat, input.Length);\r
+                       if (!m.Success)\r
+                               return input;\r
+\r
+                       StringBuilder result = new StringBuilder (input.Length);\r
+                       int ptr = startat;\r
+                       int counter = count;\r
+\r
+                       result.Append (input, 0, ptr);\r
+\r
+                       do {\r
+                               if (count != -1)\r
+                                       if (counter-- <= 0)\r
+                                               break;\r
+                               if (m.Index < ptr)\r
+                                       throw new SystemException ("how");\r
+                               result.Append (input, ptr, m.Index - ptr);\r
+                               evaluator (m, result);\r
+\r
+                               ptr = m.Index + m.Length;\r
+                               m = m.NextMatch ();\r
+                       } while (m.Success);\r
+\r
+                       result.Append (input, ptr, input.Length - ptr);\r
+\r
+                       return result.ToString ();\r
+               }\r
+\r
+               internal string RTLReplace (Regex regex, string input, MatchEvaluator evaluator, int count, int startat)\r
+               {\r
+                       Match m = Scan (regex, input, startat, input.Length);\r
+                       if (!m.Success)\r
+                               return input;\r
+\r
+                       int ptr = startat;\r
+                       int counter = count;\r
+#if NET_2_1\r
+                       var pieces = new System.Collections.Generic.List<string> ();\r
+#else\r
+                       StringCollection pieces = new StringCollection ();\r
+#endif\r
+                       \r
+                       pieces.Add (input.Substring (ptr));\r
+\r
+                       do {\r
+                               if (count != -1)\r
+                                       if (counter-- <= 0)\r
+                                               break;\r
+                               if (m.Index + m.Length > ptr)\r
+                                       throw new SystemException ("how");\r
+                               pieces.Add (input.Substring (m.Index + m.Length, ptr - m.Index - m.Length));\r
+                               pieces.Add (evaluator (m));\r
+\r
+                               ptr = m.Index;\r
+                               m = m.NextMatch ();\r
+                       } while (m.Success);\r
+\r
+                       StringBuilder result = new StringBuilder ();\r
+\r
+                       result.Append (input, 0, ptr);\r
+                       for (int i = pieces.Count; i > 0; )\r
+                               result.Append (pieces [--i]);\r
+\r
+                       pieces.Clear ();\r
+\r
+                       return result.ToString ();\r
+               }\r
+\r
+               // Specify whenever Match objects created by this machine need to be fully\r
+               // built. If false, these can be omitted, avoiding some memory allocations and\r
+               // processing time.\r
+               protected bool needs_groups_or_captures = true; \r
+       }\r
+}\r