diff --git a/UApp.pas b/UApp.pas index 72d2973..41e3f34 100644 --- a/UApp.pas +++ b/UApp.pas @@ -109,7 +109,10 @@ begin if HasOption('html') then FWriter.Add(THTMLWriter.Create(GetOptionValue('html'))); - DumpFile(FLogFileName); + if HasOption('poll') then + PollFile(FLogFileName) + else + DumpFile(FLogFileName); // One run is enough. Terminate; @@ -243,8 +246,95 @@ begin end; procedure TLogFilterApplication.PollFile(AFileName: String); +const + BUFSIZE = 8192; +var + f: File of char; + b: array[0..BUFSIZE-1] of Char; + lastSize, currentSize: Int64; + bufPos, bufMax, read, checkStart: Word; + breakPos, breakLen: Word; + pos: Int64; + s: String; + i: Integer; begin + AssignFile(f, AFileName); + Reset(f); + bufPos := 0; + bufMax := 0; + lastSize := 0; + while true do + begin + currentSize := FileSize(f); + if currentSize > lastSize then + begin + pos := FilePos(f); + breakPos := 0; + while (pos < currentSize) or (breakPos > 0) do + begin + breakPos := 0; + breakLen := 0; + BlockRead(f, b[bufMax], Min(BUFSIZE-bufMax, currentSize-pos), read); + Inc(pos, read); + Inc(bufMax, read); + + if bufMax = 0 then + Continue; + + if bufPos > 0 then + checkStart := bufPos - 1 //we could miss a #13 in a #13#10 + else + checkStart := bufPos; + + for i := checkStart to bufMax do + begin + if b[i] = #10 then + begin + breakPos := i + 1; + breakLen := 1; + end + else if (b[i] = #13) and (i < bufMax) and (b[i+1] = #10) then + begin + breakPos := i + 2; + breakLen := 2; + end + else if b[i] = #13 then + begin + breakPos := i + 1; + breakLen := 1; + end; + + if breakPos > 0 then + break; + end; + + if breakPos > 0 then + begin + SetLength(s, breakPos - breakLen); //We don't want the actual line break + Move(b[0], s[1], breakPos - breakLen); + FilterLine(s); + Move(b[breakPos], b[0], bufMax - breakPos); + bufPos := 0; + Dec(bufMax, breakPos); + end else + begin + bufPos := bufMax; + if bufPos = BUFSIZE then // Nothing we can do here; we need to dump + begin + SetLength(s, BUFSIZE); + Move(b[0], s[1], BUFSIZE); + FilterLine(s); + bufPos := 0; + bufMax := 0; + end; + end; + end; + + lastSize := currentSize; + end; + Sleep(100); + end; end; constructor TLogFilterApplication.Create(TheOwner: TComponent);