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; }
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); }