using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Reflection; using Developpez.Dotnet.Language; using Developpez.Dotnet.Language.Grammar; using Developpez.Dotnet.Properties; #if !NETFX_CORE using Developpez.Dotnet.Reflection; #endif using CH = Developpez.Dotnet.CompatibilityHelper; namespace Developpez.Dotnet { /// /// Fournit des méthodes de conversion d'un nombre en toutes lettres. /// public static class NumberConverter { #region Private data private static readonly object _spellerLock = new object(); private static readonly IDictionary _spellers; private static readonly IDictionary _bestSpellers; #endregion #region Constructor static NumberConverter() { _spellers = new Dictionary(CH.StringComparer.InvariantCultureIgnoreCase); _bestSpellers = new Dictionary(CH.StringComparer.InvariantCulture); #if NETFX_CORE LoadSpellers(typeof (NumberConverter).GetTypeInfo().Assembly); #else LoadSpellers(typeof (NumberConverter).Assembly); #endif } #endregion #region Private methods private static INumberSpeller GetSpeller() { return GetSpeller(CultureInfo.CurrentCulture); } /// /// Renvoie un convertisseur de nombre en toutes lettres pour la culture spécifiée /// /// Culture pour laquelle obtenir un convertisseur /// Un convertisseur de nombre en toutes lettres pour la culture spécifiée public static INumberSpeller GetSpeller(CultureInfo culture) { culture.CheckArgumentNull("culture"); INumberSpeller bestAvailable; lock (_spellerLock) { if (!_bestSpellers.TryGetValue(culture.Name, out bestAvailable)) { bestAvailable = FindBestAvailableSpeller(culture); _bestSpellers[culture.Name] = bestAvailable; } } return bestAvailable; } /// /// Renvoie un convertisseur de nombre en toutes lettres pour la culture spécifiée /// /// Culture pour laquelle obtenir un convertisseur /// Un convertisseur de nombre en toutes lettres pour la culture spécifiée public static INumberSpeller GetSpeller(string culture) { #if SILVERLIGHT || NETFX_CORE var c = new CultureInfo(culture); #else var c = CultureInfo.GetCultureInfo(culture); #endif return GetSpeller(c); } private static INumberSpeller FindBestAvailableSpeller(CultureInfo culture) { var candidates = SpellerHelper.GetCultureAndParents(culture).Join( _spellers, c => c.Name, kvp => kvp.Key, (c, kvp) => kvp.Value, CH.StringComparer.InvariantCultureIgnoreCase); INumberSpeller bestAvailable = candidates.FirstOrDefault(); if (bestAvailable == null) throw new NotSupportedException(string.Format(ExceptionMessages.NumberConverter_NoSpellerAvailable, culture.Name)); return bestAvailable; } #endregion #region Public methods /// /// Recherche tous les convertisseurs de nombre en lettres /// dans l'assembly spécifié. Utilisez cette méthode pour /// détecter un convertisseur personnalisé. /// /// L'assembly dans lequel les convertisseurs sont définis /// /// Les convertisseurs prédéfinis sont chargés automatiquement, /// il n'est donc pas nécessaire d'appeler LoadSpellers pour /// les utiliser. /// public static void LoadSpellers(Assembly assembly) { var spellers = #if NETFX_CORE from a in assembly.GetCustomAttributes() #else from a in assembly.GetAttributes() #endif group a.Culture by a.Implementation into g let speller = (INumberSpeller)Activator.CreateInstance(g.Key) from culture in g select new { Culture = culture, Speller = speller }; lock (_spellerLock) { foreach (var s in spellers) { _spellers[s.Culture] = s.Speller; } // Clear best choice cache in case a better speller is // now available for a language _bestSpellers.Clear(); } } /// /// Convertit un nombre entier en toutes lettres. /// /// Nombre entier. /// Le nombre en toutes lettres. public static string Spell(long value) { return Spell(value, Gender.Masculine); } /// /// Convertit un nombre entier en toutes lettres. /// /// Nombre entier. /// Genre du nombre entier. /// Le nombre en toutes lettres. public static string Spell(long value, Gender gender) { return Spell(value, gender, NumeralAdjective.Cardinal); } /// /// Convertit un nombre entier en toutes lettres. /// /// Nombre entier. /// Genre du nombre entier. /// Nature de l'adjectif numéral. /// Le nombre en toutes lettres. public static string Spell(long value, Gender gender, NumeralAdjective numeralAdjective) { return GetSpeller().Spell(value, gender, numeralAdjective); } /// /// Convertit un nombre entier en toutes lettres. /// /// Nombre entier. /// Le nombre en toutes lettres. public static string Spell(ulong value) { return Spell(value, Gender.Masculine); } /// /// Convertit un nombre entier en toutes lettres. /// /// Nombre entier. /// Genre du nombre entier. /// Le nombre en toutes lettres. public static string Spell(ulong value, Gender gender) { return Spell(value, gender, NumeralAdjective.Cardinal); } /// /// Convertit un nombre entier en toutes lettres. /// /// Nombre entier. /// Genre du nombre entier. /// Nature de l'adjectif numéral. /// Le nombre en toutes lettres. public static string Spell(ulong value, Gender gender, NumeralAdjective numeralAdjective) { return GetSpeller().Spell(value, gender, numeralAdjective); } /// /// Convertit un nombre en virgule flottante en toutes lettres, avec le nombre de chiffres spécifié après la virgule. /// /// Nombre en virgule flottante /// Nombre de chiffres après la virgule /// Le nombre en toutes lettres public static string Spell(double value, int decimalPlaces) { return GetSpeller().Spell(value, decimalPlaces); } /// /// Convertit un nombre décimal en toutes lettres, avec le nombre de chiffres spécifié après la virgule. /// /// Nombre décimal /// Nombre de chiffres après la virgule /// Le nombre en toutes lettres public static string Spell(decimal value, int decimalPlaces) { return GetSpeller().Spell(value, decimalPlaces); } /// /// Convertit un montant en toutes lettres, avec la devise spécifiée. /// /// Montant en virgule flottante /// Devise utilisée /// Le montant en toutes lettres public static string SpellAmount(double value, CurrencyDescriptor currency) { return GetSpeller().SpellAmount(value, currency); } /// /// Convertit un montant en toutes lettres, avec la devise spécifiée. /// /// Montant décimal /// Devise utilisée /// Le montant en toutes lettres public static string SpellAmount(decimal value, CurrencyDescriptor currency) { return GetSpeller().SpellAmount(value, currency); } #endregion } }