Exemple #1
0
 public void Dispose()
 {
     _pageOffsets.Clear();
     _pageGranules.Clear();
     _pagePacketCounts.Clear();
     _pageContinuations.Clear();
     _packetGranuleCounts.Clear();
     _cachedPageIndex = null;
     _cachedSegments  = null;
     _lastPacket      = null;
     _isEndOfStream   = true;
     _packetCount     = 0;
     _reader          = null;
 }
Exemple #2
0
        public DataPacket GetPacket(int packetIndex)
        {
            if (_reader == null)
            {
                throw new ObjectDisposedException(nameof(LightPacketProvider));
            }

            // if we're returning the same packet as last call, the caller probably wants the same instance...
            if (_lastPacket != null && _lastPacket.Index == packetIndex)
            {
                return(_lastPacket);
            }

            // figure out which page the requested packet starts on, and which packet it is in the sequence
            var pageIndex = 0;
            var pktIdx    = packetIndex;

            while (pageIndex < _pagePacketCounts.Count && pktIdx >= _pagePacketCounts[pageIndex])
            {
                pktIdx -= _pagePacketCounts[pageIndex];
                if (++pageIndex == _pageContinuations.Count && !_isEndOfStream)
                {
                    if (!GetNextPage())
                    {
                        // no more pages
                        _isEndOfStream = true;
                        return(null);
                    }
                }
            }
            if (pageIndex == _pagePacketCounts.Count)
            {
                // couldn't find it
                return(null);
            }
            // if the found page is a continuation, ignore the first packet (it's the continuation)
            if (_pageContinuations[pageIndex])
            {
                ++pktIdx;
            }

            var pktList = new List <Tuple <long, int> >();

            // get all the packets in the page (including continued / continuations)
            var pkts = GetPagePackets(pageIndex, out var lastContinues, out var isResync, out var pageSeqNo);

            pktList.Add(pkts[pktIdx]);

            // if our packet is continued, read in the rest of it from the next page(s)
            var startPageIdx = pageIndex;
            var keepReading  = lastContinues;

            while (keepReading && pktIdx >= _pagePacketCounts[pageIndex] - 1)
            {
                if (++pageIndex == _pagePacketCounts.Count)
                {
                    if (_isEndOfStream)
                    {
                        // per the spec, a continued packet at the end of the stream should be dropped
                        return(null);
                    }
                    if (!GetNextPage())
                    {
                        // no more pages
                        _isEndOfStream = true;
                        return(null);
                    }
                }

                pktIdx = 0;
                pkts   = GetPagePackets(pageIndex, out keepReading, out var contResync, out pageSeqNo);
                if (contResync)
                {
                    // if we're in a resync, just return what we could get.
                    break;
                }
                pktList.Add(pkts[0]);
            }

            // create the packet instance and populate it with the appropriate initial data
            var packet = new LightPacket(_reader, this, packetIndex, pktList)
            {
                PageGranulePosition = _pageGranules[startPageIdx],
                PageSequenceNumber  = pageSeqNo,
                IsResync            = isResync
            };

            // if we're the last packet completed in the page, set the .GranulePosition
            if (pktIdx == pkts.Count - 1 || pktIdx == 0 && lastContinues)
            {
                packet.GranulePosition = packet.PageGranulePosition;

                // if we're the last packet completed in the page, no more pages are available, and _isEndOfStream is set, set .IsEndOfStream
                if (pageIndex == _pageOffsets.Count - 1 && _isEndOfStream)
                {
                    packet.IsEndOfStream = true;
                }
            }
            if (_packetGranuleCounts.TryGetValue(packetIndex, out var granuleCount))
            {
                packet.GranuleCount = granuleCount;

                if (_packetGranulePositions.TryGetValue(packetIndex, out var granulePos))
                {
                    packet.GranulePosition = granulePos;
                }
            }

            _lastPacket = packet;
            return(packet);
        }