1 //------------------------------------------------------------------------------
2 // <copyright file="SqlInt32.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
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 //------------------------------------------------------------------------------
10 //**************************************************************************
15 // Purpose: Implementation of SqlInt32 which is equivalent to
16 // data type "int" in SQL Server
22 // 09/17/99 JunFang Created and implemented as first drop.
25 //**************************************************************************
28 using System.Data.Common;
29 using System.Runtime.InteropServices;
30 using System.Globalization;
32 using System.Xml.Schema;
33 using System.Xml.Serialization;
35 namespace System.Data.SqlTypes {
39 /// Represents a 32-bit signed integer to be stored in
40 /// or retrieved from a database.
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
50 private const long x_iIntMin = Int32.MinValue; // minimum (signed) int value
51 private const long x_lBitNotIntMax = ~(long)(Int32.MaxValue);
55 private SqlInt32(bool fNull) {
61 /// <para>[To be supplied.]</para>
63 public SqlInt32(int value) {
71 /// <para>[To be supplied.]</para>
74 get { return !m_fNotNull;}
79 /// <para>[To be supplied.]</para>
84 throw new SqlNullValueException();
90 // Implicit conversion from int to SqlInt32
92 /// <para>[To be supplied.]</para>
94 public static implicit operator SqlInt32(int x) {
95 return new SqlInt32(x);
98 // Explicit conversion from SqlInt32 to int. Throw exception if x is Null.
100 /// <para>[To be supplied.]</para>
102 public static explicit operator int(SqlInt32 x) {
107 /// <para>[To be supplied.]</para>
109 public override String ToString() {
110 return IsNull ? SQLResource.NullString : m_value.ToString((IFormatProvider)null);
114 /// <para>[To be supplied.]</para>
116 public static SqlInt32 Parse(String s) {
117 if (s == SQLResource.NullString)
118 return SqlInt32.Null;
120 return new SqlInt32(Int32.Parse(s, (IFormatProvider)null));
126 /// <para>[To be supplied.]</para>
128 public static SqlInt32 operator -(SqlInt32 x) {
129 return x.IsNull ? Null : new SqlInt32(-x.m_value);
133 /// <para>[To be supplied.]</para>
135 public static SqlInt32 operator ~(SqlInt32 x) {
136 return x.IsNull ? Null : new SqlInt32(~x.m_value);
142 // Arithmetic operators
144 /// <para>[To be supplied.]</para>
146 public static SqlInt32 operator +(SqlInt32 x, SqlInt32 y) {
147 if (x.IsNull || y.IsNull)
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);
154 return new SqlInt32(iResult);
158 /// <para>[To be supplied.]</para>
160 public static SqlInt32 operator -(SqlInt32 x, SqlInt32 y) {
161 if (x.IsNull || y.IsNull)
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);
168 return new SqlInt32(iResult);
172 /// <para>[To be supplied.]</para>
174 public static SqlInt32 operator *(SqlInt32 x, SqlInt32 y) {
175 if (x.IsNull || y.IsNull)
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);
183 return new SqlInt32((int)lResult);
187 /// <para>[To be supplied.]</para>
189 public static SqlInt32 operator /(SqlInt32 x, SqlInt32 y) {
190 if (x.IsNull || y.IsNull)
193 if (y.m_value != 0) {
194 if ((x.m_value == x_iIntMin) && (y.m_value == -1))
195 throw new OverflowException(SQLResource.ArithOverflowMessage);
197 return new SqlInt32(x.m_value / y.m_value);
200 throw new DivideByZeroException(SQLResource.DivideByZeroMessage);
204 /// <para>[To be supplied.]</para>
206 public static SqlInt32 operator %(SqlInt32 x, SqlInt32 y) {
207 if (x.IsNull || y.IsNull)
210 if (y.m_value != 0) {
211 if ((x.m_value == x_iIntMin) && (y.m_value == -1))
212 throw new OverflowException(SQLResource.ArithOverflowMessage);
214 return new SqlInt32(x.m_value % y.m_value);
217 throw new DivideByZeroException(SQLResource.DivideByZeroMessage);
222 /// <para>[To be supplied.]</para>
224 public static SqlInt32 operator &(SqlInt32 x, SqlInt32 y) {
225 return(x.IsNull || y.IsNull) ? Null : new SqlInt32(x.m_value & y.m_value);
229 /// <para>[To be supplied.]</para>
231 public static SqlInt32 operator |(SqlInt32 x, SqlInt32 y) {
232 return(x.IsNull || y.IsNull) ? Null : new SqlInt32(x.m_value | y.m_value);
236 /// <para>[To be supplied.]</para>
238 public static SqlInt32 operator ^(SqlInt32 x, SqlInt32 y) {
239 return(x.IsNull || y.IsNull) ? Null : new SqlInt32(x.m_value ^ y.m_value);
243 // Implicit conversions
245 // Implicit conversion from SqlBoolean to SqlInt32
247 /// <para>[To be supplied.]</para>
249 public static explicit operator SqlInt32(SqlBoolean x) {
250 return x.IsNull ? Null : new SqlInt32((int)x.ByteValue);
253 // Implicit conversion from SqlByte to SqlInt32
255 /// <para>[To be supplied.]</para>
257 public static implicit operator SqlInt32(SqlByte x) {
258 return x.IsNull ? Null : new SqlInt32(x.Value);
261 // Implicit conversion from SqlInt16 to SqlInt32
263 /// <para>[To be supplied.]</para>
265 public static implicit operator SqlInt32(SqlInt16 x) {
266 return x.IsNull ? Null : new SqlInt32(x.Value);
270 // Explicit conversions
272 // Explicit conversion from SqlInt64 to SqlInt32
274 /// <para>[To be supplied.]</para>
276 public static explicit operator SqlInt32(SqlInt64 x) {
280 long value = x.Value;
281 if (value > (long)Int32.MaxValue || value < (long)Int32.MinValue)
282 throw new OverflowException(SQLResource.ArithOverflowMessage);
284 return new SqlInt32((int)value);
287 // Explicit conversion from SqlSingle to SqlInt32
289 /// <para>[To be supplied.]</para>
291 public static explicit operator SqlInt32(SqlSingle x) {
295 float value = x.Value;
296 if (value > (float)Int32.MaxValue || value < (float)Int32.MinValue)
297 throw new OverflowException(SQLResource.ArithOverflowMessage);
299 return new SqlInt32((int)value);
302 // Explicit conversion from SqlDouble to SqlInt32
304 /// <para>[To be supplied.]</para>
306 public static explicit operator SqlInt32(SqlDouble x) {
310 double value = x.Value;
311 if (value > (double)Int32.MaxValue || value < (double)Int32.MinValue)
312 throw new OverflowException(SQLResource.ArithOverflowMessage);
314 return new SqlInt32((int)value);
317 // Explicit conversion from SqlMoney to SqlInt32
319 /// <para>[To be supplied.]</para>
321 public static explicit operator SqlInt32(SqlMoney x) {
322 return x.IsNull ? Null : new SqlInt32(x.ToInt32());
325 // Explicit conversion from SqlDecimal to SqlInt32
327 /// <para>[To be supplied.]</para>
329 public static explicit operator SqlInt32(SqlDecimal x) {
331 return SqlInt32.Null;
333 x.AdjustScale(-x.Scale, true);
335 long ret = (long)x.m_data1;
339 if (x.m_bLen > 1 || ret > (long)Int32.MaxValue || ret < (long)Int32.MinValue)
340 throw new OverflowException(SQLResource.ConversionOverflowMessage);
342 return new SqlInt32((int)ret);
345 // Explicit conversion from SqlString to SqlInt
346 // Throws FormatException or OverflowException if necessary.
348 /// <para>[To be supplied.]</para>
350 public static explicit operator SqlInt32(SqlString x) {
351 return x.IsNull ? SqlInt32.Null : new SqlInt32(Int32.Parse(x.Value, (IFormatProvider)null));
355 private static bool SameSignInt(int x, int y) {
356 return((x ^ y) & 0x80000000) == 0;
359 // Overloading comparison operators
361 /// <para>[To be supplied.]</para>
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);
368 /// <para>[To be supplied.]</para>
370 public static SqlBoolean operator!=(SqlInt32 x, SqlInt32 y) {
375 /// <para>[To be supplied.]</para>
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);
382 /// <para>[To be supplied.]</para>
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);
389 /// <para>[To be supplied.]</para>
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);
396 /// <para>[To be supplied.]</para>
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);
402 //--------------------------------------------------
403 // Alternative methods for overloaded operators
404 //--------------------------------------------------
406 // Alternative method for operator ~
407 public static SqlInt32 OnesComplement(SqlInt32 x) {
411 // Alternative method for operator +
412 public static SqlInt32 Add(SqlInt32 x, SqlInt32 y) {
415 // Alternative method for operator -
416 public static SqlInt32 Subtract(SqlInt32 x, SqlInt32 y) {
420 // Alternative method for operator *
421 public static SqlInt32 Multiply(SqlInt32 x, SqlInt32 y) {
425 // Alternative method for operator /
426 public static SqlInt32 Divide(SqlInt32 x, SqlInt32 y) {
430 // Alternative method for operator %
431 public static SqlInt32 Mod(SqlInt32 x, SqlInt32 y) {
435 public static SqlInt32 Modulus(SqlInt32 x, SqlInt32 y) {
439 // Alternative method for operator &
440 public static SqlInt32 BitwiseAnd(SqlInt32 x, SqlInt32 y) {
444 // Alternative method for operator |
445 public static SqlInt32 BitwiseOr(SqlInt32 x, SqlInt32 y) {
449 // Alternative method for operator ^
450 public static SqlInt32 Xor(SqlInt32 x, SqlInt32 y) {
454 // Alternative method for operator ==
455 public static SqlBoolean Equals(SqlInt32 x, SqlInt32 y) {
459 // Alternative method for operator !=
460 public static SqlBoolean NotEquals(SqlInt32 x, SqlInt32 y) {
464 // Alternative method for operator <
465 public static SqlBoolean LessThan(SqlInt32 x, SqlInt32 y) {
469 // Alternative method for operator >
470 public static SqlBoolean GreaterThan(SqlInt32 x, SqlInt32 y) {
474 // Alternative method for operator <=
475 public static SqlBoolean LessThanOrEqual(SqlInt32 x, SqlInt32 y) {
479 // Alternative method for operator >=
480 public static SqlBoolean GreaterThanOrEqual(SqlInt32 x, SqlInt32 y) {
484 // Alternative method for conversions.
486 public SqlBoolean ToSqlBoolean() {
487 return (SqlBoolean)this;
490 public SqlByte ToSqlByte() {
491 return (SqlByte)this;
494 public SqlDouble ToSqlDouble() {
495 return (SqlDouble)this;
498 public SqlInt16 ToSqlInt16() {
499 return (SqlInt16)this;
502 public SqlInt64 ToSqlInt64() {
503 return (SqlInt64)this;
506 public SqlMoney ToSqlMoney() {
507 return (SqlMoney)this;
510 public SqlDecimal ToSqlDecimal() {
511 return (SqlDecimal)this;
514 public SqlSingle ToSqlSingle() {
515 return (SqlSingle)this;
518 public SqlString ToSqlString() {
519 return (SqlString)this;
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.
532 /// <para>[To be supplied.]</para>
534 public int CompareTo(Object value) {
535 if (value is SqlInt32) {
536 SqlInt32 i = (SqlInt32)value;
540 throw ADP.WrongType(value.GetType(), typeof(SqlInt32));
543 public int CompareTo(SqlInt32 value) {
544 // If both Null, consider them equal.
545 // Otherwise, Null is less than anything.
547 return value.IsNull ? 0 : -1;
548 else if (value.IsNull)
551 if (this < value) return -1;
552 if (this > value) return 1;
556 // Compares this instance with a specified object
558 /// <para>[To be supplied.]</para>
560 public override bool Equals(Object value) {
561 if (!(value is SqlInt32)) {
565 SqlInt32 i = (SqlInt32)value;
567 if (i.IsNull || IsNull)
568 return (i.IsNull && IsNull);
570 return (this == i).Value;
573 // For hashing purpose
575 /// <para>[To be supplied.]</para>
577 public override int GetHashCode() {
578 return IsNull ? 0 : Value.GetHashCode();
582 /// <para>[To be supplied.]</para>
584 XmlSchema IXmlSerializable.GetSchema() { return null; }
587 /// <para>[To be supplied.]</para>
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();
597 m_value = XmlConvert.ToInt32(reader.ReadElementString());
603 /// <para>[To be supplied.]</para>
605 void IXmlSerializable.WriteXml(XmlWriter writer) {
607 writer.WriteAttributeString("xsi", "nil", XmlSchema.InstanceNamespace, "true");
610 writer.WriteString(XmlConvert.ToString(m_value));
615 /// <para>[To be supplied.]</para>
617 public static XmlQualifiedName GetXsdType(XmlSchemaSet schemaSet) {
618 return new XmlQualifiedName("int", XmlSchema.Namespace);
622 /// <para>[To be supplied.]</para>
624 public static readonly SqlInt32 Null = new SqlInt32(true);
626 /// <para>[To be supplied.]</para>
628 public static readonly SqlInt32 Zero = new SqlInt32(0);
630 /// <para>[To be supplied.]</para>
632 public static readonly SqlInt32 MinValue = new SqlInt32(Int32.MinValue);
634 /// <para>[To be supplied.]</para>
636 public static readonly SqlInt32 MaxValue = new SqlInt32(Int32.MaxValue);
640 } // namespace System.Data.SqlTypes