In System.Text.RegularExpressions:
[mono.git] / mcs / class / System / System.Text.RegularExpressions / MatchCollection.cs
1 //
2 // System.Text.RegularExpressions.MatchCollection
3 //
4 // Authors:
5 //      Dan Lewis (dlewis@gmx.co.uk)
6 //      Dick Porter (dick@ximian.com)
7 //
8 // (C) 2002 Dan Lewis
9 // (C) 2004 Novell, Inc.
10 //
11
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33 using System;
34 using System.Collections;
35
36 namespace System.Text.RegularExpressions
37 {
38         [Serializable]
39         public class MatchCollection: ICollection, IEnumerable {
40                 private Match current;
41                 private ArrayList list;
42
43                 /* No public constructor */
44                 internal MatchCollection (Match start)
45                 {
46                         current = start;
47                         list = new ArrayList ();
48                 }
49
50                 public virtual int Count {
51                         get {
52                                 TryToGet (Int32.MaxValue);
53                                 return list.Count;
54                         }
55                 }
56
57                 public bool IsReadOnly {
58                         get { return true; }
59                 }
60
61                 public virtual bool IsSynchronized {
62                         get { return false; }
63                 }
64
65                 private bool TryToGet (int i)
66                 {
67                         while (i >= list.Count && current.Success) {
68                                 list.Add (current);
69                                 current = current.NextMatch ();
70                         }
71                         return i < list.Count;
72                 }
73
74                 public Match this [int i] {
75                         get {
76                                 if (i < 0 || !TryToGet (i))
77                                         throw new ArgumentOutOfRangeException ("index out of range", "i");
78                                 return (Match) list [i];
79                         }
80                 }
81
82                 public virtual object SyncRoot {
83                         get { return list; }
84                 }
85
86                 public virtual void CopyTo (Array array, int index)
87                 {
88                         TryToGet (Int32.MaxValue);
89                         list.CopyTo (array, index);
90                 }
91
92                 public virtual IEnumerator GetEnumerator ()
93                 {
94                         // If !current.Success, the list is fully populated.  So, just use it.
95                         return current.Success ? new Enumerator (this) : list.GetEnumerator ();
96                 }
97
98                 class Enumerator : IEnumerator {
99                         int index;
100                         MatchCollection coll;
101
102                         internal Enumerator (MatchCollection coll)
103                         {
104                                 this.coll = coll;
105                                 index = -1;
106                         }
107
108                         void IEnumerator.Reset ()
109                         {
110                                 index = -1;
111                         }
112
113                         object IEnumerator.Current {
114                                 get {
115                                         if (index < 0 || index >= coll.list.Count)
116                                                 throw new InvalidOperationException ();
117                                         return coll.list [index];
118                                 }
119                         }
120
121                         bool IEnumerator.MoveNext ()
122                         {
123                                 if (coll.TryToGet (++index))
124                                         return true;
125                                 index = coll.list.Count;
126                                 return false;
127                         }
128                 }
129         }
130 }