Пример #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SignalSample{T}" /> class.
 /// </summary>
 /// <param name="unitOfOutput">
 /// The discrete unit of output that was read from the channel's output stream.
 /// </param>
 /// <param name="lookBehindRange">
 /// A range of discrete units of output preceding <paramref name="unitOfOutput" /> in the channel's output stream, or an
 /// empty range if look-behind was not requested.
 /// </param>
 /// <param name="lookAheadRange">
 /// A range of discrete units of output following <paramref name="unitOfOutput" /> in the channel's output stream, or an
 /// empty range if look-ahead was not requested.
 /// </param>
 /// <exception cref="ArgumentNullException">
 /// <paramref name="unitOfOutput" /> is <see langword="null" /> -or- <paramref name="lookAheadRange" /> is
 /// <see langword="null" /> -or- <paramref name="lookBehindRange" /> is <see langword="null" />.
 /// </exception>
 public SignalSample(DiscreteUnitOfOutput <T> unitOfOutput, OutputRange <T> lookBehindRange, OutputRange <T> lookAheadRange)
 {
     UnitOfOutput    = unitOfOutput.RejectIf().IsNull(nameof(unitOfOutput));
     LookAheadRange  = lookAheadRange.RejectIf().IsNull(nameof(lookAheadRange));
     LookBehindRange = lookBehindRange.RejectIf().IsNull(nameof(lookBehindRange));
 }
Пример #2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SignalSample{T}" /> class.
 /// </summary>
 /// <param name="unitOfOutput">
 /// The discrete unit of output that was read from the channel's output stream.
 /// </param>
 /// <exception cref="ArgumentNullException">
 /// <paramref name="unitOfOutput" /> is <see langword="null" />.
 /// </exception>
 public SignalSample(DiscreteUnitOfOutput <T> unitOfOutput)
     : this(unitOfOutput, new OutputRange <T>())
 {
     return;
 }
Пример #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SignalSample{T}" /> class.
 /// </summary>
 /// <param name="unitOfOutput">
 /// The discrete unit of output that was read from the channel's output stream.
 /// </param>
 /// <param name="lookBehindRange">
 /// A range of discrete units of output preceding <paramref name="unitOfOutput" /> in the channel's output stream, or an
 /// empty range if look-behind was not requested.
 /// </param>
 /// <exception cref="ArgumentNullException">
 /// <paramref name="unitOfOutput" /> is <see langword="null" /> -or- <paramref name="lookBehindRange" /> is
 /// <see langword="null" />.
 /// </exception>
 public SignalSample(DiscreteUnitOfOutput <T> unitOfOutput, OutputRange <T> lookBehindRange)
     : this(unitOfOutput, lookBehindRange, new OutputRange <T>())
 {
     return;
 }
Пример #4
0
        /// <summary>
        /// Asynchronously reads a sample from the channel's output stream at the specified index.
        /// </summary>
        /// <param name="index">
        /// A zero-based index within the output stream at which to read.
        /// </param>
        /// <param name="lookBehindLength">
        /// The number of discrete units of output preceding the specified index to include with the sample. The default value is
        /// zero.
        /// </param>
        /// <param name="lookAheadLength">
        /// The number of discrete units of output following the specified index to include with the sample. The default value is
        /// zero.
        /// </param>
        /// <returns>
        /// A task representing the asynchronous operation and containing a sample from the channel's output stream at the specified
        /// index.
        /// </returns>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <see cref="InvalidReadBehavior" /> is equal to <see cref="InvalidReadBehavior.RaiseException" /> and
        /// <paramref name="index" /> is less than zero -or- <paramref name="lookBehindLength" /> is less than zero -or-
        /// <paramref name="lookAheadLength" /> is less than zero -or- the resulting sample range precedes the start boundary of the
        /// channel's output stream -or- the resulting sample range exceeds the end boundary of the channel's output stream.
        /// </exception>
        /// <exception cref="ChannelReadException">
        /// An exception was raised while performing the read operation, or the channel was unavailable.
        /// </exception>
        public Task <SignalSample <T> > ReadAsync(Int32 index, Int32 lookBehindLength, Int32 lookAheadLength)
        {
            switch (Status)
            {
            case ChannelStatus.Live:

                break;

            case ChannelStatus.Silent:

                return(Task.FromResult(new SignalSample <T>(ReadSilence(index))));

            case ChannelStatus.Unavailable:

                throw new ChannelReadException(this);

            default:

                throw new InvalidOperationException($"The specified channel status, {Status}, is not supported.");
            }

            if (OutputLengthIsFixed)
            {
                var argumentOutOfRangeExceptionParameterName = (String)null;

                if (index < 0 || index >= OutputLength)
                {
                    argumentOutOfRangeExceptionParameterName = nameof(index);
                }
                else if (lookBehindLength < 0 || lookBehindLength > index)
                {
                    argumentOutOfRangeExceptionParameterName = nameof(lookBehindLength);
                }
                else if (lookAheadLength < 0 || lookAheadLength >= (OutputLength - index))
                {
                    argumentOutOfRangeExceptionParameterName = nameof(lookAheadLength);
                }

                if (argumentOutOfRangeExceptionParameterName is null == false)
                {
                    switch (InvalidReadBehavior)
                    {
                    case InvalidReadBehavior.RaiseException:

                        throw new ArgumentOutOfRangeException(argumentOutOfRangeExceptionParameterName);

                    case InvalidReadBehavior.ReadSilence:

                        return(Task.FromResult(new SignalSample <T>(ReadSilence(index))));

                    default:

                        throw new InvalidOperationException($"The specified invalid read behavior, {InvalidReadBehavior}, is not supported.");
                    }
                }
            }

            var startIndex = (index - lookBehindLength);
            var count      = (lookBehindLength + lookAheadLength + 1);
            var endIndex   = (startIndex + count);
            var range      = default(T[]);

            using (var controlToken = StateControl.Enter())
            {
                try
                {
                    var outputRange = new T[count];

                    if (TryRead(startIndex, count, outputRange))
                    {
                        range = outputRange;
                    }
                    else
                    {
                        Status = ChannelStatus.Unavailable;
                        throw new ChannelReadException(this);
                    }
                }
                catch (ChannelReadException)
                {
                    Status = ChannelStatus.Unavailable;
                    throw;
                }
                catch (Exception exception)
                {
                    Status = ChannelStatus.Unavailable;
                    throw new ChannelReadException(this, exception);
                }
            }

            var unitOfOutput   = new DiscreteUnitOfOutput <T>(range[lookBehindLength], lookBehindLength);
            var lookBehindList = new List <DiscreteUnitOfOutput <T> >(lookBehindLength);
            var lookAheadList  = new List <DiscreteUnitOfOutput <T> >(lookAheadLength);

            for (var i = 0; i < lookBehindLength; i++)
            {
                lookBehindList.Add(new DiscreteUnitOfOutput <T>(range[i], (startIndex + i)));
            }

            for (var i = 0; i < lookAheadLength; i++)
            {
                var adjustment = (lookBehindLength + i + 1);
                lookAheadList.Add(new DiscreteUnitOfOutput <T>(range[adjustment], (startIndex + adjustment)));
            }

            return(Task.FromResult(new SignalSample <T>(unitOfOutput, new OutputRange <T>(lookBehindList), new OutputRange <T>(lookAheadList))));
        }