implementing XmlElement.SetAttributeNode(localName, namespaceURI) and
[mono.git] / mcs / class / System.XML / System.Xml / XmlConvert.cs
index 5c3e278b9b4c4913a6681a98cfbc88063c69227e..cc078e21fdc1a80aaee92fb296998a6ad581fc19 100755 (executable)
-// Author: Dwivedi, Ajay kumar\r
-//            Adwiv@Yahoo.com\r
-// XmlConvert.cs: Xml data type conversion\r
-// \r
+//\r
+// System.Xml.XmlConvert\r
+//\r
+// Authors:\r
+//      Dwivedi, Ajay kumar (Adwiv@Yahoo.com)\r
+//     Gonzalo Paniagua Javier (gonzalo@ximian.com)\r
+//\r
+// (C) 2002 Ximian, Inc (http://www.ximian.com)\r
+//\r
 using System;\r
+using System.Text;\r
 using System.Globalization;\r
 \r
 namespace System.Xml {\r
 \r
        public class XmlConvert {\r
 \r
+               static string encodedColon = "_x003A_";\r
+\r
                public XmlConvert()\r
                {}\r
 \r
-               // Methods\r
-               [MonoTODO]\r
-               public static string DecodeName(string name)\r
+               private static string TryDecoding (string s)\r
+               {\r
+                       if (s == null || s.Length < 6)\r
+                               return s;\r
+\r
+                       char c = '\uFFFF';\r
+                       try {\r
+                               c = (char) Int32.Parse (s.Substring (1, 4), NumberStyles.HexNumber);\r
+                       } catch {\r
+                               return s [0] + DecodeName (s.Substring (1));\r
+                       }\r
+                       \r
+                       if (s.Length == 6)\r
+                               return c.ToString ();\r
+                       return c + DecodeName (s.Substring (6));\r
+               }\r
+               \r
+               public static string DecodeName (string name)\r
+               {\r
+                       if (name == null || name.Length == 0)\r
+                               return name;\r
+\r
+                       int pos = name.IndexOf ('_');\r
+                       if (pos == -1 || pos + 6 >= name.Length)\r
+                               return name;\r
+\r
+                       if (Char.ToUpper (name [pos + 1]) != 'X' || name [pos + 6] != '_')\r
+                               return name [0] + DecodeName (name.Substring (1));\r
+\r
+                       return name.Substring (0, pos) + TryDecoding (name.Substring (pos + 1));\r
+               }\r
+\r
+               public static string EncodeLocalName (string name)\r
                {\r
-                       return null;\r
+                       string encoded = EncodeName (name);\r
+                       int pos = encoded.IndexOf (':');\r
+                       if (pos == -1)\r
+                               return encoded;\r
+                       return encoded.Replace (":", encodedColon);\r
                }\r
-               [MonoTODO]\r
-               public static string EncodeLocalName(string name)\r
+\r
+               private static bool IsInvalid (char c, bool firstOnlyLetter)\r
                {\r
-                       return null;\r
+                       if (c == ':') // Special case. allowed in EncodeName, but encoded in EncodeLocalName\r
+                               return false;\r
+                       \r
+                       if (firstOnlyLetter && !Char.IsLetter (c) && c != '_')\r
+                               return false;\r
+                       \r
+                       return !Char.IsLetterOrDigit (c);\r
+               }\r
+\r
+               private static string EncodeName (string name, bool nmtoken)\r
+               {\r
+                       StringBuilder sb = new StringBuilder ();\r
+                       int length = name.Length;\r
+                       for (int i = 0; i < length; i++) {\r
+                               char c = name [i];\r
+                               if (c != '_' || i + 6 >= length) {\r
+                                       bool firstOnlyLetter = (i == 0 && !nmtoken);\r
+                                       if (IsInvalid (c, firstOnlyLetter)) {\r
+                                               sb.AppendFormat ("_x{0:X4}_", (int) c);\r
+                                               continue;\r
+                                       }\r
+                               } else { \r
+                                       if (Char.ToUpper (name [i + 1]) == 'X' && name [i + 6] == '_') {\r
+                                               string decoded = TryDecoding (name.Substring (i + 1, 6));\r
+                                               if (decoded.Length == 1) {\r
+                                                       sb.AppendFormat ("_x{0:X4}_", (int) c);\r
+                                                       continue;\r
+                                               }\r
+                                       }\r
+                               }\r
+                               sb.Append (c);\r
+                       }\r
+                       return sb.ToString ();\r
                }\r
-               [MonoTODO]\r
-               public static string EncodeName(string name)\r
+\r
+               public static string EncodeName (string name)\r
                {\r
-                       return null;\r
+                       return EncodeName (name, false);\r
                }\r
-               [MonoTODO]\r
+               \r
                public static string EncodeNmToken(string name)\r
                {\r
-                       return null;\r
+                       return EncodeName (name, true);\r
                }\r
 \r
                // {true, false, 1, 0}\r
@@ -75,10 +149,11 @@ namespace System.Xml {
                        return DateTime.Parse(s, d);\r
                }\r
 \r
-               [MonoTODO]\r
                public static DateTime ToDateTime(string s, string[] formats)\r
                {\r
-                       return DateTime.Parse(s);\r
+                       DateTimeStyles style = DateTimeStyles.AllowLeadingWhite |\r
+                                              DateTimeStyles.AllowTrailingWhite;\r
+                       return DateTime.ParseExact (s, formats, DateTimeFormatInfo.InvariantInfo, style);\r
                }\r
                \r
                public static Decimal ToDecimal(string s)\r