Invoke the callback in separate threads
[mono.git] / mcs / class / System / System.Text.RegularExpressions / PatternGrouping.jvm.cs
1 //
2 // PatternGrouping.jvm.cs
3 //
4 // Author:
5 //      Arina Itkes  <arinai@mainsoft.com>
6 //
7 // Copyright (C) 2007 Mainsoft, Inc.
8 //
9
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31
32
33 using System;
34 using System.Collections.Generic;
35 using System.Text;
36 using System.Collections;
37
38 namespace System.Text.RegularExpressions
39 {
40         sealed class PatternGrouping
41         {
42                 int _groupCount;
43                 IDictionary _groupNameToNumberMap;
44                 int [] _javaToNetGroupNumbersMap;
45                 string [] _groupNumberToNameMap;
46                 int [] _netToJavaNumbersMap;
47                 bool _sameGroupsFlag;
48
49                 internal string [] GroupNumberToNameMap {
50                         get { return _groupNumberToNameMap; }
51                 }
52
53                 internal int [] JavaToNetGroupNumbersMap {
54                         get { return _javaToNetGroupNumbersMap; }
55                 }
56
57                 internal IDictionary GroupNameToNumberMap {
58                         get { return _groupNameToNumberMap; }
59                 }
60
61                 internal int [] NetToJavaNumbersMap {
62                         get { return _netToJavaNumbersMap; }
63                 }
64
65                 internal bool SameGroupsFlag {
66                         get { return _sameGroupsFlag; }
67                 }
68
69                 internal int GroupCount {
70                         get { return _groupCount; }
71                 }
72
73                 internal PatternGrouping () {
74                         this._groupCount = -1;
75                 }
76
77                 internal void SetGroups (int netGroupCount, int javaGroupCount) {
78                         this._groupCount = netGroupCount;
79
80                         _groupNameToNumberMap = new Hashtable (_groupCount + 1);
81                         _javaToNetGroupNumbersMap = new int [javaGroupCount + 1];
82                         _groupNumberToNameMap = new string [_groupCount + 1];
83                         _netToJavaNumbersMap = new int [_groupCount + 1];
84
85                         for (int i = 0; i <= _groupCount; ++i) {
86                                 _groupNameToNumberMap.Add (i.ToString (), i);
87                                 _javaToNetGroupNumbersMap [i] = i;
88                                 _groupNumberToNameMap [i] = i.ToString ();
89                                 _netToJavaNumbersMap [i] = i;
90                         }
91                         for (int i = _groupCount + 1; i <= javaGroupCount; ++i) {
92                                 _javaToNetGroupNumbersMap [i] = -1;
93                         }
94                 }
95
96                 internal void SetGroups (string [] namedGroups,
97                                                                 int [] javaGroupNumberToNetGroupNumber,
98                                                                 int noNamedGroupNumber,
99                                                                 int capturedGroupsCount,
100                                                                 int sameGroupsCounter,
101                                                                 RegexOptions options) {
102                         _groupNumberToNameMap = new string [capturedGroupsCount + 1];
103                         _groupNameToNumberMap = new Hashtable (capturedGroupsCount + 1);
104                         _netToJavaNumbersMap = new int [capturedGroupsCount + 1];
105
106                         _javaToNetGroupNumbersMap = javaGroupNumberToNetGroupNumber;
107
108                         if ((options & RegexOptions.ExplicitCapture) == RegexOptions.ExplicitCapture) {
109                                 FillExplicitGroupMaps (namedGroups,
110                                 capturedGroupsCount,
111                                 sameGroupsCounter,
112                                 options);
113                                 return;
114                         }
115                         else {
116                                 FillImplicitGroupMaps (namedGroups,
117                                         noNamedGroupNumber + 1,
118                                         capturedGroupsCount,
119                                         sameGroupsCounter,
120                                         options);
121                         }
122
123                 }
124
125                 private void FillImplicitGroupMaps (string [] namedGroups,
126                         int namedGroupNumber,
127                         int capturedGroupsCount,
128                         int sameGroupsCounter,
129                         RegexOptions options) {
130                         int addedNamedGroupsCount = 0;
131
132                         for (int i = 0; i < capturedGroupsCount + 1; ++i) {
133                                 int netGroupNumber = _javaToNetGroupNumbersMap [i];
134                                 if (netGroupNumber == -1) {
135                                         if (_groupNameToNumberMap.Contains (namedGroups [addedNamedGroupsCount])) {
136                                                 _javaToNetGroupNumbersMap [i] = (int) _groupNameToNumberMap [namedGroups [addedNamedGroupsCount]];
137                                                 ++sameGroupsCounter;
138                                         }
139                                         else {
140                                                 _javaToNetGroupNumbersMap [i] = namedGroupNumber;
141                                                 _groupNumberToNameMap [namedGroupNumber] = namedGroups [addedNamedGroupsCount];
142                                                 ++namedGroupNumber;
143                                         }
144
145                                         netGroupNumber = _javaToNetGroupNumbersMap [i];
146                                         ++addedNamedGroupsCount;
147                                 }
148                                 else {
149                                         _groupNumberToNameMap [netGroupNumber] =
150                                                 netGroupNumber.ToString ();
151                                 }
152                                 _groupNameToNumberMap [_groupNumberToNameMap [netGroupNumber]] = netGroupNumber;
153                                 _netToJavaNumbersMap [_javaToNetGroupNumbersMap [i]] = i;
154                         }
155                         _groupCount = capturedGroupsCount - sameGroupsCounter;
156                         _sameGroupsFlag = (sameGroupsCounter != 0);
157
158                 }
159
160                 private void FillExplicitGroupMaps (string [] namedGroups,
161                         int capturedGroupsCount,
162                         int sameGroupsCounter,
163                         RegexOptions options) {
164                         int addedNamedGroupsCount = 0;
165                         int namedGroupNumber = 1;
166                         int nonCapturedGroupsNumber = 0;
167
168                         for (int i = 1; i < capturedGroupsCount + 1; ++i) {
169                                 int netGroupNumber = _javaToNetGroupNumbersMap [i];
170                                 if (netGroupNumber >= 0) {
171                                         _javaToNetGroupNumbersMap [i] = -1;
172                                         ++nonCapturedGroupsNumber;
173                                         continue;
174                                 }
175
176                                 if (_groupNameToNumberMap.Contains (namedGroups [addedNamedGroupsCount])) {
177                                         _javaToNetGroupNumbersMap [i] = (int) _groupNameToNumberMap [namedGroups [addedNamedGroupsCount]];
178                                         ++sameGroupsCounter;
179                                 }
180                                 else {
181                                         _javaToNetGroupNumbersMap [i] = namedGroupNumber;
182                                         _groupNumberToNameMap [namedGroupNumber] = namedGroups [addedNamedGroupsCount];
183                                         ++namedGroupNumber;
184                                 }
185
186                                 netGroupNumber = _javaToNetGroupNumbersMap [i];
187                                 ++addedNamedGroupsCount;
188
189                                 _groupNameToNumberMap [_groupNumberToNameMap [netGroupNumber]] = netGroupNumber;
190                                 _netToJavaNumbersMap [_javaToNetGroupNumbersMap [i]] = i;
191                         }
192                         _groupCount = capturedGroupsCount - sameGroupsCounter - nonCapturedGroupsNumber;
193                         _sameGroupsFlag = (sameGroupsCounter != 0);
194                 }
195         }
196 }