internal ODataMetadataOutputContext(
            ODataFormat format,
            Stream messageStream,
            Encoding encoding,
            ODataMessageWriterSettings messageWriterSettings,
            bool writingResponse,
            bool synchronous,
            IEdmModel model,
            IODataUrlResolver urlResolver)
            : base(format, messageWriterSettings, writingResponse, synchronous, model, urlResolver)
        {
            Debug.Assert(messageStream != null, "messageStream != null");
            Debug.Assert(synchronous, "Metadata output context is only supported in synchronous operations.");

            try
            {
                this.messageOutputStream = messageStream;
                this.xmlWriter           = ODataAtomWriterUtils.CreateXmlWriter(messageStream, messageWriterSettings, encoding);
            }
            catch (Exception e)
            {
                // Dispose the message stream if we failed to create the output context.
                if (ExceptionUtils.IsCatchableExceptionType(e) && messageStream != null)
                {
                    messageStream.Dispose();
                }

                throw;
            }
        }
        /// <summary>
        /// Returns enumeration of tasks to run to buffer the entire input stream.
        /// </summary>
        /// <returns>Enumeration of tasks to run to buffer the input stream.</returns>
        /// <remarks>This method relies on lazy eval of the enumerator, never enumerate through it synchronously.</remarks>
        private IEnumerable <Task> BufferInputStream()
        {
            while (this.inputStream != null)
            {
                Debug.Assert(this.currentBufferIndex >= -1 && this.currentBufferIndex < this.buffers.Count, "The currentBufferIndex is outside of the valid range.");

                DataBuffer currentBuffer = this.currentBufferIndex == -1 ? null : this.buffers[this.currentBufferIndex];

                // Here we intentionally leave some memory unused (smaller than MinReadBufferSize)
                // in order to issue big enough read requests. This is a perf optimization.
                if (currentBuffer != null && currentBuffer.FreeBytes < DataBuffer.MinReadBufferSize)
                {
                    currentBuffer = null;
                }

                if (currentBuffer == null)
                {
                    currentBuffer = this.AddNewBuffer();
                }

                yield return(Task.Factory.FromAsync(
                                 (asyncCallback, asyncState) => this.inputStream.BeginRead(
                                     currentBuffer.Buffer,
                                     currentBuffer.OffsetToWriteTo,
                                     currentBuffer.FreeBytes,
                                     asyncCallback,
                                     asyncState),
                                 (asyncResult) =>
                {
                    try
                    {
                        int bytesRead = this.inputStream.EndRead(asyncResult);
                        if (bytesRead == 0)
                        {
                            this.inputStream = null;
                        }
                        else
                        {
                            currentBuffer.MarkBytesAsWritten(bytesRead);
                        }
                    }
                    catch (Exception exception)
                    {
                        if (!ExceptionUtils.IsCatchableExceptionType(exception))
                        {
                            throw;
                        }

                        this.inputStream = null;
                        throw;
                    }
                },
                                 null));
            }
        }
        private T InterceptException <T>(Func <T> action)
        {
            try
            {
                return(action());
            }
            catch (Exception e)
            {
                if (ExceptionUtils.IsCatchableExceptionType(e))
                {
                    this.EnterScope(ODataParameterReaderState.Exception, null, null);
                }

                throw;
            }
        }
        private T InterceptException <T>(Func <T> action)
        {
            try
            {
                return(action());
            }
            catch (Exception e)
            {
                if (ExceptionUtils.IsCatchableExceptionType(e))
                {
                    this.State = ODataBatchReaderState.Exception;
                }

                throw;
            }
        }
