diff options
Diffstat (limited to 'src/mscorlib/src/System/Resources')
18 files changed, 799 insertions, 1071 deletions
diff --git a/src/mscorlib/src/System/Resources/FileBasedResourceGroveler.cs b/src/mscorlib/src/System/Resources/FileBasedResourceGroveler.cs index c5e92165f1..e1bbd2814a 100644 --- a/src/mscorlib/src/System/Resources/FileBasedResourceGroveler.cs +++ b/src/mscorlib/src/System/Resources/FileBasedResourceGroveler.cs @@ -13,7 +13,9 @@ ** ** ===========================================================*/ -namespace System.Resources { + +namespace System.Resources +{ using System; using System.Collections; using System.Collections.Generic; @@ -39,7 +41,7 @@ namespace System.Resources { // Consider modifying IResourceGroveler interface (hence this method signature) when we figure out // serialization compat story for moving ResourceManager members to either file-based or // manifest-based classes. Want to continue tightening the design to get rid of unused params. - public ResourceSet GrovelForResourceSet(CultureInfo culture, Dictionary<String, ResourceSet> localResourceSets, bool tryParents, bool createIfNotExists, ref StackCrawlMark stackMark) + public ResourceSet GrovelForResourceSet(CultureInfo culture, Dictionary<String, ResourceSet> localResourceSets, bool tryParents, bool createIfNotExists, ref StackCrawlMark stackMark) { Debug.Assert(culture != null, "culture shouldn't be null; check caller"); @@ -60,7 +62,7 @@ namespace System.Resources { { // We really don't think this should happen - we always // expect the neutral locale's resources to be present. - throw new MissingManifestResourceException(Environment.GetResourceString("MissingManifestResource_NoNeutralDisk") + Environment.NewLine + "baseName: " + _mediator.BaseNameField + " locationInfo: " + (_mediator.LocationInfo == null ? "<null>" : _mediator.LocationInfo.FullName) + " fileName: " + _mediator.GetResourceFileName(culture)); + throw new MissingManifestResourceException(SR.MissingManifestResource_NoNeutralDisk + Environment.NewLine + "baseName: " + _mediator.BaseNameField + " locationInfo: " + (_mediator.LocationInfo == null ? "<null>" : _mediator.LocationInfo.FullName) + " fileName: " + _mediator.GetResourceFileName(culture)); } } } @@ -90,7 +92,7 @@ namespace System.Resources { { #if _DEBUG if (ResourceManager.DEBUG >= 3) - BCLDebug.Log("FindResourceFile: checking module dir: \""+_mediator.ModuleDir+'\"'); + BCLDebug.Log("FindResourceFile: checking module dir: \"" + _mediator.ModuleDir + '\"'); #endif String path = Path.Combine(_mediator.ModuleDir, fileName); @@ -98,7 +100,7 @@ namespace System.Resources { { #if _DEBUG if (ResourceManager.DEBUG >= 3) - BCLDebug.Log("Found resource file in module dir! "+path); + BCLDebug.Log("Found resource file in module dir! " + path); #endif return path; } @@ -106,7 +108,7 @@ namespace System.Resources { #if _DEBUG if (ResourceManager.DEBUG >= 3) - BCLDebug.Log("Couldn't find resource file in module dir, checking .\\"+fileName); + BCLDebug.Log("Couldn't find resource file in module dir, checking .\\" + fileName); #endif // look in . @@ -140,7 +142,7 @@ namespace System.Resources { } catch (MissingMethodException e) { - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResMgrBadResSet_Type", _mediator.UserResourceSet.AssemblyQualifiedName), e); + throw new InvalidOperationException(SR.Format(SR.InvalidOperation_ResMgrBadResSet_Type, _mediator.UserResourceSet.AssemblyQualifiedName), e); } } } diff --git a/src/mscorlib/src/System/Resources/IResourceGroveler.cs b/src/mscorlib/src/System/Resources/IResourceGroveler.cs index 77c5c95890..bdd8826c77 100644 --- a/src/mscorlib/src/System/Resources/IResourceGroveler.cs +++ b/src/mscorlib/src/System/Resources/IResourceGroveler.cs @@ -12,16 +12,18 @@ ** ** ===========================================================*/ -namespace System.Resources { - using System; - using System.Globalization; - using System.Threading; - using System.Collections.Generic; - using System.Runtime.Versioning; +using System; +using System.Globalization; +using System.Threading; +using System.Collections.Generic; +using System.Runtime.Versioning; + +namespace System.Resources +{ internal interface IResourceGroveler { - ResourceSet GrovelForResourceSet(CultureInfo culture, Dictionary<String, ResourceSet> localResourceSets, bool tryParents, + ResourceSet GrovelForResourceSet(CultureInfo culture, Dictionary<String, ResourceSet> localResourceSets, bool tryParents, bool createIfNotExists, ref StackCrawlMark stackMark); } } diff --git a/src/mscorlib/src/System/Resources/IResourceReader.cs b/src/mscorlib/src/System/Resources/IResourceReader.cs deleted file mode 100644 index de8f9db18e..0000000000 --- a/src/mscorlib/src/System/Resources/IResourceReader.cs +++ /dev/null @@ -1,30 +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: Abstraction to read streams of resources. -** -** -===========================================================*/ -namespace System.Resources { - using System; - using System.IO; - using System.Collections; - - public interface IResourceReader : IEnumerable, IDisposable - { - // Interface does not need to be marked with the serializable attribute - // Closes the ResourceReader, releasing any resources associated with it. - // This could close a network connection, a file, or do nothing. - void Close(); - - - new IDictionaryEnumerator GetEnumerator(); - } -} diff --git a/src/mscorlib/src/System/Resources/LooselyLinkedResourceReference.cs b/src/mscorlib/src/System/Resources/LooselyLinkedResourceReference.cs index 9287ae4590..3179df09b7 100644 --- a/src/mscorlib/src/System/Resources/LooselyLinkedResourceReference.cs +++ b/src/mscorlib/src/System/Resources/LooselyLinkedResourceReference.cs @@ -39,9 +39,9 @@ namespace System.Resources { if (typeName == null) throw new ArgumentNullException(nameof(typeName)); if (looselyLinkedResourceName.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(looselyLinkedResourceName)); + throw new ArgumentException(SR.Argument_EmptyName, nameof(looselyLinkedResourceName)); if (typeName.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(typeName)); + throw new ArgumentException(SR.Argument_EmptyName, nameof(typeName)); Contract.EndContractBlock(); _manifestResourceName = looselyLinkedResourceName; @@ -64,7 +64,7 @@ namespace System.Resources { Stream data = assembly.GetManifestResourceStream(_manifestResourceName); if (data == null) - throw new MissingManifestResourceException(Environment.GetResourceString("MissingManifestResource_LooselyLinked", _manifestResourceName, assembly.FullName)); + throw new MissingManifestResourceException(SR.Format(SR.MissingManifestResource_LooselyLinked, _manifestResourceName, assembly.FullName)); Type type = Type.GetType(_typeName, true); diff --git a/src/mscorlib/src/System/Resources/ManifestBasedResourceGroveler.cs b/src/mscorlib/src/System/Resources/ManifestBasedResourceGroveler.cs index 78e961a7f9..0e9666b2b1 100644 --- a/src/mscorlib/src/System/Resources/ManifestBasedResourceGroveler.cs +++ b/src/mscorlib/src/System/Resources/ManifestBasedResourceGroveler.cs @@ -13,8 +13,9 @@ ** ** ===========================================================*/ -namespace System.Resources { +namespace System.Resources +{ using System; using System.Collections; using System.Collections.Generic; @@ -41,7 +42,6 @@ namespace System.Resources { // internal class ManifestBasedResourceGroveler : IResourceGroveler { - private ResourceManager.ResourceManagerMediator _mediator; public ManifestBasedResourceGroveler(ResourceManager.ResourceManagerMediator mediator) @@ -52,7 +52,6 @@ namespace System.Resources { _mediator = mediator; } - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable public ResourceSet GrovelForResourceSet(CultureInfo culture, Dictionary<String, ResourceSet> localResourceSets, bool tryParents, bool createIfNotExists, ref StackCrawlMark stackMark) { Debug.Assert(culture != null, "culture shouldn't be null; check caller"); @@ -132,7 +131,6 @@ namespace System.Resources { private CultureInfo UltimateFallbackFixup(CultureInfo lookForCulture) { - CultureInfo returnCulture = lookForCulture; // If our neutral resources were written in this culture AND we know the main assembly @@ -155,15 +153,18 @@ namespace System.Resources { Debug.Assert(a != null, "assembly != null"); string cultureName = null; short fallback = 0; - if (GetNeutralResourcesLanguageAttribute(((RuntimeAssembly)a).GetNativeHandle(), - JitHelpers.GetStringHandleOnStack(ref cultureName), - out fallback)) { - if ((UltimateResourceFallbackLocation)fallback < UltimateResourceFallbackLocation.MainAssembly || (UltimateResourceFallbackLocation)fallback > UltimateResourceFallbackLocation.Satellite) { - throw new ArgumentException(Environment.GetResourceString("Arg_InvalidNeutralResourcesLanguage_FallbackLoc", fallback)); + if (GetNeutralResourcesLanguageAttribute(((RuntimeAssembly)a).GetNativeHandle(), + JitHelpers.GetStringHandleOnStack(ref cultureName), + out fallback)) + { + if ((UltimateResourceFallbackLocation)fallback < UltimateResourceFallbackLocation.MainAssembly || (UltimateResourceFallbackLocation)fallback > UltimateResourceFallbackLocation.Satellite) + { + throw new ArgumentException(SR.Format(SR.Arg_InvalidNeutralResourcesLanguage_FallbackLoc, fallback)); } fallbackLocation = (UltimateResourceFallbackLocation)fallback; } - else { + else + { fallbackLocation = UltimateResourceFallbackLocation.MainAssembly; return CultureInfo.InvariantCulture; } @@ -180,11 +181,11 @@ namespace System.Resources { // fires, please fix the build process for the BCL directory. if (a == typeof(Object).Assembly) { - Debug.Assert(false, System.CoreLib.Name+"'s NeutralResourcesLanguageAttribute is a malformed culture name! name: \"" + cultureName + "\" Exception: " + e); + Debug.Assert(false, System.CoreLib.Name + "'s NeutralResourcesLanguageAttribute is a malformed culture name! name: \"" + cultureName + "\" Exception: " + e); return CultureInfo.InvariantCulture; } - throw new ArgumentException(Environment.GetResourceString("Arg_InvalidNeutralResourcesLanguage_Asm_Culture", a.ToString(), cultureName), e); + throw new ArgumentException(SR.Format(SR.Arg_InvalidNeutralResourcesLanguage_Asm_Culture, a.ToString(), cultureName), e); } } @@ -202,10 +203,10 @@ namespace System.Resources { if (store.CanSeek && store.Length > 4) { long startPos = store.Position; - + // not disposing because we want to leave stream open BinaryReader br = new BinaryReader(store); - + // Look for our magic number as a little endian Int32. int bytes = br.ReadInt32(); if (bytes == ResourceManager.MagicNumber) @@ -237,7 +238,7 @@ namespace System.Resources { // resMgrHeaderVersion is older than this ResMgr version. // We should add in backwards compatibility support here. - throw new NotSupportedException(Environment.GetResourceString("NotSupported_ObsoleteResourcesFile", _mediator.MainAssembly.GetSimpleName())); + throw new NotSupportedException(SR.Format(SR.NotSupported_ObsoleteResourcesFile, _mediator.MainAssembly.GetSimpleName())); } store.Position = startPos; @@ -294,7 +295,6 @@ namespace System.Resources { { store.Position = startPos; } - } if (_mediator.UserResourceSet == null) @@ -334,7 +334,7 @@ namespace System.Resources { } catch (MissingMethodException e) { - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResMgrBadResSet_Type", _mediator.UserResourceSet.AssemblyQualifiedName), e); + throw new InvalidOperationException(SR.Format(SR.InvalidOperation_ResMgrBadResSet_Type, _mediator.UserResourceSet.AssemblyQualifiedName), e); } } } @@ -362,7 +362,7 @@ namespace System.Resources { // case-insensitive lookup rules. Yes, this is slow. The metadata // dev lead refuses to make all assembly manifest resource lookups case-insensitive, // even optionally case-insensitive. - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable + [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod private Stream CaseInsensitiveManifestResourceStreamLookup(RuntimeAssembly satellite, String name) { Contract.Requires(satellite != null, "satellite shouldn't be null; check caller"); @@ -394,7 +394,7 @@ namespace System.Resources { } else { - throw new MissingManifestResourceException(Environment.GetResourceString("MissingManifestResource_MultipleBlobs", givenName, satellite.ToString())); + throw new MissingManifestResourceException(SR.Format(SR.MissingManifestResource_MultipleBlobs, givenName, satellite.ToString())); } } } @@ -412,7 +412,6 @@ namespace System.Resources { return satellite.GetManifestResourceStream(canonicalName, ref stackMark, canSkipSecurityCheck); } - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable private RuntimeAssembly GetSatelliteAssembly(CultureInfo lookForCulture, ref StackCrawlMark stackMark) { if (!_mediator.LookedForSatelliteContractVersion) @@ -493,7 +492,7 @@ namespace System.Resources { private String GetSatelliteAssemblyName() { String satAssemblyName = _mediator.MainAssembly.GetSimpleName(); - satAssemblyName += ".resources"; + satAssemblyName += ".resources"; return satAssemblyName; } @@ -522,7 +521,7 @@ namespace System.Resources { { missingCultureName = "<invariant>"; } - throw new MissingSatelliteAssemblyException(Environment.GetResourceString("MissingSatelliteAssembly_Culture_Name", _mediator.NeutralResourcesCulture, satAssemName), missingCultureName); + throw new MissingSatelliteAssemblyException(SR.Format(SR.MissingSatelliteAssembly_Culture_Name, _mediator.NeutralResourcesCulture, satAssemName), missingCultureName); } private void HandleResourceStreamMissing(String fileName) @@ -531,8 +530,8 @@ namespace System.Resources { if (_mediator.MainAssembly == typeof(Object).Assembly && _mediator.BaseName.Equals(System.CoreLib.Name)) { // This would break CultureInfo & all our exceptions. - Debug.Assert(false, "Couldn't get " + System.CoreLib.Name+ResourceManager.ResFileExtension + " from "+System.CoreLib.Name+"'s assembly" + Environment.NewLine + Environment.NewLine + "Are you building the runtime on your machine? Chances are the BCL directory didn't build correctly. Type 'build -c' in the BCL directory. If you get build errors, look at buildd.log. If you then can't figure out what's wrong (and you aren't changing the assembly-related metadata code), ask a BCL dev.\n\nIf you did NOT build the runtime, you shouldn't be seeing this and you've found a bug."); - + Debug.Assert(false, "Couldn't get " + System.CoreLib.Name + ResourceManager.ResFileExtension + " from " + System.CoreLib.Name + "'s assembly" + Environment.NewLine + Environment.NewLine + "Are you building the runtime on your machine? Chances are the BCL directory didn't build correctly. Type 'build -c' in the BCL directory. If you get build errors, look at buildd.log. If you then can't figure out what's wrong (and you aren't changing the assembly-related metadata code), ask a BCL dev.\n\nIf you did NOT build the runtime, you shouldn't be seeing this and you've found a bug."); + // We cannot continue further - simply FailFast. string mesgFailFast = System.CoreLib.Name + ResourceManager.ResFileExtension + " couldn't be found! Large parts of the BCL won't work!"; System.Environment.FailFast(mesgFailFast); @@ -543,12 +542,12 @@ namespace System.Resources { if (_mediator.LocationInfo != null && _mediator.LocationInfo.Namespace != null) resName = _mediator.LocationInfo.Namespace + Type.Delimiter; resName += fileName; - throw new MissingManifestResourceException(Environment.GetResourceString("MissingManifestResource_NoNeutralAsm", resName, _mediator.MainAssembly.GetSimpleName())); + throw new MissingManifestResourceException(SR.Format(SR.MissingManifestResource_NoNeutralAsm, resName, _mediator.MainAssembly.GetSimpleName())); } - [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] - [System.Security.SuppressUnmanagedCodeSecurity] - [return: MarshalAs(UnmanagedType.Bool)] - internal static extern bool GetNeutralResourcesLanguageAttribute(RuntimeAssembly assemblyHandle, StringHandleOnStack cultureName, out short fallbackLocation); + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [System.Security.SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GetNeutralResourcesLanguageAttribute(RuntimeAssembly assemblyHandle, StringHandleOnStack cultureName, out short fallbackLocation); } } diff --git a/src/mscorlib/src/System/Resources/MissingManifestResourceException.cs b/src/mscorlib/src/System/Resources/MissingManifestResourceException.cs deleted file mode 100644 index 2e82f19c7b..0000000000 --- a/src/mscorlib/src/System/Resources/MissingManifestResourceException.cs +++ /dev/null @@ -1,41 +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: Exception for a missing assembly-level resource -** -** -===========================================================*/ - -using System; -using System.Runtime.Serialization; - -namespace System.Resources { - [Serializable] - public class MissingManifestResourceException : SystemException - { - public MissingManifestResourceException() - : base(Environment.GetResourceString("Arg_MissingManifestResourceException")) { - SetErrorCode(System.__HResults.COR_E_MISSINGMANIFESTRESOURCE); - } - - public MissingManifestResourceException(String message) - : base(message) { - SetErrorCode(System.__HResults.COR_E_MISSINGMANIFESTRESOURCE); - } - - public MissingManifestResourceException(String message, Exception inner) - : base(message, inner) { - SetErrorCode(System.__HResults.COR_E_MISSINGMANIFESTRESOURCE); - } - - protected MissingManifestResourceException(SerializationInfo info, StreamingContext context) : base (info, context) { - } - } -} diff --git a/src/mscorlib/src/System/Resources/MissingSatelliteAssemblyException.cs b/src/mscorlib/src/System/Resources/MissingSatelliteAssemblyException.cs deleted file mode 100644 index fc676a8dd5..0000000000 --- a/src/mscorlib/src/System/Resources/MissingSatelliteAssemblyException.cs +++ /dev/null @@ -1,55 +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: Exception for a missing satellite assembly needed -** for ultimate resource fallback. This usually -** indicates a setup and/or deployment problem. -** -** -===========================================================*/ - -using System; -using System.Runtime.Serialization; - -namespace System.Resources { - [Serializable] - public class MissingSatelliteAssemblyException : SystemException - { - private String _cultureName; - - public MissingSatelliteAssemblyException() - : base(Environment.GetResourceString("MissingSatelliteAssembly_Default")) { - SetErrorCode(System.__HResults.COR_E_MISSINGSATELLITEASSEMBLY); - } - - public MissingSatelliteAssemblyException(String message) - : base(message) { - SetErrorCode(System.__HResults.COR_E_MISSINGSATELLITEASSEMBLY); - } - - public MissingSatelliteAssemblyException(String message, String cultureName) - : base(message) { - SetErrorCode(System.__HResults.COR_E_MISSINGSATELLITEASSEMBLY); - _cultureName = cultureName; - } - - public MissingSatelliteAssemblyException(String message, Exception inner) - : base(message, inner) { - SetErrorCode(System.__HResults.COR_E_MISSINGSATELLITEASSEMBLY); - } - - protected MissingSatelliteAssemblyException(SerializationInfo info, StreamingContext context) : base (info, context) { - } - - public String CultureName { - get { return _cultureName; } - } - } -} diff --git a/src/mscorlib/src/System/Resources/NeutralResourcesLanguageAttribute.cs b/src/mscorlib/src/System/Resources/NeutralResourcesLanguageAttribute.cs deleted file mode 100644 index a2ed6fbd57..0000000000 --- a/src/mscorlib/src/System/Resources/NeutralResourcesLanguageAttribute.cs +++ /dev/null @@ -1,64 +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: Tells the ResourceManager what language your main -** assembly's resources are written in. The -** ResourceManager won't try loading a satellite -** assembly for that culture, which helps perf. -** -** -** NOTE: -** -** This custom attribute is no longer implemented in managed code. As part of a perf optimization, -** it is now read in Module::GetNeutralResourcesLanguage, accessed from ManifestBasedResourceGroveler -** through an internal runtime call. -===========================================================*/ - -namespace System.Resources { - using System; - using System.Diagnostics.Contracts; - - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple=false)] - public sealed class NeutralResourcesLanguageAttribute : Attribute - { - private String _culture; - private UltimateResourceFallbackLocation _fallbackLoc; - - public NeutralResourcesLanguageAttribute(String cultureName) - { - if (cultureName == null) - throw new ArgumentNullException(nameof(cultureName)); - Contract.EndContractBlock(); - - _culture = cultureName; - _fallbackLoc = UltimateResourceFallbackLocation.MainAssembly; - } - - public NeutralResourcesLanguageAttribute(String cultureName, UltimateResourceFallbackLocation location) - { - if (cultureName == null) - throw new ArgumentNullException(nameof(cultureName)); - if (!Enum.IsDefined(typeof(UltimateResourceFallbackLocation), location)) - throw new ArgumentException(Environment.GetResourceString("Arg_InvalidNeutralResourcesLanguage_FallbackLoc", location)); - Contract.EndContractBlock(); - - _culture = cultureName; - _fallbackLoc = location; - } - - public String CultureName { - get { return _culture; } - } - - public UltimateResourceFallbackLocation Location { - get { return _fallbackLoc; } - } - } -} diff --git a/src/mscorlib/src/System/Resources/ResourceFallbackManager.cs b/src/mscorlib/src/System/Resources/ResourceFallbackManager.cs index de50cccc33..4ad7b4c93a 100644 --- a/src/mscorlib/src/System/Resources/ResourceFallbackManager.cs +++ b/src/mscorlib/src/System/Resources/ResourceFallbackManager.cs @@ -68,7 +68,7 @@ namespace System.Resources CultureInfo currentCulture = m_startingCulture; do { - if (m_neutralResourcesCulture != null && currentCulture.Name == m_neutralResourcesCulture.Name) + if (m_neutralResourcesCulture != null && currentCulture.Name == m_neutralResourcesCulture.Name) { // Return the invariant culture all the time, even if the UltimateResourceFallbackLocation // is a satellite assembly. This is fixed up later in ManifestBasedResourceGroveler::UltimateFallbackFixup. @@ -85,180 +85,12 @@ namespace System.Resources yield break; } - // 2. user preferred cultures, omitting starting culture if tried already - // Compat note: For console apps, this API will return cultures like Arabic - // or Hebrew that are displayed right-to-left. These don't work with today's - // CMD.exe. Since not all apps can short-circuit RTL languages to look at - // US English resources, we're exposing an appcompat flag for this, to make the - // osFallbackArray an empty array, mimicing our V2 behavior. Apps should instead - // be using CultureInfo.GetConsoleFallbackUICulture, and then test whether that - // culture's code page can be displayed on the console, and if not, they should - // set their culture to their neutral resources language. - // Note: the app compat switch will omit the OS Preferred fallback culture. - // Compat note 2: This feature breaks certain apps dependent on fallback to neutral - // resources. See extensive note in GetResourceFallbackArray. - CultureInfo[] osFallbackArray = LoadPreferredCultures(); - if (osFallbackArray != null) - { - foreach (CultureInfo ci in osFallbackArray) - { - // only have to check starting culture and immediate parent for now. - // in Dev10, revisit this policy. - if (m_startingCulture.Name != ci.Name && m_startingCulture.Parent.Name != ci.Name) - { - yield return ci; - } - } - } - - // 3. invariant + // 2. invariant // Don't return invariant twice though. if (reachedNeutralResourcesCulture) yield break; yield return CultureInfo.InvariantCulture; } - - private static CultureInfo[] LoadPreferredCultures() - { - // The list of preferred cultures includes thread, process, user, and OS - // information and may theoretically change every time we call it. - // The caching does save us some allocations - this complexity saved about - // 7% of the wall clock time on a US English machine, and may save more on non-English - // boxes (since the fallback list may be longer). - String[] cultureNames = GetResourceFallbackArray(); - if (cultureNames == null) - return null; - - bool useCachedNames = (cachedOsFallbackArray != null && cultureNames.Length == cachedOsFallbackArray.Length); - if (useCachedNames) - { - for (int i = 0; i < cultureNames.Length; i++) - { - if (!String.Equals(cultureNames[i], cachedOsFallbackArray[i].Name)) - { - useCachedNames = false; - break; - } - } - } - if (useCachedNames) - return cachedOsFallbackArray; - - cachedOsFallbackArray = LoadCulturesFromNames(cultureNames); - return cachedOsFallbackArray; - } - - private static CultureInfo[] LoadCulturesFromNames(String[] cultureNames) - { - if (cultureNames == null) - return null; - - CultureInfo[] cultures = new CultureInfo[cultureNames.Length]; - int culturesIndex = 0; - for (int i = 0; i < cultureNames.Length; i++) - { - // get cached, read-only cultures to avoid excess allocations - cultures[culturesIndex] = CultureInfo.GetCultureInfo(cultureNames[i]); - // Note GetCultureInfo can return null for a culture name that we don't support on the current OS. - // Don't leave a null in the middle of the array. - if (!Object.ReferenceEquals(cultures[culturesIndex], null)) - culturesIndex++; - } - - // If we couldn't create a culture, return an array of the right length. - if (culturesIndex != cultureNames.Length) - { - CultureInfo[] ret = new CultureInfo[culturesIndex]; - Array.Copy(cultures, ret, culturesIndex); - cultures = ret; - } - - return cultures; - } - - - // Note: May return null. - private static String[] GetResourceFallbackArray() - { - // AppCompat note: We've added this feature for desktop V4 but we ripped it out - // before shipping V4. It shipped in SL 2 and SL 3. We preserved this behavior in SL 4 - // for compat with previous Silverlight releases. We considered re-introducing this in .NET - // 4.5 for Windows 8 but chose not to because the Windows 8 immersive resources model - // has been redesigned from the ground up and we chose to support it (for portable libraries - // only) instead of further enhancing support for the classic resources model. - // --------------------------------------------------------------------- - // - // We have an appcompat problem that prevents us from adopting the ideal MUI model for - // culture fallback. Up until .NET Framework v4, our fallback was this: - // - // CurrentUICulture & parents Neutral - // - // We also had applications that took a dependency on falling back to neutral resources. - // IE, say an app is developed by US English developers - they may include English resources - // in the main assembly, not ship an "en" satellite assembly, and ship a French satellite. - // They may also omit the NeutralResourcesLanguageAttribute. - // - // Starting with Silverlight v2 and following advice from the MUI team, we wanted to call - // the OS's GetThreadPreferredUILanguages, inserting the results like this: - // - // CurrentUICulture & parents user-preferred fallback OS-preferred fallback Neutral - // - // This does not fit well for two reasons: - // 1) There is no concept of neutral resources in MUI - // 2) The user-preferred culture fallbacks make no sense in servers & non-interactive apps - // This leads to bad results on certain combinations of OS language installations, user - // settings, and applications built in certain styles. The OS-preferred fallback should - // be last, and the user-preferred fallback just breaks certain apps no matter where you put it. - // - // Necessary and sufficient conditions for an AppCompat bug (if we respected user & OS fallbacks): - // 1) A French OS (ie, you walk into an Internet café in Paris) - // 2) A .NET application whose neutral resources are authored in English. - // 3) The application did not provide an English satellite assembly (a common pattern). - // 4) The application is localized to French. - // 5) The user wants to read English, expressed in either of two ways: - // a. Changing Windows’ Display Language in the Regional Options Control Panel - // b. The application explicitly ASKS THE USER what language to display. - // - // Obviously the exact languages above can be interchanged a bit - I’m keeping this concrete. - // Also the NeutralResourcesLanguageAttribute will allow this to work, but usually we set it - // to en-US for our assemblies, meaning all other English cultures are broken. - // - // Workarounds: - // *) Use the NeutralResourcesLanguageAttribute and tell us that your neutral resources - // are in region-neutral English (en). - // *) Consider shipping a region-neutral English satellite assembly. - - // Future work: - // 2) Consider a mechanism for individual assemblies to opt into wanting user-preferred fallback. - // They should ship their neutral resources in a satellite assembly, or use the - // NeutralResourcesLanguageAttribute to say their neutral resources are in a REGION-NEUTRAL - // language. An appdomain or process-wide flag may not be sufficient. - // 3) Ask Windows to clarify the scenario for the OS preferred fallback list, to decide whether - // we should probe there before or after looking at the neutral resources. If we move it - // to after the neutral resources, ask Windows to return a user-preferred fallback list - // without the OS preferred fallback included. This is a feature request for - // GetThreadPreferredUILanguages. We can muddle through without it by removing the OS - // preferred fallback cultures from end of the combined user + OS preferred fallback list, carefully. - // 4) Do not look at user-preferred fallback if Environment.UserInteractive is false. (IE, - // the Windows user who launches ASP.NET shouldn't determine how a web page gets - // localized - the server itself must respect the remote client's requested languages.) - // 6) Figure out what should happen in servers (ASP.NET, SQL, NT Services, etc). - // - // Done: - // 1) Got data from Windows on priority of supporting OS preferred fallback. We need to do it. - // Helps with consistency w/ Windows, and may be necessary for a long tail of other languages - // (ie, Windows has various degrees of localization support for ~135 languages, and fallbacks - // to certain languages is important.) - // 5) Revisited guidance for using the NeutralResourcesLanguageAttribute. Our docs should now say - // always pick a region-neutral language (ie, "en"). - -// TODO (matell): I think we actually want to pull this into the PAL on CultureInfo? -#if FEATURE_COREFX_GLOBALIZATION - return null; -#else - return CultureInfo.nativeGetResourceFallbackArray(); -#endif - } } } diff --git a/src/mscorlib/src/System/Resources/ResourceManager.cs b/src/mscorlib/src/System/Resources/ResourceManager.cs index f17a7c8f8e..993efddbfc 100644 --- a/src/mscorlib/src/System/Resources/ResourceManager.cs +++ b/src/mscorlib/src/System/Resources/ResourceManager.cs @@ -14,7 +14,8 @@ ** ===========================================================*/ -namespace System.Resources { +namespace System.Resources +{ using System; using System.IO; using System.Globalization; @@ -38,20 +39,21 @@ namespace System.Resources { // allowing us to ask for a WinRT-specific ResourceManager. // It is important to have WindowsRuntimeResourceManagerBase as regular class with virtual methods and default implementations. // Defining WindowsRuntimeResourceManagerBase as abstract class or interface will cause issues when adding more methods to it - // because it’ll create dependency between mscorlib and System.Runtime.WindowsRuntime which will require always shipping both DLLs together. + // because it�ll create dependency between mscorlib and System.Runtime.WindowsRuntime which will require always shipping both DLLs together. // Also using interface or abstract class will not play nice with FriendAccessAllowed. // [FriendAccessAllowed] internal class WindowsRuntimeResourceManagerBase { - public virtual bool Initialize(string libpath, string reswFilename, out PRIExceptionInfo exceptionInfo){exceptionInfo = null; return false;} + public virtual bool Initialize(string libpath, string reswFilename, out PRIExceptionInfo exceptionInfo) { exceptionInfo = null; return false; } - public virtual String GetString(String stringName, String startingCulture, String neutralResourcesCulture){return null;} + public virtual String GetString(String stringName, String startingCulture, String neutralResourcesCulture) { return null; } - public virtual CultureInfo GlobalResourceContextBestFitCultureInfo { - get { return null; } + public virtual CultureInfo GlobalResourceContextBestFitCultureInfo + { + get { return null; } } - + public virtual bool SetGlobalResourceContextDefaultCulture(CultureInfo ci) { return false; } } @@ -150,8 +152,8 @@ namespace System.Resources { [Serializable] public class ResourceManager { - - internal class CultureNameResourceSetPair { + internal class CultureNameResourceSetPair + { public String lastCultureName; public ResourceSet lastResourceSet; } @@ -161,11 +163,11 @@ namespace System.Resources { // Don't synchronize ResourceSets - too fine-grained a lock to be effective [Obsolete("call InternalGetResourceSet instead")] internal Hashtable ResourceSets; - + // don't serialize the cache of ResourceSets [NonSerialized] - private Dictionary <String,ResourceSet> _resourceSets; + private Dictionary<String, ResourceSet> _resourceSets; private String moduleDir; // For assembly-ignorant directory location protected Assembly MainAssembly; // Need the assembly manifest sometimes. private Type _locationInfo; // For Assembly or type-based directory layout @@ -182,11 +184,11 @@ namespace System.Resources { // unused! But need to keep for serialization [OptionalField(VersionAdded = 1)] private bool UseSatelliteAssem; // Are all the .resources files in the - // main assembly, or in satellite assemblies for each culture? + // main assembly, or in satellite assemblies for each culture? #if RESOURCE_SATELLITE_CONFIG private static volatile Hashtable _installedSatelliteInfo; // Give the user the option - // to prevent certain satellite assembly probes via a config file. - // Note that config files are per-appdomain, not per-assembly nor process + // to prevent certain satellite assembly probes via a config file. + // Note that config files are per-appdomain, not per-assembly nor process private static volatile bool _checkedConfigFile; // Did we read the app's config file? #endif @@ -246,16 +248,16 @@ namespace System.Resources { // My private debugging aid. Set to 5 or 6 for verbose output. Set to 3 // for summary level information. internal static readonly int DEBUG = 0; //Making this const causes C# to consider all of the code that it guards unreachable. - + private static volatile bool s_IsAppXModel; - - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + + [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod private void Init() { m_callingAssembly = (RuntimeAssembly)Assembly.GetCallingAssembly(); } - protected ResourceManager() + protected ResourceManager() { Init(); @@ -263,7 +265,7 @@ namespace System.Resources { ResourceManagerMediator mediator = new ResourceManagerMediator(this); resourceGroveler = new ManifestBasedResourceGroveler(mediator); } - + // Constructs a Resource Manager for files beginning with // baseName in the directory specified by resourceDir // or in the current directory. This Assembly-ignorant constructor is @@ -274,10 +276,11 @@ namespace System.Resources { // // Note: System.Windows.Forms uses this method at design time. // - private ResourceManager(String baseName, String resourceDir, Type usingResourceSet) { - if (null==baseName) + private ResourceManager(String baseName, String resourceDir, Type usingResourceSet) + { + if (null == baseName) throw new ArgumentNullException(nameof(baseName)); - if (null==resourceDir) + if (null == resourceDir) throw new ArgumentNullException(nameof(resourceDir)); Contract.EndContractBlock(); @@ -296,18 +299,18 @@ namespace System.Resources { resourceGroveler = new FileBasedResourceGroveler(mediator); } - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable + [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod public ResourceManager(String baseName, Assembly assembly) { - if (null==baseName) + if (null == baseName) throw new ArgumentNullException(nameof(baseName)); - if (null==assembly) + if (null == assembly) throw new ArgumentNullException(nameof(assembly)); Contract.EndContractBlock(); if (!(assembly is RuntimeAssembly)) - throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeAssembly")); + throw new ArgumentException(SR.Argument_MustBeRuntimeAssembly); MainAssembly = assembly; BaseNameField = baseName; @@ -327,23 +330,23 @@ namespace System.Resources { } } - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod public ResourceManager(String baseName, Assembly assembly, Type usingResourceSet) { - if (null==baseName) + if (null == baseName) throw new ArgumentNullException(nameof(baseName)); - if (null==assembly) + if (null == assembly) throw new ArgumentNullException(nameof(assembly)); Contract.EndContractBlock(); if (!(assembly is RuntimeAssembly)) - throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeAssembly")); + throw new ArgumentException(SR.Argument_MustBeRuntimeAssembly); MainAssembly = assembly; BaseNameField = baseName; - + if (usingResourceSet != null && (usingResourceSet != _minResourceSet) && !(usingResourceSet.IsSubclassOf(_minResourceSet))) - throw new ArgumentException(Environment.GetResourceString("Arg_ResMgrNotResSet"), nameof(usingResourceSet)); + throw new ArgumentException(SR.Arg_ResMgrNotResSet, nameof(usingResourceSet)); _userResourceSet = usingResourceSet; CommonAssemblyInit(); @@ -355,21 +358,21 @@ namespace System.Resources { if (assembly == typeof(Object).Assembly && m_callingAssembly != assembly) m_callingAssembly = null; } - - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + + [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod public ResourceManager(Type resourceSource) { - if (null==resourceSource) + if (null == resourceSource) throw new ArgumentNullException(nameof(resourceSource)); Contract.EndContractBlock(); if (!(resourceSource is RuntimeType)) - throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType")); + throw new ArgumentException(SR.Argument_MustBeRuntimeType); _locationInfo = resourceSource; MainAssembly = _locationInfo.Assembly; BaseNameField = resourceSource.Name; - + SetAppXConfiguration(); CommonAssemblyInit(); @@ -385,9 +388,9 @@ namespace System.Resources { [OnDeserializing] private void OnDeserializing(StreamingContext ctx) { - this._resourceSets = null; - this.resourceGroveler = null; - this._lastUsedResourceCache = null; + _resourceSets = null; + resourceGroveler = null; + _lastUsedResourceCache = null; } [OnDeserialized] @@ -408,13 +411,13 @@ namespace System.Resources { } // correct callingAssembly for v2 - if (this.m_callingAssembly == null) + if (m_callingAssembly == null) { - this.m_callingAssembly = (RuntimeAssembly)_callingAssembly; + m_callingAssembly = (RuntimeAssembly)_callingAssembly; } // v2 does this lazily - if (UseManifest && this._neutralResourcesCulture == null) + if (UseManifest && _neutralResourcesCulture == null) { _neutralResourcesCulture = ManifestBasedResourceGroveler.GetNeutralResourcesLanguage(MainAssembly, ref _fallbackLoc); } @@ -430,7 +433,7 @@ namespace System.Resources { ResourceSets = new Hashtable(); // for backward compatibility #pragma warning restore 618 } - + // Trying to unify code as much as possible, even though having to do a // security check in each constructor prevents it. @@ -439,8 +442,8 @@ namespace System.Resources { if (_bUsingModernResourceManagement == false) { UseManifest = true; - - _resourceSets = new Dictionary<String,ResourceSet>(); + + _resourceSets = new Dictionary<String, ResourceSet>(); _lastUsedResourceCache = new CultureNameResourceSetPair(); _fallbackLoc = UltimateResourceFallbackLocation.MainAssembly; @@ -453,20 +456,23 @@ namespace System.Resources { } // Gets the base name for the ResourceManager. - public virtual String BaseName { + public virtual String BaseName + { get { return BaseNameField; } } - + // Whether we should ignore the capitalization of resources when calling // GetString or GetObject. - public virtual bool IgnoreCase { + public virtual bool IgnoreCase + { get { return _ignoreCase; } set { _ignoreCase = value; } } // Returns the Type of the ResourceSet the ResourceManager uses // to construct ResourceSets. - public virtual Type ResourceSetType { + public virtual Type ResourceSetType + { get { return (_userResourceSet == null) ? typeof(RuntimeResourceSet) : _userResourceSet; } } @@ -491,13 +497,15 @@ namespace System.Resources { // If any calls to Close throw, at least leave ourselves in a // consistent state. - _resourceSets = new Dictionary<String,ResourceSet>(); + _resourceSets = new Dictionary<String, ResourceSet>(); _lastUsedResourceCache = new CultureNameResourceSetPair(); - - lock(localResourceSets) { + + lock (localResourceSets) + { IDictionaryEnumerator setEnum = localResourceSets.GetEnumerator(); - while (setEnum.MoveNext()) { + while (setEnum.MoveNext()) + { ((ResourceSet)setEnum.Value).Close(); } } @@ -507,7 +515,7 @@ namespace System.Resources { { return new ResourceManager(baseName, resourceDir, usingResourceSet); } - + // Given a CultureInfo, GetResourceFileName generates the name for // the binary file for the given CultureInfo. This method uses // CultureInfo's Name property as part of the file name for all cultures @@ -518,7 +526,8 @@ namespace System.Resources { // // This method can be overriden to look for a different extension, // such as ".ResX", or a completely different format for naming files. - protected virtual String GetResourceFileName(CultureInfo culture) { + protected virtual String GetResourceFileName(CultureInfo culture) + { StringBuilder sb = new StringBuilder(255); sb.Append(BaseNameField); // If this is the neutral culture, don't append culture name. @@ -537,24 +546,26 @@ namespace System.Resources { internal ResourceSet GetFirstResourceSet(CultureInfo culture) { // Logic from ResourceFallbackManager.GetEnumerator() - if (_neutralResourcesCulture != null && culture.Name == _neutralResourcesCulture.Name) + if (_neutralResourcesCulture != null && culture.Name == _neutralResourcesCulture.Name) { culture = CultureInfo.InvariantCulture; } - if(_lastUsedResourceCache != null) { - lock (_lastUsedResourceCache) { + if (_lastUsedResourceCache != null) + { + lock (_lastUsedResourceCache) + { if (culture.Name == _lastUsedResourceCache.lastCultureName) return _lastUsedResourceCache.lastResourceSet; } } // Look in the ResourceSet table - Dictionary<String,ResourceSet> localResourceSets = _resourceSets; + Dictionary<String, ResourceSet> localResourceSets = _resourceSets; ResourceSet rs = null; - if (localResourceSets != null) + if (localResourceSets != null) { - lock (localResourceSets) + lock (localResourceSets) { localResourceSets.TryGetValue(culture.Name, out rs); } @@ -563,8 +574,10 @@ namespace System.Resources { if (rs != null) { // update the cache with the most recent ResourceSet - if (_lastUsedResourceCache != null) { - lock (_lastUsedResourceCache) { + if (_lastUsedResourceCache != null) + { + lock (_lastUsedResourceCache) + { _lastUsedResourceCache.lastCultureName = culture.Name; _lastUsedResourceCache.lastResourceSet = rs; } @@ -574,7 +587,7 @@ namespace System.Resources { return null; } - + // Looks up a set of resources for a particular CultureInfo. This is // not useful for most users of the ResourceManager - call // GetString() or GetObject() instead. @@ -583,16 +596,19 @@ namespace System.Resources { // if it hasn't yet been loaded and if parent CultureInfos should be // loaded as well for resource inheritance. // - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable - public virtual ResourceSet GetResourceSet(CultureInfo culture, bool createIfNotExists, bool tryParents) { - if (null==culture) + [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod + public virtual ResourceSet GetResourceSet(CultureInfo culture, bool createIfNotExists, bool tryParents) + { + if (null == culture) throw new ArgumentNullException(nameof(culture)); Contract.EndContractBlock(); - Dictionary<String,ResourceSet> localResourceSets = _resourceSets; + Dictionary<String, ResourceSet> localResourceSets = _resourceSets; ResourceSet rs; - if (localResourceSets != null) { - lock (localResourceSets) { + if (localResourceSets != null) + { + lock (localResourceSets) + { if (localResourceSets.TryGetValue(culture.Name, out rs)) return rs; } @@ -600,13 +616,15 @@ namespace System.Resources { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - if (UseManifest && culture.HasInvariantCultureName) { + if (UseManifest && culture.HasInvariantCultureName) + { string fileName = GetResourceFileName(culture); RuntimeAssembly mainAssembly = (RuntimeAssembly)MainAssembly; Stream stream = mainAssembly.GetManifestResourceStream(_locationInfo, fileName, m_callingAssembly == MainAssembly, ref stackMark); - if (createIfNotExists && stream!=null) { + if (createIfNotExists && stream != null) + { rs = ((ManifestBasedResourceGroveler)resourceGroveler).CreateResourceSet(stream, MainAssembly); - AddResourceSet(localResourceSets, culture.Name, ref rs); + AddResourceSet(localResourceSets, culture.Name, ref rs); return rs; } } @@ -626,13 +644,13 @@ namespace System.Resources { // for getting a resource set lives. Access to it is controlled by // threadsafe methods such as GetResourceSet, GetString, & GetObject. // This will take a minimal number of locks. - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable - protected virtual ResourceSet InternalGetResourceSet(CultureInfo culture, bool createIfNotExists, bool tryParents) + [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod + protected virtual ResourceSet InternalGetResourceSet(CultureInfo culture, bool createIfNotExists, bool tryParents) { Debug.Assert(culture != null, "culture != null"); StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return InternalGetResourceSet(culture,createIfNotExists,tryParents, ref stackMark); + return InternalGetResourceSet(culture, createIfNotExists, tryParents, ref stackMark); } // InternalGetResourceSet is a non-threadsafe method where all the logic @@ -644,8 +662,10 @@ namespace System.Resources { Dictionary<String, ResourceSet> localResourceSets = _resourceSets; ResourceSet rs = null; CultureInfo foundCulture = null; - lock (localResourceSets) { - if (localResourceSets.TryGetValue(requestedCulture.Name, out rs)) { + lock (localResourceSets) + { + if (localResourceSets.TryGetValue(requestedCulture.Name, out rs)) + { return rs; } } @@ -654,10 +674,12 @@ namespace System.Resources { foreach (CultureInfo currentCultureInfo in mgr) { - lock(localResourceSets) { - if (localResourceSets.TryGetValue(currentCultureInfo.Name, out rs)) { + lock (localResourceSets) + { + if (localResourceSets.TryGetValue(currentCultureInfo.Name, out rs)) + { // we need to update the cache if we fellback - if(requestedCulture != currentCultureInfo) foundCulture = currentCultureInfo; + if (requestedCulture != currentCultureInfo) foundCulture = currentCultureInfo; break; } } @@ -668,7 +690,7 @@ namespace System.Resources { // Assembly load event, which could fail then call back into the // ResourceManager). It's happened. - rs = resourceGroveler.GrovelForResourceSet(currentCultureInfo, localResourceSets, + rs = resourceGroveler.GrovelForResourceSet(currentCultureInfo, localResourceSets, tryParents, createIfNotExists, ref stackMark); // found a ResourceSet; we're done @@ -677,7 +699,6 @@ namespace System.Resources { foundCulture = currentCultureInfo; break; } - } if (rs != null && foundCulture != null) @@ -696,23 +717,26 @@ namespace System.Resources { { break; } - } + } } return rs; } // Simple helper to ease maintenance and improve readability. - private static void AddResourceSet(Dictionary<String,ResourceSet> localResourceSets, String cultureName, ref ResourceSet rs) + private static void AddResourceSet(Dictionary<String, ResourceSet> localResourceSets, String cultureName, ref ResourceSet rs) { // InternalGetResourceSet is both recursive and reentrant - // assembly load callbacks in particular are a way we can call // back into the ResourceManager in unexpectedly on the same thread. - lock(localResourceSets) { + lock (localResourceSets) + { // If another thread added this culture, return that. ResourceSet lostRace; - if (localResourceSets.TryGetValue(cultureName, out lostRace)) { - if (!Object.ReferenceEquals(lostRace, rs)) { + if (localResourceSets.TryGetValue(cultureName, out lostRace)) + { + if (!Object.ReferenceEquals(lostRace, rs)) + { // Note: In certain cases, we can be trying to add a ResourceSet for multiple // cultures on one thread, while a second thread added another ResourceSet for one // of those cultures. If there is a race condition we must make sure our ResourceSet @@ -722,7 +746,8 @@ namespace System.Resources { rs = lostRace; } } - else { + else + { localResourceSets.Add(cultureName, rs); } } @@ -731,8 +756,9 @@ namespace System.Resources { protected static Version GetSatelliteContractVersion(Assembly a) { // Ensure that the assembly reference is not null - if (a == null) { - throw new ArgumentNullException(nameof(a), Environment.GetResourceString("ArgumentNull_Assembly")); + if (a == null) + { + throw new ArgumentNullException(nameof(a), SR.ArgumentNull_Assembly); } Contract.EndContractBlock(); @@ -752,7 +778,7 @@ namespace System.Resources { // IGNORES VERSION internal static bool CompareNames(String asmTypeName1, - String typeName2, + String typeName2, AssemblyName asmName2) { Debug.Assert(asmTypeName1 != null, "asmTypeName1 was unexpectedly null"); @@ -770,7 +796,7 @@ namespace System.Resources { // Now, compare assembly display names (IGNORES VERSION AND PROCESSORARCHITECTURE) // also, for mscorlib ignores everything, since that's what the binder is going to do - while(Char.IsWhiteSpace(asmTypeName1[++comma])); + while (Char.IsWhiteSpace(asmTypeName1[++comma])) ; // case insensitive AssemblyName an1 = new AssemblyName(asmTypeName1.Substring(comma)); @@ -793,12 +819,14 @@ namespace System.Resources { byte[] pkt1 = an1.GetPublicKeyToken(); byte[] pkt2 = asmName2.GetPublicKeyToken(); - if ((pkt1 != null) && (pkt2 != null)) { + if ((pkt1 != null) && (pkt2 != null)) + { if (pkt1.Length != pkt2.Length) return false; - for(int i=0; i < pkt1.Length; i++) { - if(pkt1[i] != pkt2[i]) + for (int i = 0; i < pkt1.Length; i++) + { + if (pkt1[i] != pkt2[i]) return false; } } @@ -807,15 +835,16 @@ namespace System.Resources { } #if FEATURE_APPX - private string GetStringFromPRI(String stringName, String startingCulture, String neutralResourcesCulture) { + private string GetStringFromPRI(String stringName, String startingCulture, String neutralResourcesCulture) + { Debug.Assert(_bUsingModernResourceManagement); Debug.Assert(_WinRTResourceManager != null); Debug.Assert(_PRIonAppXInitialized); Debug.Assert(AppDomain.IsAppXModel()); - + if (stringName.Length == 0) return null; - + string resourceString = null; // Do not handle exceptions. See the comment in SetAppXConfiguration about throwing @@ -824,7 +853,7 @@ namespace System.Resources { stringName, String.IsNullOrEmpty(startingCulture) ? null : startingCulture, String.IsNullOrEmpty(neutralResourcesCulture) ? null : neutralResourcesCulture); - + return resourceString; } @@ -882,9 +911,9 @@ namespace System.Resources { if ((platformResourceRoots != null) && (platformResourceRoots != String.Empty)) { string resourceAssemblyPath = resourcesAssembly.Location; - + // Loop through the PLATFORM_RESOURCE_ROOTS and see if the assembly is contained in it. - foreach(string pathPlatformResourceRoot in platformResourceRoots.Split(Path.PathSeparator)) + foreach (string pathPlatformResourceRoot in platformResourceRoots.Split(Path.PathSeparator)) { if (resourceAssemblyPath.StartsWith(pathPlatformResourceRoot, StringComparison.CurrentCultureIgnoreCase)) { @@ -924,7 +953,7 @@ namespace System.Resources { { // Cannot load the WindowsRuntimeResourceManager when in a compilation process, since it // lives in System.Runtime.WindowsRuntime and only mscorlib may be loaded for execution. - if (AppDomain.IsAppXModel() && !AppDomain.IsAppXNGen) + if (AppDomain.IsAppXModel()) { s_IsAppXModel = true; @@ -945,16 +974,17 @@ namespace System.Resources { WindowsRuntimeResourceManagerBase WRRM = null; bool bWRRM_Initialized = false; - + if (AppDomain.IsAppXDesignMode()) { WRRM = GetWinRTResourceManager(); - try { + try + { PRIExceptionInfo exceptionInfo; // If the exception info is filled in, we will ignore it. bWRRM_Initialized = WRRM.Initialize(resourcesAssembly.Location, reswFilename, out exceptionInfo); bUsingSatelliteAssembliesUnderAppX = !bWRRM_Initialized; } - catch(Exception e) + catch (Exception e) { bUsingSatelliteAssembliesUnderAppX = true; if (e.IsTransient) @@ -966,7 +996,7 @@ namespace System.Resources { { // See AssemblyNative::IsFrameworkAssembly for details on which kinds of assemblies are considered Framework assemblies. // The Modern Resource Manager is not used for such assemblies - they continue to use satellite assemblies (i.e. .resources.dll files). - _bUsingModernResourceManagement = !ShouldUseSatelliteAssemblyResourceLookupUnderAppX(resourcesAssembly); + _bUsingModernResourceManagement = !ShouldUseSatelliteAssemblyResourceLookupUnderAppX(resourcesAssembly); if (_bUsingModernResourceManagement) { @@ -989,11 +1019,12 @@ namespace System.Resources { _WinRTResourceManager = WRRM; _PRIonAppXInitialized = true; } - else + else { _WinRTResourceManager = GetWinRTResourceManager(); - - try { + + try + { _PRIonAppXInitialized = _WinRTResourceManager.Initialize(resourcesAssembly.Location, reswFilename, out _PRIExceptionInfo); // Note that _PRIExceptionInfo might be null - this is OK. @@ -1007,12 +1038,12 @@ namespace System.Resources { // and since they are part of the portable profile, we cannot start throwing a new exception type // as that would break existing portable libraries. Hence we must save the exception information // now and throw the exception on the first call to GetString. - catch(FileNotFoundException) + catch (FileNotFoundException) { // We will throw MissingManifestResource_NoPRIresources from GetString // when we see that _PRIonAppXInitialized is false. } - catch(Exception e) + catch (Exception e) { // ERROR_MRM_MAP_NOT_FOUND can be thrown by the call to ResourceManager.get_AllResourceMaps // in WindowsRuntimeResourceManager.Initialize. @@ -1053,31 +1084,33 @@ namespace System.Resources { // current thread's CultureInfo, and if not found, all parent CultureInfos. // Returns null if the resource wasn't found. // - public virtual String GetString(String name) { + public virtual String GetString(String name) + { return GetString(name, (CultureInfo)null); } - + // Looks up a resource value for a particular name. Looks in the // specified CultureInfo, and if not found, all parent CultureInfos. // Returns null if the resource wasn't found. // - public virtual String GetString(String name, CultureInfo culture) { - if (null==name) + public virtual String GetString(String name, CultureInfo culture) + { + if (null == name) throw new ArgumentNullException(nameof(name)); Contract.EndContractBlock(); #if FEATURE_APPX - if(s_IsAppXModel) + if (s_IsAppXModel) { - // If the caller explictily passed in a culture that was obtained by calling CultureInfo.CurrentUICulture, - // null it out, so that we re-compute it. If we use modern resource lookup, we may end up getting a "better" - // match, since CultureInfo objects can't represent all the different languages the AppX resource model supports. - // For classic resources, this causes us to ignore the languages list and instead use the older Win32 behavior, - // which is the design choice we've made. (See the call a little later to GetCurrentUICultureNoAppX()). - if(Object.ReferenceEquals(culture, CultureInfo.CurrentUICulture)) - { - culture = null; - } + // If the caller explictily passed in a culture that was obtained by calling CultureInfo.CurrentUICulture, + // null it out, so that we re-compute it. If we use modern resource lookup, we may end up getting a "better" + // match, since CultureInfo objects can't represent all the different languages the AppX resource model supports. + // For classic resources, this causes us to ignore the languages list and instead use the older Win32 behavior, + // which is the design choice we've made. (See the call a little later to GetCurrentUICultureNoAppX()). + if (Object.ReferenceEquals(culture, CultureInfo.CurrentUICulture)) + { + culture = null; + } } if (_bUsingModernResourceManagement) @@ -1087,11 +1120,11 @@ namespace System.Resources { // Always throw if we did not fully succeed in initializing the WinRT Resource Manager. if (_PRIExceptionInfo != null && _PRIExceptionInfo._PackageSimpleName != null && _PRIExceptionInfo._ResWFile != null) - throw new MissingManifestResourceException(Environment.GetResourceString("MissingManifestResource_ResWFileNotLoaded", _PRIExceptionInfo._ResWFile, _PRIExceptionInfo._PackageSimpleName)); + throw new MissingManifestResourceException(SR.Format(SR.MissingManifestResource_ResWFileNotLoaded, _PRIExceptionInfo._ResWFile, _PRIExceptionInfo._PackageSimpleName)); - throw new MissingManifestResourceException(Environment.GetResourceString("MissingManifestResource_NoPRIresources")); + throw new MissingManifestResourceException(SR.MissingManifestResource_NoPRIresources); } - + // Throws WinRT hresults. return GetStringFromPRI(name, culture == null ? null : culture.Name, @@ -1100,10 +1133,11 @@ namespace System.Resources { else #endif // FEATURE_APPX { - if (null==culture) { + if (culture == null) + { // When running inside AppX we want to ignore the languages list when trying to come up with our CurrentUICulture. // This line behaves the same way as CultureInfo.CurrentUICulture would have in .NET 4 - culture = Thread.CurrentThread.GetCurrentUICultureNoAppX(); + culture = CultureInfo.GetCurrentUICultureNoAppX(); } ResourceSet last = GetFirstResourceSet(culture); @@ -1114,25 +1148,28 @@ namespace System.Resources { if (value != null) return value; } - - + + // This is the CultureInfo hierarchy traversal code for resource // lookups, similar but necessarily orthogonal to the ResourceSet // lookup logic. ResourceFallbackManager mgr = new ResourceFallbackManager(culture, _neutralResourcesCulture, true); - foreach (CultureInfo currentCultureInfo in mgr) { - + foreach (CultureInfo currentCultureInfo in mgr) + { ResourceSet rs = InternalGetResourceSet(currentCultureInfo, true, true); if (rs == null) break; - if (rs != last) { + if (rs != last) + { String value = rs.GetString(name, _ignoreCase); if (value != null) { // update last used ResourceSet - if (_lastUsedResourceCache != null) { - lock (_lastUsedResourceCache) { + if (_lastUsedResourceCache != null) + { + lock (_lastUsedResourceCache) + { _lastUsedResourceCache.lastCultureName = currentCultureInfo.Name; _lastUsedResourceCache.lastResourceSet = rs; } @@ -1147,46 +1184,49 @@ namespace System.Resources { return null; } - - + + // Looks up a resource value for a particular name. Looks in the // current thread's CultureInfo, and if not found, all parent CultureInfos. // Returns null if the resource wasn't found. // - public virtual Object GetObject(String name) { + public virtual Object GetObject(String name) + { return GetObject(name, (CultureInfo)null, true); } - + // Looks up a resource value for a particular name. Looks in the // specified CultureInfo, and if not found, all parent CultureInfos. // Returns null if the resource wasn't found. - public virtual Object GetObject(String name, CultureInfo culture) { + public virtual Object GetObject(String name, CultureInfo culture) + { return GetObject(name, culture, true); } private Object GetObject(String name, CultureInfo culture, bool wrapUnmanagedMemStream) { - if (null==name) + if (null == name) throw new ArgumentNullException(nameof(name)); Contract.EndContractBlock(); #if FEATURE_APPX - if(s_IsAppXModel) + if (s_IsAppXModel) { - // If the caller explictily passed in a culture that was obtained by calling CultureInfo.CurrentUICulture, - // null it out, so that we re-compute it based on the Win32 value and not the AppX language list value. - // (See the call a little later to GetCurrentUICultureNoAppX()). - if(Object.ReferenceEquals(culture, CultureInfo.CurrentUICulture)) - { - culture = null; - } + // If the caller explictily passed in a culture that was obtained by calling CultureInfo.CurrentUICulture, + // null it out, so that we re-compute it based on the Win32 value and not the AppX language list value. + // (See the call a little later to GetCurrentUICultureNoAppX()). + if (Object.ReferenceEquals(culture, CultureInfo.CurrentUICulture)) + { + culture = null; + } } #endif - if (null==culture) { + if (null == culture) + { // When running inside AppX we want to ignore the languages list when trying to come up with our CurrentUICulture. // This line behaves the same way as CultureInfo.CurrentUICulture would have in .NET 4 - culture = Thread.CurrentThread.GetCurrentUICultureNoAppX(); + culture = CultureInfo.GetCurrentUICultureNoAppX(); } ResourceSet last = GetFirstResourceSet(culture); @@ -1194,7 +1234,7 @@ namespace System.Resources { { Object value = last.GetObject(name, _ignoreCase); - if (value != null) + if (value != null) { UnmanagedMemoryStream stream = value as UnmanagedMemoryStream; if (stream != null && wrapUnmanagedMemStream) @@ -1203,13 +1243,14 @@ namespace System.Resources { return value; } } - + // This is the CultureInfo hierarchy traversal code for resource // lookups, similar but necessarily orthogonal to the ResourceSet // lookup logic. ResourceFallbackManager mgr = new ResourceFallbackManager(culture, _neutralResourcesCulture, true); - - foreach (CultureInfo currentCultureInfo in mgr) { + + foreach (CultureInfo currentCultureInfo in mgr) + { // Note: Technically this method should be passed in a stack crawl mark that we then pass // to InternalGetResourceSet for ensuring we demand permissions to read your private resources // if you're reading resources from an assembly other than yourself. But, we must call our @@ -1219,12 +1260,16 @@ namespace System.Resources { if (rs == null) break; - if (rs != last) { + if (rs != last) + { Object value = rs.GetObject(name, _ignoreCase); - if (value != null) { + if (value != null) + { // update the last used ResourceSet - if (_lastUsedResourceCache != null) { - lock (_lastUsedResourceCache) { + if (_lastUsedResourceCache != null) + { + lock (_lastUsedResourceCache) + { _lastUsedResourceCache.lastCultureName = currentCultureInfo.Name; _lastUsedResourceCache.lastResourceSet = rs; } @@ -1244,15 +1289,17 @@ namespace System.Resources { return null; } - public UnmanagedMemoryStream GetStream(String name) { + public UnmanagedMemoryStream GetStream(String name) + { return GetStream(name, (CultureInfo)null); } - - public UnmanagedMemoryStream GetStream(String name, CultureInfo culture) { + + public UnmanagedMemoryStream GetStream(String name, CultureInfo culture) + { Object obj = GetObject(name, culture, false); UnmanagedMemoryStream ums = obj as UnmanagedMemoryStream; if (ums == null && obj != null) - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResourceNotStream_Name", name)); + throw new InvalidOperationException(SR.Format(SR.InvalidOperation_ResourceNotStream_Name, name)); return ums; } @@ -1261,9 +1308,12 @@ namespace System.Resources { // satellite assembly probes for certain cultures via a config file. private bool TryLookingForSatellite(CultureInfo lookForCulture) { - if (!_checkedConfigFile) { - lock (this) { - if (!_checkedConfigFile) { + if (!_checkedConfigFile) + { + lock (this) + { + if (!_checkedConfigFile) + { _checkedConfigFile = true; _installedSatelliteInfo = GetSatelliteAssembliesFromConfig(); } @@ -1273,7 +1323,7 @@ namespace System.Resources { if (_installedSatelliteInfo == null) return true; - String[] installedSatellites = (String[]) _installedSatelliteInfo[MainAssembly.FullName]; + String[] installedSatellites = (String[])_installedSatelliteInfo[MainAssembly.FullName]; if (installedSatellites == null) return true; @@ -1317,7 +1367,7 @@ namespace System.Resources { get { return _rm._locationInfo; } } - internal Type UserResourceSet + internal Type UserResourceSet { get { return _rm._userResourceSet; } } @@ -1358,7 +1408,7 @@ namespace System.Resources { internal UltimateResourceFallbackLocation FallbackLoc { - get { return _rm.FallbackLocation; } + get { return _rm.FallbackLocation; } set { _rm._fallbackLoc = value; } } diff --git a/src/mscorlib/src/System/Resources/ResourceReader.cs b/src/mscorlib/src/System/Resources/ResourceReader.cs index d752771020..9734343f92 100644 --- a/src/mscorlib/src/System/Resources/ResourceReader.cs +++ b/src/mscorlib/src/System/Resources/ResourceReader.cs @@ -14,7 +14,9 @@ ** Version 2 support on October 6, 2003 ** ===========================================================*/ -namespace System.Resources { + +namespace System.Resources +{ using System; using System.IO; using System.Text; @@ -47,14 +49,16 @@ namespace System.Resources { _value = value; } - internal int DataPosition { + 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 { + internal Object Value + { get { return _value; } set { _value = value; } } @@ -63,7 +67,7 @@ namespace System.Resources { { Debug.Assert(value >= 0, "negative ResourceTypeCode. What?"); return value <= ResourceTypeCode.LastPrimitive; - } + } } @@ -111,23 +115,25 @@ namespace System.Resources { { _resCache = new Dictionary<String, ResourceLocator>(FastResourceComparer.Default); _store = new BinaryReader(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultFileStreamBufferSize, FileOptions.RandomAccess), Encoding.UTF8); - BCLDebug.Log("RESMGRFILEFORMAT", "ResourceReader .ctor(String). UnmanagedMemoryStream: "+(_ums!=null)); + BCLDebug.Log("RESMGRFILEFORMAT", "ResourceReader .ctor(String). UnmanagedMemoryStream: " + (_ums != null)); - try { + try + { ReadResources(); } - catch { + catch + { _store.Close(); // If we threw an exception, close the file. throw; } } - + public ResourceReader(Stream stream) { - if (stream==null) + if (stream == null) throw new ArgumentNullException(nameof(stream)); if (!stream.CanRead) - throw new ArgumentException(Environment.GetResourceString("Argument_StreamNotReadable")); + throw new ArgumentException(SR.Argument_StreamNotReadable); Contract.EndContractBlock(); _resCache = new Dictionary<String, ResourceLocator>(FastResourceComparer.Default); @@ -135,10 +141,10 @@ namespace System.Resources { // We have a faster code path for reading resource files from an assembly. _ums = stream as UnmanagedMemoryStream; - BCLDebug.Log("RESMGRFILEFORMAT", "ResourceReader .ctor(Stream). UnmanagedMemoryStream: "+(_ums!=null)); + BCLDebug.Log("RESMGRFILEFORMAT", "ResourceReader .ctor(Stream). UnmanagedMemoryStream: " + (_ums != null)); 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 @@ -154,16 +160,16 @@ namespace System.Resources { _ums = stream as UnmanagedMemoryStream; - BCLDebug.Log("RESMGRFILEFORMAT", "ResourceReader .ctor(Stream, Hashtable). UnmanagedMemoryStream: "+(_ums!=null)); + BCLDebug.Log("RESMGRFILEFORMAT", "ResourceReader .ctor(Stream, Hashtable). UnmanagedMemoryStream: " + (_ums != null)); ReadResources(); } - + public void Close() { Dispose(true); } - + public void Dispose() { Close(); @@ -171,9 +177,11 @@ namespace System.Resources { private unsafe void Dispose(bool disposing) { - if (_store != null) { + if (_store != null) + { _resCache = null; - if (disposing) { + 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; @@ -189,27 +197,29 @@ namespace System.Resources { _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); } - - private void SkipString() { + + private void SkipString() + { int stringLength = _store.Read7BitEncodedInt(); - if (stringLength < 0) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_NegativeStringLength")); + 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) || + 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]; @@ -219,16 +229,17 @@ namespace System.Resources { 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) || + 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(Environment.GetResourceString("BadImageFormat_ResourcesNameInvalidOffset", r)); + if (r < 0 || r > _dataSectionOffset - _nameSectionOffset) + { + throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesNameInvalidOffset, r)); } return r; } @@ -241,7 +252,7 @@ namespace System.Resources { public IDictionaryEnumerator GetEnumerator() { if (_resCache == null) - throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed")); + throw new InvalidOperationException(SR.ResourceReaderIsClosed); return new ResourceEnumerator(this); } @@ -258,14 +269,15 @@ namespace System.Resources { { Debug.Assert(_store != null, "ResourceReader is closed!"); int hash = FastResourceComparer.HashFunction(name); - BCLDebug.Log("RESMGRFILEFORMAT", "FindPosForResource for "+name+" hash: "+hash.ToString("x", CultureInfo.InvariantCulture)); + BCLDebug.Log("RESMGRFILEFORMAT", "FindPosForResource for " + name + " hash: " + hash.ToString("x", CultureInfo.InvariantCulture)); // 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) { + while (lo <= hi) + { index = (lo + hi) >> 1; // Do NOT use subtraction here, since it will wrap for large // negative numbers. @@ -278,7 +290,8 @@ namespace System.Resources { else c = 1; //BCLDebug.Log("RESMGRFILEFORMAT", " Probing index "+index+" lo: "+lo+" hi: "+hi+" c: "+c); - if (c == 0) { + if (c == 0) + { success = true; break; } @@ -287,7 +300,8 @@ namespace System.Resources { else hi = index - 1; } - if (!success) { + if (!success) + { #if RESOURCE_FILE_FORMAT_DEBUG String lastReadString; lock(this) { @@ -298,36 +312,42 @@ namespace System.Resources { #endif 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) { + if (lo != index) + { lo = index; while (lo > 0 && GetNameHash(lo - 1) == hash) lo--; } - if (hi != index) { + if (hi != index) + { hi = index; while (hi < _numResources - 1 && GetNameHash(hi + 1) == hash) hi++; } - lock(this) { - for(int i = lo; i<=hi; i++) { + lock (this) + { + for (int i = lo; i <= hi; i++) + { _store.BaseStream.Seek(_nameSectionOffset + GetNamePosition(i), SeekOrigin.Begin); - if (CompareStringEqualsName(name)) { + if (CompareStringEqualsName(name)) + { int dataPos = _store.ReadInt32(); - if (dataPos < 0 || dataPos >= _store.BaseStream.Length - _dataSectionOffset) { - throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesDataInvalidOffset", dataPos)); + if (dataPos < 0 || dataPos >= _store.BaseStream.Length - _dataSectionOffset) + { + throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesDataInvalidOffset, dataPos)); } return dataPos; } } } - BCLDebug.Log("RESMGRFILEFORMAT", "FindPosForResource for "+name+": Found a hash collision, HOWEVER, neither of these collided values equaled the given string."); + BCLDebug.Log("RESMGRFILEFORMAT", "FindPosForResource for " + name + ": Found a hash collision, HOWEVER, neither of these collided values equaled the given string."); return -1; } @@ -339,15 +359,18 @@ namespace System.Resources { { Debug.Assert(_store != null, "ResourceReader is closed!"); int byteLen = _store.Read7BitEncodedInt(); - if (byteLen < 0) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_NegativeStringLength")); + if (byteLen < 0) + { + throw new BadImageFormatException(SR.BadImageFormat_NegativeStringLength); } - if (_ums != null) { + 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(Environment.GetResourceString("BadImageFormat_ResourcesNameTooLong")); + if (_ums.Position > _ums.Length) + { + throw new BadImageFormatException(SR.BadImageFormat_ResourcesNameTooLong); } // On 64-bit machines, these char*'s may be misaligned. Use a @@ -355,17 +378,19 @@ namespace System.Resources { //return FastResourceComparer.CompareOrdinal((char*)bytes, byteLen/2, name) == 0; return FastResourceComparer.CompareOrdinal(bytes, byteLen, name) == 0; } - else { + else + { // This code needs to be fast byte[] bytes = new byte[byteLen]; int numBytesToRead = byteLen; - while(numBytesToRead > 0) { + while (numBytesToRead > 0) + { int n = _store.Read(bytes, byteLen - numBytesToRead, numBytesToRead); if (n == 0) - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceNameCorrupted")); + throw new BadImageFormatException(SR.BadImageFormat_ResourceNameCorrupted); numBytesToRead -= n; } - return FastResourceComparer.CompareOrdinal(bytes, byteLen/2, name) == 0; + return FastResourceComparer.CompareOrdinal(bytes, byteLen / 2, name) == 0; } } @@ -378,17 +403,20 @@ namespace System.Resources { byte[] bytes; int byteLen; long nameVA = GetNamePosition(index); - lock (this) { + lock (this) + { _store.BaseStream.Seek(nameVA + _nameSectionOffset, SeekOrigin.Begin); // Can't use _store.ReadString, since it's using UTF-8! byteLen = _store.Read7BitEncodedInt(); - if (byteLen < 0) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_NegativeStringLength")); + if (byteLen < 0) + { + throw new BadImageFormatException(SR.BadImageFormat_NegativeStringLength); } - if (_ums != null) { + if (_ums != null) + { if (_ums.Position > _ums.Length - byteLen) - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesIndexTooLong", index)); + throw new BadImageFormatException(SR.Format(SR.BadImageFormat_ResourcesIndexTooLong, index)); String s = null; char* charPtr = (char*)_ums.PositionPointer; @@ -402,14 +430,15 @@ namespace System.Resources { } else { #endif //IA64 - s = new String(charPtr, 0, byteLen/2); + s = new String(charPtr, 0, byteLen / 2); #if IA64 } #endif //IA64 _ums.Position += byteLen; dataOffset = _store.ReadInt32(); - if (dataOffset < 0 || dataOffset >= _store.BaseStream.Length - _dataSectionOffset) { - throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesDataInvalidOffset", dataOffset)); + if (dataOffset < 0 || dataOffset >= _store.BaseStream.Length - _dataSectionOffset) + { + throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesDataInvalidOffset, dataOffset)); } return s; } @@ -419,15 +448,17 @@ namespace System.Resources { // Use a blocking read in case the stream doesn't give us back // everything immediately. int count = byteLen; - while(count > 0) { + while (count > 0) + { int n = _store.Read(bytes, byteLen - count, count); if (n == 0) - throw new EndOfStreamException(Environment.GetResourceString("BadImageFormat_ResourceNameCorrupted_NameIndex", index)); + 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(Environment.GetResourceString("BadImageFormat_ResourcesDataInvalidOffset", dataOffset)); + if (dataOffset < 0 || dataOffset >= _store.BaseStream.Length - _dataSectionOffset) + { + throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesDataInvalidOffset, dataOffset)); } } return Encoding.Unicode.GetString(bytes, 0, byteLen); @@ -440,15 +471,17 @@ namespace System.Resources { { Debug.Assert(_store != null, "ResourceReader is closed!"); long nameVA = GetNamePosition(index); - lock(this) { + 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(Environment.GetResourceString("BadImageFormat_ResourcesDataInvalidOffset", dataPos)); + if (dataPos < 0 || dataPos >= _store.BaseStream.Length - _dataSectionOffset) + { + throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesDataInvalidOffset, dataPos)); } - BCLDebug.Log("RESMGRFILEFORMAT", "GetValueForNameIndex: dataPos: "+dataPos); + BCLDebug.Log("RESMGRFILEFORMAT", "GetValueForNameIndex: dataPos: " + dataPos); ResourceTypeCode junk; if (_version == 1) return LoadObjectV1(dataPos); @@ -464,30 +497,33 @@ namespace System.Resources { internal String LoadString(int pos) { Debug.Assert(_store != null, "ResourceReader is closed!"); - _store.BaseStream.Seek(_dataSectionOffset+pos, SeekOrigin.Begin); + _store.BaseStream.Seek(_dataSectionOffset + pos, SeekOrigin.Begin); String s = null; int typeIndex = _store.Read7BitEncodedInt(); - if (_version == 1) { + if (_version == 1) + { if (typeIndex == -1) return null; if (FindType(typeIndex) != typeof(String)) - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResourceNotString_Type", FindType(typeIndex).FullName)); + 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) { + 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(Environment.GetResourceString("InvalidOperation_ResourceNotString_Type", typeString)); + throw new InvalidOperationException(SR.Format(SR.InvalidOperation_ResourceNotString_Type, typeString)); } if (typeCode == ResourceTypeCode.String) // ignore Null s = _store.ReadString(); } - BCLDebug.Log("RESMGRFILEFORMAT", "LoadString("+pos.ToString("x", CultureInfo.InvariantCulture)+" returned "+(s==null ? "[a null string]" : s)); + BCLDebug.Log("RESMGRFILEFORMAT", "LoadString(" + pos.ToString("x", CultureInfo.InvariantCulture) + " returned " + (s == null ? "[a null string]" : s)); return s; } @@ -502,7 +538,8 @@ namespace System.Resources { internal Object LoadObject(int pos, out ResourceTypeCode typeCode) { - if (_version == 1) { + if (_version == 1) + { Object o = LoadObjectV1(pos); typeCode = (o is String) ? ResourceTypeCode.String : ResourceTypeCode.StartOfUserTypes; return o; @@ -519,26 +556,30 @@ namespace System.Resources { Debug.Assert(_store != null, "ResourceReader is closed!"); Debug.Assert(_version == 1, ".resources file was not a V1 .resources file!"); - try { + 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(Environment.GetResourceString("BadImageFormat_TypeMismatch"), eof); + catch (EndOfStreamException eof) + { + throw new BadImageFormatException(SR.BadImageFormat_TypeMismatch, eof); } - catch (ArgumentOutOfRangeException e) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_TypeMismatch"), e); + catch (ArgumentOutOfRangeException e) + { + throw new BadImageFormatException(SR.BadImageFormat_TypeMismatch, e); } } - private Object _LoadObjectV1(int pos) { - _store.BaseStream.Seek(_dataSectionOffset+pos, SeekOrigin.Begin); + private Object _LoadObjectV1(int pos) + { + _store.BaseStream.Seek(_dataSectionOffset + pos, SeekOrigin.Begin); int typeIndex = _store.Read7BitEncodedInt(); if (typeIndex == -1) return null; RuntimeType type = FindType(typeIndex); - BCLDebug.Log("RESMGRFILEFORMAT", "LoadObject type: "+type.Name+" pos: 0x"+_store.BaseStream.Position.ToString("x", CultureInfo.InvariantCulture)); + BCLDebug.Log("RESMGRFILEFORMAT", "LoadObject type: " + type.Name + " pos: 0x" + _store.BaseStream.Position.ToString("x", CultureInfo.InvariantCulture)); // 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. @@ -565,21 +606,24 @@ namespace System.Resources { return _store.ReadSingle(); else if (type == typeof(Double)) return _store.ReadDouble(); - else if (type == typeof(DateTime)) { + 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)) { + else if (type == typeof(Decimal)) + { int[] bits = new int[4]; - for(int i=0; i<bits.Length; i++) + for (int i = 0; i < bits.Length; i++) bits[i] = _store.ReadInt32(); return new Decimal(bits); } - else { - throw new NotSupportedException(Environment.GetResourceString("NotSupported_ResourceObjectSerialization")); + else + { + throw new NotSupportedException(SR.NotSupported_ResourceObjectSerialization); } } @@ -588,136 +632,152 @@ namespace System.Resources { Debug.Assert(_store != null, "ResourceReader is closed!"); Debug.Assert(_version >= 2, ".resources file was not a V2 (or higher) .resources file!"); - try { + 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(Environment.GetResourceString("BadImageFormat_TypeMismatch"), eof); + catch (EndOfStreamException eof) + { + throw new BadImageFormatException(SR.BadImageFormat_TypeMismatch, eof); } - catch (ArgumentOutOfRangeException e) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_TypeMismatch"), e); + 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) _store.Read7BitEncodedInt(); + private Object _LoadObjectV2(int pos, out ResourceTypeCode typeCode) + { + _store.BaseStream.Seek(_dataSectionOffset + pos, SeekOrigin.Begin); + typeCode = (ResourceTypeCode)_store.Read7BitEncodedInt(); - BCLDebug.Log("RESMGRFILEFORMAT", "LoadObjectV2 type: "+typeCode+" pos: 0x"+_store.BaseStream.Position.ToString("x", CultureInfo.InvariantCulture)); - - switch(typeCode) { - case ResourceTypeCode.Null: - return null; + BCLDebug.Log("RESMGRFILEFORMAT", "LoadObjectV2 type: " + typeCode + " pos: 0x" + _store.BaseStream.Position.ToString("x", CultureInfo.InvariantCulture)); - case ResourceTypeCode.String: - return _store.ReadString(); - - case ResourceTypeCode.Boolean: - return _store.ReadBoolean(); + switch (typeCode) + { + case ResourceTypeCode.Null: + return null; - case ResourceTypeCode.Char: - return (char) _store.ReadUInt16(); + case ResourceTypeCode.String: + return _store.ReadString(); - case ResourceTypeCode.Byte: - return _store.ReadByte(); + case ResourceTypeCode.Boolean: + return _store.ReadBoolean(); - case ResourceTypeCode.SByte: - return _store.ReadSByte(); + case ResourceTypeCode.Char: + return (char)_store.ReadUInt16(); - case ResourceTypeCode.Int16: - return _store.ReadInt16(); + case ResourceTypeCode.Byte: + return _store.ReadByte(); - case ResourceTypeCode.UInt16: - return _store.ReadUInt16(); + case ResourceTypeCode.SByte: + return _store.ReadSByte(); - case ResourceTypeCode.Int32: - return _store.ReadInt32(); + case ResourceTypeCode.Int16: + return _store.ReadInt16(); - case ResourceTypeCode.UInt32: - return _store.ReadUInt32(); + case ResourceTypeCode.UInt16: + return _store.ReadUInt16(); - case ResourceTypeCode.Int64: - return _store.ReadInt64(); + case ResourceTypeCode.Int32: + return _store.ReadInt32(); - case ResourceTypeCode.UInt64: - return _store.ReadUInt64(); + case ResourceTypeCode.UInt32: + return _store.ReadUInt32(); - case ResourceTypeCode.Single: - return _store.ReadSingle(); + case ResourceTypeCode.Int64: + return _store.ReadInt64(); - case ResourceTypeCode.Double: - return _store.ReadDouble(); + case ResourceTypeCode.UInt64: + return _store.ReadUInt64(); - case ResourceTypeCode.Decimal: - return _store.ReadDecimal(); - - case ResourceTypeCode.DateTime: - // Use DateTime's ToBinary & FromBinary. - Int64 data = _store.ReadInt64(); - return DateTime.FromBinary(data); - - case ResourceTypeCode.TimeSpan: - Int64 ticks = _store.ReadInt64(); - return new TimeSpan(ticks); - - // Special types - case ResourceTypeCode.ByteArray: { - int len = _store.ReadInt32(); - if (len < 0) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceDataLengthInvalid", len)); - } + case ResourceTypeCode.Single: + return _store.ReadSingle(); + + case ResourceTypeCode.Double: + return _store.ReadDouble(); + + case ResourceTypeCode.Decimal: + return _store.ReadDecimal(); - if (_ums == null) { - if (len > _store.BaseStream.Length) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceDataLengthInvalid", len)); + case ResourceTypeCode.DateTime: + // Use DateTime's ToBinary & FromBinary. + Int64 data = _store.ReadInt64(); + return DateTime.FromBinary(data); + + case ResourceTypeCode.TimeSpan: + Int64 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)); } - return _store.ReadBytes(len); - } - if (len > _ums.Length - _ums.Position) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceDataLengthInvalid", len)); - } + if (_ums == null) + { + if (len > _store.BaseStream.Length) + { + throw new BadImageFormatException(SR.Format(SR.BadImageFormat_ResourceDataLengthInvalid, len)); + } + return _store.ReadBytes(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; - } + if (len > _ums.Length - _ums.Position) + { + throw new BadImageFormatException(SR.Format(SR.BadImageFormat_ResourceDataLengthInvalid, len)); + } - case ResourceTypeCode.Stream: { - int len = _store.ReadInt32(); - if (len < 0) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceDataLengthInvalid", len)); - } - if (_ums == null) { - byte[] bytes = _store.ReadBytes(len); - // Lifetime of memory == lifetime of this stream. - return new PinnedBufferMemoryStream(bytes); + 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; } - // make sure we don't create an UnmanagedMemoryStream that is longer than the resource stream. - if (len > _ums.Length - _ums.Position) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceDataLengthInvalid", len)); + 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); + } } - // 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); } - } - - default: - if (typeCode < ResourceTypeCode.StartOfUserTypes) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_TypeMismatch")); - } - break; + break; } // Normal serialized objects - throw new NotSupportedException(Environment.GetResourceString("NotSupported_ResourceObjectSerialization")); + throw new NotSupportedException(SR.NotSupported_ResourceObjectSerialization); } @@ -729,16 +789,19 @@ namespace System.Resources { { Debug.Assert(_store != null, "ResourceReader is closed!"); - try { + try + { // mega try-catch performs exceptionally bad on x64; factored out body into // _ReadResources and wrap here. _ReadResources(); } - catch (EndOfStreamException eof) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"), eof); + catch (EndOfStreamException eof) + { + throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted, eof); } - catch (IndexOutOfRangeException e) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"), e); + catch (IndexOutOfRangeException e) + { + throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted, e); } } @@ -748,21 +811,24 @@ namespace System.Resources { // Check for magic number int magicNum = _store.ReadInt32(); if (magicNum != ResourceManager.MagicNumber) - throw new ArgumentException(Environment.GetResourceString("Resources_StreamNotValid")); + 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(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted")); + if (numBytesToSkip < 0 || resMgrHeaderVersion < 0) + { + throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted); } - if (resMgrHeaderVersion > 1) { + if (resMgrHeaderVersion > 1) + { BCLDebug.Log("RESMGRFILEFORMAT", LogLevel.Status, "ReadResources: Unexpected ResMgr header version: {0} Skipping ahead {1} bytes.", resMgrHeaderVersion, numBytesToSkip); _store.BaseStream.Seek(numBytesToSkip, SeekOrigin.Current); } - else { + else + { BCLDebug.Log("RESMGRFILEFORMAT", "ReadResources: Parsing ResMgr header v1."); // We don't care about numBytesToSkip; read the rest of the header @@ -773,7 +839,7 @@ namespace System.Resources { AssemblyName mscorlib = new AssemblyName(ResourceManager.MscorlibName); if (!ResourceManager.CompareNames(readerType, ResourceManager.ResReaderTypeName, mscorlib)) - throw new NotSupportedException(Environment.GetResourceString("NotSupported_WrongResourceReader_Type", readerType)); + throw new NotSupportedException(SR.Format(SR.NotSupported_WrongResourceReader_Type, readerType)); // Skip over type name for a suitable ResourceSet SkipString(); @@ -783,7 +849,7 @@ namespace System.Resources { // Do file version check int version = _store.ReadInt32(); if (version != RuntimeResourceSet.Version && version != 1) - throw new ArgumentException(Environment.GetResourceString("Arg_ResourceFileUnsupportedVersion", RuntimeResourceSet.Version, version)); + throw new ArgumentException(SR.Format(SR.Arg_ResourceFileUnsupportedVersion, RuntimeResourceSet.Version, version)); _version = version; #if RESOURCE_FILE_FORMAT_DEBUG @@ -807,8 +873,9 @@ namespace System.Resources { #endif _numResources = _store.ReadInt32(); - if (_numResources < 0) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted")); + if (_numResources < 0) + { + throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted); } BCLDebug.Log("RESMGRFILEFORMAT", "ReadResources: Expecting " + _numResources + " resources."); #if RESOURCE_FILE_FORMAT_DEBUG @@ -819,13 +886,15 @@ namespace System.Resources { // Read type positions into type positions array. // But delay initialize the type table. int numTypes = _store.ReadInt32(); - if (numTypes < 0) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted")); + if (numTypes < 0) + { + throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted); } _typeTable = new RuntimeType[numTypes]; _typeNamePositions = new int[numTypes]; - for (int i=0; i<numTypes; i++) { - _typeNamePositions[i] = (int) _store.BaseStream.Position; + 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(); @@ -844,8 +913,10 @@ namespace System.Resources { // 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++) { + if (alignBytes != 0) + { + for (int i = 0; i < 8 - alignBytes; i++) + { _store.ReadByte(); } } @@ -858,18 +929,23 @@ namespace System.Resources { } #endif - if (_ums == null) { + if (_ums == null) + { _nameHashes = new int[_numResources]; - for (int i = 0; i < _numResources; i++) { + for (int i = 0; i < _numResources; i++) + { _nameHashes[i] = _store.ReadInt32(); } } - else { + else + { int seekPos = unchecked(4 * _numResources); - if (seekPos < 0) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted")); + if (seekPos < 0) + { + throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted); } - unsafe { + unsafe + { _nameHashesPtr = (int*)_ums.PositionPointer; // Skip over the array of nameHashes. _ums.Seek(seekPos, SeekOrigin.Current); @@ -885,23 +961,29 @@ namespace System.Resources { _store.BaseStream.Position += 8; } #endif - if (_ums == null) { + if (_ums == null) + { _namePositions = new int[_numResources]; - for (int i = 0; i < _numResources; i++) { + for (int i = 0; i < _numResources; i++) + { int namePosition = _store.ReadInt32(); - if (namePosition < 0) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted")); + if (namePosition < 0) + { + throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted); } _namePositions[i] = namePosition; } } - else { + else + { int seekPos = unchecked(4 * _numResources); - if (seekPos < 0) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted")); + if (seekPos < 0) + { + throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted); } - unsafe { + unsafe + { _namePositionsPtr = (int*)_ums.PositionPointer; // Skip over the array of namePositions. _ums.Seek(seekPos, SeekOrigin.Current); @@ -912,16 +994,18 @@ namespace System.Resources { // Read location of data section. _dataSectionOffset = _store.ReadInt32(); - if (_dataSectionOffset < 0) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted")); + 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(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted")); + if (_dataSectionOffset < _nameSectionOffset) + { + throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted); } BCLDebug.Log("RESMGRFILEFORMAT", String.Format(CultureInfo.InvariantCulture, "ReadResources: _nameOffset = 0x{0:x} _dataOffset = 0x{1:x}", _nameSectionOffset, _dataSectionOffset)); @@ -932,12 +1016,15 @@ namespace System.Resources { // and initialize Reflection. private RuntimeType FindType(int typeIndex) { - if (typeIndex < 0 || typeIndex >= _typeTable.Length) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_InvalidType")); + if (typeIndex < 0 || typeIndex >= _typeTable.Length) + { + throw new BadImageFormatException(SR.BadImageFormat_InvalidType); } - if (_typeTable[typeIndex] == null) { + if (_typeTable[typeIndex] == null) + { long oldPos = _store.BaseStream.Position; - try { + try + { _store.BaseStream.Position = _typeNamePositions[typeIndex]; String typeName = _store.ReadString(); _typeTable[typeIndex] = (RuntimeType)Type.GetType(typeName, true); @@ -954,9 +1041,10 @@ namespace System.Resources { // getting to Type.GetType -- this is costly with v1 resource formats. catch (FileNotFoundException) { - throw new NotSupportedException(Environment.GetResourceString("NotSupported_ResourceObjectSerialization")); + throw new NotSupportedException(SR.NotSupported_ResourceObjectSerialization); } - finally { + finally + { _store.BaseStream.Position = oldPos; } } @@ -971,7 +1059,7 @@ namespace System.Resources { throw new ArgumentNullException(nameof(resourceName)); Contract.EndContractBlock(); if (_resCache == null) - throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed")); + 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 @@ -979,24 +1067,29 @@ namespace System.Resources { // off the length of the type code). int[] sortedDataPositions = new int[_numResources]; int dataPos = FindPosForResource(resourceName); - if( dataPos == -1) { - throw new ArgumentException(Environment.GetResourceString("Arg_ResourceNameNotExist", resourceName)); + if (dataPos == -1) + { + throw new ArgumentException(SR.Format(SR.Arg_ResourceNameNotExist, resourceName)); } - - lock(this) { + + lock (this) + { // Read all the positions of data within the data section. - for(int i=0; i<_numResources; i++) { + for (int i = 0; i < _numResources; i++) + { _store.BaseStream.Position = _nameSectionOffset + GetNamePosition(i); // Skip over name of resource int numBytesToSkip = _store.Read7BitEncodedInt(); - if (numBytesToSkip < 0) { - throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesNameInvalidOffset", numBytesToSkip)); + 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(Environment.GetResourceString("BadImageFormat_ResourcesDataInvalidOffset", dPos)); + if (dPos < 0 || dPos >= _store.BaseStream.Length - _dataSectionOffset) + { + throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesDataInvalidOffset, dPos)); } sortedDataPositions[i] = dPos; } @@ -1005,23 +1098,24 @@ namespace System.Resources { 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!"); + 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) _store.Read7BitEncodedInt(); - if (typeCode < 0 || typeCode >= ResourceTypeCode.StartOfUserTypes + _typeTable.Length) { - throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_InvalidType")); + ResourceTypeCode typeCode = (ResourceTypeCode)_store.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)); + len -= (int)(_store.BaseStream.Position - (_dataSectionOffset + dataPos)); byte[] bytes = _store.ReadBytes(len); if (bytes.Length != len) - throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourceNameCorrupted")); + throw new FormatException(SR.BadImageFormat_ResourceNameCorrupted); resourceData = bytes; } } @@ -1029,19 +1123,23 @@ namespace System.Resources { private String TypeNameFromTypeCode(ResourceTypeCode typeCode) { Contract.Requires(typeCode >= 0, "can't be negative"); - if (typeCode < ResourceTypeCode.StartOfUserTypes) { + 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 { + else + { int typeIndex = typeCode - ResourceTypeCode.StartOfUserTypes; Debug.Assert(typeIndex >= 0 && typeIndex < _typeTable.Length, "TypeCode is broken or corrupted!"); long oldPos = _store.BaseStream.Position; - try { + try + { _store.BaseStream.Position = _typeNamePositions[typeIndex]; return _store.ReadString(); } - finally { + finally + { _store.BaseStream.Position = oldPos; } } @@ -1068,7 +1166,8 @@ namespace System.Resources { public bool MoveNext() { - if (_currentName == _reader._numResources - 1 || _currentName == ENUM_DONE) { + if (_currentName == _reader._numResources - 1 || _currentName == ENUM_DONE) + { _currentIsValid = false; _currentName = ENUM_DONE; return false; @@ -1077,49 +1176,61 @@ namespace System.Resources { _currentName++; return true; } - - public Object Key { - get { - if (_currentName == ENUM_DONE) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumEnded)); - if (!_currentIsValid) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted)); - if (_reader._resCache == null) throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed")); + + public Object Key + { + get + { + if (_currentName == ENUM_DONE) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumEnded)); + if (!_currentIsValid) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumNotStarted)); + if (_reader._resCache == null) throw new InvalidOperationException(SR.ResourceReaderIsClosed); return _reader.AllocateStringForNameIndex(_currentName, out _dataPosition); } } - - public Object Current { - get { + + 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 { + internal int DataPosition + { + get + { return _dataPosition; } } - public DictionaryEntry Entry { - get { - if (_currentName == ENUM_DONE) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumEnded)); - if (!_currentIsValid) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted)); - if (_reader._resCache == null) throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed")); + public DictionaryEntry Entry + { + get + { + if (_currentName == ENUM_DONE) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumEnded)); + if (!_currentIsValid) throw new InvalidOperationException(SR.GetResourceString(ResId.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) { + 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)) { + if (_reader._resCache.TryGetValue(key, out locator)) + { value = locator.Value; } - if (value == null) { - if (_dataPosition == -1) + if (value == null) + { + if (_dataPosition == -1) value = _reader.GetValueForNameIndex(_currentName); - else + else value = _reader.LoadObject(_dataPosition); // If enumeration and subsequent lookups happen very // frequently in the same process, add a ResourceLocator @@ -1132,12 +1243,14 @@ namespace System.Resources { return new DictionaryEntry(key, value); } } - - public Object Value { - get { - if (_currentName == ENUM_DONE) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumEnded)); - if (!_currentIsValid) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted)); - if (_reader._resCache == null) throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed")); + + public Object Value + { + get + { + if (_currentName == ENUM_DONE) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumEnded)); + if (!_currentIsValid) throw new InvalidOperationException(SR.GetResourceString(ResId.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. @@ -1149,7 +1262,7 @@ namespace System.Resources { public void Reset() { - if (_reader._resCache == null) throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed")); + if (_reader._resCache == null) throw new InvalidOperationException(SR.ResourceReaderIsClosed); _currentIsValid = false; _currentName = ENUM_NOT_STARTED; } diff --git a/src/mscorlib/src/System/Resources/ResourceSet.cs b/src/mscorlib/src/System/Resources/ResourceSet.cs index 8fd9346f91..8775f6411a 100644 --- a/src/mscorlib/src/System/Resources/ResourceSet.cs +++ b/src/mscorlib/src/System/Resources/ResourceSet.cs @@ -12,7 +12,9 @@ ** ** ===========================================================*/ -namespace System.Resources { + +namespace System.Resources +{ using System; using System.Collections; using System.IO; @@ -75,7 +77,7 @@ namespace System.Resources { ReadResources(); } #endif // LOOSELY_LINKED_RESOURCE_REFERENCE - + // Creates a ResourceSet using the system default ResourceReader // implementation. Use this constructor to read from an open stream // of data. @@ -119,7 +121,7 @@ namespace System.Resources { ReadResources(); } #endif // LOOSELY_LINKED_RESOURCE_REFERENCE - + private void CommonInit() { Table = new Hashtable(); @@ -133,10 +135,11 @@ namespace System.Resources { { Dispose(true); } - + protected virtual void Dispose(bool disposing) { - if (disposing) { + if (disposing) + { // Close the Reader in a thread-safe way. IResourceReader copyOfReader = Reader; Reader = null; @@ -169,7 +172,7 @@ namespace System.Resources { { 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. @@ -183,7 +186,6 @@ namespace System.Resources { return GetEnumeratorHelper(); } - /// <internalonly/> IEnumerator IEnumerable.GetEnumerator() { return GetEnumeratorHelper(); @@ -193,7 +195,7 @@ namespace System.Resources { { Hashtable copyOfTable = Table; // Avoid a race with Dispose if (copyOfTable == null) - throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_ResourceSet")); + throw new ObjectDisposedException(null, SR.ObjectDisposed_ResourceSet); return copyOfTable.GetEnumerator(); } @@ -202,11 +204,13 @@ namespace System.Resources { public virtual String GetString(String name) { Object obj = GetObjectInternal(name); - try { + try + { return (String)obj; } - catch (InvalidCastException) { - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResourceNotString_Name", name)); + catch (InvalidCastException) + { + throw new InvalidOperationException(SR.Format(SR.InvalidOperation_ResourceNotString_Name, name)); } } @@ -217,28 +221,33 @@ namespace System.Resources { // Case-sensitive lookup obj = GetObjectInternal(name); - try { + try + { s = (String)obj; } - catch (InvalidCastException) { - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResourceNotString_Name", name)); + catch (InvalidCastException) + { + throw new InvalidOperationException(SR.Format(SR.InvalidOperation_ResourceNotString_Name, name)); } // case-sensitive lookup succeeded - if (s != null || !ignoreCase) { + if (s != null || !ignoreCase) + { return s; - } + } // Try doing a case-insensitive lookup obj = GetCaseInsensitiveObjectInternal(name); - try { + try + { return (String)obj; } - catch (InvalidCastException) { - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResourceNotString_Name", name)); + 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) @@ -249,17 +258,18 @@ namespace System.Resources { 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()) { + while (en.MoveNext()) + { Object value = en.Value; #if LOOSELY_LINKED_RESOURCE_REFERENCE if (Assembly != null && value is LooselyLinkedResourceReference) { @@ -282,7 +292,7 @@ namespace System.Resources { Hashtable copyOfTable = Table; // Avoid a race with Dispose if (copyOfTable == null) - throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_ResourceSet")); + throw new ObjectDisposedException(null, SR.ObjectDisposed_ResourceSet); return copyOfTable[name]; } @@ -292,7 +302,7 @@ namespace System.Resources { Hashtable copyOfTable = Table; // Avoid a race with Dispose if (copyOfTable == null) - throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_ResourceSet")); + throw new ObjectDisposedException(null, SR.ObjectDisposed_ResourceSet); Hashtable caseTable = _caseInsensitiveTable; // Avoid a race condition with Close if (caseTable == null) @@ -300,7 +310,7 @@ namespace System.Resources { caseTable = new Hashtable(StringComparer.OrdinalIgnoreCase); #if _DEBUG //Console.WriteLine("ResourceSet::GetObject loading up case-insensitive data"); - BCLDebug.Perf(false, "Using case-insensitive lookups is bad perf-wise. Consider capitalizing "+name+" correctly in your source"); + BCLDebug.Perf(false, "Using case-insensitive lookups is bad perf-wise. Consider capitalizing " + name + " correctly in your source"); #endif IDictionaryEnumerator en = copyOfTable.GetEnumerator(); diff --git a/src/mscorlib/src/System/Resources/ResourceTypeCode.cs b/src/mscorlib/src/System/Resources/ResourceTypeCode.cs deleted file mode 100644 index 64fb076eb5..0000000000 --- a/src/mscorlib/src/System/Resources/ResourceTypeCode.cs +++ /dev/null @@ -1,57 +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: Marker for types in .resources files -** -** -===========================================================*/ - -namespace System.Resources { - /* An internal implementation detail for .resources files, describing - what type an object is. - Ranges: - 0 - 0x1F Primitives and reserved values - 0x20 - 0x3F Specially recognized types, like byte[] and Streams - - Note this data must be included in any documentation describing the - internals of .resources files. - */ - [Serializable] - internal enum ResourceTypeCode { - // Primitives - Null = 0, - String = 1, - Boolean = 2, - Char = 3, - Byte = 4, - SByte = 5, - Int16 = 6, - UInt16 = 7, - Int32 = 8, - UInt32 = 9, - Int64 = 0xa, - UInt64 = 0xb, - Single = 0xc, - Double = 0xd, - Decimal = 0xe, - DateTime = 0xf, - TimeSpan = 0x10, - - // A meta-value - change this if you add new primitives - LastPrimitive = TimeSpan, - - // Types with a special representation, like byte[] and Stream - ByteArray = 0x20, - Stream = 0x21, - - // User types - serialized using the binary formatter. - StartOfUserTypes = 0x40 - } -} diff --git a/src/mscorlib/src/System/Resources/RuntimeResourceSet.cs b/src/mscorlib/src/System/Resources/RuntimeResourceSet.cs index a94ac82781..e9c038a498 100644 --- a/src/mscorlib/src/System/Resources/RuntimeResourceSet.cs +++ b/src/mscorlib/src/System/Resources/RuntimeResourceSet.cs @@ -12,7 +12,9 @@ ** ** ===========================================================*/ -namespace System.Resources { + +namespace System.Resources +{ using System; using System.IO; using System.Collections; @@ -162,7 +164,7 @@ namespace System.Resources { internal sealed class RuntimeResourceSet : ResourceSet, IEnumerable { internal const int Version = 2; // File format version number - + // Cache for resources. Key is the resource name, which can be cached // for arbitrarily long times, since the object is usually a string // literal that will live for the lifetime of the appdomain. The @@ -217,11 +219,14 @@ namespace System.Resources { { if (Reader == null) return; - - if (disposing) { - lock(Reader) { + + if (disposing) + { + lock (Reader) + { _resCache = null; - if (_defaultReader != null) { + if (_defaultReader != null) + { _defaultReader.Close(); _defaultReader = null; } @@ -229,8 +234,9 @@ namespace System.Resources { // Set Reader to null to avoid a race in GetObject. base.Dispose(disposing); } - } - else { + } + else + { // Just to make sure we always clear these fields in the future... _resCache = null; _caseInsensitiveTable = null; @@ -253,7 +259,7 @@ namespace System.Resources { { IResourceReader copyOfReader = Reader; if (copyOfReader == null || _resCache == null) - throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_ResourceSet")); + throw new ObjectDisposedException(null, SR.ObjectDisposed_ResourceSet); return copyOfReader.GetEnumerator(); } @@ -262,13 +268,13 @@ namespace System.Resources { public override String GetString(String key) { Object o = GetObject(key, false, true); - return (String) o; + return (String)o; } public override String GetString(String key, bool ignoreCase) { Object o = GetObject(key, ignoreCase, true); - return (String) o; + return (String)o; } public override Object GetObject(String key) @@ -283,34 +289,39 @@ namespace System.Resources { private Object GetObject(String key, bool ignoreCase, bool isString) { - if (key==null) + if (key == null) throw new ArgumentNullException(nameof(key)); if (Reader == null || _resCache == null) - throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_ResourceSet")); + throw new ObjectDisposedException(null, SR.ObjectDisposed_ResourceSet); Contract.EndContractBlock(); Object value = null; ResourceLocator resLocation; - - lock(Reader) { + + lock (Reader) + { if (Reader == null) - throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_ResourceSet")); - - if (_defaultReader != null) { + throw new ObjectDisposedException(null, SR.ObjectDisposed_ResourceSet); + + if (_defaultReader != null) + { BCLDebug.Log("RESMGRFILEFORMAT", "Going down fast path in RuntimeResourceSet::GetObject"); - + // Find the offset within the data section int dataPos = -1; - if (_resCache.TryGetValue(key, out resLocation)) { + if (_resCache.TryGetValue(key, out resLocation)) + { value = resLocation.Value; dataPos = resLocation.DataPosition; } - - if (dataPos == -1 && value == null) { + + if (dataPos == -1 && value == null) + { dataPos = _defaultReader.FindPosForResource(key); } - if (dataPos != -1 && value == null) { + if (dataPos != -1 && value == null) + { Debug.Assert(dataPos >= 0, "data section offset cannot be negative!"); // Normally calling LoadString or LoadObject requires // taking a lock. Note that in this case, we took a @@ -318,28 +329,32 @@ namespace System.Resources { // sufficient since we never pass this ResourceReader // to anyone else. ResourceTypeCode typeCode; - if (isString) { + if (isString) + { value = _defaultReader.LoadString(dataPos); typeCode = ResourceTypeCode.String; } - else { + else + { value = _defaultReader.LoadObject(dataPos, out typeCode); } resLocation = new ResourceLocator(dataPos, (ResourceLocator.CanCache(typeCode)) ? value : null); - lock(_resCache) { + lock (_resCache) + { _resCache[key] = resLocation; } } - - if (value != null || !ignoreCase) { + + if (value != null || !ignoreCase) + { #if LOOSELY_LINKED_RESOURCE_REFERENCE if (Assembly != null && (value is LooselyLinkedResourceReference)) { LooselyLinkedResourceReference assRef = (LooselyLinkedResourceReference) value; value = assRef.Resolve(Assembly); } #endif // LOOSELY_LINKED_RESOURCE_REFERENCE - + return value; // may be null } } // if (_defaultReader != null) @@ -347,20 +362,24 @@ namespace System.Resources { // At this point, we either don't have our default resource reader // or we haven't found the particular resource we're looking for // and may have to search for it in a case-insensitive way. - if (!_haveReadFromReader) { + if (!_haveReadFromReader) + { // If necessary, init our case insensitive hash table. - if (ignoreCase && _caseInsensitiveTable == null) { + if (ignoreCase && _caseInsensitiveTable == null) + { _caseInsensitiveTable = new Dictionary<String, ResourceLocator>(StringComparer.OrdinalIgnoreCase); } #if _DEBUG - BCLDebug.Perf(!ignoreCase, "Using case-insensitive lookups is bad perf-wise. Consider capitalizing "+key+" correctly in your source"); + BCLDebug.Perf(!ignoreCase, "Using case-insensitive lookups is bad perf-wise. Consider capitalizing " + key + " correctly in your source"); #endif - if (_defaultReader == null) { + if (_defaultReader == null) + { IDictionaryEnumerator en = Reader.GetEnumerator(); - while (en.MoveNext()) { + while (en.MoveNext()) + { DictionaryEntry entry = en.Entry; - String readKey = (String) entry.Key; + String readKey = (String)entry.Key; ResourceLocator resLoc = new ResourceLocator(-1, entry.Value); _resCache.Add(readKey, resLoc); if (ignoreCase) @@ -371,12 +390,14 @@ namespace System.Resources { if (!ignoreCase) Reader.Close(); } - else { + else + { Debug.Assert(ignoreCase, "This should only happen for case-insensitive lookups"); ResourceReader.ResourceEnumerator en = _defaultReader.GetEnumeratorInternal(); - while (en.MoveNext()) { + while (en.MoveNext()) + { // Note: Always ask for the resource key before the data position. - String currentKey = (String) en.Key; + String currentKey = (String)en.Key; int dataPos = en.DataPosition; ResourceLocator resLoc = new ResourceLocator(dataPos, null); _caseInsensitiveTable.Add(currentKey, resLoc); @@ -387,19 +408,23 @@ namespace System.Resources { Object obj = null; bool found = false; bool keyInWrongCase = false; - if (_defaultReader != null) { - if (_resCache.TryGetValue(key, out resLocation)) { + if (_defaultReader != null) + { + if (_resCache.TryGetValue(key, out resLocation)) + { found = true; - obj = ResolveResourceLocator(resLocation, key, _resCache, keyInWrongCase); + obj = ResolveResourceLocator(resLocation, key, _resCache, keyInWrongCase); } } - if (!found && ignoreCase) { - if (_caseInsensitiveTable.TryGetValue(key, out resLocation)) { + if (!found && ignoreCase) + { + if (_caseInsensitiveTable.TryGetValue(key, out resLocation)) + { found = true; keyInWrongCase = true; obj = ResolveResourceLocator(resLocation, key, _resCache, keyInWrongCase); } - } + } return obj; } // lock(Reader) } @@ -412,12 +437,15 @@ namespace System.Resources { // We need to explicitly resolve loosely linked manifest // resources, and we need to resolve ResourceLocators with null objects. Object value = resLocation.Value; - if (value == null) { + if (value == null) + { ResourceTypeCode typeCode; - lock(Reader) { + lock (Reader) + { value = _defaultReader.LoadObject(resLocation.DataPosition, out typeCode); } - if (!keyInWrongCase && ResourceLocator.CanCache(typeCode)) { + if (!keyInWrongCase && ResourceLocator.CanCache(typeCode)) + { resLocation.Value = value; copyOfCache[key] = resLocation; } diff --git a/src/mscorlib/src/System/Resources/SatelliteContractVersionAttribute.cs b/src/mscorlib/src/System/Resources/SatelliteContractVersionAttribute.cs deleted file mode 100644 index 86e972efdd..0000000000 --- a/src/mscorlib/src/System/Resources/SatelliteContractVersionAttribute.cs +++ /dev/null @@ -1,38 +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: Specifies which version of a satellite assembly -** the ResourceManager should ask for. -** -** -===========================================================*/ - -namespace System.Resources { - using System; - using System.Diagnostics.Contracts; - - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple=false)] - public sealed class SatelliteContractVersionAttribute : Attribute - { - private String _version; - - public SatelliteContractVersionAttribute(String version) - { - if (version == null) - throw new ArgumentNullException(nameof(version)); - Contract.EndContractBlock(); - _version = version; - } - - public String Version { - get { return _version; } - } - } -} diff --git a/src/mscorlib/src/System/Resources/UltimateResourceFallbackLocation.cs b/src/mscorlib/src/System/Resources/UltimateResourceFallbackLocation.cs deleted file mode 100644 index aa4069a366..0000000000 --- a/src/mscorlib/src/System/Resources/UltimateResourceFallbackLocation.cs +++ /dev/null @@ -1,28 +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: Tells the ResourceManager where to find the -** ultimate fallback resources for your assembly. -** -** -===========================================================*/ - -using System; - -namespace System.Resources { - -[Serializable] - public enum UltimateResourceFallbackLocation - { - MainAssembly, - Satellite - } -} diff --git a/src/mscorlib/src/System/Resources/__FastResourceComparer.cs b/src/mscorlib/src/System/Resources/__FastResourceComparer.cs index e0911fae1d..8bce02abc3 100644 --- a/src/mscorlib/src/System/Resources/__FastResourceComparer.cs +++ b/src/mscorlib/src/System/Resources/__FastResourceComparer.cs @@ -13,13 +13,15 @@ ** ** ===========================================================*/ -namespace System.Resources { - using System; - using System.Collections; - using System.Collections.Generic; - using System.Diagnostics; - using System.Diagnostics.Contracts; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.Contracts; + +namespace System.Resources +{ internal sealed class FastResourceComparer : IComparer, IEqualityComparer, IComparer<String>, IEqualityComparer<String> { internal static readonly FastResourceComparer Default = new FastResourceComparer(); @@ -27,7 +29,7 @@ namespace System.Resources { // Implements IHashCodeProvider too, due to Hashtable requirements. public int GetHashCode(Object key) { - String s = (String) key; + String s = (String)key; return FastResourceComparer.HashFunction(s); } @@ -45,9 +47,9 @@ namespace System.Resources { // others can read & write our .resources files. Additionally, we // have a copy of it in InternalResGen as well. uint hash = 5381; - for(int i=0; i<key.Length; i++) + for (int i = 0; i < key.Length; i++) hash = ((hash << 5) + hash) ^ key[i]; - return (int) hash; + return (int)hash; } // Compares Strings quickly in a case-sensitive way @@ -74,7 +76,7 @@ namespace System.Resources { if (a == b) return true; String sa = (String)a; String sb = (String)b; - return String.Equals(sa,sb); + return String.Equals(sa, sb); } // Input is one string to compare with, and a byte[] containing chars in @@ -93,10 +95,11 @@ namespace System.Resources { numChars = bCharLength; if (bCharLength == 0) // Can't use fixed on a 0-element array. return (a.Length == 0) ? 0 : -1; - fixed(byte* pb = bytes) { - - byte *pChar = pb; - while (i < numChars && r == 0) { + fixed (byte* pb = bytes) + { + byte* pChar = pb; + while (i < numChars && r == 0) + { // little endian format int b = pChar[0] | pChar[1] << 8; r = a[i++] - b; @@ -126,9 +129,10 @@ namespace System.Resources { int numChars = byteLen >> 1; if (numChars > b.Length) numChars = b.Length; - while(i < numChars && r == 0) { + while (i < numChars && r == 0) + { // Must compare character by character, not byte by byte. - char aCh = (char) (*a++ | (*a++ << 8)); + char aCh = (char)(*a++ | (*a++ << 8)); r = aCh - b[i++]; } if (r != 0) return r; diff --git a/src/mscorlib/src/System/Resources/__HResults.cs b/src/mscorlib/src/System/Resources/__HResults.cs index c1546edc63..5817161665 100644 --- a/src/mscorlib/src/System/Resources/__HResults.cs +++ b/src/mscorlib/src/System/Resources/__HResults.cs @@ -11,7 +11,8 @@ // //===========================================================================*/ #if FEATURE_APPX -namespace System.Resources { +namespace System.Resources +{ using System; // Only static data no need to serialize internal static class __HResults |