Example #1
0
        // Convert from TimeSpan, rounded to one three-hundredth second, due to loss of precision
        private static SqlDateTime FromTimeSpan(TimeSpan value)
        {
            if (value < MinTimeSpan || value > MaxTimeSpan)
            {
                throw new SqlTypeException(SQLResource.DateTimeOverflowMessage);
            }

            int day = value.Days;

            long ticks = value.Ticks - day * TimeSpan.TicksPerDay;

            if (ticks < 0L)
            {
                day--;
                ticks += TimeSpan.TicksPerDay;
            }

            int time = (int)((double)ticks / TimeSpan.TicksPerMillisecond * SQLTicksPerMillisecond + 0.5);

            if (time > MaxTime)
            {
                // Only rounding up could cause time to become greater than MaxTime.
                SQLDebug.Check(time == MaxTime + 1);

                // Make time to be zero, and increment day.
                time = 0;
                day++;
            }

            return(new SqlDateTime(day, time));
        }
Example #2
0
        // Hash a byte array.
        // Trailing zeroes/spaces would affect the hash value, so caller needs to
        // perform trimming as necessary.
        internal static int HashByteArray(byte[] rgbValue, int length)
        {
            SQLDebug.Check(length >= 0);

            if (length <= 0)
            {
                return(0);
            }

            SQLDebug.Check(rgbValue.Length >= length);

            int ulValue = 0;
            int ulHi;

            // Size of CRC window (hashing bytes, ssstr, sswstr, numeric)
            const int x_cbCrcWindow = 4;
            // const int iShiftVal = (sizeof ulValue) * (8*sizeof(char)) - x_cbCrcWindow;
            const int iShiftVal = 4 * 8 - x_cbCrcWindow;

            for (int i = 0; i < length; i++)
            {
                ulHi      = (ulValue >> iShiftVal) & 0xff;
                ulValue <<= x_cbCrcWindow;
                ulValue   = ulValue ^ rgbValue[i] ^ ulHi;
            }

            return(ulValue);
        }
Example #3
0
 private void SetCompareInfo()
 {
     SQLDebug.Check(!IsNull);
     if (m_cmpInfo == null)
     {
         m_cmpInfo = (CultureInfo.GetCultureInfo(m_lcid)).CompareInfo;
     }
 }
        // Builtin functions


        // utility functions
        private static void AssertValidSqlDateTime(SqlDateTime x)
        {
            SQLDebug.Check(!x.IsNull, "!x.IsNull", "Datetime: Null");
            SQLDebug.Check(x.m_day >= MinDay && x.m_day <= MaxDay, "day >= MinDay && day <= MaxDay",
                           "DateTime: Day out of range");
            SQLDebug.Check(x.m_time >= MinTime && x.m_time <= MaxTime, "time >= MinTime && time <= MaxTime",
                           "DateTime: Time out of range");
        }
Example #5
0
        //    Wide-character string comparison for Binary Unicode Collation
        //    Return values:
        //        -1 : wstr1 < wstr2
        //        0  : wstr1 = wstr2
        //        1  : wstr1 > wstr2
        //
        //    Does a memory comparison.
        private static int CompareBinary(SqlString x, SqlString y)
        {
            byte[] rgDataX = x_UnicodeEncoding.GetBytes(x.m_value);
            byte[] rgDataY = x_UnicodeEncoding.GetBytes(y.m_value);
            int    cbX     = rgDataX.Length;
            int    cbY     = rgDataY.Length;
            int    cbMin   = cbX < cbY ? cbX : cbY;
            int    i;

            SQLDebug.Check(cbX % 2 == 0);
            SQLDebug.Check(cbY % 2 == 0);

            for (i = 0; i < cbMin; i++)
            {
                if (rgDataX[i] < rgDataY[i])
                {
                    return(-1);
                }
                else if (rgDataX[i] > rgDataY[i])
                {
                    return(1);
                }
            }

            i = cbMin;

            int iCh;
            int iSpace = (int)' ';

            if (cbX < cbY)
            {
                for (; i < cbY; i += 2)
                {
                    iCh = ((int)rgDataY[i + 1]) << 8 + rgDataY[i];
                    if (iCh != iSpace)
                    {
                        return((iSpace > iCh) ? 1 : -1);
                    }
                }
            }
            else
            {
                for (; i < cbX; i += 2)
                {
                    iCh = ((int)rgDataX[i + 1]) << 8 + rgDataX[i];
                    if (iCh != iSpace)
                    {
                        return((iCh > iSpace) ? 1 : -1);
                    }
                }
            }

            return(0);
        }
