diff options
author | Jan Kotas <jkotas@microsoft.com> | 2018-09-16 23:56:38 +0300 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2018-09-17 06:53:24 +0300 |
commit | 4f10c2ad36c8ef2fe82366c6dc3b5ea88c1f3543 (patch) | |
tree | 8f2c1a4eec11d08127afb9cd7d62b6515f463917 | |
parent | a11fabf11537bbe3bdf4691d29e91c862d55f9b4 (diff) |
Delete files moved to shared partition
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); - } - } - } -} |