/// <summary> /// Gets the payload type name for an OData OM instance for JsonLight. /// </summary> /// <param name="payloadItem">The payload item to get the type name for.</param> /// <returns>The type name as read from the payload item (or constructed for primitive items).</returns> internal static string GetPayloadTypeName(object payloadItem) { if (payloadItem == null) { return(null); } TypeCode typeCode = ODataPlatformHelper.GetTypeCode(payloadItem.GetType()); switch (typeCode) { // In JSON only boolean, String, Int32 and Double are recognized as primitive types // (without additional type conversion). So only check for those; if not one of these primitive // types it must be a complex, entity or collection value. case TypeCode.Boolean: return(Metadata.EdmConstants.EdmBooleanTypeName); case TypeCode.String: return(Metadata.EdmConstants.EdmStringTypeName); case TypeCode.Int32: return(Metadata.EdmConstants.EdmInt32TypeName); case TypeCode.Double: return(Metadata.EdmConstants.EdmDoubleTypeName); default: Debug.Assert(typeCode == TypeCode.Object, "If not one of the primitive types above, it must be an object in JSON."); break; } ODataComplexValue complexValue = payloadItem as ODataComplexValue; if (complexValue != null) { return(complexValue.TypeName); } ODataCollectionValue collectionValue = payloadItem as ODataCollectionValue; if (collectionValue != null) { return(EdmLibraryExtensions.GetCollectionTypeFullName(collectionValue.TypeName)); } ODataEntry entry = payloadItem as ODataEntry; if (entry != null) { return(entry.TypeName); } throw new ODataException(ODataErrorStrings.General_InternalError(InternalErrorCodes.ODataJsonLightReader_ReadEntryStart)); }
internal static object CoerceNumericType(object primitiveValue, IEdmPrimitiveType targetEdmType) { // This is implemented to match TypePromotionUtils and MetadataUtilsCommon.CanConvertPrimitiveTypeTo() ExceptionUtils.CheckArgumentNotNull(primitiveValue, "primitiveValue"); ExceptionUtils.CheckArgumentNotNull(targetEdmType, "targetEdmType"); Type fromType = primitiveValue.GetType(); TypeCode fromTypeCode = ODataPlatformHelper.GetTypeCode(fromType); EdmPrimitiveTypeKind targetPrimitiveKind = targetEdmType.PrimitiveKind; switch (fromTypeCode) { case TypeCode.SByte: switch (targetPrimitiveKind) { case EdmPrimitiveTypeKind.SByte: return(primitiveValue); case EdmPrimitiveTypeKind.Int16: return(Convert.ToInt16((SByte)primitiveValue)); case EdmPrimitiveTypeKind.Int32: return(Convert.ToInt32((SByte)primitiveValue)); case EdmPrimitiveTypeKind.Int64: return(Convert.ToInt64((SByte)primitiveValue)); case EdmPrimitiveTypeKind.Single: return(Convert.ToSingle((SByte)primitiveValue)); case EdmPrimitiveTypeKind.Double: return(Convert.ToDouble((SByte)primitiveValue)); case EdmPrimitiveTypeKind.Decimal: return(Convert.ToDecimal((SByte)primitiveValue)); } break; case TypeCode.Byte: switch (targetPrimitiveKind) { case EdmPrimitiveTypeKind.Byte: return(primitiveValue); case EdmPrimitiveTypeKind.Int16: return(Convert.ToInt16((Byte)primitiveValue)); case EdmPrimitiveTypeKind.Int32: return(Convert.ToInt32((Byte)primitiveValue)); case EdmPrimitiveTypeKind.Int64: return(Convert.ToInt64((Byte)primitiveValue)); case EdmPrimitiveTypeKind.Single: return(Convert.ToSingle((Byte)primitiveValue)); case EdmPrimitiveTypeKind.Double: return(Convert.ToDouble((Byte)primitiveValue)); case EdmPrimitiveTypeKind.Decimal: return(Convert.ToDecimal((Byte)primitiveValue)); } break; case TypeCode.Int16: switch (targetPrimitiveKind) { case EdmPrimitiveTypeKind.Int16: return(primitiveValue); case EdmPrimitiveTypeKind.Int32: return(Convert.ToInt32((Int16)primitiveValue)); case EdmPrimitiveTypeKind.Int64: return(Convert.ToInt64((Int16)primitiveValue)); case EdmPrimitiveTypeKind.Single: return(Convert.ToSingle((Int16)primitiveValue)); case EdmPrimitiveTypeKind.Double: return(Convert.ToDouble((Int16)primitiveValue)); case EdmPrimitiveTypeKind.Decimal: return(Convert.ToDecimal((Int16)primitiveValue)); } break; case TypeCode.Int32: switch (targetPrimitiveKind) { case EdmPrimitiveTypeKind.Int32: return(primitiveValue); case EdmPrimitiveTypeKind.Int64: return(Convert.ToInt64((Int32)primitiveValue)); case EdmPrimitiveTypeKind.Single: return(Convert.ToSingle((Int32)primitiveValue)); case EdmPrimitiveTypeKind.Double: return(Convert.ToDouble((Int32)primitiveValue)); case EdmPrimitiveTypeKind.Decimal: return(Convert.ToDecimal((Int32)primitiveValue)); } break; case TypeCode.Int64: switch (targetPrimitiveKind) { case EdmPrimitiveTypeKind.Int64: return(primitiveValue); case EdmPrimitiveTypeKind.Single: return(Convert.ToSingle((Int64)primitiveValue)); case EdmPrimitiveTypeKind.Double: return(Convert.ToDouble((Int64)primitiveValue)); case EdmPrimitiveTypeKind.Decimal: return(Convert.ToDecimal((Int64)primitiveValue)); } break; case TypeCode.Single: switch (targetPrimitiveKind) { case EdmPrimitiveTypeKind.Single: return(primitiveValue); case EdmPrimitiveTypeKind.Double: /*to string then to double, avoid losing precision like "(double)123.001f" which is 123.00099945068359, instead of 123.001d.*/ return(double.Parse(((Single)primitiveValue).ToString("R", CultureInfo.InvariantCulture), CultureInfo.InvariantCulture)); case EdmPrimitiveTypeKind.Decimal: return(Convert.ToDecimal((Single)primitiveValue)); } break; case TypeCode.Double: switch (targetPrimitiveKind) { case EdmPrimitiveTypeKind.Double: return(primitiveValue); case EdmPrimitiveTypeKind.Decimal: // TODO: extract these convertion steps to an individual function decimal doubleToDecimalR; // To keep the full presion of the current value, which if necessary is all 17 digits of precision supported by the Double type. if (decimal.TryParse(((Double)primitiveValue).ToString("R", CultureInfo.InvariantCulture), out doubleToDecimalR)) { return(doubleToDecimalR); } return(Convert.ToDecimal((Double)primitiveValue)); } break; case TypeCode.Decimal: switch (targetPrimitiveKind) { case EdmPrimitiveTypeKind.Decimal: return(primitiveValue); } break; default: break; } return(null); }
/// <summary> /// Writes a primitive value. /// </summary> /// <param name="jsonWriter">The <see cref="JsonWriter"/> to write to.</param> /// <param name="value">The value to write.</param> internal static void WritePrimitiveValue(this IJsonWriter jsonWriter, object value) { TypeCode typeCode = ODataPlatformHelper.GetTypeCode(value.GetType()); switch (typeCode) { case TypeCode.Boolean: jsonWriter.WriteValue((bool)value); break; case TypeCode.Byte: jsonWriter.WriteValue((byte)value); break; case TypeCode.Decimal: jsonWriter.WriteValue((decimal)value); break; case TypeCode.Double: jsonWriter.WriteValue((double)value); break; case TypeCode.Int16: jsonWriter.WriteValue((Int16)value); break; case TypeCode.Int32: jsonWriter.WriteValue((Int32)value); break; case TypeCode.Int64: jsonWriter.WriteValue((Int64)value); break; case TypeCode.SByte: jsonWriter.WriteValue((sbyte)value); break; case TypeCode.Single: jsonWriter.WriteValue((Single)value); break; case TypeCode.String: jsonWriter.WriteValue((string)value); break; default: { byte[] valueAsByteArray = value as byte[]; if (valueAsByteArray != null) { jsonWriter.WriteValue(valueAsByteArray); break; } if (value is DateTimeOffset) { jsonWriter.WriteValue((DateTimeOffset)value); break; } if (value is Guid) { jsonWriter.WriteValue((Guid)value); break; } if (value is TimeSpan) { jsonWriter.WriteValue((TimeSpan)value); break; } } throw new ODataException(ODataErrorStrings.ODataJsonWriter_UnsupportedValueType(value.GetType().FullName)); } }