**** Merged from MCS ****
[mono-project.git] / mcs / class / System.XML / System.Xml.Query / XQueryComparisonOperator.cs
blobc0d7a83ce1a166f69a805c95b428c09fa1fb4358
1 //
2 // XQueryComparisonOperator.cs
3 //
4 // Author:
5 // Atsushi Enomoto <atsushi@ximian.com>
6 //
7 //
8 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 #if NET_2_0
31 using System;
32 using System.Collections;
33 using System.Reflection;
34 using System.Xml;
35 using System.Xml.Schema;
36 using System.Xml.Query;
37 using System.Xml.XPath;
38 using System.Xml.Xsl;
40 namespace Mono.Xml.XPath2
42 // FIXME: Handle complete type promotion and subtype substitution.
43 // See XQuery 1.0 Appendix B.*.
44 public class XQueryComparisonOperator
46 private static bool OpBooleanLessThan (bool b1, bool b2)
48 return !b1 && b2;
51 private static bool OpBooleanGreaterThan (bool b1, bool b2)
53 return b1 && !b2;
56 private static bool CompareEquality (XPathAtomicValue lvalue, XPathAtomicValue rvalue)
58 switch (lvalue.XmlType.TypeCode) {
59 case XmlTypeCode.Boolean:
60 return lvalue.ValueAsBoolean == rvalue.ValueAsBoolean;
61 case XmlTypeCode.String:
62 return lvalue.Value == rvalue.Value;
63 case XmlTypeCode.Date:
64 case XmlTypeCode.Time:
65 case XmlTypeCode.DateTime:
66 case XmlTypeCode.YearMonthDuration:
67 case XmlTypeCode.DayTimeDuration:
68 return lvalue.ValueAsDateTime == rvalue.ValueAsDateTime;
69 case XmlTypeCode.HexBinary:
70 case XmlTypeCode.Base64Binary:
71 case XmlTypeCode.AnyUri:
72 case XmlTypeCode.QName:
73 case XmlTypeCode.Notation:
74 throw new NotImplementedException ();
76 throw new XmlQueryException (String.Format ("Not allowed value comparison between {0} and {1}.", lvalue.XmlType.QualifiedName, rvalue.XmlType.QualifiedName));
79 public static bool ValueEQ (XPathAtomicValue lvalue, XPathAtomicValue rvalue)
81 if (lvalue.XmlType.TypeCode == XmlTypeCode.Decimal &&
82 rvalue.XmlType.TypeCode == XmlTypeCode.Decimal)
83 return lvalue.ValueAsDecimal == rvalue.ValueAsDecimal;
84 if (SequenceType.IsNumeric (lvalue.XmlType.TypeCode) &&
85 SequenceType.IsNumeric (lvalue.XmlType.TypeCode))
86 return lvalue.ValueAsDouble == rvalue.ValueAsDouble;
87 if (lvalue.XmlType.TypeCode == rvalue.XmlType.TypeCode)
88 return CompareEquality (lvalue, rvalue);
90 throw new XmlQueryException (String.Format ("Not allowed value comparison between {0} and {1}.", lvalue.XmlType.QualifiedName, rvalue.XmlType.QualifiedName));
93 public static bool ValueNE (XPathAtomicValue lvalue, XPathAtomicValue rvalue)
95 if (lvalue.XmlType.TypeCode == XmlTypeCode.Decimal &&
96 rvalue.XmlType.TypeCode == XmlTypeCode.Decimal)
97 return lvalue.ValueAsDecimal != rvalue.ValueAsDecimal;
98 if (SequenceType.IsNumeric (lvalue.XmlType.TypeCode) &&
99 SequenceType.IsNumeric (lvalue.XmlType.TypeCode))
100 return lvalue.ValueAsDouble != rvalue.ValueAsDouble;
101 if (lvalue.XmlType.TypeCode == rvalue.XmlType.TypeCode)
102 return !CompareEquality (lvalue, rvalue);
104 throw new XmlQueryException (String.Format ("Not allowed value comparison between {0} and {1}.", lvalue.XmlType.QualifiedName, rvalue.XmlType.QualifiedName));
107 private static bool CompareLT (XPathAtomicValue lvalue, XPathAtomicValue rvalue)
109 switch (lvalue.XmlType.TypeCode) {
110 case XmlTypeCode.Boolean:
111 return OpBooleanLessThan (lvalue.ValueAsBoolean, rvalue.ValueAsBoolean);
112 case XmlTypeCode.String:
113 return lvalue.Value == rvalue.Value;
114 case XmlTypeCode.Date:
115 case XmlTypeCode.Time:
116 case XmlTypeCode.DateTime:
117 case XmlTypeCode.YearMonthDuration:
118 case XmlTypeCode.DayTimeDuration:
119 return lvalue.ValueAsDateTime < rvalue.ValueAsDateTime;
121 throw new XmlQueryException (String.Format ("Not allowed value comparison between {0} and {1}.", lvalue.XmlType.QualifiedName, rvalue.XmlType.QualifiedName));
124 public static bool ValueLT (XPathAtomicValue lvalue, XPathAtomicValue rvalue)
126 if (lvalue.XmlType.TypeCode == XmlTypeCode.Decimal &&
127 rvalue.XmlType.TypeCode == XmlTypeCode.Decimal)
128 return lvalue.ValueAsDecimal < rvalue.ValueAsDecimal;
129 if (SequenceType.IsNumeric (lvalue.XmlType.TypeCode) &&
130 SequenceType.IsNumeric (lvalue.XmlType.TypeCode))
131 return lvalue.ValueAsDouble < rvalue.ValueAsDouble;
132 if (lvalue.XmlType.TypeCode == rvalue.XmlType.TypeCode)
133 return CompareLT (lvalue, rvalue);
135 throw new XmlQueryException (String.Format ("Not allowed value comparison between {0} and {1}.", lvalue.XmlType.QualifiedName, rvalue.XmlType.QualifiedName));
138 private static bool CompareLE (XPathAtomicValue lvalue, XPathAtomicValue rvalue)
140 switch (lvalue.XmlType.TypeCode) {
141 case XmlTypeCode.Boolean:
142 return !OpBooleanGreaterThan (lvalue.ValueAsBoolean, rvalue.ValueAsBoolean);
143 case XmlTypeCode.String:
144 return lvalue.Value == rvalue.Value;
145 case XmlTypeCode.Date:
146 case XmlTypeCode.Time:
147 case XmlTypeCode.DateTime:
148 case XmlTypeCode.YearMonthDuration:
149 case XmlTypeCode.DayTimeDuration:
150 return lvalue.ValueAsDateTime <= rvalue.ValueAsDateTime;
152 throw new XmlQueryException (String.Format ("Not allowed value comparison between {0} and {1}.", lvalue.XmlType.QualifiedName, rvalue.XmlType.QualifiedName));
155 public static bool ValueLE (XPathAtomicValue lvalue, XPathAtomicValue rvalue)
157 if (lvalue.XmlType.TypeCode == XmlTypeCode.Decimal &&
158 rvalue.XmlType.TypeCode == XmlTypeCode.Decimal)
159 return lvalue.ValueAsDecimal <= rvalue.ValueAsDecimal;
160 if (SequenceType.IsNumeric (lvalue.XmlType.TypeCode) &&
161 SequenceType.IsNumeric (lvalue.XmlType.TypeCode))
162 return lvalue.ValueAsDouble <= rvalue.ValueAsDouble;
163 if (lvalue.XmlType.TypeCode == rvalue.XmlType.TypeCode)
164 return CompareLE (lvalue, rvalue);
166 throw new XmlQueryException (String.Format ("Not allowed value comparison between {0} and {1}.", lvalue.XmlType.QualifiedName, rvalue.XmlType.QualifiedName));
169 private static bool CompareGT (XPathAtomicValue lvalue, XPathAtomicValue rvalue)
171 switch (lvalue.XmlType.TypeCode) {
172 case XmlTypeCode.Boolean:
173 return OpBooleanGreaterThan (lvalue.ValueAsBoolean, rvalue.ValueAsBoolean);
174 case XmlTypeCode.String:
175 return lvalue.Value == rvalue.Value;
176 case XmlTypeCode.Date:
177 case XmlTypeCode.Time:
178 case XmlTypeCode.DateTime:
179 case XmlTypeCode.YearMonthDuration:
180 case XmlTypeCode.DayTimeDuration:
181 return lvalue.ValueAsDateTime > rvalue.ValueAsDateTime;
183 throw new XmlQueryException (String.Format ("Not allowed value comparison between {0} and {1}.", lvalue.XmlType.QualifiedName, rvalue.XmlType.QualifiedName));
186 public static bool ValueGT (XPathAtomicValue lvalue, XPathAtomicValue rvalue)
188 if (lvalue.XmlType.TypeCode == XmlTypeCode.Decimal &&
189 rvalue.XmlType.TypeCode == XmlTypeCode.Decimal)
190 return lvalue.ValueAsDecimal > rvalue.ValueAsDecimal;
191 if (SequenceType.IsNumeric (lvalue.XmlType.TypeCode) &&
192 SequenceType.IsNumeric (lvalue.XmlType.TypeCode))
193 return lvalue.ValueAsDouble > rvalue.ValueAsDouble;
194 if (lvalue.XmlType.TypeCode == rvalue.XmlType.TypeCode)
195 return CompareGT (lvalue, rvalue);
197 throw new XmlQueryException (String.Format ("Not allowed value comparison between {0} and {1}.", lvalue.XmlType.QualifiedName, rvalue.XmlType.QualifiedName));
200 private static bool CompareGE (XPathAtomicValue lvalue, XPathAtomicValue rvalue)
202 switch (lvalue.XmlType.TypeCode) {
203 case XmlTypeCode.Boolean:
204 return !OpBooleanLessThan (lvalue.ValueAsBoolean, rvalue.ValueAsBoolean);
205 case XmlTypeCode.String:
206 return lvalue.Value == rvalue.Value;
207 case XmlTypeCode.Date:
208 case XmlTypeCode.Time:
209 case XmlTypeCode.DateTime:
210 case XmlTypeCode.YearMonthDuration:
211 case XmlTypeCode.DayTimeDuration:
212 return lvalue.ValueAsDateTime >= rvalue.ValueAsDateTime;
214 throw new XmlQueryException (String.Format ("Not allowed value comparison between {0} and {1}.", lvalue.XmlType.QualifiedName, rvalue.XmlType.QualifiedName));
217 public static bool ValueGE (XPathAtomicValue lvalue, XPathAtomicValue rvalue)
219 if (lvalue.XmlType.TypeCode == XmlTypeCode.Decimal &&
220 rvalue.XmlType.TypeCode == XmlTypeCode.Decimal)
221 return lvalue.ValueAsDecimal >= rvalue.ValueAsDecimal;
222 if (SequenceType.IsNumeric (lvalue.XmlType.TypeCode) &&
223 SequenceType.IsNumeric (lvalue.XmlType.TypeCode))
224 return lvalue.ValueAsDouble >= rvalue.ValueAsDouble;
225 if (lvalue.XmlType.TypeCode == rvalue.XmlType.TypeCode)
226 return CompareGE (lvalue, rvalue);
228 throw new XmlQueryException (String.Format ("Not allowed value comparison between {0} and {1}.", lvalue.XmlType.QualifiedName, rvalue.XmlType.QualifiedName));
232 #endif