/[projects]/dao/DelphiScanner/Components/tpsystools_4.04/source/StGenLog.pas
ViewVC logotype

Contents of /dao/DelphiScanner/Components/tpsystools_4.04/source/StGenLog.pas

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2671 - (show annotations) (download)
Tue Aug 25 18:15:15 2015 UTC (8 years, 9 months ago) by torben
File size: 23583 byte(s)
Added tpsystools component
1 // Upgraded to Delphi 2009: Sebastian Zierer
2
3 (* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1
5 *
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
10 *
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
15 *
16 * The Original Code is TurboPower SysTools
17 *
18 * The Initial Developer of the Original Code is
19 * TurboPower Software
20 *
21 * Portions created by the Initial Developer are Copyright (C) 1996-2002
22 * the Initial Developer. All Rights Reserved.
23 *
24 * Contributor(s):
25 *
26 * ***** END LICENSE BLOCK ***** *)
27
28 {*********************************************************}
29 {* SysTools: StGenLog.pas 4.04 *}
30 {*********************************************************}
31 {* SysTools: General Logging *}
32 {*********************************************************}
33
34 {$I StDefine.inc}
35
36 unit StGenLog;
37
38 interface
39
40 uses
41 Windows, SysUtils, Classes, StBase;
42
43 const
44
45 StDefBufferSize = 65536; { Default buffer size }
46 StDefHighLevel = 0; { Default high level point }
47 StMaxLogSize = 16000000; { Max size of general log buffer }
48 // StCRLF = #10#13; {!!.01}
49 StCRLF = #13#10; {!!.01}
50 StLogFileFooter = '';
51 StLogFileHeader = 'SysTools General Log' + StCRLF +
52 '=============================================================================' +
53 StCRLF + StCRLF;
54
55 { General log constants }
56 leEnabled = 1;
57 leDisabled = 2;
58
59 leString = DWORD($80000000);
60
61 type
62
63 TStGetLogStringEvent = procedure(Sender : TObject; const D1, D2, D3, D4 : DWORD;
64 var LogString : AnsiString) of object;
65
66 TStWriteMode = (wmOverwrite, wmAppend);
67
68 { Record for log entries }
69 PStLogRec = ^TStLogRec;
70 TStLogRec = record
71 lrTime : DWORD;
72 lrData1 : DWORD;
73 lrData2 : DWORD;
74 lrData3 : DWORD;
75 lrData4 : DWORD;
76 end;
77
78 PStLogBuffer = ^TStLogBuffer;
79 TStLogBuffer = array[0..StMaxLogSize] of Byte;
80
81 StGenOptions = (goSuppressEnableMsg, goSuppressDisableMsg); {!!.01}
82 StGenOptionSet = set of StGenOptions; {!!.01}
83
84 TStGeneralLog = class(TStComponent)
85 private
86 { Property variables }
87 FBufferSize : DWORD;
88 FEnabled : Boolean;
89 FFileName : TFileName;
90 FHighLevel : Byte;
91 FLogFileFooter : string;
92 FLogFileHeader : string;
93 FLogOptions : StGenOptionSet; {!!.01}
94 FWriteMode : TStWriteMode;
95 { Event variables }
96 FOnHighLevel : TNotifyEvent;
97 FOnGetLogString : TStGetLogStringEvent;
98 { Private variables }
99 glBuffer : PStLogBuffer;
100 glBufferHead : DWORD;
101 glBufferTail : DWORD;
102 glHighLevelMark : DWORD;
103 glHighLevelTriggered : Boolean;
104 glLogCS : TRTLCriticalSection;
105 glTempBuffer : PByteArray;
106 glTempSize : DWORD;
107 glTimeBase : DWORD;
108 protected
109 { Property access methods }
110 procedure DoGetLogString(const D1, D2, D3, D4 : DWORD; var LogString : AnsiString); virtual;
111 function GetBufferEmpty : Boolean;
112 function GetBufferFree : DWORD;
113 function GetBufferSize : DWORD;
114 function GetEnabled : Boolean;
115 function GetFileName : TFileName;
116 function GetHighLevel : Byte;
117 function GetLogOptions : StGenOptionSet; {!!.01}
118 function GetWriteMode : TStWriteMode;
119 procedure SetBufferSize(const Value : DWORD);
120 procedure SetEnabled(const Value : Boolean); virtual;
121 procedure SetFileName(const Value : TFileName); virtual;
122 procedure SetHighLevel(const Value : Byte);
123 procedure SetLogOptions(const Value : StGenOptionSet); {!!.01}
124 procedure SetWriteMode(const Value : TStWriteMode);
125 { Internal methods }
126 procedure glCalcHighLevel;
127 procedure glCheckTempSize(SizeReq : DWORD);
128 procedure glHighLevelCheck;
129 procedure glLockLog;
130 function glPopLogEntry(var LogRec : TStLogRec) : Boolean;
131 function glTimeStamp(Mark : DWORD) : string;
132 procedure glUnlockLog;
133 public
134 { Public methods }
135 constructor Create(Owner : TComponent); override;
136 destructor Destroy; override;
137 procedure AddLogEntry(const D1, D2, D3, D4 : DWORD);
138 procedure ClearBuffer;
139 procedure DumpLog; virtual;
140 procedure WriteLogString(const LogString : AnsiString);
141 { Public properties }
142 property BufferEmpty : Boolean read GetBufferEmpty;
143 property BufferFree : DWORD read GetBufferFree;
144 published
145 { Published properties }
146 property BufferSize : DWORD
147 read GetBufferSize write SetBufferSize default StDefBufferSize;
148 property Enabled : Boolean read GetEnabled write SetEnabled default True;
149 property FileName : TFileName read GetFileName write SetFileName;
150 property HighLevel : Byte read GetHighLevel write SetHighLevel default StDefHighLevel;
151 property LogFileFooter : string read FLogFileFooter write FLogFileFooter;
152 property LogFileHeader : string read FLogFileHeader write FLogFileHeader;
153 property LogOptions : StGenOptionSet read GetLogOptions {!!.01}
154 write SetLogOptions default []; {!!.01}
155 property WriteMode : TStWriteMode read GetWriteMode write SetWriteMode;
156 { Event properties }
157 property OnHighLevel : TNotifyEvent read FOnHighLevel write FOnHighLevel;
158 property OnGetLogString : TStGetLogStringEvent
159 read FOnGetLogString write FOnGetLogString;
160 end;
161
162 function HexifyBlock(var Buffer; BufferSize : Integer) : AnsiString;
163
164 implementation
165
166 { TStGeneralLog }
167
168 { Gives text representation of a block of data }
169 function HexifyBlock(var Buffer; BufferSize : Integer) : AnsiString;
170 type
171 TCastCharArray = array[0..Pred(High(LongInt))] of AnsiChar;
172 const
173 { Starting string to work with - this is directly written to by index }
174 { below, so any positional changes here will also have to be made below. }
175 StockString = ' %6.6x: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : 0000000000000000' + StCRLF;
176 HexDigits : array[0..$F] of AnsiChar = '0123456789ABCDEF';
177 var
178 I, J, K, Lines : Integer;
179 TempStr : AnsiString;
180 Hex1, Hex2 : array[0..23] of AnsiChar;
181 Ascii1, Ascii2 : array[0..7] of AnsiChar;
182 begin
183 K := 0;
184 FillChar(Hex1, SizeOf(Hex1), #32);
185 FillChar(Hex2, SizeOf(Hex2), #32);
186
187 { Calculate number of lines required }
188 Lines := BufferSize div 16;
189 if (BufferSize mod 16) <> 0 then Inc(Lines);
190
191 { Process and append lines }
192 for I := 0 to Lines-1 do begin
193
194 { Load string, add index marker }
195 TempStr := Format(StockString, [I*16]);
196
197 { Format data for first word }
198 for J := 0 to 7 do begin
199 if J+K >= BufferSize then begin
200 Ascii1[J] := ' ';
201 Hex1[J*3] := ' ';
202 Hex1[J*3+1] := ' ';
203 end else begin
204 Ascii1[J] := TCastCharArray(Buffer)[J+K];
205 Hex1[J*3] := HexDigits[Byte(Ascii1[J]) shr 4];
206 Hex1[J*3+1] := HexDigits[Byte(Ascii1[J]) and $F];
207
208 { Clamp Ascii to printable range }
209 if (Ascii1[J] < #32) or (Ascii1[J] > #126) then Ascii1[J] := '.';
210 end;
211 end;
212 Inc(K,8);
213
214 { Format data for second word }
215 for J := 0 to 7 do begin
216 if J+K >= BufferSize then begin
217 Ascii2[J] := ' ';
218 Hex2[J*3] := ' ';
219 Hex2[J*3+1] := ' ';
220 end else begin
221 Ascii2[J] := TCastCharArray(Buffer)[J+K];
222 Hex2[J*3] := HexDigits[Byte(Ascii2[J]) shr 4];
223 Hex2[J*3+1] := HexDigits[Byte(Ascii2[J]) and $F];
224 { Clamp Ascii to printable range }
225 if (Ascii2[J] < #32) or (Ascii2[J] > #126) then Ascii2[J] := '.';
226 end;
227 end;
228 Inc(K,8);
229
230 { Move data to existing temp string }
231 Move(Hex1[0], TempStr[11], SizeOf(Hex1));
232 Move(Hex2[0], TempStr[36], SizeOf(Hex2));
233
234 Move(Ascii1[0], TempStr[62], SizeOf(Ascii1));
235 Move(Ascii2[0], TempStr[70], SizeOf(Ascii2));
236
237 { Append temp string to result }
238 Result := Result + TempStr;
239 end;
240 end;
241
242 constructor TStGeneralLog.Create(Owner : TComponent);
243 begin
244 inherited Create(Owner);
245 InitializeCriticalSection(glLogCS);
246 BufferSize := StDefBufferSize;
247 FEnabled := True;
248 FFileName := 'debug.log';
249 FLogFileFooter := StLogFileFooter;
250 FLogFileHeader := StLogFileHeader;
251 HighLevel := StDefHighLevel;
252 glHighLevelTriggered := False;
253 glTimeBase := GetTickCount;
254 end;
255
256 destructor TStGeneralLog.Destroy;
257 begin
258 FreeMem(glBuffer);
259 FreeMem(glTempBuffer);
260 DeleteCriticalSection(glLogCS);
261 inherited Destroy;
262 end;
263
264 procedure TStGeneralLog.glLockLog;
265 begin
266 if IsMultiThread then
267 EnterCriticalSection(glLogCS);
268 end;
269
270 procedure TStGeneralLog.glUnlockLog;
271 begin
272 if IsMultiThread then
273 LeaveCriticalSection(glLogCS);
274 end;
275
276 { AddLogEntry notes: }
277 { }
278 { D1 = $FFFFFFFF is reserved for internal events }
279 { }
280 { D1, D2, D3, D4 are "info" fields to be used in the OnGetLogString }
281 { handler to identify the logged event and what type of data would be }
282 { appropriate for the corresponding log entry. }
283 { }
284 { While you're free to come up with your own logging scheme, it was }
285 { envisioned that D1 would identify the logged event in the broadest }
286 { terms, and the event classification would be narrowed further and }
287 { further with D2 --> D4. }
288 { }
289 { Special case: If the high bit of D2 is set, D3 becomes a pointer }
290 { to data, and D4 is the size of the data. Make *sure* the high bit }
291 { isn't set unless you are using this special situation. }
292 { }
293 { If you just have a simple case for logging that probably won't get }
294 { used that often, consider adding entries with the WriteDebugString }
295 { method. }
296 procedure TStGeneralLog.AddLogEntry(const D1, D2, D3, D4 : DWORD);
297 var
298 LogEntry : TStLogRec;
299 EntryPtr : PStLogRec;
300 SizeReq, TimeMrk, ChunkSize : DWORD;
301 HasData : Boolean;
302 begin
303 glLockLog;
304 try
305 { Bail if we're not logging }
306 if not Enabled then Exit;
307
308 TimeMrk := GetTickCount;
309
310 { Determine size needed }
311 SizeReq := SizeOf(TStLogRec);
312 if (D2 and $80000000) = $80000000 then begin
313 HasData := True;
314 Inc(SizeReq, D4);
315 end else begin
316 HasData := False;
317 end;
318
319 { Bail if SizeReq is bigger than the whole buffer }
320 if SizeReq > FBufferSize then Exit;
321
322 { Make more room in buffer if necessary }
323 while (SizeReq > BufferFree) and glPopLogEntry(LogEntry) do ;
324
325 { Do we need to wrap this entry? }
326 if (glBufferTail + SizeReq) <= FBufferSize then begin
327
328 { Wrap not required, write directly to glBuffer }
329 EntryPtr := @glBuffer[glBufferTail];
330 EntryPtr.lrTime := TimeMrk;
331 EntryPtr.lrData1 := D1;
332 EntryPtr.lrData2 := D2;
333 EntryPtr.lrData3 := D3;
334 EntryPtr.lrData4 := D4;
335
336 { Write add'l data if necessary }
337 if HasData then begin
338 Move(Pointer(D3)^, glBuffer[glBufferTail + SizeOf(TStLogRec)], D4);
339 end;
340 Inc(glBufferTail, SizeReq);
341
342 { Fix tail if necessary }
343 if glBufferTail = FBufferSize then
344 glBufferTail := 0;
345
346 end else begin
347
348 { Wrap required, use temp buffer }
349 glCheckTempSize(SizeReq);
350
351 EntryPtr := @glTempBuffer[0];
352 EntryPtr.lrTime := TimeMrk;
353 EntryPtr.lrData1 := D1;
354 EntryPtr.lrData2 := D2;
355 EntryPtr.lrData3 := D3;
356 EntryPtr.lrData4 := D4;
357
358 { Write add'l data if necessary }
359 if HasData then begin
360 Move(Pointer(D3)^, glTempBuffer[SizeOf(TStLogRec)], D4);
361 end;
362
363 { Move first half }
364 ChunkSize := FBufferSize - glBufferTail;
365 Move(glTempBuffer[0], glBuffer[glBufferTail], ChunkSize);
366
367 { Move second half }
368 Move(glTempBuffer[ChunkSize], glBuffer[0], SizeReq - ChunkSize);
369
370 { Set tail }
371 glBufferTail := SizeReq - ChunkSize;
372 end;
373 glHighLevelCheck;
374 finally
375 glUnlockLog;
376 end;
377 end;
378
379 { Clears all data from buffer (does not write data to disk) }
380 procedure TStGeneralLog.ClearBuffer;
381 begin
382 glLockLog;
383 try
384 glBufferHead := 0;
385 glBufferTail := 0;
386 finally
387 glUnlockLog;
388 end;
389 end;
390
391 { Let user fill in the data for the LogString }
392 procedure TStGeneralLog.DoGetLogString(const D1, D2, D3, D4 : DWORD; var LogString : AnsiString);
393 begin
394 if Assigned(FOnGetLogString) then
395 FOnGetLogString(Self, D1, D2, D3, D4, LogString);
396 end;
397
398 { Calculate the BufferFree level, in bytes, to trip the high level alarm }
399 procedure TStGeneralLog.glCalcHighLevel;
400 begin
401 glLockLog;
402 try
403 glHighLevelMark := FBufferSize - Round(FBufferSize * FHighLevel / 100);
404 glHighLevelCheck;
405 finally
406 glUnlockLog;
407 end;
408 end;
409
410 { Verifies the size of the temp buffer }
411 procedure TStGeneralLog.glCheckTempSize(SizeReq : DWORD);
412 begin
413 if (SizeReq > glTempSize) then begin
414 ReallocMem(glTempBuffer, SizeReq);
415 glTempSize := SizeReq;
416 end;
417 end;
418
419 { Test for high level condition, fire event if necessary }
420 procedure TStGeneralLog.glHighLevelCheck;
421 begin
422 glLockLog;
423 try
424 if FHighLevel = 0 then Exit;
425 if BufferFree < glHighLevelMark then begin
426 if Assigned(FOnHighLevel) and not glHighLevelTriggered then begin
427 FOnHighLevel(Self);
428 glHighLevelTriggered := True;
429 end;
430 end else begin
431 glHighLevelTriggered := False;
432 end;
433 finally
434 glUnlockLog;
435 end;
436 end;
437
438 { Pop log record from log, return False if no record to return }
439 function TStGeneralLog.glPopLogEntry(var LogRec : TStLogRec) : Boolean;
440 type
441 BytesArray = array[0..SizeOf(TStLogRec)-1] of Byte;
442 var
443 Bytes : BytesArray absolute LogRec;
444 ChunkSize : DWORD;
445 begin
446 glLockLog;
447 try
448 { Check for empty buffer }
449 if (glBufferHead = glBufferTail) then begin
450 Result := False;
451 Exit;
452 end else begin
453 Result := True;
454 end;
455
456 { Check to see if log record wraps }
457 if (glBufferHead + SizeOf(TStLogRec)) <= FBufferSize then begin
458
459 { No wrap, copy directly over }
460 Move(glBuffer[glBufferHead], LogRec, SizeOf(LogRec));
461 Inc(glBufferHead, SizeOf(LogRec));
462
463 { Fix head if needed }
464 if (glBufferHead = FBufferSize) then glBufferHead := 0;
465 end else begin
466
467 { Need to deal with wrap -- copy first half }
468 ChunkSize := (FBufferSize - glBufferHead);
469 Move(glBuffer[glBufferHead], Bytes[0], ChunkSize);
470
471 { Copy second half }
472 Move(glBuffer[0], Bytes[ChunkSize], (SizeOf(LogRec) - ChunkSize));
473 glBufferHead := SizeOf(LogRec) - ChunkSize;
474 end;
475
476 { Do we have data? If so, deal with it }
477 if (LogRec.lrData2 and $80000000) = $80000000 then begin
478
479 { Check to see if log data wraps }
480 if (glBufferHead + LogRec.lrData4) <= FBufferSize then begin
481
482 { No wrap -- point D2 to buffer }
483 LogRec.lrData3 := DWORD(@glBuffer[glBufferHead]);
484 Inc(glBufferHead, LogRec.lrData4);
485 end else begin
486
487 { Wrap -- copy first half to temp buffer }
488 glCheckTempSize(LogRec.lrData4);
489 ChunkSize := (FBufferSize - glBufferHead);
490 Move(glBuffer[glBufferHead], glTempBuffer[0], ChunkSize);
491
492 { Copy second half }
493 Move(glBuffer[0], glTempBuffer[ChunkSize], (LogRec.lrData4 - ChunkSize));
494 LogRec.lrData3 := DWORD(@glTempBuffer[0]);
495 glBufferHead := LogRec.lrData4 - ChunkSize;
496 end;
497 end
498
499 finally
500 glUnlockLog;
501 end;
502 end;
503
504 { Return time stamp string }
505 function TStGeneralLog.glTimeStamp(Mark : DWORD) : string;
506 begin
507 Result := Format('%07.7d : ', [Mark - glTimeBase]);
508 Insert('.', Result, 5);
509 end;
510
511 { Dumps log file to disk }
512 procedure TStGeneralLog.DumpLog;
513 var
514 LR : TStLogRec;
515 FS : TFileStream;
516 S, T : AnsiString;
517 begin
518 glLockLog;
519
520 try
521 { Open file stream }
522 if FileExists(FileName) and (WriteMode = wmAppend) then begin
523 FS := TFileStream.Create(FileName, fmOpenReadWrite or fmShareDenyWrite);
524 FS.Seek(0, soFromEnd);
525 end else begin
526 FS := TFileStream.Create(FileName, fmCreate or fmShareDenyWrite);
527 end;
528
529 try
530 { Do file header if appropriate }
531 if (FS.Size = 0) then begin
532 S := FLogFileHeader;
533 FS.Write(S[1], Length(S));
534
535 { Write trailing CRLF } {!!.02}
536 FS.Write(StCRLF[1], Length(StCRLF)); {!!.02}
537 end;
538
539 { Cycle through all data }
540 while glPopLogEntry(LR) do begin
541 if LR.lrData1 <> $FFFFFFFF then begin
542
543 { It belongs to somone else, let them process it }
544 DoGetLogString(LR.lrData1, LR.lrData2, LR.lrData3, LR.lrData4, S);
545 end else begin
546
547 { Something we're supposed to know about, deal with it }
548 case LR.lrData2 of
549
550 { Logging enabled }
551 leEnabled : S := '**** Logging Enabled' + StCRLF;
552
553 { Logging disabled }
554 leDisabled : S := '**** Logging Disabled' + StCRLF;
555
556 { WriteLogString entry }
557 leString :
558 begin
559 if LR.lrData4 > 0 then begin {!!.02}
560 SetLength(S, LR.lrData4);
561 Move(PByteArray(LR.lrData3)[0], S[1], LR.lrData4);
562 end else begin {!!.02}
563 S := ''; { empty string } {!!.02}
564 end; {!!.02}
565 end;
566
567 else
568 S := Format('!! Unknown log entry : [%8.8x][%8.8x][%8.8x][%8.8x]' + StCRLF,
569 [LR.lrData1, LR.lrData2, LR.lrData3, LR.lrData4]);
570
571 end;
572 end;
573
574 { Write time stamp }
575 T := glTimeStamp(LR.lrTime);
576 FS.Write(T[1], Length(T));
577
578 { Write log string }
579 if Length(S) > 0 then {!!.02}
580 FS.Write(S[1], Length(S));
581
582 { Write trailing CRLF }
583 FS.Write(StCRLF[1], Length(StCRLF));
584 end;
585
586 { Do file header if appropriate }
587 if (FLogFileFooter <> '') then begin
588 S := FLogFileFooter;
589 FS.Write(S[1], Length(S));
590
591 { Write trailing CRLF } {!!.02}
592 FS.Write(StCRLF[1], Length(StCRLF)); {!!.02}
593 end;
594
595 glHighLevelTriggered := False;
596
597 finally
598 FS.Free;
599 end;
600
601 finally
602 glUnlockLog;
603 end;
604 end;
605
606 { Determines whether something is in the buffer }
607 function TStGeneralLog.GetBufferEmpty : Boolean;
608 begin
609 glLockLog;
610 try
611 Result := (glBufferHead = glBufferTail);
612 finally
613 glUnlockLog;
614 end;
615 end;
616
617 { Calculates free space in the buffer }
618 function TStGeneralLog.GetBufferFree : DWORD;
619 begin
620 glLockLog;
621 try
622 if (glBufferHead <= glBufferTail) then
623 { One less than actual, since we always leave one byte free }
624 Result := Pred(FBufferSize - (glBufferTail - glBufferHead))
625 else
626 Result := Pred(glBufferHead - glBufferTail);
627 finally
628 glUnlockLog;
629 end;
630 end;
631
632 { Retrieves buffer size }
633 function TStGeneralLog.GetBufferSize : DWORD;
634 begin
635 glLockLog;
636 try
637 Result := FBufferSize;
638 finally
639 glUnlockLog;
640 end;
641 end;
642
643 { Get Enabled property }
644 function TStGeneralLog.GetEnabled : Boolean;
645 begin
646 glLockLog;
647 try
648 Result := FEnabled;
649 finally
650 glUnlockLog;
651 end;
652 end;
653
654 { Get FileName property }
655 function TStGeneralLog.GetFileName : TFileName;
656 begin
657 glLockLog;
658 try
659 Result := FFileName;
660 finally
661 glUnlockLog;
662 end;
663 end;
664
665 { Retrieves high level setpoint }
666 function TStGeneralLog.GetHighLevel : Byte;
667 begin
668 glLockLog;
669 try
670 Result := FHighLevel;
671 finally
672 glUnlockLog;
673 end;
674 end;
675
676 {!!.01 - added}
677 { Retrieves log options }
678 function TStGeneralLog.GetLogOptions : StGenOptionSet;
679 begin
680 glLockLog;
681 try
682 Result := FLogOptions;
683 finally
684 glUnlockLog;
685 end;
686 end;
687
688 { Retrieves write mode }
689 function TStGeneralLog.GetWriteMode : TStWriteMode;
690 begin
691 glLockLog;
692 try
693 Result := FWriteMode;
694 finally
695 glUnlockLog;
696 end;
697 end;
698
699 { Sets the size of the logging buffer }
700 procedure TStGeneralLog.SetBufferSize(const Value : DWORD);
701 begin
702 glLockLog;
703 try
704 if Value <> FBufferSize then begin
705 FBufferSize := Value;
706 ReallocMem(glBuffer, Value);
707 ClearBuffer;
708 glCalcHighLevel;
709 end;
710 finally
711 glUnlockLog;
712 end;
713 end;
714
715 { Enables (or disables) logging }
716 procedure TStGeneralLog.SetEnabled(const Value : Boolean);
717 begin
718 glLockLog;
719 try
720 if (Value = True) then begin
721
722 { Allocate buffer if not already done }
723 if (glBuffer = nil) then begin
724 GetMem(glBuffer, FBufferSize);
725 end;
726
727 { Init temp buffer if not already done }
728 if (glTempBuffer = nil) then begin
729 glTempSize := 1024;
730 GetMem(glTempBuffer, glTempSize);
731 end;
732 end else if not (goSuppressDisableMsg in LogOptions) then begin {!!.01}
733 AddLogEntry($FFFFFFFF, leDisabled, 0, 0);
734 end;
735
736 FEnabled := Value;
737
738 finally
739 glUnlockLog;
740 end;
741
742 if (Value = True) and not (goSuppressEnableMsg in LogOptions) then {!!.01}
743 AddLogEntry($FFFFFFFF, leEnabled, 0, 0);
744 end;
745
746 { Set FileName property }
747 procedure TStGeneralLog.SetFileName(const Value : TFileName);
748 begin
749 glLockLog;
750 try
751 FFileName := Value;
752 finally
753 glUnlockLog;
754 end;
755 end;
756
757 { Set HighLevel property }
758 procedure TStGeneralLog.SetHighLevel(const Value : Byte);
759 begin
760 glLockLog;
761 try
762 if (FHighLevel <> Value) and (Value <= 100) then begin
763 FHighLevel := Value;
764 glCalcHighLevel;
765 end;
766 finally
767 glUnlockLog;
768 end;
769 end;
770
771 {!!.01 - added}
772 { Set LogOptions property }
773 procedure TStGeneralLog.SetLogOptions(const Value : StGenOptionSet);
774 begin
775 glLockLog;
776 try
777 FLogOptions := Value;
778 finally
779 glUnlockLog;
780 end;
781 end;
782
783 { Set WriteMode property }
784 procedure TStGeneralLog.SetWriteMode(const Value : TStWriteMode);
785 begin
786 glLockLog;
787 try
788 FWriteMode := Value;
789 finally
790 glUnlockLog;
791 end;
792 end;
793
794 { Write log string to log buffer }
795 procedure TStGeneralLog.WriteLogString(const LogString : AnsiString);
796 begin
797 AddLogEntry($FFFFFFFF, leString, DWORD(LogString), Length(LogString));
798 end;
799
800 end.

  ViewVC Help
Powered by ViewVC 1.1.20