using System; using NBitcoin; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Linq; using System.Text; using System.Globalization; namespace BTCPayServer.Services.Rates { public class CurrencyData { public string Name { get; internal set; } public string Code { get; internal set; } public int Divisibility { get; internal set; } public string Symbol { get; internal set; } } public class CurrencyNameTable { public CurrencyNameTable() { _Currencies = LoadCurrency().ToDictionary(k => k.Code); } static Dictionary _CurrencyProviders = new Dictionary(); public IFormatProvider GetCurrencyProvider(string currency) { lock (_CurrencyProviders) { if (_CurrencyProviders.Count == 0) { foreach (var culture in CultureInfo.GetCultures(CultureTypes.AllCultures).Where(c => !c.IsNeutralCulture)) { try { _CurrencyProviders.TryAdd(new RegionInfo(culture.LCID).ISOCurrencySymbol, culture); } catch { } } AddCurrency(_CurrencyProviders, "BTC", 8, "BTC"); } return _CurrencyProviders.TryGet(currency); } } private void AddCurrency(Dictionary currencyProviders, string code, int divisibility, string symbol) { var culture = new CultureInfo("en-US"); var number = new NumberFormatInfo(); number.CurrencyDecimalDigits = divisibility; number.CurrencySymbol = symbol; number.CurrencyDecimalSeparator = culture.NumberFormat.CurrencyDecimalSeparator; number.CurrencyGroupSeparator = culture.NumberFormat.CurrencyGroupSeparator; number.CurrencyGroupSizes = culture.NumberFormat.CurrencyGroupSizes; number.CurrencyNegativePattern = 8; number.CurrencyPositivePattern = 3; number.NegativeSign = culture.NumberFormat.NegativeSign; currencyProviders.TryAdd(code, number); } Dictionary _Currencies; static CurrencyData[] LoadCurrency() { var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("BTCPayServer.Currencies.txt"); string content = null; using (var reader = new StreamReader(stream, Encoding.UTF8)) { content = reader.ReadToEnd(); } var currencies = content.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); Dictionary dico = new Dictionary(); foreach (var currency in currencies) { var splitted = currency.Split(new[] { '\t' }, StringSplitOptions.RemoveEmptyEntries); if (splitted.Length < 3) continue; CurrencyData info = new CurrencyData(); info.Name = splitted[0]; info.Code = splitted[1]; int divisibility; if (!int.TryParse(splitted[2], out divisibility)) continue; info.Divisibility = divisibility; if (!dico.ContainsKey(info.Code)) dico.Add(info.Code, info); if (splitted.Length >= 4) { info.Symbol = splitted[3]; } } return dico.Values.ToArray(); } public CurrencyData GetCurrencyData(string currency) { CurrencyData result; _Currencies.TryGetValue(currency.ToUpperInvariant(), out result); return result; } } }