Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.Data / System / Data / SQLTypes / SQLInt32.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="SqlInt32.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 //  </copyright>
5 // <owner current="true" primary="true">junfang</owner>
6 // <owner current="true" primary="false">Microsoft</owner>
7 // <owner current="true" primary="false">Microsoft</owner>
8 //------------------------------------------------------------------------------
9
10 //**************************************************************************
11 // @File: SqlInt32.cs
12 //
13 // Create by:    JunFang
14 //
15 // Purpose: Implementation of SqlInt32 which is equivalent to
16 //            data type "int" in SQL Server
17 //
18 // Notes:
19 //
20 // History:
21 //
22 //   09/17/99  JunFang    Created and implemented as first drop.
23 //
24 // @EndHeader@
25 //**************************************************************************
26
27 using System;
28 using System.Data.Common;
29 using System.Runtime.InteropServices;
30 using System.Globalization;
31 using System.Xml;
32 using System.Xml.Schema;
33 using System.Xml.Serialization;
34
35 namespace System.Data.SqlTypes {
36
37     /// <devdoc>
38     ///    <para>
39     ///       Represents a 32-bit signed integer to be stored in
40     ///       or retrieved from a database.
41     ///    </para>
42     /// </devdoc>
43     [Serializable]
44     [StructLayout(LayoutKind.Sequential)]
45     [XmlSchemaProvider("GetXsdType")]
46     public struct SqlInt32 : INullable, IComparable, IXmlSerializable {
47         private bool m_fNotNull; // false if null, the default ctor (plain 0) will make it Null
48         private int m_value;
49
50         private const long x_iIntMin          = Int32.MinValue;   // minimum (signed) int value
51         private const long x_lBitNotIntMax    = ~(long)(Int32.MaxValue);
52
53         // constructor
54         // construct a Null
55         private SqlInt32(bool fNull) {
56             m_fNotNull = false;
57             m_value = 0;
58         }
59
60         /// <devdoc>
61         ///    <para>[To be supplied.]</para>
62         /// </devdoc>
63         public SqlInt32(int value) {
64             m_value = value;
65             m_fNotNull = true;
66         }
67
68
69         // INullable
70         /// <devdoc>
71         ///    <para>[To be supplied.]</para>
72         /// </devdoc>
73         public bool IsNull {
74             get { return !m_fNotNull;}
75         }
76
77         // property: Value
78         /// <devdoc>
79         ///    <para>[To be supplied.]</para>
80         /// </devdoc>
81         public int Value {
82             get {
83                 if (IsNull)
84                     throw new SqlNullValueException();
85                 else
86                     return m_value;
87             }
88         }
89
90         // Implicit conversion from int to SqlInt32
91         /// <devdoc>
92         ///    <para>[To be supplied.]</para>
93         /// </devdoc>
94         public static implicit operator SqlInt32(int x) {
95             return new SqlInt32(x);
96         }
97
98         // Explicit conversion from SqlInt32 to int. Throw exception if x is Null.
99         /// <devdoc>
100         ///    <para>[To be supplied.]</para>
101         /// </devdoc>
102         public static explicit operator int(SqlInt32 x) {
103             return x.Value;
104         }
105
106         /// <devdoc>
107         ///    <para>[To be supplied.]</para>
108         /// </devdoc>
109         public override String ToString() {
110             return IsNull ? SQLResource.NullString : m_value.ToString((IFormatProvider)null);
111         }
112
113         /// <devdoc>
114         ///    <para>[To be supplied.]</para>
115         /// </devdoc>
116         public static SqlInt32 Parse(String s) {
117             if (s == SQLResource.NullString)
118                 return SqlInt32.Null;
119             else 
120                 return new SqlInt32(Int32.Parse(s, (IFormatProvider)null));
121         }
122
123
124         // Unary operators
125         /// <devdoc>
126         ///    <para>[To be supplied.]</para>
127         /// </devdoc>
128         public static SqlInt32 operator -(SqlInt32 x) {
129             return x.IsNull ? Null : new SqlInt32(-x.m_value);
130         }
131
132         /// <devdoc>
133         ///    <para>[To be supplied.]</para>
134         /// </devdoc>
135         public static SqlInt32 operator ~(SqlInt32 x) {
136             return x.IsNull ? Null : new SqlInt32(~x.m_value);
137         }
138
139
140         // Binary operators
141
142         // Arithmetic operators
143         /// <devdoc>
144         ///    <para>[To be supplied.]</para>
145         /// </devdoc>
146         public static SqlInt32 operator +(SqlInt32 x, SqlInt32 y) {
147             if (x.IsNull || y.IsNull)
148                 return Null;
149
150             int iResult = x.m_value + y.m_value;
151             if (SameSignInt(x.m_value, y.m_value) && !SameSignInt(x.m_value, iResult))
152                 throw new OverflowException(SQLResource.ArithOverflowMessage);
153             else
154                 return new SqlInt32(iResult);
155         }
156
157         /// <devdoc>
158         ///    <para>[To be supplied.]</para>
159         /// </devdoc>
160         public static SqlInt32 operator -(SqlInt32 x, SqlInt32 y) {
161             if (x.IsNull || y.IsNull)
162                 return Null;
163
164             int iResult = x.m_value - y.m_value;
165             if (!SameSignInt(x.m_value, y.m_value) && SameSignInt(y.m_value, iResult))
166                 throw new OverflowException(SQLResource.ArithOverflowMessage);
167             else
168                 return new SqlInt32(iResult);
169         }
170
171         /// <devdoc>
172         ///    <para>[To be supplied.]</para>
173         /// </devdoc>
174         public static SqlInt32 operator *(SqlInt32 x, SqlInt32 y) {
175             if (x.IsNull || y.IsNull)
176                 return Null;
177
178             long lResult = (long)x.m_value * (long)y.m_value;
179             long lTemp = lResult & x_lBitNotIntMax;
180             if (lTemp != 0 && lTemp != x_lBitNotIntMax)
181                 throw new OverflowException(SQLResource.ArithOverflowMessage);
182             else
183                 return new SqlInt32((int)lResult);
184         }
185
186         /// <devdoc>
187         ///    <para>[To be supplied.]</para>
188         /// </devdoc>
189         public static SqlInt32 operator /(SqlInt32 x, SqlInt32 y) {
190             if (x.IsNull || y.IsNull)
191                 return Null;
192
193             if (y.m_value != 0) {
194                 if ((x.m_value == x_iIntMin) && (y.m_value == -1))
195                     throw new OverflowException(SQLResource.ArithOverflowMessage);
196
197                 return new SqlInt32(x.m_value / y.m_value);
198             }
199             else
200                 throw new DivideByZeroException(SQLResource.DivideByZeroMessage);
201         }
202
203         /// <devdoc>
204         ///    <para>[To be supplied.]</para>
205         /// </devdoc>
206         public static SqlInt32 operator %(SqlInt32 x, SqlInt32 y) {
207             if (x.IsNull || y.IsNull)
208                 return Null;
209
210             if (y.m_value != 0) {
211                 if ((x.m_value == x_iIntMin) && (y.m_value == -1))
212                     throw new OverflowException(SQLResource.ArithOverflowMessage);
213
214                 return new SqlInt32(x.m_value % y.m_value);
215             }
216             else
217                 throw new DivideByZeroException(SQLResource.DivideByZeroMessage);
218         }
219
220         // Bitwise operators
221         /// <devdoc>
222         ///    <para>[To be supplied.]</para>
223         /// </devdoc>
224         public static SqlInt32 operator &(SqlInt32 x, SqlInt32 y) {
225             return(x.IsNull || y.IsNull) ? Null : new SqlInt32(x.m_value & y.m_value);
226         }
227
228         /// <devdoc>
229         ///    <para>[To be supplied.]</para>
230         /// </devdoc>
231         public static SqlInt32 operator |(SqlInt32 x, SqlInt32 y) {
232             return(x.IsNull || y.IsNull) ? Null : new SqlInt32(x.m_value | y.m_value);
233         }
234
235         /// <devdoc>
236         ///    <para>[To be supplied.]</para>
237         /// </devdoc>
238         public static SqlInt32 operator ^(SqlInt32 x, SqlInt32 y) {
239             return(x.IsNull || y.IsNull) ? Null : new SqlInt32(x.m_value ^ y.m_value);
240         }
241
242
243         // Implicit conversions
244
245         // Implicit conversion from SqlBoolean to SqlInt32
246         /// <devdoc>
247         ///    <para>[To be supplied.]</para>
248         /// </devdoc>
249         public static explicit operator SqlInt32(SqlBoolean x) {
250             return x.IsNull ? Null : new SqlInt32((int)x.ByteValue);
251         }
252
253         // Implicit conversion from SqlByte to SqlInt32
254         /// <devdoc>
255         ///    <para>[To be supplied.]</para>
256         /// </devdoc>
257         public static implicit operator SqlInt32(SqlByte x) {
258             return x.IsNull ? Null : new SqlInt32(x.Value);
259         }
260
261         // Implicit conversion from SqlInt16 to SqlInt32
262         /// <devdoc>
263         ///    <para>[To be supplied.]</para>
264         /// </devdoc>
265         public static implicit operator SqlInt32(SqlInt16 x) {
266             return x.IsNull ? Null : new SqlInt32(x.Value);
267         }
268
269
270         // Explicit conversions
271
272         // Explicit conversion from SqlInt64 to SqlInt32
273         /// <devdoc>
274         ///    <para>[To be supplied.]</para>
275         /// </devdoc>
276         public static explicit operator SqlInt32(SqlInt64 x) {
277             if (x.IsNull)
278                 return Null;
279
280             long value = x.Value;
281             if (value > (long)Int32.MaxValue || value < (long)Int32.MinValue)
282                 throw new OverflowException(SQLResource.ArithOverflowMessage);
283             else
284                 return new SqlInt32((int)value);
285         }
286
287         // Explicit conversion from SqlSingle to SqlInt32
288         /// <devdoc>
289         ///    <para>[To be supplied.]</para>
290         /// </devdoc>
291         public static explicit operator SqlInt32(SqlSingle x) {
292             if (x.IsNull)
293                 return Null;
294
295             float value = x.Value;
296             if (value > (float)Int32.MaxValue || value < (float)Int32.MinValue)
297                 throw new OverflowException(SQLResource.ArithOverflowMessage);
298             else
299                 return new SqlInt32((int)value);
300         }
301
302         // Explicit conversion from SqlDouble to SqlInt32
303         /// <devdoc>
304         ///    <para>[To be supplied.]</para>
305         /// </devdoc>
306         public static explicit operator SqlInt32(SqlDouble x) {
307             if (x.IsNull)
308                 return Null;
309
310             double value = x.Value;
311             if (value > (double)Int32.MaxValue || value < (double)Int32.MinValue)
312                 throw new OverflowException(SQLResource.ArithOverflowMessage);
313             else
314                 return new SqlInt32((int)value);
315         }
316
317         // Explicit conversion from SqlMoney to SqlInt32
318         /// <devdoc>
319         ///    <para>[To be supplied.]</para>
320         /// </devdoc>
321         public static explicit operator SqlInt32(SqlMoney x) {
322             return x.IsNull ? Null : new SqlInt32(x.ToInt32());
323         }
324
325         // Explicit conversion from SqlDecimal to SqlInt32
326         /// <devdoc>
327         ///    <para>[To be supplied.]</para>
328         /// </devdoc>
329         public static explicit operator SqlInt32(SqlDecimal x) {
330             if (x.IsNull)
331                 return SqlInt32.Null;
332
333             x.AdjustScale(-x.Scale, true);
334
335             long ret = (long)x.m_data1;
336             if (!x.IsPositive)
337                 ret = - ret;
338
339             if (x.m_bLen > 1 || ret > (long)Int32.MaxValue || ret < (long)Int32.MinValue)
340                 throw new OverflowException(SQLResource.ConversionOverflowMessage);
341
342             return new SqlInt32((int)ret);
343         }
344
345         // Explicit conversion from SqlString to SqlInt
346         // Throws FormatException or OverflowException if necessary.
347         /// <devdoc>
348         ///    <para>[To be supplied.]</para>
349         /// </devdoc>
350         public static explicit operator SqlInt32(SqlString x) {
351             return x.IsNull ? SqlInt32.Null : new SqlInt32(Int32.Parse(x.Value, (IFormatProvider)null));
352         }
353
354         // Utility functions
355         private static bool SameSignInt(int x, int y) {
356             return((x ^ y) & 0x80000000) == 0;
357         }
358
359         // Overloading comparison operators
360         /// <devdoc>
361         ///    <para>[To be supplied.]</para>
362         /// </devdoc>
363         public static SqlBoolean operator==(SqlInt32 x, SqlInt32 y) {
364             return(x.IsNull || y.IsNull) ? SqlBoolean.Null : new SqlBoolean(x.m_value == y.m_value);
365         }
366
367         /// <devdoc>
368         ///    <para>[To be supplied.]</para>
369         /// </devdoc>
370         public static SqlBoolean operator!=(SqlInt32 x, SqlInt32 y) {
371             return ! (x == y);
372         }
373
374         /// <devdoc>
375         ///    <para>[To be supplied.]</para>
376         /// </devdoc>
377         public static SqlBoolean operator<(SqlInt32 x, SqlInt32 y) {
378             return(x.IsNull || y.IsNull) ? SqlBoolean.Null : new SqlBoolean(x.m_value < y.m_value);
379         }
380
381         /// <devdoc>
382         ///    <para>[To be supplied.]</para>
383         /// </devdoc>
384         public static SqlBoolean operator>(SqlInt32 x, SqlInt32 y) {
385             return(x.IsNull || y.IsNull) ? SqlBoolean.Null : new SqlBoolean(x.m_value > y.m_value);
386         }
387
388         /// <devdoc>
389         ///    <para>[To be supplied.]</para>
390         /// </devdoc>
391         public static SqlBoolean operator<=(SqlInt32 x, SqlInt32 y) {
392             return(x.IsNull || y.IsNull) ? SqlBoolean.Null : new SqlBoolean(x.m_value <= y.m_value);
393         }
394
395         /// <devdoc>
396         ///    <para>[To be supplied.]</para>
397         /// </devdoc>
398         public static SqlBoolean operator>=(SqlInt32 x, SqlInt32 y) {
399             return(x.IsNull || y.IsNull) ? SqlBoolean.Null : new SqlBoolean(x.m_value >= y.m_value);
400         }
401
402         //--------------------------------------------------
403         // Alternative methods for overloaded operators
404         //--------------------------------------------------
405
406         // Alternative method for operator ~
407         public static SqlInt32 OnesComplement(SqlInt32 x) {
408             return ~x;
409         }
410
411         // Alternative method for operator +
412         public static SqlInt32 Add(SqlInt32 x, SqlInt32 y) {
413             return x + y;
414         }
415         // Alternative method for operator -
416         public static SqlInt32 Subtract(SqlInt32 x, SqlInt32 y) {
417             return x - y;
418         }
419
420         // Alternative method for operator *
421         public static SqlInt32 Multiply(SqlInt32 x, SqlInt32 y) {
422             return x * y;
423         }
424
425         // Alternative method for operator /
426         public static SqlInt32 Divide(SqlInt32 x, SqlInt32 y) {
427             return x / y;
428         }
429
430         // Alternative method for operator %
431         public static SqlInt32 Mod(SqlInt32 x, SqlInt32 y) {
432             return x % y;
433         }
434
435         public static SqlInt32 Modulus(SqlInt32 x, SqlInt32 y) {
436             return x % y;
437         }
438         
439         // Alternative method for operator &
440         public static SqlInt32 BitwiseAnd(SqlInt32 x, SqlInt32 y) {
441             return x & y;
442         }
443
444         // Alternative method for operator |
445         public static SqlInt32 BitwiseOr(SqlInt32 x, SqlInt32 y) {
446             return x | y;
447         }
448
449         // Alternative method for operator ^
450         public static SqlInt32 Xor(SqlInt32 x, SqlInt32 y) {
451             return x ^ y;
452         }
453
454         // Alternative method for operator ==
455         public static SqlBoolean Equals(SqlInt32 x, SqlInt32 y) {
456             return (x == y);
457         }
458
459         // Alternative method for operator !=
460         public static SqlBoolean NotEquals(SqlInt32 x, SqlInt32 y) {
461             return (x != y);
462         }
463
464         // Alternative method for operator <
465         public static SqlBoolean LessThan(SqlInt32 x, SqlInt32 y) {
466             return (x < y);
467         }
468
469         // Alternative method for operator >
470         public static SqlBoolean GreaterThan(SqlInt32 x, SqlInt32 y) {
471             return (x > y);
472         }
473
474         // Alternative method for operator <=
475         public static SqlBoolean LessThanOrEqual(SqlInt32 x, SqlInt32 y) {
476             return (x <= y);
477         }
478
479         // Alternative method for operator >=
480         public static SqlBoolean GreaterThanOrEqual(SqlInt32 x, SqlInt32 y) {
481             return (x >= y);
482         }
483
484         // Alternative method for conversions.
485
486         public SqlBoolean ToSqlBoolean() {
487             return (SqlBoolean)this;
488         }
489
490         public SqlByte ToSqlByte() {
491             return (SqlByte)this;
492         }
493
494         public SqlDouble ToSqlDouble() {
495             return (SqlDouble)this;
496         }
497
498         public SqlInt16 ToSqlInt16() {
499             return (SqlInt16)this;
500         }
501
502         public SqlInt64 ToSqlInt64() {
503             return (SqlInt64)this;
504         }
505
506         public SqlMoney ToSqlMoney() {
507             return (SqlMoney)this;
508         }
509
510         public SqlDecimal ToSqlDecimal() {
511             return (SqlDecimal)this;
512         }
513
514         public SqlSingle ToSqlSingle() {
515             return (SqlSingle)this;
516         }
517
518         public SqlString ToSqlString() {
519             return (SqlString)this;
520         }
521
522
523
524         // IComparable
525         // Compares this object to another object, returning an integer that
526         // indicates the relationship.
527         // Returns a value less than zero if this < object, zero if this = object,
528         // or a value greater than zero if this > object.
529         // null is considered to be less than any instance.
530         // If object is not of same type, this method throws an ArgumentException.
531         /// <devdoc>
532         ///    <para>[To be supplied.]</para>
533         /// </devdoc>
534         public int CompareTo(Object value) {
535             if (value is SqlInt32) {
536                 SqlInt32 i = (SqlInt32)value;
537
538                 return CompareTo(i);
539             }
540             throw ADP.WrongType(value.GetType(), typeof(SqlInt32));
541         }
542
543         public int CompareTo(SqlInt32 value) {
544             // If both Null, consider them equal.
545             // Otherwise, Null is less than anything.
546             if (IsNull)
547                 return value.IsNull ? 0  : -1;
548             else if (value.IsNull)
549                 return 1;
550
551             if (this < value) return -1;
552             if (this > value) return 1;
553             return 0;
554         }
555
556         // Compares this instance with a specified object
557         /// <devdoc>
558         ///    <para>[To be supplied.]</para>
559         /// </devdoc>
560         public override bool Equals(Object value) {
561             if (!(value is SqlInt32)) {
562                 return false;
563             }
564
565             SqlInt32 i = (SqlInt32)value;
566
567             if (i.IsNull || IsNull)
568                 return (i.IsNull && IsNull);
569             else
570                 return (this == i).Value;
571         }
572
573         // For hashing purpose
574         /// <devdoc>
575         ///    <para>[To be supplied.]</para>
576         /// </devdoc>
577         public override int GetHashCode() {
578             return IsNull ? 0 : Value.GetHashCode();
579         }
580
581         /// <devdoc>
582         ///    <para>[To be supplied.]</para>
583         /// </devdoc>
584         XmlSchema IXmlSerializable.GetSchema() { return null; }
585
586         /// <devdoc>
587         ///    <para>[To be supplied.]</para>
588         /// </devdoc>
589         void IXmlSerializable.ReadXml(XmlReader reader) {
590             string isNull = reader.GetAttribute("nil", XmlSchema.InstanceNamespace);
591             if (isNull != null && XmlConvert.ToBoolean(isNull)) {
592                 // VSTFDevDiv# 479603 - SqlTypes read null value infinitely and never read the next value. Fix - Read the next value.
593                 reader.ReadElementString();
594                 m_fNotNull = false;
595             }
596             else {
597                 m_value = XmlConvert.ToInt32(reader.ReadElementString());
598                 m_fNotNull = true;
599             }
600         }
601
602         /// <devdoc>
603         ///    <para>[To be supplied.]</para>
604         /// </devdoc>
605         void IXmlSerializable.WriteXml(XmlWriter writer) {
606             if (IsNull) {
607                 writer.WriteAttributeString("xsi", "nil", XmlSchema.InstanceNamespace, "true");
608             }
609             else {
610                 writer.WriteString(XmlConvert.ToString(m_value));
611             }
612         }
613
614         /// <devdoc>
615         ///    <para>[To be supplied.]</para>
616         /// </devdoc>
617         public static XmlQualifiedName GetXsdType(XmlSchemaSet schemaSet) {
618             return new XmlQualifiedName("int", XmlSchema.Namespace);
619         }
620
621         /// <devdoc>
622         ///    <para>[To be supplied.]</para>
623         /// </devdoc>
624         public static readonly SqlInt32 Null        = new SqlInt32(true);
625         /// <devdoc>
626         ///    <para>[To be supplied.]</para>
627         /// </devdoc>
628         public static readonly SqlInt32 Zero        = new SqlInt32(0);
629         /// <devdoc>
630         ///    <para>[To be supplied.]</para>
631         /// </devdoc>
632         public static readonly SqlInt32 MinValue    = new SqlInt32(Int32.MinValue);
633         /// <devdoc>
634         ///    <para>[To be supplied.]</para>
635         /// </devdoc>
636         public static readonly SqlInt32 MaxValue    = new SqlInt32(Int32.MaxValue);
637
638     } // SqlInt32
639
640 } // namespace System.Data.SqlTypes
641