Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kotas <jkotas@microsoft.com>2018-09-16 23:56:38 +0300
committerJan Kotas <jkotas@microsoft.com>2018-09-17 06:53:24 +0300
commit4f10c2ad36c8ef2fe82366c6dc3b5ea88c1f3543 (patch)
tree8f2c1a4eec11d08127afb9cd7d62b6515f463917
parenta11fabf11537bbe3bdf4691d29e91c862d55f9b4 (diff)
Delete files moved to shared partition
-rw-r--r--src/System.Private.CoreLib/src/System.Private.CoreLib.csproj2
-rw-r--r--src/System.Private.CoreLib/src/System/Resources/ResourceReader.cs1210
-rw-r--r--src/System.Private.CoreLib/src/System/Resources/ResourceSet.cs291
3 files changed, 0 insertions, 1503 deletions
diff --git a/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj
index 5bacc1219..5efa4931c 100644
--- a/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj
+++ b/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj
@@ -187,8 +187,6 @@
<Compile Include="System\Resources\IResourceGroveler.cs" />
<Compile Include="System\Resources\ManifestBasedResourceGroveler.cs" />
<Compile Include="System\Resources\ResourceManager.cs" />
- <Compile Include="System\Resources\ResourceReader.cs" />
- <Compile Include="System\Resources\ResourceSet.cs" />
<Compile Include="System\Runtime\InteropServices\CriticalHandle.cs" />
<Compile Include="System\Text\CodePageDataItem.cs" />
<Compile Include="System\__Canon.cs" Condition="'$(IsProjectNLibrary)' == 'true'" />
diff --git a/src/System.Private.CoreLib/src/System/Resources/ResourceReader.cs b/src/System.Private.CoreLib/src/System/Resources/ResourceReader.cs
deleted file mode 100644
index 1f661ac9a..000000000
--- a/src/System.Private.CoreLib/src/System/Resources/ResourceReader.cs
+++ /dev/null
@@ -1,1210 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-**
-**
-**
-**
-** Purpose: Default way to read streams of resources on
-** demand.
-**
-** Version 2 support on October 6, 2003
-**
-===========================================================*/
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Globalization;
-using System.IO;
-using System.Reflection;
-using System.Runtime.Versioning;
-using System.Text;
-
-namespace System.Resources
-{
- // Provides the default implementation of IResourceReader, reading
- // .resources file from the system default binary format. This class
- // can be treated as an enumerator once.
- //
- // See the RuntimeResourceSet overview for details on the system
- // default file format.
- //
-
- internal struct ResourceLocator
- {
- internal object _value; // Can be null. Consider WeakReference instead?
- internal int _dataPos;
-
- internal ResourceLocator(int dataPos, object value)
- {
- _dataPos = dataPos;
- _value = value;
- }
-
- internal int DataPosition
- {
- get { return _dataPos; }
- //set { _dataPos = value; }
- }
-
- // Allows adding in profiling data in a future version, or a special
- // resource profiling build. We could also use WeakReference.
- internal object Value
- {
- get { return _value; }
- set { _value = value; }
- }
-
- internal static bool CanCache(ResourceTypeCode value)
- {
- Debug.Assert(value >= 0, "negative ResourceTypeCode. What?");
- return value <= ResourceTypeCode.LastPrimitive;
- }
- }
-
- public sealed class ResourceReader : IResourceReader
- {
- // A reasonable default buffer size for reading from files, especially
- // when we will likely be seeking frequently. Could be smaller, but does
- // it make sense to use anything less than one page?
- private const int DefaultFileStreamBufferSize = 4096;
-
- private BinaryReader _store; // backing store we're reading from.
- // Used by RuntimeResourceSet and this class's enumerator. Maps
- // resource name to a value, a ResourceLocator, or a
- // LooselyLinkedManifestResource.
- internal Dictionary<string, ResourceLocator> _resCache;
- private long _nameSectionOffset; // Offset to name section of file.
- private long _dataSectionOffset; // Offset to Data section of file.
-
- // Note this class is tightly coupled with UnmanagedMemoryStream.
- // At runtime when getting an embedded resource from an assembly,
- // we're given an UnmanagedMemoryStream referring to the mmap'ed portion
- // of the assembly. The pointers here are pointers into that block of
- // memory controlled by the OS's loader.
- private int[] _nameHashes; // hash values for all names.
- private unsafe int* _nameHashesPtr; // In case we're using UnmanagedMemoryStream
- private int[] _namePositions; // relative locations of names
- private unsafe int* _namePositionsPtr; // If we're using UnmanagedMemoryStream
- private Type[] _typeTable; // Lazy array of Types for resource values.
- private int[] _typeNamePositions; // To delay initialize type table
- private int _numResources; // Num of resources files, in case arrays aren't allocated.
-
- // We'll include a separate code path that uses UnmanagedMemoryStream to
- // avoid allocating String objects and the like.
- private UnmanagedMemoryStream _ums;
-
- // Version number of .resources file, for compatibility
- private int _version;
-
-#if RESOURCE_FILE_FORMAT_DEBUG
- private bool _debug; // Whether this file has debugging stuff in it.
-#endif
-
- public ResourceReader(string fileName)
- {
- _resCache = new Dictionary<string, ResourceLocator>(FastResourceComparer.Default);
- _store = new BinaryReader(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultFileStreamBufferSize, FileOptions.RandomAccess), Encoding.UTF8);
-
- try
- {
- ReadResources();
- }
- catch
- {
- _store.Dispose(); // If we threw an exception, close the file.
- throw;
- }
- }
-
- public ResourceReader(Stream stream)
- {
- if (stream == null)
- throw new ArgumentNullException(nameof(stream));
- if (!stream.CanRead)
- throw new ArgumentException(SR.Argument_StreamNotReadable);
-
- _resCache = new Dictionary<string, ResourceLocator>(FastResourceComparer.Default);
- _store = new BinaryReader(stream, Encoding.UTF8);
- // We have a faster code path for reading resource files from an assembly.
- _ums = stream as UnmanagedMemoryStream;
-
- ReadResources();
- }
-
- // This is the constructor the RuntimeResourceSet calls,
- // passing in the stream to read from and the RuntimeResourceSet's
- // internal hash table (hash table of names with file offsets
- // and values, coupled to this ResourceReader).
- internal ResourceReader(Stream stream, Dictionary<string, ResourceLocator> resCache)
- {
- Debug.Assert(stream != null, "Need a stream!");
- Debug.Assert(stream.CanRead, "Stream should be readable!");
- Debug.Assert(resCache != null, "Need a Dictionary!");
-
- _resCache = resCache;
- _store = new BinaryReader(stream, Encoding.UTF8);
-
- _ums = stream as UnmanagedMemoryStream;
-
- ReadResources();
- }
-
-
- public void Close()
- {
- Dispose(true);
- }
-
- public void Dispose()
- {
- Close();
- }
-
- private unsafe void Dispose(bool disposing)
- {
- if (_store != null)
- {
- _resCache = null;
- if (disposing)
- {
- // Close the stream in a thread-safe way. This fix means
- // that we may call Close n times, but that's safe.
- BinaryReader copyOfStore = _store;
- _store = null;
- if (copyOfStore != null)
- copyOfStore.Dispose();
- }
- _store = null;
- _namePositions = null;
- _nameHashes = null;
- _ums = null;
- _namePositionsPtr = null;
- _nameHashesPtr = null;
- }
- }
-
- internal static unsafe int ReadUnalignedI4(int* p)
- {
- byte* buffer = (byte*)p;
- // Unaligned, little endian format
- return buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
- }
-
- internal int Read7BitEncodedInt()
- {
- // Read out an Int32 7 bits at a time. The high bit
- // of the byte when on means to continue reading more bytes.
- int count = 0;
- int shift = 0;
- byte b;
- do
- {
- // Check for a corrupted stream. Read a max of 5 bytes.
- // In a future version, add a DataFormatException.
- if (shift == 5 * 7) // 5 bytes max per Int32, shift += 7
- throw new FormatException(SR.Format_Bad7BitInt32);
-
- // ReadByte handles end of stream cases for us.
- b = _store.ReadByte();
- count |= (b & 0x7F) << shift;
- shift += 7;
- } while ((b & 0x80) != 0);
- return count;
- }
-
-
- private void SkipInt32()
- {
- _store.BaseStream.Seek(4, SeekOrigin.Current);
- }
-
-
- private void SkipString()
- {
- int stringLength = Read7BitEncodedInt();
- if (stringLength < 0)
- {
- throw new BadImageFormatException(SR.BadImageFormat_NegativeStringLength);
- }
- _store.BaseStream.Seek(stringLength, SeekOrigin.Current);
- }
-
- private unsafe int GetNameHash(int index)
- {
- Debug.Assert(index >= 0 && index < _numResources, "Bad index into hash array. index: " + index);
- Debug.Assert((_ums == null && _nameHashes != null && _nameHashesPtr == null) ||
- (_ums != null && _nameHashes == null && _nameHashesPtr != null), "Internal state mangled.");
- if (_ums == null)
- return _nameHashes[index];
- else
- return ReadUnalignedI4(&_nameHashesPtr[index]);
- }
-
- private unsafe int GetNamePosition(int index)
- {
- Debug.Assert(index >= 0 && index < _numResources, "Bad index into name position array. index: " + index);
- Debug.Assert((_ums == null && _namePositions != null && _namePositionsPtr == null) ||
- (_ums != null && _namePositions == null && _namePositionsPtr != null), "Internal state mangled.");
- int r;
- if (_ums == null)
- r = _namePositions[index];
- else
- r = ReadUnalignedI4(&_namePositionsPtr[index]);
- if (r < 0 || r > _dataSectionOffset - _nameSectionOffset)
- {
- throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesNameInvalidOffset, r));
- }
- return r;
- }
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
-
- public IDictionaryEnumerator GetEnumerator()
- {
- if (_resCache == null)
- throw new InvalidOperationException(SR.ResourceReaderIsClosed);
- return new ResourceEnumerator(this);
- }
-
- internal ResourceEnumerator GetEnumeratorInternal()
- {
- return new ResourceEnumerator(this);
- }
-
- // From a name, finds the associated virtual offset for the data.
- // To read the data, seek to _dataSectionOffset + dataPos, then
- // read the resource type & data.
- // This does a binary search through the names.
- internal int FindPosForResource(string name)
- {
- Debug.Assert(_store != null, "ResourceReader is closed!");
- int hash = FastResourceComparer.HashFunction(name);
- // Binary search over the hashes. Use the _namePositions array to
- // determine where they exist in the underlying stream.
- int lo = 0;
- int hi = _numResources - 1;
- int index = -1;
- bool success = false;
- while (lo <= hi)
- {
- index = (lo + hi) >> 1;
- // Do NOT use subtraction here, since it will wrap for large
- // negative numbers.
- int currentHash = GetNameHash(index);
- int c;
- if (currentHash == hash)
- c = 0;
- else if (currentHash < hash)
- c = -1;
- else
- c = 1;
- //BCLDebug.Log("RESMGRFILEFORMAT", " Probing index "+index+" lo: "+lo+" hi: "+hi+" c: "+c);
- if (c == 0)
- {
- success = true;
- break;
- }
- if (c < 0)
- lo = index + 1;
- else
- hi = index - 1;
- }
- if (!success)
- {
- return -1;
- }
-
- // index is the location in our hash array that corresponds with a
- // value in the namePositions array.
- // There could be collisions in our hash function. Check on both sides
- // of index to find the range of hash values that are equal to the
- // target hash value.
- if (lo != index)
- {
- lo = index;
- while (lo > 0 && GetNameHash(lo - 1) == hash)
- lo--;
- }
- if (hi != index)
- {
- hi = index;
- while (hi < _numResources - 1 && GetNameHash(hi + 1) == hash)
- hi++;
- }
-
- lock (this)
- {
- for (int i = lo; i <= hi; i++)
- {
- _store.BaseStream.Seek(_nameSectionOffset + GetNamePosition(i), SeekOrigin.Begin);
- if (CompareStringEqualsName(name))
- {
- int dataPos = _store.ReadInt32();
- if (dataPos < 0 || dataPos >= _store.BaseStream.Length - _dataSectionOffset)
- {
- throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesDataInvalidOffset, dataPos));
- }
- return dataPos;
- }
- }
- }
- return -1;
- }
-
- // This compares the String in the .resources file at the current position
- // with the string you pass in.
- // Whoever calls this method should make sure that they take a lock
- // so no one else can cause us to seek in the stream.
- private unsafe bool CompareStringEqualsName(string name)
- {
- Debug.Assert(_store != null, "ResourceReader is closed!");
- int byteLen = Read7BitEncodedInt();
- if (byteLen < 0)
- {
- throw new BadImageFormatException(SR.BadImageFormat_NegativeStringLength);
- }
- if (_ums != null)
- {
- byte* bytes = _ums.PositionPointer;
- // Skip over the data in the Stream, positioning ourselves right after it.
- _ums.Seek(byteLen, SeekOrigin.Current);
- if (_ums.Position > _ums.Length)
- {
- throw new BadImageFormatException(SR.BadImageFormat_ResourcesNameTooLong);
- }
-
- // On 64-bit machines, these char*'s may be misaligned. Use a
- // byte-by-byte comparison instead.
- //return FastResourceComparer.CompareOrdinal((char*)bytes, byteLen/2, name) == 0;
- return FastResourceComparer.CompareOrdinal(bytes, byteLen, name) == 0;
- }
- else
- {
- // This code needs to be fast
- byte[] bytes = new byte[byteLen];
- int numBytesToRead = byteLen;
- while (numBytesToRead > 0)
- {
- int n = _store.Read(bytes, byteLen - numBytesToRead, numBytesToRead);
- if (n == 0)
- throw new BadImageFormatException(SR.BadImageFormat_ResourceNameCorrupted);
- numBytesToRead -= n;
- }
- return FastResourceComparer.CompareOrdinal(bytes, byteLen / 2, name) == 0;
- }
- }
-
- // This is used in the enumerator. The enumerator iterates from 0 to n
- // of our resources and this returns the resource name for a particular
- // index. The parameter is NOT a virtual offset.
- private unsafe string AllocateStringForNameIndex(int index, out int dataOffset)
- {
- Debug.Assert(_store != null, "ResourceReader is closed!");
- byte[] bytes;
- int byteLen;
- long nameVA = GetNamePosition(index);
- lock (this)
- {
- _store.BaseStream.Seek(nameVA + _nameSectionOffset, SeekOrigin.Begin);
- // Can't use _store.ReadString, since it's using UTF-8!
- byteLen = Read7BitEncodedInt();
- if (byteLen < 0)
- {
- throw new BadImageFormatException(SR.BadImageFormat_NegativeStringLength);
- }
-
- if (_ums != null)
- {
- if (_ums.Position > _ums.Length - byteLen)
- throw new BadImageFormatException(SR.Format(SR.BadImageFormat_ResourcesIndexTooLong, index));
-
- string s = null;
- char* charPtr = (char*)_ums.PositionPointer;
- s = new string(charPtr, 0, byteLen / 2);
-
- _ums.Position += byteLen;
- dataOffset = _store.ReadInt32();
- if (dataOffset < 0 || dataOffset >= _store.BaseStream.Length - _dataSectionOffset)
- {
- throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesDataInvalidOffset, dataOffset));
- }
- return s;
- }
-
- bytes = new byte[byteLen];
- // We must read byteLen bytes, or we have a corrupted file.
- // Use a blocking read in case the stream doesn't give us back
- // everything immediately.
- int count = byteLen;
- while (count > 0)
- {
- int n = _store.Read(bytes, byteLen - count, count);
- if (n == 0)
- throw new EndOfStreamException(SR.Format(SR.BadImageFormat_ResourceNameCorrupted_NameIndex, index));
- count -= n;
- }
- dataOffset = _store.ReadInt32();
- if (dataOffset < 0 || dataOffset >= _store.BaseStream.Length - _dataSectionOffset)
- {
- throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesDataInvalidOffset, dataOffset));
- }
- }
- return Encoding.Unicode.GetString(bytes, 0, byteLen);
- }
-
- // This is used in the enumerator. The enumerator iterates from 0 to n
- // of our resources and this returns the resource value for a particular
- // index. The parameter is NOT a virtual offset.
- private object GetValueForNameIndex(int index)
- {
- Debug.Assert(_store != null, "ResourceReader is closed!");
- long nameVA = GetNamePosition(index);
- lock (this)
- {
- _store.BaseStream.Seek(nameVA + _nameSectionOffset, SeekOrigin.Begin);
- SkipString();
- //BCLDebug.Log("RESMGRFILEFORMAT", "GetValueForNameIndex for index: "+index+" skip (name length): "+skip);
- int dataPos = _store.ReadInt32();
- if (dataPos < 0 || dataPos >= _store.BaseStream.Length - _dataSectionOffset)
- {
- throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesDataInvalidOffset, dataPos));
- }
- ResourceTypeCode junk;
- if (_version == 1)
- return LoadObjectV1(dataPos);
- else
- return LoadObjectV2(dataPos, out junk);
- }
- }
-
- // This takes a virtual offset into the data section and reads a String
- // from that location.
- // Anyone who calls LoadObject should make sure they take a lock so
- // no one can cause us to do a seek in here.
- internal string LoadString(int pos)
- {
- Debug.Assert(_store != null, "ResourceReader is closed!");
- _store.BaseStream.Seek(_dataSectionOffset + pos, SeekOrigin.Begin);
- string s = null;
- int typeIndex = Read7BitEncodedInt();
- if (_version == 1)
- {
- if (typeIndex == -1)
- return null;
- if (FindType(typeIndex) != typeof(string))
- throw new InvalidOperationException(SR.Format(SR.InvalidOperation_ResourceNotString_Type, FindType(typeIndex).FullName));
- s = _store.ReadString();
- }
- else
- {
- ResourceTypeCode typeCode = (ResourceTypeCode)typeIndex;
- if (typeCode != ResourceTypeCode.String && typeCode != ResourceTypeCode.Null)
- {
- string typeString;
- if (typeCode < ResourceTypeCode.StartOfUserTypes)
- typeString = typeCode.ToString();
- else
- typeString = FindType(typeCode - ResourceTypeCode.StartOfUserTypes).FullName;
- throw new InvalidOperationException(SR.Format(SR.InvalidOperation_ResourceNotString_Type, typeString));
- }
- if (typeCode == ResourceTypeCode.String) // ignore Null
- s = _store.ReadString();
- }
- return s;
- }
-
- // Called from RuntimeResourceSet
- internal object LoadObject(int pos)
- {
- if (_version == 1)
- return LoadObjectV1(pos);
- ResourceTypeCode typeCode;
- return LoadObjectV2(pos, out typeCode);
- }
-
- internal object LoadObject(int pos, out ResourceTypeCode typeCode)
- {
- if (_version == 1)
- {
- object o = LoadObjectV1(pos);
- typeCode = (o is string) ? ResourceTypeCode.String : ResourceTypeCode.StartOfUserTypes;
- return o;
- }
- return LoadObjectV2(pos, out typeCode);
- }
-
- // This takes a virtual offset into the data section and reads an Object
- // from that location.
- // Anyone who calls LoadObject should make sure they take a lock so
- // no one can cause us to do a seek in here.
- internal object LoadObjectV1(int pos)
- {
- Debug.Assert(_store != null, "ResourceReader is closed!");
- Debug.Assert(_version == 1, ".resources file was not a V1 .resources file!");
-
- try
- {
- // mega try-catch performs exceptionally bad on x64; factored out body into
- // _LoadObjectV1 and wrap here.
- return _LoadObjectV1(pos);
- }
- catch (EndOfStreamException eof)
- {
- throw new BadImageFormatException(SR.BadImageFormat_TypeMismatch, eof);
- }
- catch (ArgumentOutOfRangeException e)
- {
- throw new BadImageFormatException(SR.BadImageFormat_TypeMismatch, e);
- }
- }
-
- private object _LoadObjectV1(int pos)
- {
- _store.BaseStream.Seek(_dataSectionOffset + pos, SeekOrigin.Begin);
- int typeIndex = Read7BitEncodedInt();
- if (typeIndex == -1)
- return null;
- Type type = FindType(typeIndex);
- // Consider putting in logic to see if this type is a
- // primitive or a value type first, so we can reach the
- // deserialization code faster for arbitrary objects.
-
- if (type == typeof(string))
- return _store.ReadString();
- else if (type == typeof(int))
- return _store.ReadInt32();
- else if (type == typeof(byte))
- return _store.ReadByte();
- else if (type == typeof(sbyte))
- return _store.ReadSByte();
- else if (type == typeof(short))
- return _store.ReadInt16();
- else if (type == typeof(long))
- return _store.ReadInt64();
- else if (type == typeof(ushort))
- return _store.ReadUInt16();
- else if (type == typeof(uint))
- return _store.ReadUInt32();
- else if (type == typeof(ulong))
- return _store.ReadUInt64();
- else if (type == typeof(float))
- return _store.ReadSingle();
- else if (type == typeof(double))
- return _store.ReadDouble();
- else if (type == typeof(DateTime))
- {
- // Ideally we should use DateTime's ToBinary & FromBinary,
- // but we can't for compatibility reasons.
- return new DateTime(_store.ReadInt64());
- }
- else if (type == typeof(TimeSpan))
- return new TimeSpan(_store.ReadInt64());
- else if (type == typeof(decimal))
- {
- int[] bits = new int[4];
- for (int i = 0; i < bits.Length; i++)
- bits[i] = _store.ReadInt32();
- return new decimal(bits);
- }
- else
- {
- throw new NotSupportedException(SR.NotSupported_ResourceObjectSerialization);
- }
- }
-
- internal object LoadObjectV2(int pos, out ResourceTypeCode typeCode)
- {
- Debug.Assert(_store != null, "ResourceReader is closed!");
- Debug.Assert(_version >= 2, ".resources file was not a V2 (or higher) .resources file!");
-
- try
- {
- // mega try-catch performs exceptionally bad on x64; factored out body into
- // _LoadObjectV2 and wrap here.
- return _LoadObjectV2(pos, out typeCode);
- }
- catch (EndOfStreamException eof)
- {
- throw new BadImageFormatException(SR.BadImageFormat_TypeMismatch, eof);
- }
- catch (ArgumentOutOfRangeException e)
- {
- throw new BadImageFormatException(SR.BadImageFormat_TypeMismatch, e);
- }
- }
-
- private object _LoadObjectV2(int pos, out ResourceTypeCode typeCode)
- {
- _store.BaseStream.Seek(_dataSectionOffset + pos, SeekOrigin.Begin);
- typeCode = (ResourceTypeCode)Read7BitEncodedInt();
-
- switch (typeCode)
- {
- case ResourceTypeCode.Null:
- return null;
-
- case ResourceTypeCode.String:
- return _store.ReadString();
-
- case ResourceTypeCode.Boolean:
- return _store.ReadBoolean();
-
- case ResourceTypeCode.Char:
- return (char)_store.ReadUInt16();
-
- case ResourceTypeCode.Byte:
- return _store.ReadByte();
-
- case ResourceTypeCode.SByte:
- return _store.ReadSByte();
-
- case ResourceTypeCode.Int16:
- return _store.ReadInt16();
-
- case ResourceTypeCode.UInt16:
- return _store.ReadUInt16();
-
- case ResourceTypeCode.Int32:
- return _store.ReadInt32();
-
- case ResourceTypeCode.UInt32:
- return _store.ReadUInt32();
-
- case ResourceTypeCode.Int64:
- return _store.ReadInt64();
-
- case ResourceTypeCode.UInt64:
- return _store.ReadUInt64();
-
- case ResourceTypeCode.Single:
- return _store.ReadSingle();
-
- case ResourceTypeCode.Double:
- return _store.ReadDouble();
-
- case ResourceTypeCode.Decimal:
- return _store.ReadDecimal();
-
- case ResourceTypeCode.DateTime:
- // Use DateTime's ToBinary & FromBinary.
- long data = _store.ReadInt64();
- return DateTime.FromBinary(data);
-
- case ResourceTypeCode.TimeSpan:
- long ticks = _store.ReadInt64();
- return new TimeSpan(ticks);
-
- // Special types
- case ResourceTypeCode.ByteArray:
- {
- int len = _store.ReadInt32();
- if (len < 0)
- {
- throw new BadImageFormatException(SR.Format(SR.BadImageFormat_ResourceDataLengthInvalid, len));
- }
-
- if (_ums == null)
- {
- if (len > _store.BaseStream.Length)
- {
- throw new BadImageFormatException(SR.Format(SR.BadImageFormat_ResourceDataLengthInvalid, len));
- }
- return _store.ReadBytes(len);
- }
-
- if (len > _ums.Length - _ums.Position)
- {
- throw new BadImageFormatException(SR.Format(SR.BadImageFormat_ResourceDataLengthInvalid, len));
- }
-
- byte[] bytes = new byte[len];
- int r = _ums.Read(bytes, 0, len);
- Debug.Assert(r == len, "ResourceReader needs to use a blocking read here. (Call _store.ReadBytes(len)?)");
- return bytes;
- }
-
- case ResourceTypeCode.Stream:
- {
- int len = _store.ReadInt32();
- if (len < 0)
- {
- throw new BadImageFormatException(SR.Format(SR.BadImageFormat_ResourceDataLengthInvalid, len));
- }
- if (_ums == null)
- {
- byte[] bytes = _store.ReadBytes(len);
- // Lifetime of memory == lifetime of this stream.
- return new PinnedBufferMemoryStream(bytes);
- }
-
- // make sure we don't create an UnmanagedMemoryStream that is longer than the resource stream.
- if (len > _ums.Length - _ums.Position)
- {
- throw new BadImageFormatException(SR.Format(SR.BadImageFormat_ResourceDataLengthInvalid, len));
- }
-
- // For the case that we've memory mapped in the .resources
- // file, just return a Stream pointing to that block of memory.
- unsafe
- {
- return new UnmanagedMemoryStream(_ums.PositionPointer, len, len, FileAccess.Read);
- }
- }
-
- default:
- if (typeCode < ResourceTypeCode.StartOfUserTypes)
- {
- throw new BadImageFormatException(SR.BadImageFormat_TypeMismatch);
- }
- break;
- }
-
- // Normal serialized objects
- throw new NotSupportedException(SR.NotSupported_ResourceObjectSerialization);
- }
-
- // Reads in the header information for a .resources file. Verifies some
- // of the assumptions about this resource set, and builds the class table
- // for the default resource file format.
- private void ReadResources()
- {
- Debug.Assert(_store != null, "ResourceReader is closed!");
-
- try
- {
- // mega try-catch performs exceptionally bad on x64; factored out body into
- // _ReadResources and wrap here.
- _ReadResources();
- }
- catch (EndOfStreamException eof)
- {
- throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted, eof);
- }
- catch (IndexOutOfRangeException e)
- {
- throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted, e);
- }
- }
-
- private void _ReadResources()
- {
- // Read ResourceManager header
- // Check for magic number
- int magicNum = _store.ReadInt32();
- if (magicNum != ResourceManager.MagicNumber)
- throw new ArgumentException(SR.Resources_StreamNotValid);
- // Assuming this is ResourceManager header V1 or greater, hopefully
- // after the version number there is a number of bytes to skip
- // to bypass the rest of the ResMgr header. For V2 or greater, we
- // use this to skip to the end of the header
- int resMgrHeaderVersion = _store.ReadInt32();
- int numBytesToSkip = _store.ReadInt32();
- if (numBytesToSkip < 0 || resMgrHeaderVersion < 0)
- {
- throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted);
- }
- if (resMgrHeaderVersion > 1)
- {
- _store.BaseStream.Seek(numBytesToSkip, SeekOrigin.Current);
- }
- else
- {
- // We don't care about numBytesToSkip; read the rest of the header
-
- // Read in type name for a suitable ResourceReader
- // Note ResourceWriter & InternalResGen use different Strings.
- string readerType = _store.ReadString();
- readerType = System.CoreLib.FixupCoreLibName(readerType);
- AssemblyName mscorlib = new AssemblyName(ResourceManager.MscorlibName);
-
- if (!ResourceManager.CompareNames(readerType, ResourceManager.ResReaderTypeName, mscorlib))
- throw new NotSupportedException(SR.Format(SR.NotSupported_WrongResourceReader_Type, readerType));
-
- // Skip over type name for a suitable ResourceSet
- SkipString();
- }
-
- // Read RuntimeResourceSet header
- // Do file version check
- int version = _store.ReadInt32();
- if (version != RuntimeResourceSet.Version && version != 1)
- throw new ArgumentException(SR.Format(SR.Arg_ResourceFileUnsupportedVersion, RuntimeResourceSet.Version, version));
- _version = version;
-
- _numResources = _store.ReadInt32();
- if (_numResources < 0)
- {
- throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted);
- }
-
- // Read type positions into type positions array.
- // But delay initialize the type table.
- int numTypes = _store.ReadInt32();
- if (numTypes < 0)
- {
- throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted);
- }
- _typeTable = new Type[numTypes];
- _typeNamePositions = new int[numTypes];
- for (int i = 0; i < numTypes; i++)
- {
- _typeNamePositions[i] = (int)_store.BaseStream.Position;
-
- // Skip over the Strings in the file. Don't create types.
- SkipString();
- }
-
- // Prepare to read in the array of name hashes
- // Note that the name hashes array is aligned to 8 bytes so
- // we can use pointers into it on 64 bit machines. (4 bytes
- // may be sufficient, but let's plan for the future)
- // Skip over alignment stuff. All public .resources files
- // should be aligned No need to verify the byte values.
- long pos = _store.BaseStream.Position;
- int alignBytes = ((int)pos) & 7;
- if (alignBytes != 0)
- {
- for (int i = 0; i < 8 - alignBytes; i++)
- {
- _store.ReadByte();
- }
- }
-
- // Read in the array of name hashes
- if (_ums == null)
- {
- _nameHashes = new int[_numResources];
- for (int i = 0; i < _numResources; i++)
- {
- _nameHashes[i] = _store.ReadInt32();
- }
- }
- else
- {
- int seekPos = unchecked(4 * _numResources);
- if (seekPos < 0)
- {
- throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted);
- }
- unsafe
- {
- _nameHashesPtr = (int*)_ums.PositionPointer;
- // Skip over the array of nameHashes.
- _ums.Seek(seekPos, SeekOrigin.Current);
- // get the position pointer once more to check that the whole table is within the stream
- byte* junk = _ums.PositionPointer;
- }
- }
-
- // Read in the array of relative positions for all the names.
- if (_ums == null)
- {
- _namePositions = new int[_numResources];
- for (int i = 0; i < _numResources; i++)
- {
- int namePosition = _store.ReadInt32();
- if (namePosition < 0)
- {
- throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted);
- }
-
- _namePositions[i] = namePosition;
- }
- }
- else
- {
- int seekPos = unchecked(4 * _numResources);
- if (seekPos < 0)
- {
- throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted);
- }
- unsafe
- {
- _namePositionsPtr = (int*)_ums.PositionPointer;
- // Skip over the array of namePositions.
- _ums.Seek(seekPos, SeekOrigin.Current);
- // get the position pointer once more to check that the whole table is within the stream
- byte* junk = _ums.PositionPointer;
- }
- }
-
- // Read location of data section.
- _dataSectionOffset = _store.ReadInt32();
- if (_dataSectionOffset < 0)
- {
- throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted);
- }
-
- // Store current location as start of name section
- _nameSectionOffset = _store.BaseStream.Position;
-
- // _nameSectionOffset should be <= _dataSectionOffset; if not, it's corrupt
- if (_dataSectionOffset < _nameSectionOffset)
- {
- throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted);
- }
- }
-
- // This allows us to delay-initialize the Type[]. This might be a
- // good startup time savings, since we might have to load assemblies
- // and initialize Reflection.
- private Type FindType(int typeIndex)
- {
- if (typeIndex < 0 || typeIndex >= _typeTable.Length)
- {
- throw new BadImageFormatException(SR.BadImageFormat_InvalidType);
- }
- if (_typeTable[typeIndex] == null)
- {
- long oldPos = _store.BaseStream.Position;
- try
- {
- _store.BaseStream.Position = _typeNamePositions[typeIndex];
- string typeName = _store.ReadString();
- _typeTable[typeIndex] = Type.GetType(typeName, true);
- }
- // If serialization isn't supported, we convert FileNotFoundException to
- // NotSupportedException for consistency with v2. This is a corner-case, but the
- // idea is that we want to give the user a more accurate error message. Even if
- // the dependency were found, we know it will require serialization since it
- // can't be one of the types we special case. So if the dependency were found,
- // it would go down the serialization code path, resulting in NotSupported for
- // SKUs without serialization.
- //
- // We don't want to regress the expected case by checking the type info before
- // getting to Type.GetType -- this is costly with v1 resource formats.
- catch (FileNotFoundException)
- {
- throw new NotSupportedException(SR.NotSupported_ResourceObjectSerialization);
- }
- finally
- {
- _store.BaseStream.Position = oldPos;
- }
- }
- Debug.Assert(_typeTable[typeIndex] != null, "Should have found a type!");
- return _typeTable[typeIndex];
- }
-
- public void GetResourceData(string resourceName, out string resourceType, out byte[] resourceData)
- {
- if (resourceName == null)
- throw new ArgumentNullException(nameof(resourceName));
- if (_resCache == null)
- throw new InvalidOperationException(SR.ResourceReaderIsClosed);
-
- // Get the type information from the data section. Also,
- // sort all of the data section's indexes to compute length of
- // the serialized data for this type (making sure to subtract
- // off the length of the type code).
- int[] sortedDataPositions = new int[_numResources];
- int dataPos = FindPosForResource(resourceName);
- if (dataPos == -1)
- {
- throw new ArgumentException(SR.Format(SR.Arg_ResourceNameNotExist, resourceName));
- }
-
- lock (this)
- {
- // Read all the positions of data within the data section.
- for (int i = 0; i < _numResources; i++)
- {
- _store.BaseStream.Position = _nameSectionOffset + GetNamePosition(i);
- // Skip over name of resource
- int numBytesToSkip = Read7BitEncodedInt();
- if (numBytesToSkip < 0)
- {
- throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesNameInvalidOffset, numBytesToSkip));
- }
- _store.BaseStream.Position += numBytesToSkip;
-
- int dPos = _store.ReadInt32();
- if (dPos < 0 || dPos >= _store.BaseStream.Length - _dataSectionOffset)
- {
- throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesDataInvalidOffset, dPos));
- }
- sortedDataPositions[i] = dPos;
- }
- Array.Sort(sortedDataPositions);
-
- int index = Array.BinarySearch(sortedDataPositions, dataPos);
- Debug.Assert(index >= 0 && index < _numResources, "Couldn't find data position within sorted data positions array!");
- long nextData = (index < _numResources - 1) ? sortedDataPositions[index + 1] + _dataSectionOffset : _store.BaseStream.Length;
- int len = (int)(nextData - (dataPos + _dataSectionOffset));
- Debug.Assert(len >= 0 && len <= (int)_store.BaseStream.Length - dataPos + _dataSectionOffset, "Length was negative or outside the bounds of the file!");
-
- // Read type code then byte[]
- _store.BaseStream.Position = _dataSectionOffset + dataPos;
- ResourceTypeCode typeCode = (ResourceTypeCode)Read7BitEncodedInt();
- if (typeCode < 0 || typeCode >= ResourceTypeCode.StartOfUserTypes + _typeTable.Length)
- {
- throw new BadImageFormatException(SR.BadImageFormat_InvalidType);
- }
- resourceType = TypeNameFromTypeCode(typeCode);
-
- // The length must be adjusted to subtract off the number
- // of bytes in the 7 bit encoded type code.
- len -= (int)(_store.BaseStream.Position - (_dataSectionOffset + dataPos));
- byte[] bytes = _store.ReadBytes(len);
- if (bytes.Length != len)
- throw new FormatException(SR.BadImageFormat_ResourceNameCorrupted);
- resourceData = bytes;
- }
- }
-
- private string TypeNameFromTypeCode(ResourceTypeCode typeCode)
- {
- Debug.Assert(typeCode >= 0, "can't be negative");
- if (typeCode < ResourceTypeCode.StartOfUserTypes)
- {
- Debug.Assert(!string.Equals(typeCode.ToString(), "LastPrimitive"), "Change ResourceTypeCode metadata order so LastPrimitive isn't what Enum.ToString prefers.");
- return "ResourceTypeCode." + typeCode.ToString();
- }
- else
- {
- int typeIndex = typeCode - ResourceTypeCode.StartOfUserTypes;
- Debug.Assert(typeIndex >= 0 && typeIndex < _typeTable.Length, "TypeCode is broken or corrupted!");
- long oldPos = _store.BaseStream.Position;
- try
- {
- _store.BaseStream.Position = _typeNamePositions[typeIndex];
- return _store.ReadString();
- }
- finally
- {
- _store.BaseStream.Position = oldPos;
- }
- }
- }
-
- internal sealed class ResourceEnumerator : IDictionaryEnumerator
- {
- private const int ENUM_DONE = int.MinValue;
- private const int ENUM_NOT_STARTED = -1;
-
- private ResourceReader _reader;
- private bool _currentIsValid;
- private int _currentName;
- private int _dataPosition; // cached for case-insensitive table
-
- internal ResourceEnumerator(ResourceReader reader)
- {
- _currentName = ENUM_NOT_STARTED;
- _reader = reader;
- _dataPosition = -2;
- }
-
- public bool MoveNext()
- {
- if (_currentName == _reader._numResources - 1 || _currentName == ENUM_DONE)
- {
- _currentIsValid = false;
- _currentName = ENUM_DONE;
- return false;
- }
- _currentIsValid = true;
- _currentName++;
- return true;
- }
-
- public object Key
- {
- get
- {
- if (_currentName == ENUM_DONE) throw new InvalidOperationException(SR.InvalidOperation_EnumEnded);
- if (!_currentIsValid) throw new InvalidOperationException(SR.InvalidOperation_EnumNotStarted);
- if (_reader._resCache == null) throw new InvalidOperationException(SR.ResourceReaderIsClosed);
-
- return _reader.AllocateStringForNameIndex(_currentName, out _dataPosition);
- }
- }
-
- public object Current
- {
- get
- {
- return Entry;
- }
- }
-
- // Warning: This requires that you call the Key or Entry property FIRST before calling it!
- internal int DataPosition
- {
- get
- {
- return _dataPosition;
- }
- }
-
- public DictionaryEntry Entry
- {
- get
- {
- if (_currentName == ENUM_DONE) throw new InvalidOperationException(SR.InvalidOperation_EnumEnded);
- if (!_currentIsValid) throw new InvalidOperationException(SR.InvalidOperation_EnumNotStarted);
- if (_reader._resCache == null) throw new InvalidOperationException(SR.ResourceReaderIsClosed);
-
- string key;
- object value = null;
- lock (_reader)
- { // locks should be taken in the same order as in RuntimeResourceSet.GetObject to avoid deadlock
- lock (_reader._resCache)
- {
- key = _reader.AllocateStringForNameIndex(_currentName, out _dataPosition); // AllocateStringForNameIndex could lock on _reader
- ResourceLocator locator;
- if (_reader._resCache.TryGetValue(key, out locator))
- {
- value = locator.Value;
- }
- if (value == null)
- {
- if (_dataPosition == -1)
- value = _reader.GetValueForNameIndex(_currentName);
- else
- value = _reader.LoadObject(_dataPosition);
- // If enumeration and subsequent lookups happen very
- // frequently in the same process, add a ResourceLocator
- // to _resCache here. But WinForms enumerates and
- // just about everyone else does lookups. So caching
- // here may bloat working set.
- }
- }
- }
- return new DictionaryEntry(key, value);
- }
- }
-
- public object Value
- {
- get
- {
- if (_currentName == ENUM_DONE) throw new InvalidOperationException(SR.InvalidOperation_EnumEnded);
- if (!_currentIsValid) throw new InvalidOperationException(SR.InvalidOperation_EnumNotStarted);
- if (_reader._resCache == null) throw new InvalidOperationException(SR.ResourceReaderIsClosed);
-
- // Consider using _resCache here, eventually, if
- // this proves to be an interesting perf scenario.
- // But mixing lookups and enumerators shouldn't be
- // particularly compelling.
- return _reader.GetValueForNameIndex(_currentName);
- }
- }
-
- public void Reset()
- {
- if (_reader._resCache == null) throw new InvalidOperationException(SR.ResourceReaderIsClosed);
- _currentIsValid = false;
- _currentName = ENUM_NOT_STARTED;
- }
- }
- }
-}
diff --git a/src/System.Private.CoreLib/src/System/Resources/ResourceSet.cs b/src/System.Private.CoreLib/src/System/Resources/ResourceSet.cs
deleted file mode 100644
index a6763c4a8..000000000
--- a/src/System.Private.CoreLib/src/System/Resources/ResourceSet.cs
+++ /dev/null
@@ -1,291 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-**
-**
-**
-**
-** Purpose: Culture-specific collection of resources.
-**
-**
-===========================================================*/
-
-using System;
-using System.Collections;
-using System.IO;
-using System.Globalization;
-using System.Runtime.InteropServices;
-using System.Reflection;
-using System.Runtime.Serialization;
-using System.Runtime.Versioning;
-using System.Collections.Generic;
-
-namespace System.Resources
-{
- // 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.
- //
- public class ResourceSet : IDisposable, IEnumerable
- {
- [NonSerialized]
- protected IResourceReader Reader;
-
- private Dictionary<object, object> _table;
- private Dictionary<object, object> _caseInsensitiveTable; // For case-insensitive lookups.
-
- 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.
- //
- public ResourceSet(string fileName)
- {
- Reader = new ResourceReader(fileName);
- CommonInit();
- ReadResources();
- }
-
- // Creates a ResourceSet using the system default ResourceReader
- // implementation. Use this constructor to read from an open stream
- // of data.
- //
- public ResourceSet(Stream stream)
- {
- Reader = new ResourceReader(stream);
- CommonInit();
- ReadResources();
- }
-
- public ResourceSet(IResourceReader reader)
- {
- if (reader == null)
- throw new ArgumentNullException(nameof(reader));
- Reader = reader;
- CommonInit();
- ReadResources();
- }
-
- private void CommonInit()
- {
- _table = new Dictionary<object, object>();
- }
-
- // 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);
- }
-
- // 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);
- }
-
- // 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()
- {
- Assembly resourceWriterAssembly = Assembly.Load("System.Resources.Writer, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
- return resourceWriterAssembly.GetType("System.Resources.ResourceWriter", true);
- }
-
- public virtual IDictionaryEnumerator GetEnumerator()
- {
- return GetEnumeratorHelper();
- }
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumeratorHelper();
- }
-
- private IDictionaryEnumerator GetEnumeratorHelper()
- {
- Dictionary<object, object> copyOfTable = _table; // Avoid a race with Dispose
- if (copyOfTable == null)
- throw new ObjectDisposedException(null, SR.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(SR.Format(SR.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(SR.Format(SR.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(SR.Format(SR.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;
- _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");
-
- Dictionary<object, object> copyOfTable = _table; // Avoid a race with Dispose
-
- if (copyOfTable == null)
- throw new ObjectDisposedException(null, SR.ObjectDisposed_ResourceSet);
- object value;
- copyOfTable.TryGetValue(name, out value);
- return value;
- }
-
- private object GetCaseInsensitiveObjectInternal(string name)
- {
- Dictionary<object, object> copyOfTable = _table; // Avoid a race with Dispose
-
- if (copyOfTable == null)
- throw new ObjectDisposedException(null, SR.ObjectDisposed_ResourceSet);
-
- Dictionary<object, object> caseTable = _caseInsensitiveTable; // Avoid a race condition with Close
- if (caseTable == null)
- {
- caseTable = new Dictionary<object, object>(CaseInsensitiveStringObjectComparer.Instance);
-
- IDictionaryEnumerator en = copyOfTable.GetEnumerator();
- while (en.MoveNext())
- {
- caseTable.Add(en.Key, en.Value);
- }
- _caseInsensitiveTable = caseTable;
- }
- object value;
- caseTable.TryGetValue(name, out value);
- return value;
- }
-
- /// <summary>
- /// Adapter for StringComparer.OrdinalIgnoreCase to allow it to be used with Dictionary
- /// </summary>
- private class CaseInsensitiveStringObjectComparer : IEqualityComparer<object>
- {
- public static CaseInsensitiveStringObjectComparer Instance { get; } = new CaseInsensitiveStringObjectComparer();
-
- private CaseInsensitiveStringObjectComparer() { }
-
- public new bool Equals(object x, object y)
- {
- return ((IEqualityComparer)StringComparer.OrdinalIgnoreCase).Equals(x, y);
- }
-
- public int GetHashCode(object obj)
- {
- return ((IEqualityComparer)StringComparer.OrdinalIgnoreCase).GetHashCode(obj);
- }
- }
- }
-}