New test.
[mono.git] / mcs / class / Microsoft.JScript / Microsoft.JScript / MemberInfoList.cs
1 //
2 // MemberInfoList.cs:
3 //
4 // Author:
5 //      Cesar Lopez Nataren (cesar@ciencias.unam.mx)
6 //
7 // (C) 2003, Cesar Lopez Nataren
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 using System;
32 using System.Reflection;
33 using System.Collections;
34
35 namespace Microsoft.JScript {
36
37         internal class Node {
38                 private MemberInfo elem;
39                 private Node next;
40                 private string name;
41
42                 internal MemberInfo Element {
43                         get { return elem; }
44                 }
45
46                 internal Node Next {
47                         get { return next; }
48                         set { next = value; }
49                 }
50
51                 internal Node (string name, MemberInfo value, Node node)
52                 {
53                         this.name = name;
54                         elem = value;
55                         next = node;
56                 }
57         }
58
59         public sealed class MemberInfoList {
60                 Node head;
61                 int size;
62
63                 internal int Size {
64                         get { return size; }
65                 }
66
67                 internal Node Head {
68                         get { return head; }
69                 }
70
71                 internal MemberInfoList ()
72                 {
73                         head = new Node (String.Empty, null, null);
74                         size = 0;
75                 }
76
77                 internal void Insert (string name, MemberInfo elem)
78                 {
79                         Node second = head.Next;
80                         head.Next = new Node (name, elem, second);
81                         size++;
82                 }
83
84                 internal bool Delete (object elem)
85                 {
86                         Node marker;
87                         for (marker = head; marker.Next != null && !marker.Next.Element.Equals (elem); marker = marker.Next)
88                                 ;
89
90                         if (marker.Next != null && marker.Next.Element.Equals (elem)) {
91                                 marker.Next = marker.Next.Next;
92                                 size--;
93                                 return true;
94                         } else return false;
95                 }
96
97                 internal Node Find (object value)
98                 {
99                         Node result = null;
100                         Node current = head.Next;
101
102                         for (int i = 0; i < size; i++) {
103                                 if (current != null) 
104                                         if (current.Element.Equals (value))
105                                                 result = current;
106                                         else
107                                                 current = current.Next;
108                         }
109                         return result;
110                 }
111         }
112
113         internal class ListIter {
114                 Node current;
115
116                 internal Node Current {
117                         get { return current; }
118                 }
119
120                 internal ListIter (MemberInfoList list)
121                 {
122                         current = list.Head;
123                 }
124
125                 internal Node Next ()
126                 {
127                         if (!End)
128                                 current = current.Next;
129                         if (!End)
130                                 return current;
131                         else
132                                 throw new Exception ("Attemp to access beyond end of list.");
133                 }
134
135                 internal bool End {
136                         get { return current == null; }
137                 }
138         }
139
140         internal class ChainHash : IEnumerable {
141
142                 MemberInfoList [] bucket;
143
144                 internal ChainHash (int size)
145                 {
146                         bucket = new MemberInfoList [size];
147
148                         for (int i = 0; i < size; i++)
149                                 bucket [i] = new MemberInfoList ();             
150                 }
151
152                 internal void Insert (string name, MemberInfo value)
153                 {
154                         bucket [Hash (name)].Insert (name, value);
155                 }
156
157                 internal object Retrieve (object value)
158                 {
159                         int n = bucket.Length;
160                         object result = null;
161
162                         for (int i = 0; i < n; i++) {
163                                 result = bucket [i].Find (value);
164                                 if (result == null)
165                                         continue;
166                                 else
167                                         break;
168                         }
169                         return result;
170                 }
171
172                 internal MemberInfoList Retrieve (string name)
173                 {
174                         return bucket [Hash (name)];
175                 }
176                 
177                 internal void Delete (object value)
178                 {
179                         if (value == null)
180                                 throw new Exception ("Delete.Error, key can't be null.");
181
182                         int n = bucket.Length;
183                         bool deleted = false;
184
185                         for (int i = 0; i < n; i++) {
186                                 deleted = bucket [i].Delete (value);
187                                 if (deleted)
188                                         break;
189                         }
190                 }
191
192                 private int Hash (string name)
193                 {
194                         return name.GetHashCode () % bucket.Length;
195                 }
196
197                 public IEnumerator GetEnumerator ()
198                 {
199                         ArrayList elems = new ArrayList ();
200                         ListIter iter;
201                         int i, n;
202
203                         foreach (MemberInfoList list in bucket) {
204                                 n = list.Size;
205                                 iter = new ListIter (list);
206                                 for (i = 0; i < n; i++)
207                                         elems.Add (iter.Next ());
208                         }
209                         return elems.GetEnumerator ();
210                 }
211         }
212 }