// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Globalization;
using System.Linq;
using System.Resources;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis
{
///
/// A localizable resource string that may possibly be formatted differently depending on culture.
///
public sealed class LocalizableResourceString : LocalizableString, IObjectWritable
{
private readonly string _nameOfLocalizableResource;
private readonly ResourceManager _resourceManager;
private readonly Type _resourceSource;
private readonly string[] _formatArguments;
static LocalizableResourceString()
{
ObjectBinder.RegisterTypeReader(typeof(LocalizableResourceString), reader => new LocalizableResourceString(reader));
}
///
/// Creates a localizable resource string with no formatting arguments.
///
/// nameof the resource that needs to be localized.
/// for the calling assembly.
/// Type handling assembly's resource management. Typically, this is the static class generated for the resources file from which resources are accessed.
public LocalizableResourceString(string nameOfLocalizableResource, ResourceManager resourceManager, Type resourceSource)
: this(nameOfLocalizableResource, resourceManager, resourceSource, Array.Empty())
{
}
///
/// Creates a localizable resource string that may possibly be formatted differently depending on culture.
///
/// nameof the resource that needs to be localized.
/// for the calling assembly.
/// Type handling assembly's resource management. Typically, this is the static class generated for the resources file from which resources are accessed.
/// Optional arguments for formatting the localizable resource string.
public LocalizableResourceString(string nameOfLocalizableResource, ResourceManager resourceManager, Type resourceSource, params string[] formatArguments)
{
if (nameOfLocalizableResource == null)
{
throw new ArgumentNullException(nameof(nameOfLocalizableResource));
}
if (resourceManager == null)
{
throw new ArgumentNullException(nameof(resourceManager));
}
if (resourceSource == null)
{
throw new ArgumentNullException(nameof(resourceSource));
}
if (formatArguments == null)
{
throw new ArgumentNullException(nameof(formatArguments));
}
_resourceManager = resourceManager;
_nameOfLocalizableResource = nameOfLocalizableResource;
_resourceSource = resourceSource;
_formatArguments = formatArguments;
}
private LocalizableResourceString(ObjectReader reader)
{
_resourceSource = reader.ReadType();
_nameOfLocalizableResource = reader.ReadString();
_resourceManager = new ResourceManager(_resourceSource);
var length = reader.ReadInt32();
if (length == 0)
{
_formatArguments = Array.Empty();
}
else
{
var argumentsBuilder = ArrayBuilder.GetInstance(length);
for (int i = 0; i < length; i++)
{
argumentsBuilder.Add(reader.ReadString());
}
_formatArguments = argumentsBuilder.ToArrayAndFree();
}
}
bool IObjectWritable.ShouldReuseInSerialization => false;
void IObjectWritable.WriteTo(ObjectWriter writer)
{
writer.WriteType(_resourceSource);
writer.WriteString(_nameOfLocalizableResource);
var length = _formatArguments.Length;
writer.WriteInt32(length);
for (int i = 0; i < length; i++)
{
writer.WriteString(_formatArguments[i]);
}
}
protected override string GetText(IFormatProvider formatProvider)
{
var culture = formatProvider as CultureInfo ?? CultureInfo.CurrentUICulture;
var resourceString = _resourceManager.GetString(_nameOfLocalizableResource, culture);
return resourceString != null ?
(_formatArguments.Length > 0 ? string.Format(resourceString, _formatArguments) : resourceString) :
string.Empty;
}
protected override bool AreEqual(object other)
{
var otherResourceString = other as LocalizableResourceString;
return otherResourceString != null &&
_nameOfLocalizableResource == otherResourceString._nameOfLocalizableResource &&
_resourceManager == otherResourceString._resourceManager &&
_resourceSource == otherResourceString._resourceSource &&
_formatArguments.SequenceEqual(otherResourceString._formatArguments, (a, b) => a == b);
}
protected override int GetHash()
{
return Hash.Combine(_nameOfLocalizableResource.GetHashCode(),
Hash.Combine(_resourceManager.GetHashCode(),
Hash.Combine(_resourceSource.GetHashCode(),
Hash.CombineValues(_formatArguments))));
}
}
}