Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DataEntity / System / Data / Common / EntitySql / Literal.cs / 2 / Literal.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] [....] //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql { using System; using System.Globalization; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Text; ////// defines literal value class /// internal enum LiteralKind { Number, String, NonUnicodeString, UnicodeString, Boolean, Binary, DateTime, Time, DateTimeOffset, Guid, Null } ////// Represents a literal ast node. /// internal sealed class Literal : Expr { private string _originalValue; private object _computedValue; private Type _type; private bool _isNull; private bool _wasValueComputed = false; private LiteralKind _literalKind; private static readonly Byte[] _emptyByteArray = new byte[0]; ////// initializes a literal ast node. /// /// literal value in cql string representation /// literal value class /// query /// input position internal Literal( string originalValue, LiteralKind kind, string query, int inputPos ) : base(query, inputPos) { _originalValue = originalValue; _literalKind = kind; } ////// static factory to create boolean literals by value only /// /// internal static Literal NewBooleanLiteral( bool value ) { return new Literal(value); } private Literal( bool boolLiteral ) : base(null, 0) { _wasValueComputed = true; _originalValue = String.Empty; _computedValue = boolLiteral; _type = typeof(System.Boolean); } ////// returns true if original value is of number kind /// internal bool IsNumberKind { get { return (_literalKind == LiteralKind.Number); } } ////// returns true if original value is signed /// internal bool IsSigned { get { return (_originalValue[0] == '-' || _originalValue[0] == '+'); } } ////// prefix a numeric literal with sign /// /// internal void PrefixSign( string sign ) { System.Diagnostics.Debug.Assert(IsNumberKind && !IsSigned); System.Diagnostics.Debug.Assert(sign[0] == '-' || sign[0] == '+', "sign symbol must be + or -"); System.Diagnostics.Debug.Assert(_computedValue == null); _originalValue = sign + _originalValue; } ////// returns the original literal value /// internal string OriginalValue { get { return _originalValue; } } // // Computed members // ////// returns literal converted value /// ////// internal object Value { get { ComputeValue(); return _computedValue; } } ////// /// Returns true if literal value is null, false otherwise /// ////// internal bool IsNullLiteral { get { ComputeValue(); return _isNull; } } ////// /// returns true if literal is string type, false otherwise /// ////// internal bool IsString { get { ComputeValue(); return (_computedValue is String); } } ////// /// returns true if literal is unicode string type, false otherwise /// ////// internal bool IsUnicodeString { get { return IsString && _literalKind == LiteralKind.UnicodeString; } } ////// /// returns literal value type. if value is null, returns null /// ////// internal Type Type { get { ComputeValue(); return _type; } } private void ComputeValue() { if (!_wasValueComputed) { _wasValueComputed = true; switch (_literalKind) { case LiteralKind.Number: _computedValue = ConvertNumericLiteral(ErrCtx, _originalValue); break; case LiteralKind.NonUnicodeString: _computedValue = GetStringLiteralValue(_originalValue, false /* isUnicode */); break; case LiteralKind.UnicodeString: _computedValue = GetStringLiteralValue(_originalValue, true /* isUnicode */); break; case LiteralKind.Boolean: _computedValue = ConvertBooleanLiteralValue(ErrCtx, _originalValue); break; case LiteralKind.Binary: _computedValue = ConvertBinaryLiteralValue(ErrCtx, _originalValue); break; case LiteralKind.DateTime: _computedValue = ConvertDateTimeLiteralValue(ErrCtx, _originalValue); break; case LiteralKind.Time: _computedValue = ConvertTimeLiteralValue(ErrCtx, _originalValue); break; case LiteralKind.DateTimeOffset: _computedValue = ConvertDateTimeOffsetLiteralValue(ErrCtx, _originalValue); break; case LiteralKind.Guid: _computedValue = ConvertGuidLiteralValue(ErrCtx, _originalValue); break; case LiteralKind.Null: _computedValue = null; _isNull = true; break; default: throw EntityUtil.NotSupported(System.Data.Entity.Strings.LiteralTypeNotSupported(_literalKind.ToString())); } _type = _isNull ? null : _computedValue.GetType(); } } // // Conversion Helpers // static char[] numberSuffixes = new char[] { 'U', 'u', 'L', 'l', 'F', 'f', 'M', 'm', 'D', 'd' }; static char[] floatTokens = new char[] { '.', 'E', 'e' }; private static object ConvertNumericLiteral(ErrorContext errCtx , string numericString) { int k = numericString.IndexOfAny(numberSuffixes); if (-1 != k) { string suffix = numericString.Substring(k).ToUpperInvariant(); string numberPart = numericString.Substring(0, numericString.Length - suffix.Length); switch (suffix) { case "U": { UInt32 value; if (!UInt32.TryParse(numberPart, NumberStyles.Integer, CultureInfo.InvariantCulture, out value)) { throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.CannotConvertNumericLiteral(numericString, "unsigned int")); } return value; } ; case "L": { long value; if (!Int64.TryParse(numberPart, NumberStyles.Integer, CultureInfo.InvariantCulture, out value)) { throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.CannotConvertNumericLiteral(numericString, "long")); } return value; } ; case "UL": case "LU": { UInt64 value; if (!UInt64.TryParse(numberPart, NumberStyles.Integer, CultureInfo.InvariantCulture, out value)) { throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.CannotConvertNumericLiteral(numericString, "unsigned long")); } return value; } ; case "F": { Single value; if (!Single.TryParse(numberPart, NumberStyles.Float, CultureInfo.InvariantCulture, out value)) { throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.CannotConvertNumericLiteral(numericString, "float")); } return value; } ; case "M": { Decimal value; if (!Decimal.TryParse(numberPart, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out value)) { throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.CannotConvertNumericLiteral(numericString, "decimal")); } return value; } ; case "D": { Double value; if (!Double.TryParse(numberPart, NumberStyles.Float, CultureInfo.InvariantCulture, out value)) { throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.CannotConvertNumericLiteral(numericString, "double")); } return value; } ; } } // // if hit this point, try default conversion // return DefaultNumericConversion(numericString, errCtx); } ////// /// performs conversion of numeric strings that have no type suffix hint. /// /// /// ///private static object DefaultNumericConversion( string numericString, ErrorContext errCtx ) { if (-1 != numericString.IndexOfAny(floatTokens)) { Double value; if (!Double.TryParse(numericString, NumberStyles.Float, CultureInfo.InvariantCulture, out value)) { throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.CannotConvertNumericLiteral(numericString, "double")); } return value; } else { Int32 int32Value; if (Int32.TryParse(numericString, NumberStyles.Integer, CultureInfo.InvariantCulture, out int32Value)) { return int32Value; } Int64 int64Value; if (!Int64.TryParse(numericString, NumberStyles.Integer, CultureInfo.InvariantCulture, out int64Value)) { throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.CannotConvertNumericLiteral(numericString, "long")); } return int64Value; } } /// /// converts boolean literal value /// /// /// ///private static bool ConvertBooleanLiteralValue( ErrorContext errCtx, string booleanLiteralValue ) { bool result = false; if (!Boolean.TryParse(booleanLiteralValue, out result)) { throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.InvalidLiteralFormat("Boolean", booleanLiteralValue)); } return result; } /// /// returns the string literal value. /// /// /// ///private static string GetStringLiteralValue( string stringLiteralValue, bool isUnicode ) { Debug.Assert(stringLiteralValue.Length >= 2); Debug.Assert(isUnicode == ('N' == stringLiteralValue[0]),"invalid string literal value"); int startIndex = (isUnicode ? 2 : 1); char delimiter = stringLiteralValue[startIndex - 1]; Debug.Assert(delimiter.Equals('\'') || delimiter.Equals('\"'), "invalid string delimiter"); // NOTE: this is not a precondition validation. This validation is for security purposes based on the // paranoid assumption that all input is evil. we should not see this exception under normal // conditions. if (delimiter != '\'' && delimiter != '\"') { throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.MalformedStringLiteralPayload); } string result = ""; // NOTE: this is not a precondition validation. This validation is for security purposes based on the // paranoid assumption that all input is evil. we should not see this exception under normal // conditions. int before = stringLiteralValue.Split(new char[] { delimiter }).Length - 1; Debug.Assert(before % 2 == 0, "must have an even number of delimiters in the string literal"); if (0 != (before % 2)) { throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.MalformedStringLiteralPayload); } // // extract the payload and replace escaped chars that match the envelope delimiter // result = stringLiteralValue.Substring(startIndex, stringLiteralValue.Length - (1 + startIndex)); result = result.Replace(new String(delimiter, 2), new String(delimiter, 1)); // NOTE: this is not a precondition validation. This validation is for security purposes based on the // paranoid assumption that all input is evil. we should not see this exception under normal // conditions. int after = result.Split(new char[] { delimiter }).Length - 1; Debug.Assert(after == (before - 2) / 2); if ((after != ((before - 2) / 2))) { throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.MalformedStringLiteralPayload); } return result; } /// /// converts hex string to byte array /// /// /// ///private static byte[] ConvertBinaryLiteralValue( ErrorContext errCtx, string binaryLiteralValue ) { Debug.Assert(null != binaryLiteralValue, "binaryStringLiteral must not be null"); if (String.IsNullOrEmpty(binaryLiteralValue)) { return _emptyByteArray; } int startIndex = 0; int endIndex = binaryLiteralValue.Length - 1; Debug.Assert(startIndex <= endIndex, "startIndex <= endIndex"); int binaryStringLen = endIndex - startIndex + 1; int byteArrayLen = binaryStringLen / 2; bool hasOddBytes = 0 != (binaryStringLen % 2); if (hasOddBytes) { byteArrayLen++; } byte[] binaryValue = new byte[byteArrayLen]; int arrayIndex = 0; if (hasOddBytes) { binaryValue[arrayIndex++] = (byte)HexDigitToBinaryValue(binaryLiteralValue[startIndex++]); } while (startIndex < endIndex) { binaryValue[arrayIndex++] = (byte)((HexDigitToBinaryValue(binaryLiteralValue[startIndex++]) << 4) | HexDigitToBinaryValue(binaryLiteralValue[startIndex++])); } return binaryValue; } /// /// parse single hex char /// PRECONDITION - hexChar must be valid hex digit /// /// ///private static int HexDigitToBinaryValue( char hexChar ) { if ( hexChar >= '0' && hexChar <= '9' ) return (int)( hexChar - '0' ); if ( hexChar >= 'A' && hexChar <= 'F' ) return (int)( hexChar - 'A' ) + 10; if ( hexChar >= 'a' && hexChar <= 'f' ) return (int)( hexChar - 'a' ) + 10; Debug.Assert(false, "Invalid Hexadecimal Digit"); throw EntityUtil.ArgumentOutOfRange("hexadecimal digit is not valid"); } static readonly char[] _datetimeSeparators = new char[] { ' ', ':', '-', '.' }; static readonly char[] _dateSeparators = new char[] { '-' }; static readonly char[] _timeSeparators = new char[] { ':', '.' }; static readonly char[] _datetimeOffsetSeparators = new char[] { ' ', ':', '-', '.', '+', '-' }; /// /// converts datetime literal value /// /// /// ///private static DateTime ConvertDateTimeLiteralValue( ErrorContext errCtx, string datetimeLiteralValue ) { string[] datetimeParts = datetimeLiteralValue.Split(_datetimeSeparators, StringSplitOptions.RemoveEmptyEntries); Debug.Assert(datetimeParts.Length >= 5, "datetime literal value must have at least 5 parts"); int year; int month; int day; GetDateParts(datetimeLiteralValue, datetimeParts, out year, out month, out day); int hour; int minute; int second; int ticks; GetTimeParts(datetimeLiteralValue, datetimeParts, 3, out hour, out minute, out second, out ticks); Debug.Assert(year >= 1 && year <= 9999); Debug.Assert(month >= 1 && month <= 12); Debug.Assert(day >= 1 && day <= 31); Debug.Assert(hour >= 0 && hour <= 24); Debug.Assert(minute >= 0 && minute <= 59); Debug.Assert(second >= 0 && second <= 59); Debug.Assert(ticks >= 0 && ticks <= 9999999); DateTime dateTime = new DateTime(year, month, day, hour, minute, second, 0); dateTime = dateTime.AddTicks(ticks); return dateTime; } private static DateTimeOffset ConvertDateTimeOffsetLiteralValue(ErrorContext errCtx, string datetimeLiteralValue) { string[] datetimeParts = datetimeLiteralValue.Split(_datetimeOffsetSeparators, StringSplitOptions.RemoveEmptyEntries); Debug.Assert(datetimeParts.Length >= 7, "datetime literal value must have at least 7 parts"); int year; int month; int day; GetDateParts(datetimeLiteralValue, datetimeParts, out year, out month, out day); int hour; int minute; int second; int ticks; //Copy the time parts into a different array since the last two parts will be handled in this method. string[] timeParts = new String[datetimeParts.Length - 2]; Array.Copy(datetimeParts, timeParts, datetimeParts.Length - 2); GetTimeParts(datetimeLiteralValue, timeParts, 3, out hour, out minute, out second, out ticks); Debug.Assert(year >= 1 && year <= 9999); Debug.Assert(month >= 1 && month <= 12); Debug.Assert(day >= 1 && day <= 31); Debug.Assert(hour >= 0 && hour <= 24); Debug.Assert(minute >= 0 && minute <= 59); Debug.Assert(second >= 0 && second <= 59); Debug.Assert(ticks >= 0 && ticks <= 9999999); int offsetHours = Int32.Parse(datetimeParts[datetimeParts.Length - 2], NumberStyles.Integer, CultureInfo.InvariantCulture); int offsetMinutes = Int32.Parse(datetimeParts[datetimeParts.Length - 1], NumberStyles.Integer, CultureInfo.InvariantCulture); TimeSpan offsetTimeSpan = new TimeSpan(offsetHours, offsetMinutes, 0); //If DateTimeOffset had a negative offset, we should negate the timespan if(datetimeLiteralValue.IndexOf('+') == -1) { offsetTimeSpan = offsetTimeSpan.Negate(); } DateTime dateTime = new DateTime(year, month, day, hour, minute, second, 0); dateTime = dateTime.AddTicks(ticks); try { return new DateTimeOffset(dateTime, offsetTimeSpan); } catch (ArgumentOutOfRangeException e) { throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.InvalidDateTimeOffsetLiteral(datetimeLiteralValue), e); } } /// /// converts time literal value /// /// /// ///private static TimeSpan ConvertTimeLiteralValue(ErrorContext errCtx, string datetimeLiteralValue) { string[] datetimeParts = datetimeLiteralValue.Split(_datetimeSeparators, StringSplitOptions.RemoveEmptyEntries); Debug.Assert(datetimeParts.Length >= 2, "time literal value must have at least 2 parts"); int hour; int minute; int second; int ticks; GetTimeParts(datetimeLiteralValue, datetimeParts, 0, out hour, out minute, out second, out ticks); Debug.Assert(hour >= 0 && hour <= 24); Debug.Assert(minute >= 0 && minute <= 59); Debug.Assert(second >= 0 && second <= 59); Debug.Assert(ticks >= 0 && ticks <= 9999999); TimeSpan ts = new TimeSpan(hour, minute, second); ts = ts.Add(new TimeSpan(ticks)); return ts; } private static void GetTimeParts(string datetimeLiteralValue, string[] datetimeParts, int timePartStartIndex, out int hour, out int minute, out int second, out int ticks) { hour = Int32.Parse(datetimeParts[timePartStartIndex], NumberStyles.Integer, CultureInfo.InvariantCulture); if (hour > 23) { throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.InvalidHour(datetimeParts[timePartStartIndex], datetimeLiteralValue)); } minute = Int32.Parse(datetimeParts[++timePartStartIndex], NumberStyles.Integer, CultureInfo.InvariantCulture); if (minute > 59) { throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.InvalidMinute(datetimeParts[timePartStartIndex], datetimeLiteralValue)); } second = 0; ticks = 0; timePartStartIndex++; if (datetimeParts.Length > timePartStartIndex) { second = Int32.Parse(datetimeParts[timePartStartIndex], NumberStyles.Integer, CultureInfo.InvariantCulture); if (second > 59) { throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.InvalidSecond(datetimeParts[timePartStartIndex], datetimeLiteralValue)); } timePartStartIndex++; if (datetimeParts.Length > timePartStartIndex) { //We need fractional time part to be seven digits string ticksString = datetimeParts[timePartStartIndex].PadRight(7, '0'); ticks = Int32.Parse(ticksString , NumberStyles.Integer, CultureInfo.InvariantCulture); } } } private static void GetDateParts(string datetimeLiteralValue, string[] datetimeParts, out int year, out int month, out int day) { year = Int32.Parse(datetimeParts[0], NumberStyles.Integer, CultureInfo.InvariantCulture); if (year < 1 || year > 9999) { throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.InvalidYear(datetimeParts[0], datetimeLiteralValue)); } month = Int32.Parse(datetimeParts[1], NumberStyles.Integer, CultureInfo.InvariantCulture); if (month < 1 || month > 12) { throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.InvalidMonth(datetimeParts[1], datetimeLiteralValue)); } day = Int32.Parse(datetimeParts[2], NumberStyles.Integer, CultureInfo.InvariantCulture); if (day < 1) { throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.InvalidDay(datetimeParts[2], datetimeLiteralValue)); } if (day > DateTime.DaysInMonth(year, month)) { throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.InvalidDayInMonth(datetimeParts[2], datetimeParts[1], datetimeLiteralValue)); } } /// /// converts guid literal value /// /// /// ///private static Guid ConvertGuidLiteralValue( ErrorContext errCtx, string guidLiteralValue ) { return new Guid(guidLiteralValue); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] [....] //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql { using System; using System.Globalization; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Text; ////// defines literal value class /// internal enum LiteralKind { Number, String, NonUnicodeString, UnicodeString, Boolean, Binary, DateTime, Time, DateTimeOffset, Guid, Null } ////// Represents a literal ast node. /// internal sealed class Literal : Expr { private string _originalValue; private object _computedValue; private Type _type; private bool _isNull; private bool _wasValueComputed = false; private LiteralKind _literalKind; private static readonly Byte[] _emptyByteArray = new byte[0]; ////// initializes a literal ast node. /// /// literal value in cql string representation /// literal value class /// query /// input position internal Literal( string originalValue, LiteralKind kind, string query, int inputPos ) : base(query, inputPos) { _originalValue = originalValue; _literalKind = kind; } ////// static factory to create boolean literals by value only /// /// internal static Literal NewBooleanLiteral( bool value ) { return new Literal(value); } private Literal( bool boolLiteral ) : base(null, 0) { _wasValueComputed = true; _originalValue = String.Empty; _computedValue = boolLiteral; _type = typeof(System.Boolean); } ////// returns true if original value is of number kind /// internal bool IsNumberKind { get { return (_literalKind == LiteralKind.Number); } } ////// returns true if original value is signed /// internal bool IsSigned { get { return (_originalValue[0] == '-' || _originalValue[0] == '+'); } } ////// prefix a numeric literal with sign /// /// internal void PrefixSign( string sign ) { System.Diagnostics.Debug.Assert(IsNumberKind && !IsSigned); System.Diagnostics.Debug.Assert(sign[0] == '-' || sign[0] == '+', "sign symbol must be + or -"); System.Diagnostics.Debug.Assert(_computedValue == null); _originalValue = sign + _originalValue; } ////// returns the original literal value /// internal string OriginalValue { get { return _originalValue; } } // // Computed members // ////// returns literal converted value /// ////// internal object Value { get { ComputeValue(); return _computedValue; } } ////// /// Returns true if literal value is null, false otherwise /// ////// internal bool IsNullLiteral { get { ComputeValue(); return _isNull; } } ////// /// returns true if literal is string type, false otherwise /// ////// internal bool IsString { get { ComputeValue(); return (_computedValue is String); } } ////// /// returns true if literal is unicode string type, false otherwise /// ////// internal bool IsUnicodeString { get { return IsString && _literalKind == LiteralKind.UnicodeString; } } ////// /// returns literal value type. if value is null, returns null /// ////// internal Type Type { get { ComputeValue(); return _type; } } private void ComputeValue() { if (!_wasValueComputed) { _wasValueComputed = true; switch (_literalKind) { case LiteralKind.Number: _computedValue = ConvertNumericLiteral(ErrCtx, _originalValue); break; case LiteralKind.NonUnicodeString: _computedValue = GetStringLiteralValue(_originalValue, false /* isUnicode */); break; case LiteralKind.UnicodeString: _computedValue = GetStringLiteralValue(_originalValue, true /* isUnicode */); break; case LiteralKind.Boolean: _computedValue = ConvertBooleanLiteralValue(ErrCtx, _originalValue); break; case LiteralKind.Binary: _computedValue = ConvertBinaryLiteralValue(ErrCtx, _originalValue); break; case LiteralKind.DateTime: _computedValue = ConvertDateTimeLiteralValue(ErrCtx, _originalValue); break; case LiteralKind.Time: _computedValue = ConvertTimeLiteralValue(ErrCtx, _originalValue); break; case LiteralKind.DateTimeOffset: _computedValue = ConvertDateTimeOffsetLiteralValue(ErrCtx, _originalValue); break; case LiteralKind.Guid: _computedValue = ConvertGuidLiteralValue(ErrCtx, _originalValue); break; case LiteralKind.Null: _computedValue = null; _isNull = true; break; default: throw EntityUtil.NotSupported(System.Data.Entity.Strings.LiteralTypeNotSupported(_literalKind.ToString())); } _type = _isNull ? null : _computedValue.GetType(); } } // // Conversion Helpers // static char[] numberSuffixes = new char[] { 'U', 'u', 'L', 'l', 'F', 'f', 'M', 'm', 'D', 'd' }; static char[] floatTokens = new char[] { '.', 'E', 'e' }; private static object ConvertNumericLiteral(ErrorContext errCtx , string numericString) { int k = numericString.IndexOfAny(numberSuffixes); if (-1 != k) { string suffix = numericString.Substring(k).ToUpperInvariant(); string numberPart = numericString.Substring(0, numericString.Length - suffix.Length); switch (suffix) { case "U": { UInt32 value; if (!UInt32.TryParse(numberPart, NumberStyles.Integer, CultureInfo.InvariantCulture, out value)) { throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.CannotConvertNumericLiteral(numericString, "unsigned int")); } return value; } ; case "L": { long value; if (!Int64.TryParse(numberPart, NumberStyles.Integer, CultureInfo.InvariantCulture, out value)) { throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.CannotConvertNumericLiteral(numericString, "long")); } return value; } ; case "UL": case "LU": { UInt64 value; if (!UInt64.TryParse(numberPart, NumberStyles.Integer, CultureInfo.InvariantCulture, out value)) { throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.CannotConvertNumericLiteral(numericString, "unsigned long")); } return value; } ; case "F": { Single value; if (!Single.TryParse(numberPart, NumberStyles.Float, CultureInfo.InvariantCulture, out value)) { throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.CannotConvertNumericLiteral(numericString, "float")); } return value; } ; case "M": { Decimal value; if (!Decimal.TryParse(numberPart, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out value)) { throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.CannotConvertNumericLiteral(numericString, "decimal")); } return value; } ; case "D": { Double value; if (!Double.TryParse(numberPart, NumberStyles.Float, CultureInfo.InvariantCulture, out value)) { throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.CannotConvertNumericLiteral(numericString, "double")); } return value; } ; } } // // if hit this point, try default conversion // return DefaultNumericConversion(numericString, errCtx); } ////// /// performs conversion of numeric strings that have no type suffix hint. /// /// /// ///private static object DefaultNumericConversion( string numericString, ErrorContext errCtx ) { if (-1 != numericString.IndexOfAny(floatTokens)) { Double value; if (!Double.TryParse(numericString, NumberStyles.Float, CultureInfo.InvariantCulture, out value)) { throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.CannotConvertNumericLiteral(numericString, "double")); } return value; } else { Int32 int32Value; if (Int32.TryParse(numericString, NumberStyles.Integer, CultureInfo.InvariantCulture, out int32Value)) { return int32Value; } Int64 int64Value; if (!Int64.TryParse(numericString, NumberStyles.Integer, CultureInfo.InvariantCulture, out int64Value)) { throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.CannotConvertNumericLiteral(numericString, "long")); } return int64Value; } } /// /// converts boolean literal value /// /// /// ///private static bool ConvertBooleanLiteralValue( ErrorContext errCtx, string booleanLiteralValue ) { bool result = false; if (!Boolean.TryParse(booleanLiteralValue, out result)) { throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.InvalidLiteralFormat("Boolean", booleanLiteralValue)); } return result; } /// /// returns the string literal value. /// /// /// ///private static string GetStringLiteralValue( string stringLiteralValue, bool isUnicode ) { Debug.Assert(stringLiteralValue.Length >= 2); Debug.Assert(isUnicode == ('N' == stringLiteralValue[0]),"invalid string literal value"); int startIndex = (isUnicode ? 2 : 1); char delimiter = stringLiteralValue[startIndex - 1]; Debug.Assert(delimiter.Equals('\'') || delimiter.Equals('\"'), "invalid string delimiter"); // NOTE: this is not a precondition validation. This validation is for security purposes based on the // paranoid assumption that all input is evil. we should not see this exception under normal // conditions. if (delimiter != '\'' && delimiter != '\"') { throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.MalformedStringLiteralPayload); } string result = ""; // NOTE: this is not a precondition validation. This validation is for security purposes based on the // paranoid assumption that all input is evil. we should not see this exception under normal // conditions. int before = stringLiteralValue.Split(new char[] { delimiter }).Length - 1; Debug.Assert(before % 2 == 0, "must have an even number of delimiters in the string literal"); if (0 != (before % 2)) { throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.MalformedStringLiteralPayload); } // // extract the payload and replace escaped chars that match the envelope delimiter // result = stringLiteralValue.Substring(startIndex, stringLiteralValue.Length - (1 + startIndex)); result = result.Replace(new String(delimiter, 2), new String(delimiter, 1)); // NOTE: this is not a precondition validation. This validation is for security purposes based on the // paranoid assumption that all input is evil. we should not see this exception under normal // conditions. int after = result.Split(new char[] { delimiter }).Length - 1; Debug.Assert(after == (before - 2) / 2); if ((after != ((before - 2) / 2))) { throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.MalformedStringLiteralPayload); } return result; } /// /// converts hex string to byte array /// /// /// ///private static byte[] ConvertBinaryLiteralValue( ErrorContext errCtx, string binaryLiteralValue ) { Debug.Assert(null != binaryLiteralValue, "binaryStringLiteral must not be null"); if (String.IsNullOrEmpty(binaryLiteralValue)) { return _emptyByteArray; } int startIndex = 0; int endIndex = binaryLiteralValue.Length - 1; Debug.Assert(startIndex <= endIndex, "startIndex <= endIndex"); int binaryStringLen = endIndex - startIndex + 1; int byteArrayLen = binaryStringLen / 2; bool hasOddBytes = 0 != (binaryStringLen % 2); if (hasOddBytes) { byteArrayLen++; } byte[] binaryValue = new byte[byteArrayLen]; int arrayIndex = 0; if (hasOddBytes) { binaryValue[arrayIndex++] = (byte)HexDigitToBinaryValue(binaryLiteralValue[startIndex++]); } while (startIndex < endIndex) { binaryValue[arrayIndex++] = (byte)((HexDigitToBinaryValue(binaryLiteralValue[startIndex++]) << 4) | HexDigitToBinaryValue(binaryLiteralValue[startIndex++])); } return binaryValue; } /// /// parse single hex char /// PRECONDITION - hexChar must be valid hex digit /// /// ///private static int HexDigitToBinaryValue( char hexChar ) { if ( hexChar >= '0' && hexChar <= '9' ) return (int)( hexChar - '0' ); if ( hexChar >= 'A' && hexChar <= 'F' ) return (int)( hexChar - 'A' ) + 10; if ( hexChar >= 'a' && hexChar <= 'f' ) return (int)( hexChar - 'a' ) + 10; Debug.Assert(false, "Invalid Hexadecimal Digit"); throw EntityUtil.ArgumentOutOfRange("hexadecimal digit is not valid"); } static readonly char[] _datetimeSeparators = new char[] { ' ', ':', '-', '.' }; static readonly char[] _dateSeparators = new char[] { '-' }; static readonly char[] _timeSeparators = new char[] { ':', '.' }; static readonly char[] _datetimeOffsetSeparators = new char[] { ' ', ':', '-', '.', '+', '-' }; /// /// converts datetime literal value /// /// /// ///private static DateTime ConvertDateTimeLiteralValue( ErrorContext errCtx, string datetimeLiteralValue ) { string[] datetimeParts = datetimeLiteralValue.Split(_datetimeSeparators, StringSplitOptions.RemoveEmptyEntries); Debug.Assert(datetimeParts.Length >= 5, "datetime literal value must have at least 5 parts"); int year; int month; int day; GetDateParts(datetimeLiteralValue, datetimeParts, out year, out month, out day); int hour; int minute; int second; int ticks; GetTimeParts(datetimeLiteralValue, datetimeParts, 3, out hour, out minute, out second, out ticks); Debug.Assert(year >= 1 && year <= 9999); Debug.Assert(month >= 1 && month <= 12); Debug.Assert(day >= 1 && day <= 31); Debug.Assert(hour >= 0 && hour <= 24); Debug.Assert(minute >= 0 && minute <= 59); Debug.Assert(second >= 0 && second <= 59); Debug.Assert(ticks >= 0 && ticks <= 9999999); DateTime dateTime = new DateTime(year, month, day, hour, minute, second, 0); dateTime = dateTime.AddTicks(ticks); return dateTime; } private static DateTimeOffset ConvertDateTimeOffsetLiteralValue(ErrorContext errCtx, string datetimeLiteralValue) { string[] datetimeParts = datetimeLiteralValue.Split(_datetimeOffsetSeparators, StringSplitOptions.RemoveEmptyEntries); Debug.Assert(datetimeParts.Length >= 7, "datetime literal value must have at least 7 parts"); int year; int month; int day; GetDateParts(datetimeLiteralValue, datetimeParts, out year, out month, out day); int hour; int minute; int second; int ticks; //Copy the time parts into a different array since the last two parts will be handled in this method. string[] timeParts = new String[datetimeParts.Length - 2]; Array.Copy(datetimeParts, timeParts, datetimeParts.Length - 2); GetTimeParts(datetimeLiteralValue, timeParts, 3, out hour, out minute, out second, out ticks); Debug.Assert(year >= 1 && year <= 9999); Debug.Assert(month >= 1 && month <= 12); Debug.Assert(day >= 1 && day <= 31); Debug.Assert(hour >= 0 && hour <= 24); Debug.Assert(minute >= 0 && minute <= 59); Debug.Assert(second >= 0 && second <= 59); Debug.Assert(ticks >= 0 && ticks <= 9999999); int offsetHours = Int32.Parse(datetimeParts[datetimeParts.Length - 2], NumberStyles.Integer, CultureInfo.InvariantCulture); int offsetMinutes = Int32.Parse(datetimeParts[datetimeParts.Length - 1], NumberStyles.Integer, CultureInfo.InvariantCulture); TimeSpan offsetTimeSpan = new TimeSpan(offsetHours, offsetMinutes, 0); //If DateTimeOffset had a negative offset, we should negate the timespan if(datetimeLiteralValue.IndexOf('+') == -1) { offsetTimeSpan = offsetTimeSpan.Negate(); } DateTime dateTime = new DateTime(year, month, day, hour, minute, second, 0); dateTime = dateTime.AddTicks(ticks); try { return new DateTimeOffset(dateTime, offsetTimeSpan); } catch (ArgumentOutOfRangeException e) { throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.InvalidDateTimeOffsetLiteral(datetimeLiteralValue), e); } } /// /// converts time literal value /// /// /// ///private static TimeSpan ConvertTimeLiteralValue(ErrorContext errCtx, string datetimeLiteralValue) { string[] datetimeParts = datetimeLiteralValue.Split(_datetimeSeparators, StringSplitOptions.RemoveEmptyEntries); Debug.Assert(datetimeParts.Length >= 2, "time literal value must have at least 2 parts"); int hour; int minute; int second; int ticks; GetTimeParts(datetimeLiteralValue, datetimeParts, 0, out hour, out minute, out second, out ticks); Debug.Assert(hour >= 0 && hour <= 24); Debug.Assert(minute >= 0 && minute <= 59); Debug.Assert(second >= 0 && second <= 59); Debug.Assert(ticks >= 0 && ticks <= 9999999); TimeSpan ts = new TimeSpan(hour, minute, second); ts = ts.Add(new TimeSpan(ticks)); return ts; } private static void GetTimeParts(string datetimeLiteralValue, string[] datetimeParts, int timePartStartIndex, out int hour, out int minute, out int second, out int ticks) { hour = Int32.Parse(datetimeParts[timePartStartIndex], NumberStyles.Integer, CultureInfo.InvariantCulture); if (hour > 23) { throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.InvalidHour(datetimeParts[timePartStartIndex], datetimeLiteralValue)); } minute = Int32.Parse(datetimeParts[++timePartStartIndex], NumberStyles.Integer, CultureInfo.InvariantCulture); if (minute > 59) { throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.InvalidMinute(datetimeParts[timePartStartIndex], datetimeLiteralValue)); } second = 0; ticks = 0; timePartStartIndex++; if (datetimeParts.Length > timePartStartIndex) { second = Int32.Parse(datetimeParts[timePartStartIndex], NumberStyles.Integer, CultureInfo.InvariantCulture); if (second > 59) { throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.InvalidSecond(datetimeParts[timePartStartIndex], datetimeLiteralValue)); } timePartStartIndex++; if (datetimeParts.Length > timePartStartIndex) { //We need fractional time part to be seven digits string ticksString = datetimeParts[timePartStartIndex].PadRight(7, '0'); ticks = Int32.Parse(ticksString , NumberStyles.Integer, CultureInfo.InvariantCulture); } } } private static void GetDateParts(string datetimeLiteralValue, string[] datetimeParts, out int year, out int month, out int day) { year = Int32.Parse(datetimeParts[0], NumberStyles.Integer, CultureInfo.InvariantCulture); if (year < 1 || year > 9999) { throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.InvalidYear(datetimeParts[0], datetimeLiteralValue)); } month = Int32.Parse(datetimeParts[1], NumberStyles.Integer, CultureInfo.InvariantCulture); if (month < 1 || month > 12) { throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.InvalidMonth(datetimeParts[1], datetimeLiteralValue)); } day = Int32.Parse(datetimeParts[2], NumberStyles.Integer, CultureInfo.InvariantCulture); if (day < 1) { throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.InvalidDay(datetimeParts[2], datetimeLiteralValue)); } if (day > DateTime.DaysInMonth(year, month)) { throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.InvalidDayInMonth(datetimeParts[2], datetimeParts[1], datetimeLiteralValue)); } } /// /// converts guid literal value /// /// /// ///private static Guid ConvertGuidLiteralValue( ErrorContext errCtx, string guidLiteralValue ) { return new Guid(guidLiteralValue); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ProcessHostFactoryHelper.cs
- SmiXetterAccessMap.cs
- ServiceModelEnumValidatorAttribute.cs
- QueryOperatorEnumerator.cs
- SafeFileHandle.cs
- IdentityNotMappedException.cs
- XamlReader.cs
- CategoryAttribute.cs
- SqlDataSourceSelectingEventArgs.cs
- RectAnimationClockResource.cs
- SiteMapDataSourceView.cs
- SystemUdpStatistics.cs
- FunctionMappingTranslator.cs
- ProcessInputEventArgs.cs
- Tokenizer.cs
- MetadataArtifactLoaderCompositeFile.cs
- ViewDesigner.cs
- TabControl.cs
- DeferredTextReference.cs
- Section.cs
- Speller.cs
- WorkflowApplicationTerminatedException.cs
- MetadataArtifactLoaderResource.cs
- Set.cs
- GenericXmlSecurityTokenAuthenticator.cs
- DataMemberAttribute.cs
- EntryWrittenEventArgs.cs
- DummyDataSource.cs
- ColumnResizeAdorner.cs
- BulletDecorator.cs
- TypeUtils.cs
- TdsParserStaticMethods.cs
- RegexMatchCollection.cs
- DateTimeOffsetConverter.cs
- Hash.cs
- SchemaTableOptionalColumn.cs
- XmlSignatureProperties.cs
- PriorityRange.cs
- HtmlInputText.cs
- Decoder.cs
- JoinCqlBlock.cs
- SqlNotificationRequest.cs
- FileUtil.cs
- ProfileSection.cs
- Vector.cs
- SpellerInterop.cs
- RootBrowserWindow.cs
- BindingCollection.cs
- CommandHelper.cs
- Environment.cs
- DataGridViewComboBoxColumn.cs
- Compiler.cs
- SqlRecordBuffer.cs
- RankException.cs
- EditingCommands.cs
- SourceElementsCollection.cs
- CompressEmulationStream.cs
- SHA256Managed.cs
- WorkflowQueue.cs
- NetTcpSection.cs
- XmlTextReaderImplHelpers.cs
- HtmlTable.cs
- IdentityVerifier.cs
- RouteData.cs
- HotSpot.cs
- XmlDictionaryString.cs
- TypeDescriptionProviderAttribute.cs
- ExecutionEngineException.cs
- NameTable.cs
- FactoryGenerator.cs
- ConditionalAttribute.cs
- JoinQueryOperator.cs
- PaperSource.cs
- RootProjectionNode.cs
- XmlUTF8TextWriter.cs
- Drawing.cs
- SaveWorkflowAsyncResult.cs
- FilteredXmlReader.cs
- QilCloneVisitor.cs
- HwndPanningFeedback.cs
- GlobalizationSection.cs
- ManualWorkflowSchedulerService.cs
- XmlFormatExtensionAttribute.cs
- TemplateBamlTreeBuilder.cs
- SerializationInfoEnumerator.cs
- ExpressionCopier.cs
- CancelAsyncOperationRequest.cs
- WSSecureConversationDec2005.cs
- SvcMapFile.cs
- DesignTimeTemplateParser.cs
- FrameSecurityDescriptor.cs
- NativeMethods.cs
- SelectionListComponentEditor.cs
- XPathNavigator.cs
- WebPartPersonalization.cs
- PathHelper.cs
- Input.cs
- HMACSHA256.cs
- NamespaceExpr.cs
- SettingsProperty.cs