2004-10-09 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.XML / System.Xml.XPath / DefaultContext.cs
index 41b394a713972283f6104c097844e4f0b54b4983..b1454a1013659e7049c2a0ad028dab5fd19f85d8 100644 (file)
@@ -6,8 +6,30 @@
 //
 // (C) 2002 Piers Haken
 //
+
+//
+// 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.
+//
 using System;
 using System.Collections;
+using System.Globalization;\r
 using System.Xml;
 using System.Xml.XPath;
 using System.Xml.Xsl;
@@ -35,9 +57,33 @@ namespace System.Xml.XPath
                                BaseIterator iter = (BaseIterator) arg;
                                return iter.MoveNext ();
                        }
+                       if (arg is XPathNavigator)
+                       {
+                               return ToBoolean (((XPathNavigator) arg).SelectChildren (XPathNodeType.All));
+                       }
                        throw new ArgumentException ();
                }
-               [MonoTODO]
+
+               public static bool ToBoolean (bool b)
+               {
+                       return b;
+               }
+
+               public static bool ToBoolean (double d)
+               {
+                       return d != 0.0 && d != double.NaN;
+               }
+
+               public static bool ToBoolean (string s)
+               {
+                       return s != null && s.Length > 0;
+               }
+
+               public static bool ToBoolean (BaseIterator iter)
+               {
+                       return iter != null && iter.MoveNext ();
+               }
+
                public static string ToString (object arg)
                {
                        if (arg == null)
@@ -55,26 +101,23 @@ namespace System.Xml.XPath
                                        return "";
                                return iter.Current.Value;
                        }
+                       if (arg is XPathNavigator)
+                       {
+                               return ((XPathNavigator) arg).Value;
+                       }
                        throw new ArgumentException ();
                }
-               [MonoTODO]
+
                public static double ToNumber (object arg)
                {
                        if (arg == null)
                                throw new ArgumentNullException ();
-                       if (arg is string)
-                       {
-                               try
-                               {
-                                       return XmlConvert.ToDouble ((string) arg);      // TODO: spec? convert string to number
-                               }
-                               catch (System.FormatException)
-                               {
-                                       return double.NaN;
-                               }
-                       }
-                       if (arg is BaseIterator)
+                       if (arg is BaseIterator || arg is XPathNavigator)
                                arg = ToString (arg);   // follow on
+                       if (arg is string) {
+                               string s = arg as string;
+                               return ToNumber (s); // use explicit overload
+                       }
                        if (arg is double)
                                return (double) arg;
                        if (arg is bool)
@@ -84,8 +127,13 @@ namespace System.Xml.XPath
                
                public static double ToNumber (string arg)
                {
+                       if (arg == null)
+                               throw new ArgumentNullException ();
+                       string s = arg.Trim (XmlChar.WhitespaceChars);
+                       if (s.Length == 0)
+                               return double.NaN;
                        try {
-                               return XmlConvert.ToDouble ((string) arg.Trim (XmlChar.WhitespaceChars));
+                               return XmlConvert.ToDouble (s);
                        } catch (System.OverflowException) {
                                return double.NaN;
                        } catch (System.FormatException) {
@@ -119,6 +167,10 @@ namespace System.Xml.XPath
                {
                        return "last()";
                }
+
+               internal override bool IsPositional {
+                       get { return true; }
+               }
        }
 
 
@@ -141,6 +193,10 @@ namespace System.Xml.XPath
                {
                        return "position()";
                }
+
+               internal override bool IsPositional {
+                       get { return true; }
+               }
        }
 
 
@@ -212,14 +268,13 @@ namespace System.Xml.XPath
                        
                        XPathNavigator n = iter.Current.Clone ();
                        ArrayList rgNodes = new ArrayList ();
-                       foreach (string strArg in strArgs.Split (rgchWhitespace))
-                       {
-                               if (n.MoveToId (strArg)) {
+                       string [] ids = strArgs.Split (rgchWhitespace);
+                       for (int i = 0; i < ids.Length; i++)
+                               if (n.MoveToId (ids [i]))
                                        rgNodes.Add (n.Clone ());
-                               }
-                       }
+
                        rgNodes.Sort (XPathNavigatorComparer.Instance);
-                       return new EnumeratorIterator (iter, rgNodes.GetEnumerator ());
+                       return new ListIterator (iter, rgNodes, true);
                }
 
                public override string ToString ()
@@ -386,10 +441,10 @@ namespace System.Xml.XPath
                        StringBuilder sb = new StringBuilder ();
                        sb.Append ("concat(");
                        for (int i = 0; i < rgs.Count - 1; i++) {
-                               sb.Append (rgs [i].ToString ());
+                               sb.AppendFormat (CultureInfo.InvariantCulture, "{0}", rgs [i].ToString ());
                                sb.Append (',');
                        }
-                       sb.Append (rgs [rgs.Count - 1].ToString ());
+                       sb.AppendFormat (CultureInfo.InvariantCulture, "{0}", rgs [rgs.Count - 1].ToString ());
                        sb.Append (')');
                        return sb.ToString ();
                }
@@ -630,8 +685,8 @@ namespace System.Xml.XPath
                                str = iter.Current.Value;
                        System.Text.StringBuilder sb = new System.Text.StringBuilder ();
                        bool fSpace = false;
-                       foreach (char ch in str)
-                       {
+                       for (int i = 0; i < str.Length; i++) {
+                               char ch = str [i];
                                if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n')
                                {
                                        fSpace = true;
@@ -825,8 +880,8 @@ namespace System.Xml.XPath
 
                public override object Evaluate (BaseIterator iter)
                {
-                       string lang = arg0.EvaluateString (iter).ToLower ();
-                       string actualLang = iter.Current.XmlLang.ToLower ();
+                       string lang = arg0.EvaluateString (iter).ToLower (CultureInfo.InvariantCulture);
+                       string actualLang = iter.Current.XmlLang.ToLower (CultureInfo.InvariantCulture);
                        
                        return lang == actualLang || lang == (actualLang.Split ('-')[0]);
                }