(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / Mono.Xml.Ext / Mono.Xml.XPath2 / XQueryArithmeticOperator.cs
blob665a5212eabbc4eb1bdd35e7885932dbdf053163
1 //
2 // XQueryArithmeticOperator.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;
39 using Mono.Xml;
41 namespace Mono.Xml.XPath2
43 // FIXME: Handle complete type promotion and subtype substitution.
44 // See XQuery 1.0 Appendix B.*.
45 public class XQueryArithmeticOperator
47 /// <summary>
48 /// x + y
49 /// </summary>
50 public static XPathAtomicValue Add (XPathAtomicValue lvalue, XPathAtomicValue rvalue)
52 // numeric, date, time, dateTime, yearMonthDuration, dayTimeDuration
53 switch (lvalue.XmlType.TypeCode) {
55 // numerics
56 case XmlTypeCode.Integer:
57 switch (rvalue.XmlType.TypeCode) {
58 case XmlTypeCode.Integer:
59 return new XPathAtomicValue (lvalue.ValueAsInt64 + rvalue.ValueAsInt64, rvalue.XmlType);
60 case XmlTypeCode.Decimal:
61 return new XPathAtomicValue (lvalue.ValueAsDecimal + rvalue.ValueAsDecimal, rvalue.XmlType);
62 case XmlTypeCode.Float:
63 case XmlTypeCode.Double:
64 return new XPathAtomicValue (lvalue.ValueAsDouble + rvalue.ValueAsDouble, rvalue.XmlType);
66 break;
68 case XmlTypeCode.Decimal:
69 switch (rvalue.XmlType.TypeCode) {
70 case XmlTypeCode.Integer:
71 case XmlTypeCode.Decimal:
72 return new XPathAtomicValue (lvalue.ValueAsDecimal + rvalue.ValueAsDecimal, rvalue.XmlType);
73 case XmlTypeCode.Float:
74 case XmlTypeCode.Double:
75 return new XPathAtomicValue (lvalue.ValueAsDouble + rvalue.ValueAsDouble, rvalue.XmlType);
77 break;
79 case XmlTypeCode.Float:
80 case XmlTypeCode.Double:
81 switch (rvalue.XmlType.TypeCode) {
82 case XmlTypeCode.Integer:
83 case XmlTypeCode.Decimal:
84 case XmlTypeCode.Float:
85 case XmlTypeCode.Double:
86 return new XPathAtomicValue (lvalue.ValueAsDouble + rvalue.ValueAsDouble, rvalue.XmlType);
88 break;
90 // datetimes
91 case XmlTypeCode.Time:
92 if (rvalue.XmlType.TypeCode == XmlTypeCode.DayTimeDuration)
93 goto case XmlTypeCode.DateTime;
94 break;
95 case XmlTypeCode.DateTime:
96 case XmlTypeCode.Date:
97 switch (rvalue.XmlType.TypeCode) {
98 case XmlTypeCode.YearMonthDuration:
99 case XmlTypeCode.DayTimeDuration:
100 return new XPathAtomicValue (lvalue.ValueAsDateTime + new TimeSpan (rvalue.ValueAsDateTime.Ticks), lvalue.XmlType);
102 break;
103 // durations
104 case XmlTypeCode.YearMonthDuration:
105 switch (rvalue.XmlType.TypeCode) {
106 case XmlTypeCode.Date:
107 case XmlTypeCode.DateTime:
108 return new XPathAtomicValue (lvalue.ValueAsDateTime + new TimeSpan (rvalue.ValueAsDateTime.Ticks), rvalue.XmlType);
109 case XmlTypeCode.YearMonthDuration:
110 return new XPathAtomicValue (new DateTime (lvalue.ValueAsDateTime.Ticks + rvalue.ValueAsDateTime.Ticks), InternalPool.XdtYearMonthDuration);
112 break;
113 case XmlTypeCode.DayTimeDuration:
114 switch (rvalue.XmlType.TypeCode) {
115 case XmlTypeCode.Date:
116 case XmlTypeCode.Time:
117 case XmlTypeCode.DateTime:
118 return new XPathAtomicValue (lvalue.ValueAsDateTime + new TimeSpan (rvalue.ValueAsDateTime.Ticks), rvalue.XmlType);
119 case XmlTypeCode.DayTimeDuration:
120 return new XPathAtomicValue (new DateTime (lvalue.ValueAsDateTime.Ticks + rvalue.ValueAsDateTime.Ticks), InternalPool.XdtDayTimeDuration);
122 break;
125 throw new XmlQueryException (String.Format ("Not allowed arithmetic operation: {0} + {1}", lvalue.XmlType.QualifiedName, rvalue.XmlType.QualifiedName));
128 /// <summary>
129 /// x - y
130 /// </summary>
131 public static XPathAtomicValue Subtract (XPathAtomicValue lvalue, XPathAtomicValue rvalue)
133 // numeric, date, time, dateTime, yearMonthDuration, dayTimeDuration
134 switch (lvalue.XmlType.TypeCode) {
136 // numerics
137 case XmlTypeCode.Integer:
138 switch (rvalue.XmlType.TypeCode) {
139 case XmlTypeCode.Integer:
140 return new XPathAtomicValue (lvalue.ValueAsInt64 - rvalue.ValueAsInt64, rvalue.XmlType);
141 case XmlTypeCode.Decimal:
142 return new XPathAtomicValue (lvalue.ValueAsDecimal - rvalue.ValueAsDecimal, rvalue.XmlType);
143 case XmlTypeCode.Float:
144 case XmlTypeCode.Double:
145 return new XPathAtomicValue (lvalue.ValueAsDouble - rvalue.ValueAsDouble, rvalue.XmlType);
147 break;
149 case XmlTypeCode.Decimal:
150 switch (rvalue.XmlType.TypeCode) {
151 case XmlTypeCode.Integer:
152 case XmlTypeCode.Decimal:
153 return new XPathAtomicValue (lvalue.ValueAsDecimal - rvalue.ValueAsDecimal, rvalue.XmlType);
154 case XmlTypeCode.Float:
155 case XmlTypeCode.Double:
156 return new XPathAtomicValue (lvalue.ValueAsDouble - rvalue.ValueAsDouble, rvalue.XmlType);
158 break;
160 case XmlTypeCode.Float:
161 case XmlTypeCode.Double:
162 switch (rvalue.XmlType.TypeCode) {
163 case XmlTypeCode.Integer:
164 case XmlTypeCode.Decimal:
165 case XmlTypeCode.Float:
166 case XmlTypeCode.Double:
167 return new XPathAtomicValue (lvalue.ValueAsDouble - rvalue.ValueAsDouble, rvalue.XmlType);
169 break;
171 // datetimes
172 case XmlTypeCode.Time:
173 switch (rvalue.XmlType.TypeCode) {
174 case XmlTypeCode.Time:
175 return new XPathAtomicValue (lvalue.ValueAsDateTime - rvalue.ValueAsDateTime, InternalPool.XdtDayTimeDuration);
176 case XmlTypeCode.DayTimeDuration:
177 return new XPathAtomicValue (lvalue.ValueAsDateTime - new TimeSpan (rvalue.ValueAsDateTime.Ticks), lvalue.XmlType);
179 break;
181 case XmlTypeCode.DateTime:
182 switch (rvalue.XmlType.TypeCode) {
183 case XmlTypeCode.DateTime:
184 // FIXME: check fn:subtract-daytimes-yielding-dayTimeDuration()
185 return new XPathAtomicValue (lvalue.ValueAsDateTime - rvalue.ValueAsDateTime, InternalPool.XdtDayTimeDuration);
186 case XmlTypeCode.YearMonthDuration:
187 case XmlTypeCode.DayTimeDuration:
188 return new XPathAtomicValue (lvalue.ValueAsDateTime - new TimeSpan (rvalue.ValueAsDateTime.Ticks), lvalue.XmlType);
190 break;
192 case XmlTypeCode.Date:
193 switch (rvalue.XmlType.TypeCode) {
194 case XmlTypeCode.Date:
195 // FIXME: check fn:subtract-daytimes-yielding-dayTimeDuration()
196 return new XPathAtomicValue (lvalue.ValueAsDateTime - rvalue.ValueAsDateTime, InternalPool.XdtDayTimeDuration);
197 case XmlTypeCode.YearMonthDuration:
198 case XmlTypeCode.DayTimeDuration:
199 return new XPathAtomicValue (lvalue.ValueAsDateTime - new TimeSpan (rvalue.ValueAsDateTime.Ticks), lvalue.XmlType);
201 break;
203 // durations
204 case XmlTypeCode.YearMonthDuration:
205 if (rvalue.XmlType.TypeCode == XmlTypeCode.YearMonthDuration)
206 return new XPathAtomicValue (new TimeSpan (lvalue.ValueAsDateTime.Ticks - rvalue.ValueAsDateTime.Ticks), InternalPool.XdtYearMonthDuration);
207 break;
208 case XmlTypeCode.DayTimeDuration:
209 if (rvalue.XmlType.TypeCode == XmlTypeCode.DayTimeDuration)
210 return new XPathAtomicValue (new TimeSpan (lvalue.ValueAsDateTime.Ticks - rvalue.ValueAsDateTime.Ticks), InternalPool.XdtDayTimeDuration);
211 break;
214 throw new XmlQueryException (String.Format ("Not allowed arithmetic operation: {0} - {1}", lvalue.XmlType.QualifiedName, rvalue.XmlType.QualifiedName));
217 /// <summary>
218 /// x * y
219 /// </summary>
220 public static XPathAtomicValue Multiply (XPathAtomicValue lvalue, XPathAtomicValue rvalue)
222 // numeric, date, time, dateTime, yearMonthDuration, dayTimeDuration
223 switch (lvalue.XmlType.TypeCode) {
225 // numerics
226 case XmlTypeCode.Integer:
227 switch (rvalue.XmlType.TypeCode) {
228 case XmlTypeCode.Integer:
229 return new XPathAtomicValue (lvalue.ValueAsInt64 * rvalue.ValueAsInt64, rvalue.XmlType);
230 case XmlTypeCode.Decimal:
231 return new XPathAtomicValue (lvalue.ValueAsDecimal * rvalue.ValueAsDecimal, rvalue.XmlType);
232 case XmlTypeCode.Float:
233 case XmlTypeCode.Double:
234 return new XPathAtomicValue (lvalue.ValueAsDouble * rvalue.ValueAsDouble, rvalue.XmlType);
236 case XmlTypeCode.DayTimeDuration:
237 case XmlTypeCode.YearMonthDuration:
238 goto case XmlTypeCode.Decimal;
240 break;
242 case XmlTypeCode.Decimal:
243 switch (rvalue.XmlType.TypeCode) {
244 case XmlTypeCode.Integer:
245 case XmlTypeCode.Decimal:
246 return new XPathAtomicValue (lvalue.ValueAsDecimal * rvalue.ValueAsDecimal, rvalue.XmlType);
247 case XmlTypeCode.Float:
248 case XmlTypeCode.Double:
249 return new XPathAtomicValue (lvalue.ValueAsDouble * rvalue.ValueAsDouble, rvalue.XmlType);
251 case XmlTypeCode.YearMonthDuration:
252 case XmlTypeCode.DayTimeDuration:
253 return new XPathAtomicValue (new TimeSpan ((long) (lvalue.ValueAsDateTime.Ticks * rvalue.ValueAsDecimal)), rvalue.XmlType);
255 break;
257 case XmlTypeCode.Float:
258 case XmlTypeCode.Double:
259 switch (rvalue.XmlType.TypeCode) {
260 case XmlTypeCode.Integer:
261 case XmlTypeCode.Decimal:
262 case XmlTypeCode.Float:
263 case XmlTypeCode.Double:
264 return new XPathAtomicValue (lvalue.ValueAsDouble * rvalue.ValueAsDouble, rvalue.XmlType);
266 case XmlTypeCode.DayTimeDuration:
267 case XmlTypeCode.YearMonthDuration:
268 goto case XmlTypeCode.Decimal;
270 break;
272 // durations
273 case XmlTypeCode.DayTimeDuration:
274 case XmlTypeCode.YearMonthDuration:
275 switch (rvalue.XmlType.TypeCode) {
276 case XmlTypeCode.Integer:
277 case XmlTypeCode.Decimal:
278 case XmlTypeCode.Float:
279 case XmlTypeCode.Double:
280 return Multiply (rvalue, lvalue);
282 break;
285 throw new XmlQueryException (String.Format ("Not allowed arithmetic operation: {0} * {1}", lvalue.XmlType.QualifiedName, rvalue.XmlType.QualifiedName));
288 /// <summary>
289 /// x / y
290 /// </summary>
291 public static XPathAtomicValue Divide (XPathAtomicValue lvalue, XPathAtomicValue rvalue)
293 // numeric, date, time, dateTime, yearMonthDuration, dayTimeDuration
294 switch (lvalue.XmlType.TypeCode) {
296 // numerics
297 case XmlTypeCode.Integer:
298 switch (rvalue.XmlType.TypeCode) {
299 case XmlTypeCode.Integer:
300 return new XPathAtomicValue (lvalue.ValueAsInt64 / rvalue.ValueAsInt64, rvalue.XmlType);
301 case XmlTypeCode.Decimal:
302 return new XPathAtomicValue (lvalue.ValueAsDecimal / rvalue.ValueAsDecimal, rvalue.XmlType);
303 case XmlTypeCode.Float:
304 case XmlTypeCode.Double:
305 return new XPathAtomicValue (lvalue.ValueAsDouble / rvalue.ValueAsDouble, rvalue.XmlType);
307 break;
309 case XmlTypeCode.Decimal:
310 switch (rvalue.XmlType.TypeCode) {
311 case XmlTypeCode.Integer:
312 case XmlTypeCode.Decimal:
313 return new XPathAtomicValue (lvalue.ValueAsDecimal / rvalue.ValueAsDecimal, rvalue.XmlType);
314 case XmlTypeCode.Float:
315 case XmlTypeCode.Double:
316 return new XPathAtomicValue (lvalue.ValueAsDouble / rvalue.ValueAsDouble, rvalue.XmlType);
318 break;
320 case XmlTypeCode.Float:
321 case XmlTypeCode.Double:
322 switch (rvalue.XmlType.TypeCode) {
323 case XmlTypeCode.Integer:
324 case XmlTypeCode.Decimal:
325 case XmlTypeCode.Float:
326 case XmlTypeCode.Double:
327 return new XPathAtomicValue (lvalue.ValueAsDouble / rvalue.ValueAsDouble, rvalue.XmlType);
329 case XmlTypeCode.DayTimeDuration:
330 case XmlTypeCode.YearMonthDuration:
331 goto case XmlTypeCode.Decimal;
333 break;
335 // durations
336 case XmlTypeCode.DayTimeDuration:
337 case XmlTypeCode.YearMonthDuration:
338 switch (rvalue.XmlType.TypeCode) {
339 case XmlTypeCode.Integer:
340 case XmlTypeCode.Decimal:
341 case XmlTypeCode.Float:
342 case XmlTypeCode.Double:
343 return new XPathAtomicValue (new DateTime ((long) (lvalue.ValueAsDateTime.Ticks / rvalue.ValueAsDouble)), rvalue.XmlType);
345 break;
348 throw new XmlQueryException (String.Format ("Not allowed arithmetic operation: {0} div {1}", lvalue.XmlType.QualifiedName, rvalue.XmlType.QualifiedName));
351 /// <summary>
352 /// x idiv y
353 /// </summary>
354 public static XPathAtomicValue IntDivide (XPathAtomicValue lvalue, XPathAtomicValue rvalue)
356 return new XPathAtomicValue (lvalue.ValueAsInt64 / rvalue.ValueAsInt64, InternalPool.XsInteger);
359 /// <summary>
360 /// x imod y
361 /// </summary>
362 public static XPathAtomicValue Remainder (XPathAtomicValue lvalue, XPathAtomicValue rvalue)
364 return new XPathAtomicValue (lvalue.ValueAsInt64 % rvalue.ValueAsInt64, InternalPool.XsInteger);
368 #endif