//\r
// author: Dan Lewis (dlewis@gmx.co.uk)\r
// (c) 2002\r
+
+//
+// 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.
+//
\r
using System;\r
\r
[Serializable]\r
public class Capture {\r
public int Index {\r
- get {\r
- if (!IsDefined)\r
- return 0; // capture not completed\r
- else if (start <= end)\r
- return start; // normal capture\r
- else\r
- return end; // reverse capture\r
- }\r
+ get { return index; }\r
}\r
\r
public int Length {\r
- get {\r
- if (!IsDefined)\r
- return 0;\r
- else if (start <= end)\r
- return end - start;\r
- else\r
- return start - end;\r
- }\r
+ get { return length; }\r
}\r
\r
public string Value {\r
- get { return IsDefined ? text.Substring (Index, Length) : ""; }\r
+ get {
+ if (text!= null)
+ return text.Substring (index, length);
+ else
+ return String.Empty;
+ }\r
}\r
\r
public override string ToString () {\r
\r
// internal members\r
\r
- internal Capture () { // empty capture\r
- this.previous = null;\r
- this.text = null;\r
- this.checkpoint = 0;\r
-\r
- this.start = -1;\r
- this.end = -1;\r
- }\r
+ internal Capture (string text) : this (text, 0, 0) { }\r
\r
- internal Capture (Capture cap) { // copy constructor\r
- this.previous = cap.previous;\r
- this.text = cap.text;\r
- this.checkpoint = cap.checkpoint;\r
-\r
- this.start = cap.start;\r
- this.end = cap.end;\r
- }\r
-\r
- internal Capture (string text) { // first capture\r
- this.previous = null;\r
+ internal Capture (string text, int index, int length) {\r
this.text = text;\r
- this.checkpoint = 0;\r
-\r
- this.start = -1;\r
- this.end = -1;\r
+ this.index = index;\r
+ this.length = length;\r
}\r
\r
- internal Capture (Capture previous, int checkpoint) {\r
- this.previous = previous;\r
- this.text = previous.text;\r
- this.checkpoint = checkpoint;\r
-\r
- this.start = -1;\r
- this.end = -1;\r
- }\r
-\r
- internal Capture Previous {\r
- get { return previous; }\r
- }\r
-\r
internal string Text {\r
get { return text; }\r
}\r
\r
- internal int Checkpoint {\r
- get { return checkpoint; }\r
- }\r
-\r
- internal bool IsDefined {\r
- get { return start >= 0 && end >= 0; }\r
- }\r
-\r
- internal Capture GetLastDefined () {\r
- Capture cap = this;\r
- while (cap != null && !cap.IsDefined)\r
- cap = cap.Previous;\r
-\r
- return cap;\r
- }\r
-\r
- internal void Open (int ptr) {\r
- this.start = ptr;\r
- }\r
-\r
- internal void Close (int ptr) {\r
- this.end = ptr;\r
- }\r
-\r
// private\r
\r
- private int start, end;\r
- private string text;\r
- private int checkpoint;\r
- private Capture previous;\r
+ internal int index, length;\r
+ internal string text;\r
}\r
\r
+ [Serializable]\r
public class Group : Capture {\r
public static Group Synchronized (Group inner) {\r
return inner; // is this enough?\r
}\r
\r
public bool Success {\r
- get { return GetLastDefined () != null; }\r
+ get { return success; }\r
}\r
\r
// internal\r
\r
- internal Group () : base () {\r
+ internal Group (string text, int[] caps) : base (text) {\r
+ this.captures = new CaptureCollection ();\r
+\r
+ if (caps == null || caps.Length == 0) {\r
+ this.success = false;\r
+ return;\r
+ }\r
+\r
+ this.success = true;\r
+ this.index = caps[0];\r
+ this.length = caps[1];\r
+ captures.Add (this);\r
+ for (int i = 2; i < caps.Length; i += 2)\r
+ captures.Add (new Capture (text, caps[i], caps[i + 1]));\r
+ captures.Reverse ();\r
}\r
\r
- internal Group (Capture last) : base (last) {\r
- captures = new CaptureCollection (last);\r
-\r
- // TODO make construction of captures lazy\r
+ internal Group (): base ("")\r
+ {\r
+ captures = new CaptureCollection ();\r
}\r
\r
+ private bool success;\r
private CaptureCollection captures;\r
}\r
\r
+ [Serializable]\r
public class Match : Group {\r
public static Match Empty {\r
get { return empty; }\r
\r
// internal\r
\r
- internal Match () : base () {\r
+ internal Match () : base (null, null) {\r
this.regex = null;\r
this.machine = null;\r
this.text_length = 0;\r
groups.Add (this);\r
}\r
\r
- internal Match (Regex regex, IMachine machine, int text_length, Capture[] captures) : base (captures[0]) {\r
+ internal Match (Regex regex, IMachine machine, string text, int text_length, int[][] grps) :\r
+ base (text, grps[0])\r
+ {\r
this.regex = regex;\r
this.machine = machine;\r
this.text_length = text_length;\r
- this.groups = new GroupCollection ();\r
\r
+ this.groups = new GroupCollection ();\r
groups.Add (this);\r
- for (int i = 1; i < captures.Length; ++ i)\r
- groups.Add (new Group (captures[i]));\r
+ for (int i = 1; i < grps.Length; ++ i)\r
+ groups.Add (new Group (text, grps[i]));\r
}\r
\r
internal Regex Regex {\r