Example #1
0
        /// <summary>
        /// Function to normalize quoted string, ensuring single quotes are escaped properly.
        /// If the string is double-quoted, no op since single quote doesn't need to be escaped.
        /// </summary>
        /// <param name="str">The quoted string item to be normalized.</param>
        /// <returns>The double-quoted string with single quotes properly escaped.</returns>
        private static string NormalizeStringItem(string str)
        {
            // Validate the string item is quoted properly.
            if (!((str[0] == '\'' && str[str.Length - 1] == '\'') || (str[0] == '"' && str[str.Length - 1] == '"')))
            {
                throw new ODataException(ODataErrorStrings.StringItemShouldBeQuoted(str));
            }

            // Skip conversion if the items are already in double-quote format (for backward compatibility).
            // Note that per ABNF, query option strings should use single quotes.
            string convertedString = str;

            if (str[0] == '\'')
            {
                convertedString = String.Format(CultureInfo.InvariantCulture, "\"{0}\"", UriParserHelper.RemoveQuotes(str));
            }

            return(convertedString);
        }
        private bool TryUriStringToPrimitive(string text, IEdmTypeReference targetType, out object targetValue, out UriLiteralParsingException exception)
        {
            Debug.Assert(text != null, "text != null");
            Debug.Assert(targetType != null, "targetType != null");
            exception = null;

            try
            {
                if (targetType.IsNullable)
                {
                    // COMPAT 38: Product does not support "null" literals in service operation arguments
                    // check for the 'null' constant for nullable types
                    if (text == ExpressionConstants.KeywordNull)
                    {
                        targetValue = null;
                        return(true);
                    }
                }

                IEdmPrimitiveTypeReference primitiveTargetType = targetType.AsPrimitiveOrNull();
                if (primitiveTargetType == null)
                {
                    targetValue = null;
                    return(false);
                }

                EdmPrimitiveTypeKind targetTypeKind = primitiveTargetType.PrimitiveKind();

                byte[] byteArrayValue;
                bool   binaryResult = TryUriStringToByteArray(text, out byteArrayValue);
                if (targetTypeKind == EdmPrimitiveTypeKind.Binary)
                {
                    targetValue = (object)byteArrayValue;
                    return(binaryResult);
                }
                else if (binaryResult)
                {
                    string keyValue = Encoding.UTF8.GetString(byteArrayValue, 0, byteArrayValue.Length);
                    return(this.TryUriStringToPrimitive(keyValue, targetType, out targetValue));
                }
                else if (targetTypeKind == EdmPrimitiveTypeKind.Guid)
                {
                    Guid guidValue;
                    bool result = UriUtils.TryUriStringToGuid(text, out guidValue);
                    targetValue = guidValue;
                    return(result);
                }
                else if (targetTypeKind == EdmPrimitiveTypeKind.Date)
                {
                    Date dateValue;
                    bool result = UriUtils.TryUriStringToDate(text, out dateValue);
                    targetValue = dateValue;
                    return(result);
                }
                else if (targetTypeKind == EdmPrimitiveTypeKind.DateTimeOffset)
                {
                    DateTimeOffset dateTimeOffsetValue;
                    bool           result = UriUtils.ConvertUriStringToDateTimeOffset(text, out dateTimeOffsetValue);
                    targetValue = dateTimeOffsetValue;
                    return(result);
                }
                else if (targetTypeKind == EdmPrimitiveTypeKind.Duration)
                {
                    TimeSpan timespanValue;
                    bool     result = TryUriStringToDuration(text, out timespanValue);
                    targetValue = timespanValue;
                    return(result);
                }
                else if (targetTypeKind == EdmPrimitiveTypeKind.Geography)
                {
                    Geography geographyValue;
                    bool      result = TryUriStringToGeography(text, out geographyValue, out exception);
                    targetValue = geographyValue;
                    return(result);
                }
                else if (targetTypeKind == EdmPrimitiveTypeKind.Geometry)
                {
                    Geometry geometryValue;
                    bool     result = TryUriStringToGeometry(text, out geometryValue, out exception);
                    targetValue = geometryValue;
                    return(result);
                }
                else if (targetTypeKind == EdmPrimitiveTypeKind.TimeOfDay)
                {
                    TimeOfDay timeOfDayValue;
                    bool      result = UriUtils.TryUriStringToTimeOfDay(text, out timeOfDayValue);
                    targetValue = timeOfDayValue;
                    return(result);
                }

                bool quoted = targetTypeKind == EdmPrimitiveTypeKind.String;
                if (quoted != UriParserHelper.IsUriValueQuoted(text))
                {
                    targetValue = null;
                    return(false);
                }

                if (quoted)
                {
                    text = UriParserHelper.RemoveQuotes(text);
                }

                try
                {
                    switch (targetTypeKind)
                    {
                    case EdmPrimitiveTypeKind.String:
                        targetValue = text;
                        break;

                    case EdmPrimitiveTypeKind.Boolean:
                        targetValue = XmlConvert.ToBoolean(text);
                        break;

                    case EdmPrimitiveTypeKind.Byte:
                        targetValue = XmlConvert.ToByte(text);
                        break;

                    case EdmPrimitiveTypeKind.SByte:
                        targetValue = XmlConvert.ToSByte(text);
                        break;

                    case EdmPrimitiveTypeKind.Int16:
                        targetValue = XmlConvert.ToInt16(text);
                        break;

                    case EdmPrimitiveTypeKind.Int32:
                        targetValue = XmlConvert.ToInt32(text);
                        break;

                    case EdmPrimitiveTypeKind.Int64:
                        UriParserHelper.TryRemoveLiteralSuffix(ExpressionConstants.LiteralSuffixInt64, ref text);
                        targetValue = XmlConvert.ToInt64(text);
                        break;

                    case EdmPrimitiveTypeKind.Single:
                        UriParserHelper.TryRemoveLiteralSuffix(ExpressionConstants.LiteralSuffixSingle, ref text);
                        targetValue = XmlConvert.ToSingle(text);
                        break;

                    case EdmPrimitiveTypeKind.Double:
                        UriParserHelper.TryRemoveLiteralSuffix(ExpressionConstants.LiteralSuffixDouble, ref text);
                        targetValue = XmlConvert.ToDouble(text);
                        break;

                    case EdmPrimitiveTypeKind.Decimal:
                        UriParserHelper.TryRemoveLiteralSuffix(ExpressionConstants.LiteralSuffixDecimal, ref text);
                        try
                        {
                            targetValue = XmlConvert.ToDecimal(text);
                        }
                        catch (FormatException)
                        {
                            // we need to support exponential format for decimals since we used to support them in V1
                            decimal result;
                            if (Decimal.TryParse(text, NumberStyles.Float, NumberFormatInfo.InvariantInfo, out result))
                            {
                                targetValue = result;
                            }
                            else
                            {
                                targetValue = default(Decimal);
                                return(false);
                            }
                        }

                        break;

                    default:
                        throw new ODataException(ODataErrorStrings.General_InternalError(InternalErrorCodes.UriPrimitiveTypeParser_TryUriStringToPrimitive));
                    }

                    return(true);
                }
                catch (FormatException)
                {
                    targetValue = null;
                    return(false);
                }
                catch (OverflowException)
                {
                    targetValue = null;
                    return(false);
                }
            }
            catch (Exception primitiveParserException)
            {
                exception = new UriLiteralParsingException(
                    string.Format(CultureInfo.InvariantCulture, ODataErrorStrings.UriPrimitiveTypeParsers_FailedToParseTextToPrimitiveValue(text, targetType),
                                  primitiveParserException));
                targetValue = null;
                return(false);
            }
        }