Example #6
0
        // StringCompare: Common compare function which is used by Compare and CompareTo
        //  In the case of Compare (used by comparison operators) the int result needs to be converted to SqlBoolean type
        //  while CompareTo needs the result in int type
        //  Pre-requisite: the null condition of the both string needs to be checked and handled by the caller of this function
        private static int StringCompare(SqlString x, SqlString y)
        {
            SQLDebug.Check(!x.IsNull && !y.IsNull,
                           "!x.IsNull && !y.IsNull", "Null condition should be handled by the caller of StringCompare method");

            if (x.m_lcid != y.m_lcid || x.m_flag != y.m_flag)
            {
                throw new SqlTypeException(SQLResource.CompareDiffCollationMessage);
            }

            x.SetCompareInfo();
            y.SetCompareInfo();
            SQLDebug.Check(x.FBinarySort() || (x.m_cmpInfo != null && y.m_cmpInfo != null),
                           "x.FBinarySort() || (x.m_cmpInfo != null && y.m_cmpInfo != null)", "");

            int iCmpResult;

            if ((x.m_flag & SqlCompareOptions.BinarySort) != 0)
            {
                iCmpResult = CompareBinary(x, y);
            }
            else if ((x.m_flag & SqlCompareOptions.BinarySort2) != 0)
            {
                iCmpResult = CompareBinary2(x, y);
            }
            else
            {
                // SqlString can be padded with spaces (Padding is turn on by default in SQL Server 2008
                // Trim the trailing space for comparison
                //  Avoid using String.TrimEnd function to avoid extra string allocations

                string rgchX = x.m_value;
                string rgchY = y.m_value;
                int    cwchX = rgchX.Length;
                int    cwchY = rgchY.Length;

                while (cwchX > 0 && rgchX[cwchX - 1] == ' ')
                {
                    cwchX--;
                }
                while (cwchY > 0 && rgchY[cwchY - 1] == ' ')
                {
                    cwchY--;
                }

                CompareOptions options = CompareOptionsFromSqlCompareOptions(x.m_flag);

                iCmpResult = x.m_cmpInfo.Compare(x.m_value, 0, cwchX, y.m_value, 0, cwchY, options);
            }

            return(iCmpResult);
        }
Example #7
0
        //    Wide-character string comparison for Binary2 Unicode Collation
        //    Return values:
        //        -1 : wstr1 < wstr2
        //        0  : wstr1 = wstr2
        //        1  : wstr1 > wstr2
        //
        //    Does a wchar comparison (different from memcmp of BinarySort).
        private static int CompareBinary2(SqlString x, SqlString y)
        {
            SQLDebug.Check(!x.IsNull && !y.IsNull);

            string rgDataX = x.m_value;
            string rgDataY = y.m_value;
            int    cwchX   = rgDataX.Length;
            int    cwchY   = rgDataY.Length;
            int    cwchMin = cwchX < cwchY ? cwchX : cwchY;
            int    i;

            for (i = 0; i < cwchMin; i++)
            {
                if (rgDataX[i] < rgDataY[i])
                {
                    return(-1);
                }
                else if (rgDataX[i] > rgDataY[i])
                {
                    return(1);
                }
            }

            // If compares equal up to one of the string terminates,
            // pad it with spaces and compare with the rest of the other one.
            //
            char chSpace = ' ';

            if (cwchX < cwchY)
            {
                for (i = cwchMin; i < cwchY; i++)
                {
                    if (rgDataY[i] != chSpace)
                    {
                        return((chSpace > rgDataY[i]) ? 1 : -1);
                    }
                }
            }
            else
            {
                for (i = cwchMin; i < cwchX; i++)
                {
                    if (rgDataX[i] != chSpace)
                    {
                        return((rgDataX[i] > chSpace) ? 1 : -1);
                    }
                }
            }

            return(0);
        }
Example #8
0
        // Unary operators

        /// <devdoc>
        ///    <para>
        ///       Performs a NOT operation on a <see cref='System.Data.SqlTypes.SqlBoolean'/>
        ///       .
        ///    </para>
        /// </devdoc>
        public static SqlBoolean operator !(SqlBoolean x)
        {
            switch (x.m_value)
            {
            case x_True:
                return(SqlBoolean.False);

            case x_False:
                return(SqlBoolean.True);

            default:
                SQLDebug.Check(x.m_value == x_Null);
                return(SqlBoolean.Null);
            }
        }
