/// <summary> /// Converts a string to a Duration value. /// </summary> /// <param name="text">String text to convert.</param> /// <param name="targetValue">After invocation, converted value.</param> /// <returns>true if the value was converted; false otherwise.</returns> /// <remarks>Copy of WebConvert.TryKeyStringToTime.</remarks> private static bool TryUriStringToDuration(string text, out TimeSpan targetValue) { if (!TryRemoveLiteralPrefix(ExpressionConstants.LiteralPrefixDuration, ref text)) { targetValue = default(TimeSpan); return(false); } if (!TryRemoveQuotes(ref text)) { targetValue = default(TimeSpan); return(false); } try { targetValue = EdmValueParser.ParseDuration(text); return(true); } catch (FormatException) { targetValue = default(TimeSpan); return(false); } }
public void ParseDurationWithMoreThan7DecimalPlacesShouldNotLosePrecisionUpTo7() { // 12 is the max precison supported in OData protocol, but Clr TimeSpan only supports up to 7 decimal places TimeSpan result = EdmValueParser.ParseDuration("PT0.123456789012S"); Assert.Equal(new TimeSpan(1234567), result); }
public void ParseDurationWithYearAndMonthPartsShouldThrowFormatException() { // The following values are valid xs:duration so they are successfully converted to TimeSpan if we use XmlConvert.ToTimeSpan alone var invalidDayTimeDurations = new[] { "P1Y1M", "P1Y1M1D", "P1Y1M1DT1H", "P1Y1M1DT1H1M", "P1Y1M1DT1H1M1S", "P1Y1MT1H", "P1Y1MT1H1M", "P1Y1MT1H1M1S", "-P1Y1M1D", "-P1Y1M1DT1H", "-P1Y1M1DT1H1M", "-P1Y1M1DT1H1M1S", "-P1Y1MT1H", "-P1Y1MT1H1M", "-P1Y1MT1H1M1S", }; foreach (var invalidDuration in invalidDayTimeDurations) { Action parseDuration = () => { TimeSpan result = EdmValueParser.ParseDuration(invalidDuration); }; Assert.Throws <FormatException>(parseDuration); } }
public void ParseDurationWithWhiteSpaceShouldThrowFormatException() { Action parseDuration = () => { TimeSpan result = EdmValueParser.ParseDuration(" "); }; parseDuration.ShouldThrow <FormatException>(); }
public void ParseDurationThatOverflowsShouldThrowOverflowException() { Action tryParseDuration = () => { TimeSpan result = EdmValueParser.ParseDuration("P10675199DT2H48M5.4775808S"); }; Assert.Throws <OverflowException>(tryParseDuration); }
public void ParseDurationWithNonDurationValueShouldThrowFormatException() { Action parseDuration = () => { TimeSpan result = EdmValueParser.ParseDuration("+P1D"); }; Assert.Throws <FormatException>(parseDuration); }
public void ParseDurationWithEmptyStringShouldThrowFormatException() { Action parseDuration = () => { TimeSpan result = EdmValueParser.ParseDuration(string.Empty); }; Assert.Throws <FormatException>(parseDuration); }
/// <summary> /// Converts the given JSON string value to the expected type as per OData conversion rules for JSON values. /// </summary> /// <param name="stringValue">String value to the converted.</param> /// <param name="targetType">Target type to which the string value needs to be converted.</param> /// <returns>Object which is in sync with the target type.</returns> private static object ConvertStringValue(string stringValue, Type targetType) { // COMPAT 53: Support for System.Data.Linq.Binary and System.Xml.Linq.XElement if (targetType == typeof(byte[])) { return(Convert.FromBase64String(stringValue)); } if (targetType == typeof(Guid)) { return(new Guid(stringValue)); } // Convert.ChangeType does not support TimeSpan. if (targetType == typeof(TimeSpan)) { return(EdmValueParser.ParseDuration(stringValue)); } // Date if (targetType == typeof(Date)) { return(PlatformHelper.ConvertStringToDate(stringValue)); } // Time if (targetType == typeof(TimeOfDay)) { return(PlatformHelper.ConvertStringToTimeOfDay(stringValue)); } // DateTimeOffset needs to be read using the XML rules (as per the JSON Light spec). if (targetType == typeof(DateTimeOffset)) { return(PlatformHelper.ConvertStringToDateTimeOffset(stringValue)); } if (targetType == typeof(Double) || targetType == typeof(Single)) { // Accept Infinity and -Infinity to preserve consistency if (stringValue == CultureInfo.InvariantCulture.NumberFormat.PositiveInfinitySymbol) { stringValue = JsonValueUtils.ODataJsonPositiveInfinitySymbol; } else if (stringValue == CultureInfo.InvariantCulture.NumberFormat.NegativeInfinitySymbol) { stringValue = JsonValueUtils.ODataJsonNegativeInfinitySymbol; } return(Convert.ChangeType(stringValue, targetType, JsonValueUtils.ODataNumberFormatInfo)); } // For string types, we support conversion to all possible primitive types return(Convert.ChangeType(stringValue, targetType, CultureInfo.InvariantCulture)); }
/// <summary> /// Attempts to parse a TimeSpan value from the specified text. /// </summary> /// <param name="value">Input string</param> /// <param name="result">The TimeSpan resulting from parsing the string value</param> /// <returns>true if the value was parsed successfully, false otherwise</returns> internal static bool TryParseDuration(string value, out TimeSpan?result) { try { result = EdmValueParser.ParseDuration(value); return(true); } catch (FormatException) { result = null; return(false); } catch (OverflowException) { result = null; return(false); } }
public void ParseDurationWithMinValuePlusOneShouldReturnCorrectTimeSpan() { TimeSpan result = EdmValueParser.ParseDuration("-P10675199DT2H48M5.4775807S"); Assert.Equal(TimeSpan.MinValue + new TimeSpan(1), result); }
public void ParseDurationWithMaxValueShouldReturnCorrectTimeSpan() { TimeSpan result = EdmValueParser.ParseDuration("P10675199DT2H48M5.4775807S"); Assert.Equal(TimeSpan.MaxValue, result); }
public void ParseDurationWithLeadingSpaces() { TimeSpan result = EdmValueParser.ParseDuration(" PT1S"); Assert.Equal(new TimeSpan(0, 0, 1), result); }
public void ParseDurationWithMaxValueShouldReturnCorrectTimeSpan() { TimeSpan result = EdmValueParser.ParseDuration("P10675199DT2H48M5.4775807S"); result.ShouldBeEquivalentTo(TimeSpan.MaxValue); }
public void ParseDurationWith7DecimalPlacesShouldNotLosePrecision() { TimeSpan result = EdmValueParser.ParseDuration("PT0.0000009S"); Assert.Equal(new TimeSpan(9), result); }
public void ParseDurationWithLeadingSpaces() { TimeSpan result = EdmValueParser.ParseDuration(" PT1S"); result.Should().Be(new TimeSpan(0, 0, 1)); }
public void ParseDurationWithMinValuePlusOneShouldReturnCorrectTimeSpan() { TimeSpan result = EdmValueParser.ParseDuration("-P10675199DT2H48M5.4775807S"); result.ShouldBeEquivalentTo(TimeSpan.MinValue + new TimeSpan(1)); }
internal static object ConvertStringToPrimitive(string text, IEdmPrimitiveTypeReference targetTypeReference) { Debug.Assert(text != null, "text != null"); Debug.Assert(targetTypeReference != null, "targetTypeReference != null"); try { EdmPrimitiveTypeKind primitiveKind = targetTypeReference.PrimitiveKind(); switch (primitiveKind) { case EdmPrimitiveTypeKind.Binary: return(Convert.FromBase64String(text)); case EdmPrimitiveTypeKind.Boolean: return(ConvertXmlBooleanValue(text)); case EdmPrimitiveTypeKind.Byte: return(XmlConvert.ToByte(text)); case EdmPrimitiveTypeKind.DateTimeOffset: return(PlatformHelper.ConvertStringToDateTimeOffset(text)); case EdmPrimitiveTypeKind.Decimal: return(XmlConvert.ToDecimal(text)); case EdmPrimitiveTypeKind.Double: return(XmlConvert.ToDouble(text)); case EdmPrimitiveTypeKind.Guid: return(new Guid(text)); case EdmPrimitiveTypeKind.Int16: return(XmlConvert.ToInt16(text)); case EdmPrimitiveTypeKind.Int32: return(XmlConvert.ToInt32(text)); case EdmPrimitiveTypeKind.Int64: return(XmlConvert.ToInt64(text)); case EdmPrimitiveTypeKind.SByte: return(XmlConvert.ToSByte(text)); case EdmPrimitiveTypeKind.Single: return(XmlConvert.ToSingle(text)); case EdmPrimitiveTypeKind.String: return(text); case EdmPrimitiveTypeKind.Duration: return(EdmValueParser.ParseDuration(text)); case EdmPrimitiveTypeKind.Date: return(PlatformHelper.ConvertStringToDate(text)); case EdmPrimitiveTypeKind.TimeOfDay: return(PlatformHelper.ConvertStringToTimeOfDay(text)); case EdmPrimitiveTypeKind.Stream: case EdmPrimitiveTypeKind.None: case EdmPrimitiveTypeKind.Geography: case EdmPrimitiveTypeKind.GeographyCollection: case EdmPrimitiveTypeKind.GeographyPoint: case EdmPrimitiveTypeKind.GeographyLineString: case EdmPrimitiveTypeKind.GeographyPolygon: case EdmPrimitiveTypeKind.GeometryCollection: case EdmPrimitiveTypeKind.GeographyMultiPolygon: case EdmPrimitiveTypeKind.GeographyMultiLineString: case EdmPrimitiveTypeKind.GeographyMultiPoint: case EdmPrimitiveTypeKind.Geometry: case EdmPrimitiveTypeKind.GeometryPoint: case EdmPrimitiveTypeKind.GeometryLineString: case EdmPrimitiveTypeKind.GeometryPolygon: case EdmPrimitiveTypeKind.GeometryMultiPolygon: case EdmPrimitiveTypeKind.GeometryMultiLineString: case EdmPrimitiveTypeKind.GeometryMultiPoint: default: // Note that Astoria supports XElement and Binary as well, but they are serialized as string or byte[] // and the metadata will actually talk about string and byte[] as well. Astoria will perform the conversion if necessary. throw new ODataException(Strings.General_InternalError(InternalErrorCodes.AtomValueUtils_ConvertStringToPrimitive)); } } catch (Exception e) { if (!ExceptionUtils.IsCatchableExceptionType(e)) { throw; } throw ReaderValidationUtils.GetPrimitiveTypeConversionException(targetTypeReference, e, text); } }
/// <summary> /// Create an instance of primitive type from a string representation /// </summary> /// <param name="text">The string representation</param> /// <returns>An instance of primitive type</returns> internal override object Parse(String text) { return(EdmValueParser.ParseDuration(text)); }
public void ParseDurationWith7DecimalPlacesShouldNotLosePrecision() { TimeSpan result = EdmValueParser.ParseDuration("PT0.0000009S"); result.Should().Be(new TimeSpan(9)); }