Example #1
0
        public void AppendSource(IConcatStreamSource source, bool optimizeIfPossible = true)
        {
            if (disposed)
            {
                throw new ObjectDisposedException(nameof(ConcatStream));
            }
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            lock (sources)
            {
                // CanSeek = first source valid, every other source must be 0 or Length unless it's sourceIndex. Doesn't optimize
                // Can(not)Seek = always valid, does optimization
                // If reading and seeking have already occured, don't allow appending seekable sources, otherwise internal state can be messed up

                var priorCanSeek = CanSeek;

                if (source.CanSeek)
                {
                    if (priorCanSeek && (HasFlags(PropertyFlags.EventSeekingOccured) || HasFlags(PropertyFlags.EventReadingOccured)))
                    {
                        throw new InvalidOperationException("Cannot append a seekable source to a seekable stream if reading or seeking has already occured");
                    }
                }
                var currentMeasuredIndexPosition = -1;
                if (priorCanSeek)
                {
                    currentMeasuredIndexPosition = GetIndexPosition();
                    if (source.CanSeek && sources.Count != 0 &&
                        source.Position != 0 && source.Position != source.Length &&
                        currentMeasuredIndexPosition != sources.Count)
                    {
                        throw new ArgumentException("Invalid seekable source");
                    }
                }

                ReplaceFlags(PropertyFlags.DirtyMask, PropertyFlags.DirtyAll);
                sources.Add(source);

                if (priorCanSeek && (sources.Count > 1 || source.CanSeek))
                {
                    sourceIndex = Math.Min(sources.Count - 1, currentMeasuredIndexPosition);
                    absPos      = 0;
                    for (int i = 0; i <= sourceIndex; i++)
                    {
                        absPos += sources[i].Position;
                    }
                }
                if (!source.CanSeek && optimizeIfPossible)
                {
                    OptimizeSources();
                }
            }
        }
Example #2
0
        public void Setup()
        {
            concatStreamSourceData     = Substitute.For <IConcatStreamSource>();
            concatStreamSourceDataUsed = Substitute.For <IConcatStreamSource>();
            concatStreamSourceNoData   = Substitute.For <IConcatStreamSource>();

            concatStreamSourceData.Position.Returns(0);
            concatStreamSourceData.Length.Returns(StreamSourceDefaultLength);
            concatStreamSourceData.CanSeek.Returns(true);

            concatStreamSourceDataUsed.Position.Returns(StreamSourceDefaultLength);
            concatStreamSourceDataUsed.Length.Returns(StreamSourceDefaultLength);
            concatStreamSourceDataUsed.CanSeek.Returns(true);

            concatStreamSourceNoData.Position.Returns(0);
            concatStreamSourceNoData.Length.Returns(0);
            concatStreamSourceNoData.CanSeek.Returns(true);
        }