Merge pull request #1624 from esdrubal/getprocesstimes
[mono.git] / mcs / class / corlib / System / NumberFormatter.cs
index 8cda5e437f9a01cd5cbeb8df538d6b36b1c63830..b15fa539e1e767216e8c24e0ea698cad413bd4dc 100644 (file)
 // 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;
@@ -72,7 +66,6 @@ namespace System
                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;
@@ -96,9 +89,7 @@ namespace System
                                out DigitLowerTable, out DigitUpperTable, out TenPowersList, out DecHexDigits);
                }
 
-               unsafe
-#endif
-               static long GetTenPowerOf(int i)
+               unsafe static long GetTenPowerOf(int i)
                {
                        return TenPowersList [i];
                }
@@ -212,10 +203,7 @@ namespace System
 
                // 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];
@@ -440,10 +428,7 @@ namespace System
                        _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);
 
@@ -557,9 +542,7 @@ namespace System
 
                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)
@@ -777,29 +760,36 @@ namespace System
                [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();
@@ -808,7 +798,7 @@ namespace System
 
                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();
@@ -817,7 +807,7 @@ namespace System
 
                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();
@@ -826,7 +816,7 @@ namespace System
 
                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();
@@ -835,7 +825,7 @@ namespace System
 
                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();
@@ -844,7 +834,7 @@ namespace System
 
                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();
@@ -853,7 +843,7 @@ namespace System
 
                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();
@@ -862,7 +852,7 @@ namespace System
 
                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();
@@ -871,7 +861,7 @@ namespace System
 
                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;
@@ -892,7 +882,7 @@ namespace System
 
                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;
@@ -913,7 +903,7 @@ namespace System
 
                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();
@@ -925,7 +915,7 @@ namespace System
                        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;
@@ -936,7 +926,7 @@ namespace System
                        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;
@@ -947,7 +937,7 @@ namespace System
                        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;
@@ -958,7 +948,7 @@ namespace System
                        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;
@@ -966,7 +956,7 @@ namespace System
 
                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;
@@ -985,7 +975,7 @@ namespace System
 
                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;
@@ -1144,7 +1134,7 @@ namespace System
                                }
                        }
 
-                       AppendIntegerStringWithGroupSeparator (nfi.RawCurrencyGroupSizes, nfi.CurrencyGroupSeparator);
+                       AppendIntegerStringWithGroupSeparator (nfi.CurrencyGroupSizes, nfi.CurrencyGroupSeparator);
 
                        if (precision > 0) {
                                Append (nfi.CurrencyDecimalSeparator);
@@ -1231,17 +1221,11 @@ namespace System
                        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);
@@ -1359,7 +1343,7 @@ namespace System
                                }
                        }
 
-                       AppendIntegerStringWithGroupSeparator (nfi.RawNumberGroupSizes, nfi.NumberGroupSeparator);
+                       AppendIntegerStringWithGroupSeparator (nfi.NumberGroupSizes, nfi.NumberGroupSeparator);
 
                        if (precision > 0) {
                                Append (nfi.NumberDecimalSeparator);
@@ -1410,7 +1394,7 @@ namespace System
                                }
                        }
 
-                       AppendIntegerStringWithGroupSeparator (nfi.RawPercentGroupSizes, nfi.PercentGroupSeparator);
+                       AppendIntegerStringWithGroupSeparator (nfi.PercentGroupSizes, nfi.PercentGroupSeparator);
 
                        if (precision > 0) {
                                Append (nfi.PercentDecimalSeparator);
@@ -1764,10 +1748,7 @@ namespace System
                        _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;
@@ -1956,19 +1937,19 @@ namespace System
                                int[] lens = new int [3];
                                int index = 0;
                                int lastPos = 0;
-                               char literal = '\0';
+                               bool quoted = false;
+
                                for (int i = 0; i < format.Length; i++) {
                                        char c = format [i];
 
-                                       if (c == literal || (literal == '\0' && (c == '\"' || c == '\''))) {
-                                               if (literal == '\0')
-                                                       literal = c;
-                                               else
-                                                       literal = '\0';
+                                       if (c == '\"' || c == '\'') {
+                                               if (i == 0 || format [i - 1] != '\\')
+                                                       quoted = !quoted;
+
                                                continue;
                                        }
 
-                                       if (literal == '\0' && format [i] == ';' && (i == 0 || format [i - 1] != '\\')) {
+                                       if (c == ';' && !quoted && (i == 0 || format [i - 1] != '\\')) {
                                                lens [index++] = i - lastPos;
                                                lastPos = i + 1;
                                                if (index == 3)
@@ -2187,7 +2168,7 @@ namespace System
                                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) {