-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathLightCore.LogLinesAbstract.pas
More file actions
172 lines (131 loc) · 5.27 KB
/
LightCore.LogLinesAbstract.pas
File metadata and controls
172 lines (131 loc) · 5.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
UNIT LightCore.LogLinesAbstract;
{=============================================================================================================
2026.01.29
www.GabrielMoraru.com
--------------------------------------------------------------------------------------------------------------
Abstract base class for log line storage.
This class defines the interface for log line collections, with two concrete implementations:
- TLogLinesSingleThreaded (LightCore.LogLinesS.pas) - for single-threaded use
- TLogLinesMultiThreaded (LightCore.LogLinesM.pas) - for multi-threaded use
The RLogLine record stores individual log entries with message, verbosity level,
timestamp, indentation, and bold flag.
Stream Format (Version 5):
- Header with signature "TLogLines" and version
- Integer count of lines
- Each line: Msg, Level, Indent, Bold, Time, 8-byte padding
- Footer padding
Tester:
LightSaber\Demo\LightLog\
=============================================================================================================}
INTERFACE
USES
System.SysUtils, System.Classes,
LightCore.LogTypes, LightCore.StreamBuff;
type
PLogLine=^RLogLine;
RLogLine= record
Msg : string;
Level : TLogVerbLvl;
Indent: Integer; { How many spaces are used to indent the message }
Bold : Boolean;
Time : TDateTime;
private
procedure ReadFromStream_v5(Stream: TLightStream); { Current reader }
procedure WriteToStream (Stream: TLightStream); { Current writer }
end;
{ List of lines }
TAbstractLogLines = class
private
procedure readFromStream_v5(Stream: TLightStream);
protected
FList: TList;
CONST StreamSign = 'TLogLines';
function getItem(Index: Integer): PLogLine; virtual; abstract;
public
CONST CurVer= 5;
procedure Clear; virtual; abstract;
function Count: Integer; virtual; abstract;
{ Filtered access - these methods iterate under a single lock for thread safety }
function CountFiltered(Verbosity: TLogVerbLvl): Integer; virtual;
function Row2FilteredRow(Row: Integer; Verbosity: TLogVerbLvl): Integer; virtual; abstract;
property Items[Index: Integer]: PLogLine read getItem; default;
function Add (Value: PLogLine): Integer; virtual; abstract;
function AddNewLine(Msg: string; Level: TLogVerbLvl; Bold: Boolean = False): PLogLine; virtual; abstract;
procedure ReadFromStream(Stream: TLightStream); virtual;
procedure WriteToStream (Stream: TLightStream); virtual;
end;
IMPLEMENTATION
{-------------------------------------------------------------------------------------------------------------
ABSTRACT CLASS
-------------------------------------------------------------------------------------------------------------}
{ Returns the number of log lines that meet the verbosity threshold.
In single-threaded mode, this iterates directly.
Multi-threaded subclass overrides this to hold a lock during iteration. }
function TAbstractLogLines.CountFiltered(Verbosity: TLogVerbLvl): Integer;
var
i: Integer;
begin
Result:= 0;
for i:= 0 to FList.Count - 1 do
if PLogLine(FList[i]).Level >= Verbosity
then Inc(Result);
end;
{ Read specific version }
procedure TAbstractLogLines.readFromStream_v5(Stream: TLightStream);
VAR
Line: PLogLine;
iCount, i: Integer;
begin
iCount := Stream.ReadInteger;
for i := 0 to iCount - 1 do
begin
New(Line);
Line.ReadFromStream_v5(Stream);
Add(Line);
end;
end;
{ Read }
procedure TAbstractLogLines.ReadFromStream(Stream: TLightStream);
VAR StreamVer: Word;
begin
StreamVer:= Stream.ReadHeader(StreamSign);
if StreamVer = 0 then EXIT;
if StreamVer= CurVer
then readFromStream_v5(Stream)
else RAISE Exception.Create('Unsupported stream version.');
Stream.ReadPaddingValidation;
end;
{ Write }
procedure TAbstractLogLines.WriteToStream(Stream: TLightStream);
VAR i: Integer;
begin
Stream.WriteHeader(StreamSign, CurVer);
Stream.WriteInteger(FList.Count);
for i := 0 to FList.Count - 1 do
PLogLine(FList[i]).WriteToStream(Stream);
Stream.WritePaddingValidation;
end;
{-------------------------------------------------------------------------------------------------------------
RLogLine
We don't write a header and version no for each line because we would waste too much space.
Instead, the parent (TRamLog) is responsible to do this.
-------------------------------------------------------------------------------------------------------------}
procedure RLogLine.ReadFromStream_v5(Stream: TLightStream);
begin
Msg := Stream.ReadString;
Level := TLogVerbLvl(Stream.ReadInteger);
Indent := Stream.ReadInteger;
Bold := Stream.ReadBoolean;
Time := Stream.ReadDate;
Stream.ReadPaddingValidation(8); { Padding }
end;
procedure RLogLine.WriteToStream(Stream: TLightStream);
begin
Stream.WriteString (Msg);
Stream.WriteInteger(Ord(Level));
Stream.WriteInteger(Indent);
Stream.WriteBoolean(Bold);
Stream.WriteDate(Time);
Stream.WritePaddingValidation(8); { Padding }
end;
end.