Example #9
0
        // Comparison operators
        private static SqlBoolean Compare(SqlString x, SqlString y, EComparison ecExpectedResult)
        {
            if (x.IsNull || y.IsNull)
            {
                return(SqlBoolean.Null);
            }

            int iCmpResult = StringCompare(x, y);

            bool fResult = false;

            switch (ecExpectedResult)
            {
            case EComparison.EQ:
                fResult = (iCmpResult == 0);
                break;

            case EComparison.LT:
                fResult = (iCmpResult < 0);
                break;

            case EComparison.LE:
                fResult = (iCmpResult <= 0);
                break;

            case EComparison.GT:
                fResult = (iCmpResult > 0);
                break;

            case EComparison.GE:
                fResult = (iCmpResult >= 0);
                break;

            default:
                SQLDebug.Check(false, "Invalid ecExpectedResult");
                return(SqlBoolean.Null);
            }

            return(new SqlBoolean(fResult));
        }
Example #10
0
        public SqlDateTime(int year, int month, int day, int hour, int minute, int second, double millisecond)
        {
            if (year >= MinYear && year <= MaxYear && month >= 1 && month <= 12)
            {
                int[] days = IsLeapYear(year)? DaysToMonth366: DaysToMonth365;
                if (day >= 1 && day <= days[month] - days[month - 1])
                {
                    int y        = year - 1;
                    int dayticks = y * 365 + y / 4 - y / 100 + y / 400 + days[month - 1] + day - 1;
                    dayticks -= DayBase;

                    if (dayticks >= MinDay && dayticks <= MaxDay &&
                        hour >= 0 && hour < 24 && minute >= 0 && minute < 60 &&
                        second >= 0 && second < 60 && millisecond >= 0 && millisecond < 1000.0)
                    {
                        double ticksForMilisecond = millisecond * SQLTicksPerMillisecond + 0.5;
                        int    timeticks          = hour * SQLTicksPerHour + minute * SQLTicksPerMinute + second * SQLTicksPerSecond +
                                                    (int)ticksForMilisecond;

                        if (timeticks > MaxTime)
                        {
                            // Only rounding up could cause time to become greater than MaxTime.
                            SQLDebug.Check(timeticks == MaxTime + 1);

                            // Make time to be zero, and increment day.
                            timeticks = 0;
                            dayticks++;
                        }

                        // Success. Call ctor here which will again check dayticks and timeticks are within range.
                        // All other cases will throw exception below.
                        this = new SqlDateTime(dayticks, timeticks);
                        return;
                    }
                }
            }

            throw new SqlTypeException(SQLResource.InvalidDateTimeMessage);
        }
Example #11
0
        /// <include file='doc\SQLInt64.uex' path='docs/doc[@for="SqlInt64.operator*"]/*' />
        /// <devdoc>
        ///    <para>[To be supplied.]</para>
        /// </devdoc>
        public static SqlInt64 operator *(SqlInt64 x, SqlInt64 y)
        {
            if (x.IsNull || y.IsNull)
            {
                return(Null);
            }

            bool fNeg = false;

            long lOp1 = x.m_value;
            long lOp2 = y.m_value;
            long lResult;
            long lPartialResult = 0;

            if (lOp1 < 0)
            {
                fNeg = true;
                lOp1 = -lOp1;
            }

            if (lOp2 < 0)
            {
                fNeg = !fNeg;
                lOp2 = -lOp2;
            }

            long lLow1  = lOp1 & x_lLowIntMask;
            long lHigh1 = (lOp1 >> 32) & x_lLowIntMask;
            long lLow2  = lOp2 & x_lLowIntMask;
            long lHigh2 = (lOp2 >> 32) & x_lLowIntMask;

            // if both of the high order dwords are non-zero then overflow results
            if (lHigh1 != 0 && lHigh2 != 0)
            {
                throw new OverflowException(SQLResource.ArithOverflowMessage);
            }

            lResult = lLow1 * lLow2;

            if (lResult < 0)
            {
                throw new OverflowException(SQLResource.ArithOverflowMessage);
            }

            if (lHigh1 != 0)
            {
                SQLDebug.Check(lHigh2 == 0);
                lPartialResult = lHigh1 * lLow2;
                if (lPartialResult < 0 || lPartialResult > Int64.MaxValue)
                {
                    throw new OverflowException(SQLResource.ArithOverflowMessage);
                }
            }
            else if (lHigh2 != 0)
            {
                SQLDebug.Check(lHigh1 == 0);
                lPartialResult = lLow1 * lHigh2;
                if (lPartialResult < 0 || lPartialResult > Int64.MaxValue)
                {
                    throw new OverflowException(SQLResource.ArithOverflowMessage);
                }
            }

            lResult += lPartialResult << 32;
            if (lResult < 0)
            {
                throw new OverflowException(SQLResource.ArithOverflowMessage);
            }

            if (fNeg)
            {
                lResult = -lResult;
            }

            return(new SqlInt64(lResult));
        }