In .:
[mono.git] / mcs / class / corlib / System.Resources / ResourceSet.cs
1 //
2 // System.Resources.ResourceSet.cs
3 //
4 // Authors:
5 //      Duncan Mak (duncan@ximian.com)
6 //      Dick Porter (dick@ximian.com)
7 //      Andreas Nahr (ClassDevelopment@A-SoftTech.com)
8 //
9 // (C) 2001, 2002 Ximian, Inc.          http://www.ximian.com
10 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 using System.Collections;
33 using System.IO;
34 using System.Globalization;
35 using System.Runtime.InteropServices;
36 using System.Security.Permissions;
37
38 namespace System.Resources
39 {
40         [Serializable]
41 #if NET_2_0
42         [ComVisible (true)]
43 #endif
44         public class ResourceSet : IDisposable
45
46 #if (NET_1_1)
47                                                 , IEnumerable
48 #endif
49
50         {
51
52 #if NET_2_0
53                 [NonSerialized]
54 #endif
55                 protected IResourceReader Reader;
56                 protected Hashtable Table;
57                 bool resources_read;
58
59                 [NonSerialized]
60                 private bool disposed;
61
62                 // Constructors
63                 protected ResourceSet ()
64                 {
65                         Table = new Hashtable ();
66                         resources_read = true;
67                 }
68
69                 public ResourceSet (IResourceReader reader)
70                 {
71                         if (reader == null)
72                                 throw new ArgumentNullException ("reader");
73                         Table = new Hashtable ();
74                         Reader = reader;
75                 }
76
77                 [SecurityPermission (SecurityAction.LinkDemand, SerializationFormatter = true)]
78                 public ResourceSet (Stream stream)
79                 {
80                         Table = new Hashtable ();
81                         Reader = new ResourceReader (stream);
82                 }
83
84                 internal ResourceSet (UnmanagedMemoryStream stream)
85                 {
86                         Table = new Hashtable ();
87                         Reader = new ResourceReader (stream);
88                 }
89                 
90                 public ResourceSet (string fileName)
91                 {
92                         Table = new Hashtable ();
93                         Reader = new ResourceReader (fileName);
94                 }
95
96                 public virtual void Close ()
97                 {
98                         Dispose ();
99                 }
100
101                 public void Dispose()
102                 {
103                         Dispose (true);
104
105                         // If we are explicitly disposed, we can avoid finalization.
106                         GC.SuppressFinalize (this);
107                 }
108
109                 protected virtual void Dispose (bool disposing)
110                 {
111                         if (disposing) {
112                                 if(Reader != null)
113                                         Reader.Close();
114                         }
115
116                         Reader = null;
117                         Table = null;
118                         disposed = true;
119                 }
120
121                 public virtual Type GetDefaultReader ()
122                 {
123                         return (typeof (ResourceReader));
124                 }
125
126                 public virtual Type GetDefaultWriter ()
127                 {
128                         return (typeof (ResourceWriter));
129                 }
130
131 #if NET_1_1
132                 [ComVisible (false)]
133                 public virtual IDictionaryEnumerator GetEnumerator ()
134                 {
135                         if (disposed)
136 #if NET_2_0
137                                 throw new ObjectDisposedException ("ResourceSet is closed.");
138 #else
139                                 throw new InvalidOperationException ("ResourceSet is closed.");
140 #endif
141                         ReadResources ();
142                         return Table.GetEnumerator();
143                 }
144
145                 IEnumerator IEnumerable.GetEnumerator ()
146                 {
147                         return this.GetEnumerator ();
148                 }
149 #endif
150
151                 private object GetObjectInternal (string name, bool ignoreCase)
152                 {
153                         if (name == null)
154                                 throw new ArgumentNullException ("name");
155                         if (disposed)
156 #if NET_2_0
157                                 throw new ObjectDisposedException ("ResourceSet is closed.");
158 #else
159                                 throw new InvalidOperationException ("ResourceSet is closed.");
160 #endif
161                         ReadResources ();
162
163                         object o = Table [name];
164                         if (o != null)
165                                 return o;
166
167                         if (ignoreCase) {
168                                 foreach (DictionaryEntry de in Table) {
169                                         string key = (string) de.Key;
170                                         if (String.Compare (key, name, true, CultureInfo.InvariantCulture) == 0)
171                                                 return de.Value;
172                                 }
173                         }
174
175                         return null;
176                 }
177
178                 public virtual object GetObject (string name)
179                 {
180                         return GetObjectInternal (name, false);
181                 }
182
183                 public virtual object GetObject (string name, bool ignoreCase)
184                 {
185                         return GetObjectInternal (name, ignoreCase);
186                 }
187
188                 private string GetStringInternal (string name, bool ignoreCase)
189                 {
190                         object value = GetObject (name, ignoreCase);
191                         if (value == null)
192                                 return null;
193
194                         string s = (value as string);
195                         if (s == null)
196                                 throw new InvalidOperationException (string.Format (
197                                         "Resource '{0}' is not a String. Use " +
198                                         "GetObject instead.", name));
199
200                         return s;
201                 }
202
203                 public virtual string GetString (string name)
204                 {
205                         return GetStringInternal (name, false);
206                 }
207
208                 public virtual string GetString (string name, bool ignoreCase)
209                 {
210                         return GetStringInternal (name, ignoreCase);
211                 }
212
213                 protected virtual void ReadResources ()
214                 {
215                         if (resources_read)
216                                 return;
217
218                         if (Reader == null)
219 #if NET_2_0
220                                 throw new ObjectDisposedException ("ResourceSet is closed.");
221 #else
222                                 throw new InvalidOperationException ("ResourceSet is closed.");
223 #endif
224                         lock (Table) {
225                                 if (resources_read)
226                                         return;
227
228                                 IDictionaryEnumerator i = Reader.GetEnumerator();
229                                 i.Reset ();
230                                 while (i.MoveNext ()) 
231                                         Table.Add (i.Key, i.Value);
232                                 resources_read = true;
233                         }
234                 }
235
236 #if NET_2_0
237                 internal UnmanagedMemoryStream GetStream (string name, bool ignoreCase)
238                 {
239                         if (Reader == null)
240                                 throw new ObjectDisposedException ("ResourceSet is closed.");
241
242                         IDictionaryEnumerator i = Reader.GetEnumerator();
243                         i.Reset ();
244                         while (i.MoveNext ()){
245                                 if (String.Compare (name, (string) i.Key, ignoreCase) == 0)
246                                         return ((ResourceReader.ResourceEnumerator) i).ValueAsStream;
247                         }
248                         return null;
249                 }
250 #endif
251         }
252 }