Exemple #5
0
        internal ODataMetadataInputContext(
            ODataFormat format,
            Stream messageStream,
            Encoding encoding,
            ODataMessageReaderSettings messageReaderSettings,
            bool readingResponse,
            bool synchronous,
            IEdmModel model,
            IODataUrlResolver urlResolver)
            : base(format, messageReaderSettings, readingResponse, synchronous, model, urlResolver)
        {
            Debug.Assert(messageStream != null, "stream != null");

            ExceptionUtils.CheckArgumentNotNull(format, "format");
            ExceptionUtils.CheckArgumentNotNull(messageReaderSettings, "messageReaderSettings");

            try
            {
                // Which encoding do we use when reading XML payloads
                this.baseXmlReader = ODataAtomReaderUtils.CreateXmlReader(messageStream, encoding, messageReaderSettings);

                // We use the buffering reader here only for in-stream error detection (not for buffering).
                this.xmlReader = new BufferingXmlReader(
                    this.baseXmlReader,
                    /*parentXmlReader*/ null,
                    messageReaderSettings.BaseUri,
                    /*disableXmlBase*/ false,
                    messageReaderSettings.MessageQuotas.MaxNestingDepth);
            }
            catch (Exception e)
            {
                // Dispose the message stream if we failed to create the input context.
                if (ExceptionUtils.IsCatchableExceptionType(e) && messageStream != null)
                {
                    messageStream.Dispose();
                }

                throw;
            }
        }
        internal ODataRawInputContext(
            ODataFormat format,
            Stream messageStream,
            Encoding encoding,
            ODataMessageReaderSettings messageReaderSettings,
            ODataVersion version,
            bool readingResponse,
            bool synchronous,
            IEdmModel model,
            IODataUrlResolver urlResolver,
            ODataPayloadKind readerPayloadKind)
            : base(format, messageReaderSettings, version, readingResponse, synchronous, model, urlResolver)
        {
            Debug.Assert(messageStream != null, "stream != null");
            Debug.Assert(readerPayloadKind != ODataPayloadKind.Unsupported, "readerPayloadKind != ODataPayloadKind.Unsupported");

            ExceptionUtils.CheckArgumentNotNull(format, "format");
            ExceptionUtils.CheckArgumentNotNull(messageReaderSettings, "messageReaderSettings");

            try
            {
                this.stream            = messageStream;
                this.encoding          = encoding;
                this.readerPayloadKind = readerPayloadKind;
            }
            catch (Exception e)
            {
                // Dispose the message stream if we failed to create the input context.
                if (ExceptionUtils.IsCatchableExceptionType(e) && messageStream != null)
                {
                    messageStream.Dispose();
                }

                throw;
            }
        }
Exemple #7
0
        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>
        /// Converts the given payload value to the type defined in a type definition.
        /// </summary>
        /// <param name="value">The given payload value.</param>
        /// <param name="edmTypeReference">The expected type reference from model.</param>
        /// <returns>The converted value of the type.</returns>
        public virtual object ConvertFromPayloadValue(object value, IEdmTypeReference edmTypeReference)
        {
            IEdmPrimitiveTypeReference primitiveTypeReference = edmTypeReference as IEdmPrimitiveTypeReference;

            Debug.Assert(primitiveTypeReference != null, "primitiveTypeReference != null");
            try
            {
                Type targetType = EdmLibraryExtensions.GetPrimitiveClrType(primitiveTypeReference.PrimitiveDefinition(), false);

                string stringValue = value as string;
                if (stringValue != null)
                {
                    return(ConvertStringValue(stringValue, targetType));
                }
                else if (value is Int32)
                {
                    return(ConvertInt32Value((int)value, targetType, primitiveTypeReference));
                }
                else if (value is Decimal)
                {
                    Decimal decimalValue = (Decimal)value;
                    if (targetType == typeof(Int64))
                    {
                        return(Convert.ToInt64(decimalValue));
                    }

                    if (targetType == typeof(Double))
                    {
                        return(Convert.ToDouble(decimalValue));
                    }

                    if (targetType == typeof(Single))
                    {
                        return(Convert.ToSingle(decimalValue));
                    }

                    if (targetType != typeof(Decimal))
                    {
                        throw new ODataException(ODataErrorStrings.ODataJsonReaderUtils_CannotConvertDecimal(primitiveTypeReference.FullName()));
                    }
                }
                else if (value is Double)
                {
                    Double doubleValue = (Double)value;
                    if (targetType == typeof(Single))
                    {
                        return(Convert.ToSingle(doubleValue));
                    }

                    if (targetType != typeof(Double))
                    {
                        throw new ODataException(ODataErrorStrings.ODataJsonReaderUtils_CannotConvertDouble(primitiveTypeReference.FullName()));
                    }
                }
                else if (value is bool)
                {
                    if (targetType != typeof(bool))
                    {
                        throw new ODataException(ODataErrorStrings.ODataJsonReaderUtils_CannotConvertBoolean(primitiveTypeReference.FullName()));
                    }
                }
                else if (value is DateTime)
                {
                    if (targetType != typeof(DateTime))
                    {
                        throw new ODataException(ODataErrorStrings.ODataJsonReaderUtils_CannotConvertDateTime(primitiveTypeReference.FullName()));
                    }
                }
                else if (value is DateTimeOffset)
                {
                    if (targetType != typeof(DateTimeOffset))
                    {
                        throw new ODataException(ODataErrorStrings.ODataJsonReaderUtils_CannotConvertDateTimeOffset(primitiveTypeReference.FullName()));
                    }
                }
            }
            catch (Exception e)
            {
                if (!ExceptionUtils.IsCatchableExceptionType(e))
                {
                    throw;
                }

                throw ReaderValidationUtils.GetPrimitiveTypeConversionException(primitiveTypeReference, e, value.ToString());
            }

            // otherwise just return the value without doing any conversion
            return(value);
        }