// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-// NumberFormatter is shared with Grasshopper and hence the #if TARGET_JVM for
-// marking the use of unsafe code that is not supported in Grasshopper.
-#if !TARGET_JVM
-#define UNSAFE_TABLES
-#endif
-
using System.Globalization;
using System.Text;
using System.Threading;
const double MinRoundtripVal = -1.79769313486231E+308;
const double MaxRoundtripVal = 1.79769313486231E+308;
-#if UNSAFE_TABLES
// The below arrays are taken from mono/metatdata/number-formatter.h
private static readonly unsafe ulong* MantissaBitsTable;
out DigitLowerTable, out DigitUpperTable, out TenPowersList, out DecHexDigits);
}
- unsafe
-#endif
- static long GetTenPowerOf(int i)
+ unsafe static long GetTenPowerOf(int i)
{
return TenPowersList [i];
}
// Helper to translate an int in the range 0 .. 9999 to its
// Hexadecimal digits representation.
-#if UNSAFE_TABLES
- unsafe
-#endif
- private static uint FastToDecHex (int val)
+ unsafe private static uint FastToDecHex (int val)
{
if (val < 100)
return (uint)DecHexDigits [val];
_decPointPos = _digitsLen = DecHexLen ();
}
-#if UNSAFE_TABLES // No unsafe code under TARGET_JVM
- unsafe
-#endif
- private void Init (string format, double value, int defPrecision)
+ unsafe private void Init (string format, double value, int defPrecision)
{
Init (format);
private void Resize (int len)
{
- char[] newBuf = new char [len];
- Array.Copy (_cbuf, newBuf, _ind);
- _cbuf = newBuf;
+ Array.Resize (ref _cbuf, len);
}
private void Append (char c)
[ThreadStatic]
static NumberFormatter threadNumberFormatter;
- private static NumberFormatter GetInstance()
+ [ThreadStatic]
+ static NumberFormatter userFormatProvider;
+
+ private static NumberFormatter GetInstance (IFormatProvider fp)
{
+ if (fp != null) {
+ if (userFormatProvider == null) {
+ Interlocked.CompareExchange (ref userFormatProvider, new NumberFormatter (null), null);
+ }
+
+ return userFormatProvider;
+ }
+
NumberFormatter res = threadNumberFormatter;
threadNumberFormatter = null;
if (res == null)
return new NumberFormatter (Thread.CurrentThread);
+ res.CurrentCulture = Thread.CurrentThread.CurrentCulture;
return res;
}
private void Release()
{
- threadNumberFormatter = this;
- }
-
- internal static void SetThreadCurrentCulture (CultureInfo culture)
- {
- if (threadNumberFormatter != null)
- threadNumberFormatter.CurrentCulture = culture;
+ if (this != userFormatProvider)
+ threadNumberFormatter = this;
}
public static string NumberToString (string format, sbyte value, IFormatProvider fp)
{
- NumberFormatter inst = GetInstance();
+ NumberFormatter inst = GetInstance (fp);
inst.Init (format, value, Int8DefPrecision);
string res = inst.IntegerToString (format, fp);
inst.Release();
public static string NumberToString (string format, byte value, IFormatProvider fp)
{
- NumberFormatter inst = GetInstance();
+ NumberFormatter inst = GetInstance (fp);
inst.Init (format, value, UInt8DefPrecision);
string res = inst.IntegerToString (format, fp);
inst.Release();
public static string NumberToString (string format, ushort value, IFormatProvider fp)
{
- NumberFormatter inst = GetInstance();
+ NumberFormatter inst = GetInstance (fp);
inst.Init (format, value, Int16DefPrecision);
string res = inst.IntegerToString (format, fp);
inst.Release();
public static string NumberToString (string format, short value, IFormatProvider fp)
{
- NumberFormatter inst = GetInstance();
+ NumberFormatter inst = GetInstance (fp);
inst.Init (format, value, UInt16DefPrecision);
string res = inst.IntegerToString (format, fp);
inst.Release();
public static string NumberToString (string format, uint value, IFormatProvider fp)
{
- NumberFormatter inst = GetInstance();
+ NumberFormatter inst = GetInstance (fp);
inst.Init (format, value, Int32DefPrecision);
string res = inst.IntegerToString (format, fp);
inst.Release();
public static string NumberToString (string format, int value, IFormatProvider fp)
{
- NumberFormatter inst = GetInstance();
+ NumberFormatter inst = GetInstance (fp);
inst.Init (format, value, UInt32DefPrecision);
string res = inst.IntegerToString (format, fp);
inst.Release();
public static string NumberToString (string format, ulong value, IFormatProvider fp)
{
- NumberFormatter inst = GetInstance();
+ NumberFormatter inst = GetInstance (fp);
inst.Init (format, value);
string res = inst.IntegerToString (format, fp);
inst.Release();
public static string NumberToString (string format, long value, IFormatProvider fp)
{
- NumberFormatter inst = GetInstance();
+ NumberFormatter inst = GetInstance (fp);
inst.Init (format, value);
string res = inst.IntegerToString (format, fp);
inst.Release();
public static string NumberToString (string format, float value, IFormatProvider fp)
{
- NumberFormatter inst = GetInstance();
+ NumberFormatter inst = GetInstance (fp);
inst.Init (format, value, SingleDefPrecision);
NumberFormatInfo nfi = inst.GetNumberFormatInstance (fp);
string res;
public static string NumberToString (string format, double value, IFormatProvider fp)
{
- NumberFormatter inst = GetInstance();
+ NumberFormatter inst = GetInstance (fp);
inst.Init (format, value, DoubleDefPrecision);
NumberFormatInfo nfi = inst.GetNumberFormatInstance (fp);
string res;
public static string NumberToString (string format, decimal value, IFormatProvider fp)
{
- NumberFormatter inst = GetInstance();
+ NumberFormatter inst = GetInstance (fp);
inst.Init (format, value);
string res = inst.NumberToString (format, inst.GetNumberFormatInstance (fp));
inst.Release();
if (value >= HundredMillion)
return NumberToString (null, value, fp);
- NumberFormatter inst = GetInstance();
+ NumberFormatter inst = GetInstance (fp);
string res = inst.FastIntegerToString ((int)value, fp);
inst.Release();
return res;
if (value >= HundredMillion || value <= -HundredMillion)
return NumberToString (null, value, fp);
- NumberFormatter inst = GetInstance();
+ NumberFormatter inst = GetInstance (fp);
string res = inst.FastIntegerToString (value, fp);
inst.Release();
return res;
if (value >= HundredMillion)
return NumberToString (null, value, fp);
- NumberFormatter inst = GetInstance();
+ NumberFormatter inst = GetInstance (fp);
string res = inst.FastIntegerToString ((int)value, fp);
inst.Release();
return res;
if (value >= HundredMillion || value <= -HundredMillion)
return NumberToString (null, value, fp);
- NumberFormatter inst = GetInstance();
+ NumberFormatter inst = GetInstance (fp);
string res = inst.FastIntegerToString ((int)value, fp);
inst.Release();
return res;
public static string NumberToString (float value, IFormatProvider fp)
{
- NumberFormatter inst = GetInstance();
+ NumberFormatter inst = GetInstance (fp);
inst.Init (null, value, SingleDefPrecision);
NumberFormatInfo nfi = inst.GetNumberFormatInstance (fp);
string res;
public static string NumberToString (double value, IFormatProvider fp)
{
- NumberFormatter inst = GetInstance();
+ NumberFormatter inst = GetInstance (fp);
NumberFormatInfo nfi = inst.GetNumberFormatInstance (fp);
inst.Init (null, value, DoubleDefPrecision);
string res;
}
}
- AppendIntegerStringWithGroupSeparator (nfi.RawCurrencyGroupSizes, nfi.CurrencyGroupSeparator);
+ AppendIntegerStringWithGroupSeparator (nfi.CurrencyGroupSizes, nfi.CurrencyGroupSeparator);
if (precision > 0) {
Append (nfi.CurrencyDecimalSeparator);
return new string (_cbuf, 0, _ind);
}
-#if UNSAFE_TABLES // No unsafe code under TARGET_JVM
- unsafe
-#endif
- private string FormatHexadecimal (int precision)
+ unsafe private string FormatHexadecimal (int precision)
{
int size = Math.Max (precision, _decPointPos);
-#if UNSAFE_TABLES
char* digits = _specifierIsUpper ? DigitUpperTable : DigitLowerTable;
-#else
- char[] digits = _specifierIsUpper ? DigitUpperTable : DigitLowerTable;
-#endif
+
ResetCharBuf (size);
_ind = size;
ulong val = _val1 | ((ulong)_val2 << 32);
}
}
- AppendIntegerStringWithGroupSeparator (nfi.RawNumberGroupSizes, nfi.NumberGroupSeparator);
+ AppendIntegerStringWithGroupSeparator (nfi.NumberGroupSizes, nfi.NumberGroupSeparator);
if (precision > 0) {
Append (nfi.NumberDecimalSeparator);
}
}
- AppendIntegerStringWithGroupSeparator (nfi.RawPercentGroupSizes, nfi.PercentGroupSeparator);
+ AppendIntegerStringWithGroupSeparator (nfi.PercentGroupSizes, nfi.PercentGroupSeparator);
if (precision > 0) {
Append (nfi.PercentDecimalSeparator);
_cbuf [_ind++] = (char)('0' | v & 0xf);
}
-#if UNSAFE_TABLES // No unsafe code under TARGET_JVM
- unsafe
-#endif
- private void FastAppendDigits (int val, bool force)
+ unsafe private void FastAppendDigits (int val, bool force)
{
int i = _ind;
int digits;
int sb_int_index = 0;
int sb_dec_index = 0;
- int[] groups = nfi.RawNumberGroupSizes;
+ int[] groups = nfi.NumberGroupSizes;
string groupSeparator = nfi.NumberGroupSeparator;
int intLen = 0, total = 0, groupIndex = 0, counter = 0, groupSize = 0;
if (UseGroup && groups.Length > 0) {