From f9c88642ff6a0bb876a061b5c1a999a01e05db58 Mon Sep 17 00:00:00 2001 From: Atsushi Eno Date: Wed, 25 Aug 2004 08:21:52 +0000 Subject: [PATCH] 2004-08-25 Atsushi Enomoto * SequenceType.cs : moved type inference method to XPathAtomicValue. Use IsArray in runtime type inference. Initialize fields completely. Handle collection to runtime type for functions that takes array. * XPath2Expression.cs : Add whitespaces on serializing XPath items. EBV != atomized boolean value. Add Atomize() for XPathItem (Atomize() for XPathSequence should be removed in the future). Replaced some ExprSequence to ExprSingle for optimization. * XQueryFunctionCliImpl.cs : Fixed some return types. * XQueryTokenizer.cs : Fixed weird ReadDecimal(). svn path=/trunk/mcs/; revision=32812 --- .../System.XML/System.Xml.Query/ChangeLog | 12 +++ .../System.Xml.Query/SequenceType.cs | 48 +++------- .../System.Xml.Query/XPath2Expression.cs | 91 +++++++++++++++---- .../System.Xml.Query/XQueryCompileOptions.cs | 4 +- .../System.Xml.Query/XQueryFunctionCliImpl.cs | 43 +++++---- .../System.Xml.Query/XQueryTokenizer.cs | 12 +-- 6 files changed, 132 insertions(+), 78 deletions(-) diff --git a/mcs/class/System.XML/System.Xml.Query/ChangeLog b/mcs/class/System.XML/System.Xml.Query/ChangeLog index 40f8a4f0f1d..da2295a2607 100644 --- a/mcs/class/System.XML/System.Xml.Query/ChangeLog +++ b/mcs/class/System.XML/System.Xml.Query/ChangeLog @@ -1,3 +1,15 @@ +2004-08-25 Atsushi Enomoto + + * SequenceType.cs : moved type inference method to XPathAtomicValue. + Use IsArray in runtime type inference. Initialize fields completely. + Handle collection to runtime type for functions that takes array. + * XPath2Expression.cs : Add whitespaces on serializing XPath items. + EBV != atomized boolean value. Add Atomize() for XPathItem (Atomize() + for XPathSequence should be removed in the future). + Replaced some ExprSequence to ExprSingle for optimization. + * XQueryFunctionCliImpl.cs : Fixed some return types. + * XQueryTokenizer.cs : Fixed weird ReadDecimal(). + 2004-08-24 Atsushi Enomoto * SequenceType.cs : added ToRuntimeType(). diff --git a/mcs/class/System.XML/System.Xml.Query/SequenceType.cs b/mcs/class/System.XML/System.Xml.Query/SequenceType.cs index 00976ec08de..2697e1111a6 100755 --- a/mcs/class/System.XML/System.Xml.Query/SequenceType.cs +++ b/mcs/class/System.XML/System.Xml.Query/SequenceType.cs @@ -125,32 +125,9 @@ namespace Mono.Xml.XPath2 internal static SequenceType Create (Type cliType) { - switch (Type.GetTypeCode (cliType)) { - case TypeCode.Int32: - return Int; - case TypeCode.Decimal: - return Decimal; - case TypeCode.Double: - return Double; - case TypeCode.Single: - return Single; - case TypeCode.Int64: - return Integer; - case TypeCode.Int16: - return Short; - case TypeCode.UInt16: - return UnsignedShort; - case TypeCode.UInt32: - return UnsignedInt; - case TypeCode.String: - return AtomicString; - case TypeCode.DateTime: - return DateTime; - case TypeCode.Boolean: - return Boolean; - case TypeCode.Object: - return AnyType; - } + // typed Array + if (cliType.IsArray) + return Create (XPathAtomicValue.XmlTypeCodeFromRuntimeType (cliType.GetElementType (), true), Occurence.ZeroOrMore); if (cliType == typeof (XmlQualifiedName)) return QName; if (cliType == typeof (XPathNavigator) || cliType.IsSubclassOf (typeof (XPathNavigator))) @@ -159,10 +136,7 @@ namespace Mono.Xml.XPath2 return SingleAnyAtomic; if (cliType == typeof (XPathItem)) return SingleItem; - // FIXME: typed Array - if (cliType.IsSubclassOf (typeof (ICollection))) - return AnyType; - throw new NotSupportedException (String.Format ("Specified type is not supported for {0}", cliType)); + return Create (XPathAtomicValue.XmlTypeCodeFromRuntimeType (cliType, true), Occurence.One); } internal static SequenceType Create (XmlTypeCode typeCode, Occurence occurence) @@ -221,11 +195,13 @@ namespace Mono.Xml.XPath2 private SequenceType (XmlSchemaType schemaType, Occurence occurence) { this.schemaType = schemaType; + this.itemType = ItemType.AnyItem; this.occurence = occurence; } internal SequenceType (ItemType itemType, Occurence occurence) { + this.schemaType = XmlSchemaComplexType.AnyType; this.itemType = itemType; this.occurence = occurence; } @@ -291,12 +267,16 @@ namespace Mono.Xml.XPath2 public object ToRuntimeType (XPathSequence seq) { // FIXME: handle ZeroOrMore|OneOrMore -// switch (occurence) { -// case Occurence.One: -// case Occurence.Optional: + switch (occurence) { + case Occurence.One: + case Occurence.Optional: XPathAtomicValue av = ExprSingle.Atomize (seq); return av != null ? av.TypedValue : null; -// } + } + ArrayList al = new ArrayList (); + while (seq.MoveNext ()) + al.Add (seq.Current.TypedValue); + return al.ToArray (XPathAtomicValue.RuntimeTypeFromXmlTypeCode (schemaType.TypeCode)); // return seq; } } diff --git a/mcs/class/System.XML/System.Xml.Query/XPath2Expression.cs b/mcs/class/System.XML/System.Xml.Query/XPath2Expression.cs index 7484535331b..cec4f887fef 100755 --- a/mcs/class/System.XML/System.Xml.Query/XPath2Expression.cs +++ b/mcs/class/System.XML/System.Xml.Query/XPath2Expression.cs @@ -121,8 +121,14 @@ namespace Mono.Xml.XPath2 { XmlWriter w = iter.Context.Writer; XPathSequence result = Evaluate (iter); - foreach (XPathItem item in result) + bool initial = true; + foreach (XPathItem item in result) { + if (initial) + initial = false; + else + w.WriteWhitespace (" "); WriteXPathItem (item, w); + } } private void WriteXPathItem (XPathItem item, XmlWriter w) @@ -134,11 +140,43 @@ namespace Mono.Xml.XPath2 w.WriteValue (item.Value); } - // get EBV + // get EBV (fn:boolean()) public virtual bool EvaluateAsBoolean (XPathSequence iter) { - XPathAtomicValue v = Atomize (Evaluate (iter)); - return v != null ? v.ValueAsBoolean : false; + XPathSequence result = Evaluate (iter); + if (!result.MoveNext ()) + return false; + XPathAtomicValue v = Atomize (result.Current); + if (result.MoveNext ()) + return true; + switch (v.XmlType.TypeCode) { + case XmlTypeCode.Boolean: + return v.ValueAsBoolean; + case XmlTypeCode.String: + case XmlTypeCode.UntypedAtomic: + return v.Value != String.Empty; + case XmlTypeCode.Float: + return v.ValueAsSingle != Single.NaN && v.ValueAsSingle != 0.0; + case XmlTypeCode.Double: + return v.ValueAsDouble != Double.NaN && v.ValueAsSingle != 0.0; + case XmlTypeCode.Integer: + case XmlTypeCode.NonPositiveInteger: + case XmlTypeCode.NegativeInteger: + case XmlTypeCode.Long: + case XmlTypeCode.Int: + case XmlTypeCode.Short: + case XmlTypeCode.Byte: + case XmlTypeCode.UnsignedInt: + case XmlTypeCode.UnsignedShort: + case XmlTypeCode.UnsignedByte: + return v.ValueAsInt64 != 0; + case XmlTypeCode.NonNegativeInteger: + case XmlTypeCode.UnsignedLong: + case XmlTypeCode.PositiveInteger: + return (ulong) (v.ValueAs (typeof (ulong))) != 0; + } + // otherwise, return true + return true; } public virtual int EvaluateAsInt (XPathSequence iter) @@ -153,6 +191,15 @@ namespace Mono.Xml.XPath2 return v != null ? v.Value : String.Empty; } + public static XPathAtomicValue Atomize (XPathItem item) + { + XPathNavigator nav = item as XPathNavigator; + if (nav != null) + return new XPathAtomicValue (nav.TypedValue, nav.SchemaInfo.SchemaType); + else + return (XPathAtomicValue) item; + } + // FIXME: What if iter contains list value? public static XPathAtomicValue Atomize (XPathSequence iter) { @@ -183,13 +230,13 @@ namespace Mono.Xml.XPath2 public FLWORExpr (ForLetClauseCollection forlet, ExprSequence whereClause, OrderSpecList orderBy, ExprSingle ret) { this.fl = forlet; - this.whereClause = whereClause; + this.whereClause = new ParenthesizedExpr (whereClause); this.orderBy = orderBy; this.ret = ret; } ForLetClauseCollection fl; - ExprSequence whereClause; + ExprSingle whereClause; OrderSpecList orderBy; ExprSingle ret; @@ -197,7 +244,7 @@ namespace Mono.Xml.XPath2 get { return fl; } } - public ExprSequence WhereClause { + public ExprSingle WhereClause { get { return whereClause; } } @@ -236,8 +283,9 @@ namespace Mono.Xml.XPath2 } } if (WhereClause != null) - for (int i = 0; i < WhereClause.Count; i++) - WhereClause [i] = WhereClause [i].Compile (compiler); +// for (int i = 0; i < WhereClause.Count; i++) +// WhereClause [i] = WhereClause [i].Compile (compiler); + whereClause = whereClause.Compile (compiler); if (OrderBy != null) foreach (OrderSpec os in OrderBy) os.Expression = os.Expression.Compile (compiler); @@ -601,6 +649,10 @@ namespace Mono.Xml.XPath2 public TypeswitchExpr (ExprSequence switchExpr, CaseClauseList caseList, XmlQualifiedName defaultVarName, ExprSingle defaultReturn) { + this.switchExpr = switchExpr; + this.caseList = caseList; + this.defaultVarName = defaultVarName; + this.defaultReturn = defaultReturn; } public ExprSequence SwitchExpr { @@ -725,16 +777,16 @@ namespace Mono.Xml.XPath2 { public IfExpr (ExprSequence condition, ExprSingle trueExpr, ExprSingle falseExpr) { - this.condition = condition; + this.condition = new ParenthesizedExpr (condition); this.trueExpr = trueExpr; this.falseExpr = falseExpr; } - ExprSequence condition; + ExprSingle condition; ExprSingle trueExpr; ExprSingle falseExpr; - public ExprSequence Condition { + public ExprSingle Condition { get { return condition; } set { condition = value; } } @@ -761,8 +813,9 @@ namespace Mono.Xml.XPath2 internal override ExprSingle CompileCore (XQueryASTCompiler compiler) { - for (int i = 0; i < Condition.Count; i++) - Condition [i] = Condition [i].Compile (compiler); +// for (int i = 0; i < Condition.Count; i++) +// Condition [i] = Condition [i].Compile (compiler); + condition = condition.Compile (compiler); // FIXME: check if condition is constant, and returns trueExpr or falseExpr TrueExpr = TrueExpr.Compile (compiler); FalseExpr = FalseExpr.Compile (compiler); @@ -781,10 +834,12 @@ namespace Mono.Xml.XPath2 public override XPathSequence Evaluate (XPathSequence iter) { - foreach (ExprSingle expr in Condition) { - if (expr.EvaluateAsBoolean (iter)) - return TrueExpr.Evaluate (iter); - } +// foreach (ExprSingle expr in Condition) { +// if (expr.EvaluateAsBoolean (iter)) +// return TrueExpr.Evaluate (iter); +// } + if (condition.EvaluateAsBoolean (iter)) + return TrueExpr.Evaluate (iter); return FalseExpr.Evaluate (iter); } #endregion diff --git a/mcs/class/System.XML/System.Xml.Query/XQueryCompileOptions.cs b/mcs/class/System.XML/System.Xml.Query/XQueryCompileOptions.cs index 695cabdf174..b4e0f8192aa 100755 --- a/mcs/class/System.XML/System.Xml.Query/XQueryCompileOptions.cs +++ b/mcs/class/System.XML/System.Xml.Query/XQueryCompileOptions.cs @@ -42,7 +42,7 @@ namespace Mono.Xml.XPath2 public class XQueryCompileOptions { public XQueryCompileOptions () - : this (new NameTable (), CultureInfo.InvariantCulture) + : this (new NameTable (), null) { } @@ -50,6 +50,8 @@ namespace Mono.Xml.XPath2 { this.nameTable = nameTable; this.defaultCollation = defaultCollation; + if (this.defaultCollation == null) + this.defaultCollation = CultureInfo.InvariantCulture; knownCollections = new Hashtable (); } diff --git a/mcs/class/System.XML/System.Xml.Query/XQueryFunctionCliImpl.cs b/mcs/class/System.XML/System.Xml.Query/XQueryFunctionCliImpl.cs index ec55efc2447..ca0903c859e 100755 --- a/mcs/class/System.XML/System.Xml.Query/XQueryFunctionCliImpl.cs +++ b/mcs/class/System.XML/System.Xml.Query/XQueryFunctionCliImpl.cs @@ -213,32 +213,37 @@ namespace Mono.Xml.XPath2 throw new NotImplementedException (); } - public static object FnCompare (string s1, string s2) + public static int FnCompare (XQueryContext ctx, string s1, string s2) { - return string.Compare (s1, s2); + return FnCompare (s1, s2, ctx.DefaultCollation); } - public static object FnCompare (string s1, string s2, string collation) + public static int FnCompare (XQueryContext ctx, string s1, string s2, string collation) { - throw new NotImplementedException (); + return FnCompare (s1, s2, ctx.GetCulture (collation)); + } + + private static int FnCompare (string s1, string s2, CultureInfo ci) + { + return ci.CompareInfo.Compare (s1, s2); } - public static object FnConcat (object o1, object o2) + public static string FnConcat (object o1, object o2) { return String.Concat (o1, o2); } - public static object FnStringJoin (string [] strings, string separator) + public static string FnStringJoin (string [] strings, string separator) { return String.Join (separator, strings); } - public static object FnSubstring (string src, double loc) + public static string FnSubstring (string src, double loc) { return src.Substring ((int) loc); } - public static object FnSubstring (string src, double loc, double length) + public static string FnSubstring (string src, double loc, double length) { return src.Substring ((int) loc, (int) length); } @@ -253,62 +258,62 @@ namespace Mono.Xml.XPath2 return s.Length; } - public static object FnNormalizeSpace (XQueryContext ctx) + public static string FnNormalizeSpace (XQueryContext ctx) { return FnNormalizeSpace (FnString (ctx)); } [MonoTODO] - public static object FnNormalizeSpace (string s) + public static string FnNormalizeSpace (string s) { throw new NotImplementedException (); } - public static object FnNormalizeUnicode (string arg) + public static string FnNormalizeUnicode (string arg) { return FnNormalizeUnicode (arg, "NFC"); } [MonoTODO] - public static object FnNormalizeUnicode (string arg, string normalizationForm) + public static string FnNormalizeUnicode (string arg, string normalizationForm) { throw new NotImplementedException (); } - public static object FnUpperCase (string arg) + public static string FnUpperCase (string arg) { // FIXME: supply culture return arg.ToUpper (); } - public static object FnLowerCase (string arg) + public static string FnLowerCase (string arg) { // FIXME: supply culture return arg.ToLower (); } - public static object FnTranslate (string arg, string mapString, string transString) + public static string FnTranslate (string arg, string mapString, string transString) { return arg == null ? null : arg.Replace (mapString, transString); } [MonoTODO] - public static object FnEscapeUri (string uriPart, bool escapeReserved) + public static string FnEscapeUri (string uriPart, bool escapeReserved) { throw new NotImplementedException (); } - public static object FnContains (XQueryContext ctx, string arg1, string arg2) + public static bool FnContains (XQueryContext ctx, string arg1, string arg2) { return FnContains (arg1, arg2, ctx.DefaultCollation); } - public static object FnContains (XQueryContext ctx, string arg1, string arg2, string collation) + public static bool FnContains (XQueryContext ctx, string arg1, string arg2, string collation) { return FnContains (arg1, arg2, ctx.GetCulture (collation)); } - private static object FnContains (string arg1, string arg2, CultureInfo ci) + private static bool FnContains (string arg1, string arg2, CultureInfo ci) { if (arg1 == null) arg1 = String.Empty; diff --git a/mcs/class/System.XML/System.Xml.Query/XQueryTokenizer.cs b/mcs/class/System.XML/System.Xml.Query/XQueryTokenizer.cs index 786ada8e74c..e51c7b499ef 100755 --- a/mcs/class/System.XML/System.Xml.Query/XQueryTokenizer.cs +++ b/mcs/class/System.XML/System.Xml.Query/XQueryTokenizer.cs @@ -1104,22 +1104,22 @@ namespace Mono.Xml.XQuery.Parser private decimal ReadDecimal (bool floatingPoint) { bufferIndex = 0; + bool cond = true; do { int c = PeekChar (); if (c < 0) { - ReadChar (); - break; + cond = false; } // FIXME: more complex - if (Char.IsNumber ((char) c)) { + else if (Char.IsNumber ((char) c) || c == '.') { ReadChar (); AddValueChar ((char) c); continue; } else - break; - } while (true); - string s = (floatingPoint ? "" : ".") + CreateValueString (); + cond = false; + } while (cond); + string s = (floatingPoint ? "." : "") + CreateValueString (); return decimal.Parse (s); } -- 2.25.1