private void FlushLogicalLine(LogicalLinesHistoryQueue logicalLinesHistoryQueue = null) { if (_logicalLine.IsEmpty) { return; } _logicalLine.IsVisible = !ShouldBeHided() && ShouldBeShown(); if ( (_logicalLine.IsVisible || _afterCounter > 0) && !SkipFromNumLines()) { var forPrinting = new LogicalLinesHistoryQueue(); PrepareLogicalLineForPrinting(_logicalLine, forPrinting); if (logicalLinesHistoryQueue == null) { PrintLogicalLines(forPrinting); } else { logicalLinesHistoryQueue.Enqueue(forPrinting); } if (_logicalLine.IsVisible) { _afterCounter = Configs.ContextAfter; } } _logicalLinesHistoryQueue.Enqueue(_logicalLine); _logicalLine = new LogicalLine(); }
private void PrepareLogicalLineForPrinting(LogicalLine logicalLine, LogicalLinesHistoryQueue prepared) { if (Configs.IsContextBeforeUsed && _logicalLinesHistoryQueue.Any() && _logicalLine.IsVisible) { prepared.Enqueue(_logicalLinesHistoryQueue); _logicalLinesHistoryQueue.Clear(); } prepared.Enqueue(logicalLine); if (_afterCounter > 0) { --_afterCounter; } }
// Optimization used: // read from end in pages by XXX bytes to a memory stream // and stops to read if _startFromNum lines found // // Will not works, if line length is greater than PAGE_SIZE private bool ProcessStreamInPages(Stream stream, LogicalLinesHistoryQueue logicalLines) { if (!CanProcessInPages()) { return(false); } var encoding = DetectEncoding(stream); var historyDeep = _startFromNum * (Configs.ContextLines + 1); var foundLines = new LogicalLinesHistoryQueue(historyDeep); var from = FileSize; while (from != 0 && foundLines.Count != historyDeep) { var buf = new byte[Constants.REVERS_SEARCH_PAGE_SIZE]; var pageLines = new LogicalLinesHistoryQueue(historyDeep); from = Math.Max(0, from - Constants.REVERS_SEARCH_PAGE_SIZE); stream.Seek(from, SeekOrigin.Begin); var sz = stream.Read(buf, 0, Constants.REVERS_SEARCH_PAGE_SIZE); Stream ms = null; try { ms = new MemoryStream(buf, 0, sz); using var sr = new StreamReader(ms, encoding, from == 0 // ignore BOM only at file beginning ); ms = null; // prevent disposing several times if (from != 0) { var nul = sr.ReadLine(); // ignore first line, may be incomplete var szBytes = encoding.GetByteCount(nul ?? string.Empty); if (szBytes >= Constants.REVERS_SEARCH_PAGE_SIZE) // extra long line { return(false); } from += szBytes; } var s = sr.ReadLine(); while (s != null) { if (encoding.GetByteCount(s) >= Constants.REVERS_SEARCH_PAGE_SIZE) { return(false); } ProcessReadLine(s, pageLines); s = sr.ReadLine(); } } finally { #pragma warning disable CA1508 // Avoid dead conditional code ms?.Dispose(); #pragma warning restore CA1508 // Avoid dead conditional code } FlushLogicalLine(pageLines); pageLines.Enqueue(foundLines); foundLines.ReplaceBy(pageLines); LastPos = FileSize - from; } logicalLines.ReplaceBy(foundLines); // because lines was searched in pages, line numbers are irrelevant logicalLines.SetLinesNumberToUnknown(); LastPos = FileSize; return(true); }