You've already forked linux-packaging-mono
Imported Upstream version 4.0.0~alpha1
Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
This commit is contained in:
336
external/referencesource/mscorlib/system/resources/resourceset.cs
vendored
Normal file
336
external/referencesource/mscorlib/system/resources/resourceset.cs
vendored
Normal file
@ -0,0 +1,336 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*============================================================
|
||||
**
|
||||
** Class: ResourceSet
|
||||
**
|
||||
** <OWNER>[....]</OWNER>
|
||||
**
|
||||
**
|
||||
** Purpose: Culture-specific collection of resources.
|
||||
**
|
||||
**
|
||||
===========================================================*/
|
||||
namespace System.Resources {
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Globalization;
|
||||
using System.Security.Permissions;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Diagnostics.Contracts;
|
||||
|
||||
// A ResourceSet stores all the resources defined in one particular CultureInfo.
|
||||
//
|
||||
// The method used to load resources is straightforward - this class
|
||||
// enumerates over an IResourceReader, loading every name and value, and
|
||||
// stores them in a hash table. Custom IResourceReaders can be used.
|
||||
//
|
||||
[Serializable]
|
||||
[System.Runtime.InteropServices.ComVisible(true)]
|
||||
public class ResourceSet : IDisposable, IEnumerable
|
||||
{
|
||||
[NonSerialized] protected IResourceReader Reader;
|
||||
#if FEATURE_CORECLR
|
||||
internal Hashtable Table;
|
||||
#else
|
||||
protected Hashtable Table;
|
||||
#endif
|
||||
|
||||
private Hashtable _caseInsensitiveTable; // For case-insensitive lookups.
|
||||
|
||||
#if LOOSELY_LINKED_RESOURCE_REFERENCE
|
||||
[OptionalField]
|
||||
private Assembly _assembly; // For LooselyLinkedResourceReferences
|
||||
#endif // LOOSELY_LINKED_RESOURCE_REFERENCE
|
||||
|
||||
protected ResourceSet()
|
||||
{
|
||||
// To not inconvenience people subclassing us, we should allocate a new
|
||||
// hashtable here just so that Table is set to something.
|
||||
CommonInit();
|
||||
}
|
||||
|
||||
// For RuntimeResourceSet, ignore the Table parameter - it's a wasted
|
||||
// allocation.
|
||||
internal ResourceSet(bool junk)
|
||||
{
|
||||
}
|
||||
|
||||
// Creates a ResourceSet using the system default ResourceReader
|
||||
// implementation. Use this constructor to open & read from a file
|
||||
// on disk.
|
||||
//
|
||||
#if FEATURE_CORECLR
|
||||
[System.Security.SecurityCritical] // auto-generated
|
||||
#endif
|
||||
[ResourceExposure(ResourceScope.Machine)]
|
||||
[ResourceConsumption(ResourceScope.Machine)]
|
||||
public ResourceSet(String fileName)
|
||||
{
|
||||
Reader = new ResourceReader(fileName);
|
||||
CommonInit();
|
||||
ReadResources();
|
||||
}
|
||||
|
||||
#if LOOSELY_LINKED_RESOURCE_REFERENCE
|
||||
public ResourceSet(String fileName, Assembly assembly)
|
||||
{
|
||||
Reader = new ResourceReader(fileName);
|
||||
CommonInit();
|
||||
_assembly = assembly;
|
||||
ReadResources();
|
||||
}
|
||||
#endif // LOOSELY_LINKED_RESOURCE_REFERENCE
|
||||
|
||||
// Creates a ResourceSet using the system default ResourceReader
|
||||
// implementation. Use this constructor to read from an open stream
|
||||
// of data.
|
||||
//
|
||||
[System.Security.SecurityCritical] // auto-generated_required
|
||||
public ResourceSet(Stream stream)
|
||||
{
|
||||
Reader = new ResourceReader(stream);
|
||||
CommonInit();
|
||||
ReadResources();
|
||||
}
|
||||
|
||||
#if LOOSELY_LINKED_RESOURCE_REFERENCE
|
||||
[System.Security.SecurityCritical] // auto_generated_required
|
||||
public ResourceSet(Stream stream, Assembly assembly)
|
||||
{
|
||||
Reader = new ResourceReader(stream);
|
||||
CommonInit();
|
||||
_assembly = assembly;
|
||||
ReadResources();
|
||||
}
|
||||
#endif // LOOSELY_LINKED_RESOURCE_REFERENCE
|
||||
|
||||
public ResourceSet(IResourceReader reader)
|
||||
{
|
||||
if (reader == null)
|
||||
throw new ArgumentNullException("reader");
|
||||
Contract.EndContractBlock();
|
||||
Reader = reader;
|
||||
CommonInit();
|
||||
ReadResources();
|
||||
}
|
||||
|
||||
#if LOOSELY_LINKED_RESOURCE_REFERENCE
|
||||
public ResourceSet(IResourceReader reader, Assembly assembly)
|
||||
{
|
||||
if (reader == null)
|
||||
throw new ArgumentNullException("reader");
|
||||
Contract.EndContractBlock();
|
||||
Reader = reader;
|
||||
CommonInit();
|
||||
_assembly = assembly;
|
||||
ReadResources();
|
||||
}
|
||||
#endif // LOOSELY_LINKED_RESOURCE_REFERENCE
|
||||
|
||||
private void CommonInit()
|
||||
{
|
||||
Table = new Hashtable();
|
||||
}
|
||||
|
||||
// Closes and releases any resources used by this ResourceSet, if any.
|
||||
// All calls to methods on the ResourceSet after a call to close may
|
||||
// fail. Close is guaranteed to be safely callable multiple times on a
|
||||
// particular ResourceSet, and all subclasses must support these semantics.
|
||||
public virtual void Close()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing) {
|
||||
// Close the Reader in a thread-safe way.
|
||||
IResourceReader copyOfReader = Reader;
|
||||
Reader = null;
|
||||
if (copyOfReader != null)
|
||||
copyOfReader.Close();
|
||||
}
|
||||
Reader = null;
|
||||
_caseInsensitiveTable = null;
|
||||
Table = null;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
#if LOOSELY_LINKED_RESOURCE_REFERENCE
|
||||
// Optional - used for resolving assembly manifest resource references.
|
||||
// This can safely be null.
|
||||
[ComVisible(false)]
|
||||
public Assembly Assembly {
|
||||
get { return _assembly; }
|
||||
/*protected*/ set { _assembly = value; }
|
||||
}
|
||||
#endif // LOOSELY_LINKED_RESOURCE_REFERENCE
|
||||
|
||||
// Returns the preferred IResourceReader class for this kind of ResourceSet.
|
||||
// Subclasses of ResourceSet using their own Readers &; should override
|
||||
// GetDefaultReader and GetDefaultWriter.
|
||||
public virtual Type GetDefaultReader()
|
||||
{
|
||||
return typeof(ResourceReader);
|
||||
}
|
||||
|
||||
#if !FEATURE_CORECLR
|
||||
// Returns the preferred IResourceWriter class for this kind of ResourceSet.
|
||||
// Subclasses of ResourceSet using their own Readers &; should override
|
||||
// GetDefaultReader and GetDefaultWriter.
|
||||
public virtual Type GetDefaultWriter()
|
||||
{
|
||||
return typeof(ResourceWriter);
|
||||
}
|
||||
#endif // !FEATURE_CORECLR
|
||||
|
||||
[ComVisible(false)]
|
||||
public virtual IDictionaryEnumerator GetEnumerator()
|
||||
{
|
||||
return GetEnumeratorHelper();
|
||||
}
|
||||
|
||||
/// <internalonly/>
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumeratorHelper();
|
||||
}
|
||||
|
||||
private IDictionaryEnumerator GetEnumeratorHelper()
|
||||
{
|
||||
Hashtable copyOfTable = Table; // Avoid a race with Dispose
|
||||
if (copyOfTable == null)
|
||||
throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_ResourceSet"));
|
||||
return copyOfTable.GetEnumerator();
|
||||
}
|
||||
|
||||
// Look up a string value for a resource given its name.
|
||||
//
|
||||
public virtual String GetString(String name)
|
||||
{
|
||||
Object obj = GetObjectInternal(name);
|
||||
try {
|
||||
return (String)obj;
|
||||
}
|
||||
catch (InvalidCastException) {
|
||||
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResourceNotString_Name", name));
|
||||
}
|
||||
}
|
||||
|
||||
public virtual String GetString(String name, bool ignoreCase)
|
||||
{
|
||||
Object obj;
|
||||
String s;
|
||||
|
||||
// Case-sensitive lookup
|
||||
obj = GetObjectInternal(name);
|
||||
try {
|
||||
s = (String)obj;
|
||||
}
|
||||
catch (InvalidCastException) {
|
||||
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResourceNotString_Name", name));
|
||||
}
|
||||
|
||||
// case-sensitive lookup succeeded
|
||||
if (s != null || !ignoreCase) {
|
||||
return s;
|
||||
}
|
||||
|
||||
// Try doing a case-insensitive lookup
|
||||
obj = GetCaseInsensitiveObjectInternal(name);
|
||||
try {
|
||||
return (String)obj;
|
||||
}
|
||||
catch (InvalidCastException) {
|
||||
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResourceNotString_Name", name));
|
||||
}
|
||||
}
|
||||
|
||||
// Look up an object value for a resource given its name.
|
||||
//
|
||||
public virtual Object GetObject(String name)
|
||||
{
|
||||
return GetObjectInternal(name);
|
||||
}
|
||||
|
||||
public virtual Object GetObject(String name, bool ignoreCase)
|
||||
{
|
||||
Object obj = GetObjectInternal(name);
|
||||
|
||||
if (obj != null || !ignoreCase)
|
||||
return obj;
|
||||
|
||||
return GetCaseInsensitiveObjectInternal(name);
|
||||
}
|
||||
|
||||
protected virtual void ReadResources()
|
||||
{
|
||||
IDictionaryEnumerator en = Reader.GetEnumerator();
|
||||
while (en.MoveNext()) {
|
||||
Object value = en.Value;
|
||||
#if LOOSELY_LINKED_RESOURCE_REFERENCE
|
||||
if (Assembly != null && value is LooselyLinkedResourceReference) {
|
||||
LooselyLinkedResourceReference assRef = (LooselyLinkedResourceReference) value;
|
||||
value = assRef.Resolve(Assembly);
|
||||
}
|
||||
#endif //LOOSELYLINKEDRESOURCEREFERENCE
|
||||
Table.Add(en.Key, value);
|
||||
}
|
||||
// While technically possible to close the Reader here, don't close it
|
||||
// to help with some WinRes lifetime issues.
|
||||
}
|
||||
|
||||
private Object GetObjectInternal(String name)
|
||||
{
|
||||
if (name == null)
|
||||
throw new ArgumentNullException("name");
|
||||
Contract.EndContractBlock();
|
||||
|
||||
Hashtable copyOfTable = Table; // Avoid a race with Dispose
|
||||
|
||||
if (copyOfTable == null)
|
||||
throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_ResourceSet"));
|
||||
|
||||
return copyOfTable[name];
|
||||
}
|
||||
|
||||
private Object GetCaseInsensitiveObjectInternal(String name)
|
||||
{
|
||||
Hashtable copyOfTable = Table; // Avoid a race with Dispose
|
||||
|
||||
if (copyOfTable == null)
|
||||
throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_ResourceSet"));
|
||||
|
||||
Hashtable caseTable = _caseInsensitiveTable; // Avoid ---- with Close
|
||||
if (caseTable == null)
|
||||
{
|
||||
caseTable = new Hashtable(StringComparer.OrdinalIgnoreCase);
|
||||
#if _DEBUG
|
||||
//Console.WriteLine("ResourceSet::GetObject loading up case-insensitive data");
|
||||
BCLDebug.Perf(false, "Using case-insensitive lookups is bad perf-wise. Consider capitalizing "+name+" correctly in your source");
|
||||
#endif
|
||||
|
||||
IDictionaryEnumerator en = copyOfTable.GetEnumerator();
|
||||
while (en.MoveNext())
|
||||
{
|
||||
caseTable.Add(en.Key, en.Value);
|
||||
}
|
||||
_caseInsensitiveTable = caseTable;
|
||||
}
|
||||
|
||||
return caseTable[name];
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user