New test.
[mono.git] / mcs / class / corlib / System / Char.cs
index e0eab178fd90fb0f99a6bb2b663ded7755e065ee..fc5e0de8e412cb89e8a4dc94bc089a1a8a179cc7 100644 (file)
@@ -7,7 +7,26 @@
 //   Jackson Harper (jackson@ximian.com)
 //
 // (C) Ximian, Inc.  http://www.ximian.com
-// (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
 // Note about the ToString()'s. ECMA says there's only a ToString() method, 
 // which appears to just be a Convert.ToString(char c) type method. ECMA also
 // doesn't list this class as implementing IFormattable.
 
-using System; 
 using System.Globalization;
 using System.Runtime.CompilerServices;
+#if NET_2_0
+using System.Runtime.InteropServices;
+#endif
 
 namespace System
 {
        [Serializable]
+#if NET_2_0
+       [ComVisible (true)]
+       public struct Char : IComparable, IConvertible, IComparable <char>, IEquatable <char>
+#else
        public struct Char : IComparable, IConvertible
+#endif
        {
                public const char MaxValue = (char) 0xffff;
                public const char MinValue = (char) 0;
@@ -76,9 +102,81 @@ namespace System
                        if (!(o is Char))
                                return false;
 
-                       return ((Char) o).m_value == m_value;
+                       return ((char) o) == m_value;
                }
 
+#if NET_2_0
+               public int CompareTo (char value)
+               {
+                       if (m_value == value)
+                               return 0;
+
+                       if (m_value > value)
+                               return 1;
+                       else
+                               return -1;
+               }
+
+               public static string ConvertFromUtf32 (int utf32)
+               {
+                       if (utf32 < 0 || utf32 > 0x10FFFF)
+                               throw new ArgumentOutOfRangeException ("utf32", "The argument must be from 0 to 0x10FFFF.");
+                       if (0xD800 <= utf32 && utf32 <= 0xDFFF)
+                               throw new ArgumentOutOfRangeException ("utf32", "The argument must not be in surrogate pair range.");
+                       if (utf32 < 0x10000)
+                               return new string ((char) utf32, 1);
+                       utf32 -= 0x10000;
+                       return new string (
+                               new char [] {(char) ((utf32 >> 10) + 0xD800),
+                               (char) (utf32 % 0x0400 + 0xDC00)});
+               }
+
+               public static int ConvertToUtf32 (char highSurrogate, char lowSurrogate)
+               {
+                       if (highSurrogate < 0xD800 || 0xDBFF < highSurrogate)
+                               throw new ArgumentOutOfRangeException ("highSurrogate");
+                       if (lowSurrogate < 0xDC00 || 0xDFFF < lowSurrogate)
+                               throw new ArgumentOutOfRangeException ("lowSurrogate");
+
+                       return 0x10000 + ((highSurrogate - 0xD800) << 10) + (lowSurrogate - 0xDC00);
+               }
+
+               public static int ConvertToUtf32 (string s, int index)
+               {
+                       if (s == null)
+                               throw new ArgumentNullException ("s");
+                       if (index < 0 || index >= s.Length)
+                               throw new ArgumentOutOfRangeException ("index");
+                       if (!Char.IsSurrogate (s [index]))
+                               return s [index];
+                       if (!Char.IsHighSurrogate (s [index])
+                           || index == s.Length - 1
+                           || !Char.IsLowSurrogate (s [index + 1]))
+                               throw new ArgumentException (String.Format ("The string contains invalid surrogate pair character at {0}", index));
+                       return ConvertToUtf32 (s [index], s [index + 1]);
+               }
+
+               public bool Equals (char value)
+               {
+                       return m_value == value;
+               }
+
+               public static bool IsSurrogatePair (char high, char low)
+               {
+                       return '\uD800' <= high && high <= '\uDBFF'
+                               && '\uDC00' <= low && low <= '\uDFFF';
+               }
+
+               public static bool IsSurrogatePair (string s, int index)
+               {
+                       if (s == null)
+                               throw new ArgumentNullException ("s");
+                       if (index < 0 || index >= s.Length)
+                               throw new ArgumentOutOfRangeException ("index");
+                       return index + 1 < s.Length && IsSurrogatePair (s [index], s [index + 1]);
+               }
+#endif
+
                public override int GetHashCode ()
                {
                        return m_value;
@@ -170,6 +268,24 @@ namespace System
                        return IsDigit (str[index]);
                }
 
+#if NET_2_0
+               public static bool IsHighSurrogate (char c)
+               {
+                       return c >= '\uD800' && c <= '\uDBFF';
+               }
+
+               public static bool IsHighSurrogate (string s, int index)
+               {
+                       if (s == null) 
+                               throw new ArgumentNullException ("s");
+                       
+                       if (index < 0 || index >= s.Length)
+                               throw new ArgumentOutOfRangeException ("index");
+                       
+                       return IsHighSurrogate (s [index]);
+               }
+#endif
+
                public static bool IsLetter (char c)
                {
                        unsafe {
@@ -248,6 +364,24 @@ namespace System
                        return IsLower (str[index]);
                }
 
+#if NET_2_0
+               public static bool IsLowSurrogate (char c)
+               {
+                       return c >= '\uDC00' && c <= '\uDFFF';
+               }
+
+               public static bool IsLowSurrogate (string s, int index)
+               {
+                       if (s == null) 
+                               throw new ArgumentNullException ("s");
+                       
+                       if (index < 0 || index >= s.Length)
+                               throw new ArgumentOutOfRangeException ("index");
+                       
+                       return IsLowSurrogate (s [index]);
+               }
+#endif
+
                public static bool IsNumber (char c)
                {
                        unsafe {
@@ -413,7 +547,10 @@ namespace System
                                case (char)0x0d:
                                case (char)0x85: // NEL 
                                case (char)0x2028: // Line Separator
-                               case (char)0x2029: // Paragraph Separator       
+                               case (char)0x2029: // Paragraph Separator
+#if NET_2_0
+                               case (char)0x205F: // Medium Mathematical Space
+#endif
                                        return true;
                                default:
                                        return false;
@@ -433,6 +570,19 @@ namespace System
                        return IsWhiteSpace (str[index]);
                }
 
+#if NET_2_0
+               public static bool TryParse (string s, out char result)
+               {
+                       if (s == null || s.Length != 1) {
+                               result = (char) 0;
+                               return false;
+                       }
+
+                       result = s [0];
+                       return true;
+               }
+#endif
+
                public static char Parse (string str)
                {
                        if (str == null) 
@@ -444,21 +594,22 @@ namespace System
                        return str [0];
                }
 
-               [MonoTODO ("Fix FIXME")]
                public static char ToLower (char c)
                {
-                       // FIXME: needs to call line below, but that would probably break a lot of things right now
-                       // return InternalToLower (c, CultureInfo.CurrentCulture);
-                       return ToLowerInvariant (c);
+                       return ToLower (c, CultureInfo.CurrentCulture);
                }
 
+#if NET_2_0
+               public static char ToLowerInvariant (char c)
+#else
                internal static char ToLowerInvariant (char c)
+#endif
                {
                        unsafe {
                                if (c <= ((char)0x24cf))
                                        return (char) to_lower_data_low [c];
-                               if (c >= ((char)0xff41))
-                                       return (char) to_lower_data_high[c - 0xff41];
+                               if (c >= ((char)0xff21))
+                                       return (char) to_lower_data_high[c - 0xff21];
                        }
                        return c;
                }
@@ -470,24 +621,22 @@ namespace System
                        if (culture.LCID == 0x007F) // Invariant
                                return ToLowerInvariant (c);
 
-                       return InternalToLower (c, culture);
+                       return culture.TextInfo.ToLower (c);
                }
 
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               private static extern char InternalToLower (char c, CultureInfo culture);
-
-               [MonoTODO ("Fix FIXME")]
                public static char ToUpper (char c)
                {
-                       // FIXME: needs to call line below, but that would probably break a lot of things right now
-                       // return InternalToUpper (c, CultureInfo.CurrentCulture);
-                       return ToUpperInvariant (c);
+                       return ToUpper (c, CultureInfo.CurrentCulture);
                }
 
+#if NET_2_0
+               public static char ToUpperInvariant (char c)
+#else
                internal static char ToUpperInvariant (char c)
+#endif
                {
                        unsafe {
-                               if (c <= ((char)0x24cf))
+                               if (c <= ((char)0x24e9))
                                        return (char) to_upper_data_low [c];
                                if (c >= ((char)0xff21))
                                        return (char) to_upper_data_high [c - 0xff21];
@@ -502,11 +651,8 @@ namespace System
                        if (culture.LCID == 0x007F) // Invariant
                                return ToUpperInvariant (c);
 
-                       return InternalToUpper (c, culture);
+                       return culture.TextInfo.ToUpper (c);
                }
-
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               private static extern char InternalToUpper (char c, CultureInfo culture);
                
                public override string ToString ()
                {
@@ -593,11 +739,6 @@ namespace System
                        throw new InvalidCastException();
                }
                
-               string IConvertible.ToString (IFormatProvider provider)
-               {
-                       return ToString(provider);
-               }
-
                ushort IConvertible.ToUInt16 (IFormatProvider provider)
                {
                        return System.Convert.ToUInt16(m_value);