1 //------------------------------------------------------------------------------
2 // <copyright file="RegexGroupCollection.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 //------------------------------------------------------------------------------
7 // The GroupCollection lists the captured Capture numbers
8 // contained in a compiled Regex.
10 namespace System
.Text
.RegularExpressions
{
12 using System
.Collections
;
13 using System
.Collections
.Generic
;
17 /// Represents a sequence of capture substrings. The object is used
18 /// to return the set of captures done by a single capturing group.
24 public class GroupCollection
: ICollection
{
25 internal Match _match
;
27 internal Dictionary
<Int32
, Int32
> _captureMap
;
29 internal Hashtable _captureMap
;
32 // cache of Group objects fed to the user
33 internal Group
[] _groups
;
36 * Nonpublic constructor
39 internal GroupCollection(Match match
, Dictionary
<Int32
, Int32
> caps
) {
41 internal GroupCollection(Match match
, Hashtable caps
) {
48 * The object on which to synchronize
51 /// <para>[To be supplied.]</para>
53 public Object SyncRoot
{
63 /// <para>[To be supplied.]</para>
65 public bool IsSynchronized
{
75 /// <para>[To be supplied.]</para>
77 public bool IsReadOnly
{
85 /// Returns the number of groups.
90 return _match
._matchcount
.Length
;
95 /// <para>[To be supplied.]</para>
97 public Group
this[int groupnum
]
100 return GetGroup(groupnum
);
105 /// <para>[To be supplied.]</para>
107 public Group
this[String groupname
] {
109 if (_match
._regex
== null)
110 return Group
._emptygroup
;
112 return GetGroup(_match
._regex
.GroupNumberFromName(groupname
));
116 internal Group
GetGroup(int groupnum
) {
117 if (_captureMap
!= null) {
120 o
= _captureMap
[groupnum
];
122 return Group
._emptygroup
;
123 //throw new ArgumentOutOfRangeException("groupnum");
125 return GetGroupImpl((int)o
);
128 //if (groupnum >= _match._regex.CapSize || groupnum < 0)
129 // throw new ArgumentOutOfRangeException("groupnum");
130 if (groupnum
>= _match
._matchcount
.Length
|| groupnum
< 0)
131 return Group
._emptygroup
;
133 return GetGroupImpl(groupnum
);
139 * Caches the group objects
141 internal Group
GetGroupImpl(int groupnum
) {
145 // Construct all the Group objects the first time GetGroup is called
147 if (_groups
== null) {
148 _groups
= new Group
[_match
._matchcount
.Length
- 1];
149 for (int i
= 0; i
< _groups
.Length
; i
++) {
150 string groupname
= _match
._regex
.GroupNameFromNumber(i
+ 1);
151 _groups
[i
] = new Group(_match
._text
, _match
._matches
[i
+ 1], _match
._matchcount
[i
+ 1], groupname
);
155 return _groups
[groupnum
- 1];
159 * As required by ICollection
163 /// Copies all the elements of the collection to the given array
164 /// beginning at the given index.
167 public void CopyTo(Array array
, int arrayIndex
) {
169 throw new ArgumentNullException("array");
171 for (int i
= arrayIndex
, j
= 0; j
< Count
; i
++, j
++) {
172 array
.SetValue(this[j
], i
);
177 * As required by ICollection
181 /// Provides an enumerator in the same order as Item[].
184 public IEnumerator
GetEnumerator() {
185 return new GroupEnumerator(this);
191 * This non-public enumerator lists all the captures
192 * Should it be public?
194 internal class GroupEnumerator
: IEnumerator
{
195 internal GroupCollection _rgc
;
196 internal int _curindex
;
199 * Nonpublic constructor
201 internal GroupEnumerator(GroupCollection rgc
) {
207 * As required by IEnumerator
209 public bool MoveNext() {
210 int size
= _rgc
.Count
;
212 if (_curindex
>= size
)
217 return(_curindex
< size
);
221 * As required by IEnumerator
223 public Object Current
{
224 get { return Capture;}
228 * Returns the current capture
230 public Capture Capture
{
232 if (_curindex
< 0 || _curindex
>= _rgc
.Count
)
233 throw new InvalidOperationException(SR
.GetString(SR
.EnumNotStarted
));
235 return _rgc
[_curindex
];
240 * Reset to before the first item
242 public void Reset() {