You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
186 lines
4.9 KiB
Plaintext
186 lines
4.9 KiB
Plaintext
{
|
|
This file is part of R&Q.
|
|
Under same license
|
|
}
|
|
unit RQlog;
|
|
{$I ForRnQConfig.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
Windows, Messages, SysUtils, Classes, System.Generics.Collections, Graphics, Controls, Forms, StdCtrls, ExtCtrls, Menus,
|
|
Sciter, SciterApi, RDGlobal, JSON, BaseWindow;
|
|
|
|
{$I PubRTTI.inc}
|
|
|
|
type
|
|
PLogItem = ^TLogItem;
|
|
|
|
TLogItem = record
|
|
pkt: Boolean;
|
|
Cpt, Text: String;
|
|
PktData: String;
|
|
Img: TPicName;
|
|
end;
|
|
|
|
TLogEntry = record
|
|
time, method, caption, text, original: String;
|
|
json: Boolean;
|
|
icon: TPicName;
|
|
end;
|
|
|
|
{$I NoRTTI.inc}
|
|
|
|
TLog = class(TBaseWindow)
|
|
public
|
|
procedure Add(Entry: TLogEntry);
|
|
end;
|
|
|
|
procedure AddToLog(const Time, Method, Caption, Text, Icon: String);
|
|
procedure LogEvent(Text: String; const Img: TPicName = ''; const pFlush: Boolean = False);
|
|
procedure LogPacket(const Method, Head: String; const Data: String; const Img: TPicName; NeedHex: Boolean = True);
|
|
procedure FlushLogEvFile;
|
|
|
|
function PrettyPrintJSON(Value: TJSONValue; Indent: Integer = 0): String; forward;
|
|
|
|
implementation
|
|
|
|
uses
|
|
Clipbrd, SciterLib, GlobalLib, UtilLib,
|
|
RQUtil, RDUtils, RnQSysUtils, RDFileUtil,
|
|
RQThemes, RnQGlobal, RnQGraphics32;
|
|
|
|
var
|
|
LogEvFileData: String;
|
|
|
|
const
|
|
INDENT_SIZE = 2;
|
|
|
|
function PrettyPrintPair(Value: TJSONPair; Last: Boolean; Indent: Integer): String;
|
|
const
|
|
TEMPLATE = '%s : %s';
|
|
var
|
|
Line: string;
|
|
JSONText: String;
|
|
begin
|
|
try
|
|
JSONText := PrettyPrintJSON(Value.JsonValue, Indent);
|
|
Line := Format(TEMPLATE, [Value.JsonString.ToString, Trim(JSONText)]);
|
|
except end;
|
|
|
|
Line := StringOfChar(' ', Indent * INDENT_SIZE) + Line;
|
|
if not Last then
|
|
Line := Line + ',';
|
|
Result := Line;
|
|
end;
|
|
|
|
function PrettyPrintArrayValue(Value: TJSONValue; Last: Boolean; Indent: Integer): String;
|
|
const
|
|
TEMPLATE = '%s';
|
|
var
|
|
Line: string;
|
|
JSONText: String;
|
|
begin
|
|
try
|
|
JSONText := PrettyPrintJSON(Value, Indent);
|
|
Line := Format(TEMPLATE, [Trim(JSONText)]);
|
|
except end;
|
|
|
|
Line := StringOfChar(' ', Indent * INDENT_SIZE) + Line;
|
|
if not Last then
|
|
Line := Line + ',';
|
|
Result := Line;
|
|
end;
|
|
|
|
function PrettyPrintJSON(Value: TJSONValue; Indent: Integer = 0): String;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
if Value is TJSONObject then
|
|
begin
|
|
Result := Result + CRLF + StringOfChar(' ', Indent * INDENT_SIZE) + '{';
|
|
for i := 0 to TJSONObject(Value).Count - 1 do
|
|
Result := Result + CRLF + PrettyPrintPair(TJSONObject(Value).Pairs[i], i = TJSONObject(Value).Count - 1, Indent + 1);
|
|
Result := Result + CRLF + StringOfChar(' ', Indent * INDENT_SIZE) + '}';
|
|
end
|
|
else if Value is TJSONArray then
|
|
begin
|
|
Result := Result + CRLF + StringOfChar(' ', Indent * INDENT_SIZE) + '[';
|
|
for i := 0 to TJSONArray(Value).Count - 1 do
|
|
Result := Result + CRLF + PrettyPrintArrayValue(TJSONArray(Value).Items[i], i = TJSONArray(Value).Count - 1, Indent + 1);
|
|
Result := Result + CRLF + StringOfChar(' ', Indent * INDENT_SIZE) + ']';
|
|
end else
|
|
Result := Result + CRLF + StringOfChar(' ', Indent * INDENT_SIZE) + Value.ToString;
|
|
end;
|
|
|
|
procedure AddToLog(const Time, Method, Caption, Text, Icon: String);
|
|
var
|
|
JSON: TJSONValue;
|
|
Entry: TLogEntry;
|
|
begin
|
|
if not Running then
|
|
Exit;
|
|
|
|
Entry.time := Time;
|
|
Entry.caption := Caption;
|
|
Entry.icon := Icon;
|
|
Entry.method := Method;
|
|
Entry.json := False;
|
|
Entry.text := Text;
|
|
Entry.original := Text;
|
|
|
|
if not (Caption = Text) then
|
|
try
|
|
JSON := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(Text), 0); // Broken double encoding
|
|
Entry.json := Assigned(json);
|
|
if Entry.json then
|
|
Entry.text := Trim(PrettyPrintJSON(JSON));
|
|
JSON.Free;
|
|
except end;
|
|
|
|
if Assigned(UI) and Assigned(UI.Log) then
|
|
UI.Log.Add(Entry);
|
|
end;
|
|
|
|
procedure TLog.Add(Entry: TLogEntry);
|
|
begin
|
|
Call('addEntry', [UI.RecordToVar(Entry)]);
|
|
end;
|
|
|
|
procedure LogEvent(Text: String; const Img: TPicName = ''; const pFlush: Boolean = False);
|
|
var
|
|
Lines: TArray |
|
ToWindow, ToFile, Time: String;
|
|
begin
|
|
Time := LogTimestamp;
|
|
Lines := Text.Split([#13#10, #10]);
|
|
ToWindow := String.Join(#10, Lines).TrimRight([#13, #10]);
|
|
ToFile := Time + '> ' + String.Join(#13#10, Lines).TrimRight([#13, #10]);
|
|
|
|
if LogPref.evts.onFile then
|
|
LogEvFileData := LogEvFileData + ToFile + CRLF;
|
|
|
|
if pFlush then
|
|
FlushLogEvFile
|
|
else
|
|
ActionManager.Execute(AK_FLUSHEVENTS, 1000);
|
|
|
|
if LogPref.evts.onWindow then
|
|
AddToLog(Time, '', Lines[0], ToWindow, Img);
|
|
end;
|
|
|
|
procedure LogPacket(const Method, Head: String; const Data: String; const Img: TPicName; NeedHex: Boolean = True);
|
|
begin
|
|
if LogPref.pkts.onWindow then
|
|
AddToLog(LogTimestamp, Method, Head, Data, Img);
|
|
end;
|
|
|
|
procedure FlushLogEvFile;
|
|
begin
|
|
if Length(LogEvFileData) > 0 then
|
|
if AppendFile(LogPath + EventsLogFilename, UTF(LogEvFileData)) or (Length(LogEvFileData) > MByte) then
|
|
LogEvFileData := '';
|
|
end;
|
|
|
|
end.
|