1
0
mirror of synced 2024-09-07 21:55:05 +00:00
x2log/X2Log.Details.Default.pas
2019-10-30 15:01:19 +01:00

1045 lines
28 KiB
ObjectPascal

unit X2Log.Details.Default;
interface
uses
System.Classes,
System.Generics.Collections,
Vcl.Graphics,
X2Log.Details.Intf,
X2Log.Intf;
type
TX2LogStringDetails = class(TInterfacedObject, IX2LogDetails, IX2LogDetailsText,
IX2LogDetailsCopyable, IX2LogDetailsStreamable)
private
FText: string;
public
class function CreateIfNotEmpty(const AText: string): TX2LogStringDetails;
constructor Create(const AText: string);
{ IX2LogDetails }
function GetSerializerIID: TGUID;
function Clone: IX2LogDetails;
{ IX2LogDetailsText }
function GetAsString: string;
{ IX2LogDetailsCopyable }
procedure CopyToClipboard;
{ IX2LogDetailsStreamable }
procedure SaveToStream(AStream: TStream);
end;
TX2LogDictionaryValueClass = class of TX2LogDictionaryValue;
TX2LogDictionaryValue = class(TObject)
private
FValueType: TX2LogValueType;
protected
constructor Create(AValueType: TX2LogValueType; AStream: TStream = nil; ASize: Cardinal = 0); overload; virtual;
function Clone: TX2LogDictionaryValue; virtual; abstract;
procedure LoadFromStream(AStream: TStream; ASize: Cardinal); virtual; abstract;
procedure SaveToStream(AStream: TStream); virtual; abstract;
function GetDisplayValue: string; virtual; abstract;
property DisplayValue: string read GetDisplayValue;
property ValueType: TX2LogValueType read FValueType;
end;
IX2LogDetailsDictionaryAccess = interface(IX2LogDetailsDictionary)
['{60C46488-9DBD-4596-8BE9-916C61006F0E}']
function GetValue(const Key: string): TX2LogDictionaryValue;
property Value[const Key: string]: TX2LogDictionaryValue read GetValue;
end;
TX2LogValueDictionary = TObjectDictionary<string, TX2LogDictionaryValue>;
IX2LogDetailsDictionaryWriter = interface(IX2LogDetailsDictionary)
procedure SetStringValue(const Key: string; const AValue: string);
procedure SetBooleanValue(const Key: string; const AValue: Boolean);
procedure SetIntValue(const Key: string; const AValue: Int64);
procedure SetFloatValue(const Key: string; const AValue: Extended);
procedure SetDateTimeValue(const Key: string; const AValue: TDateTime);
end;
TX2LogDictionaryDetails = class(TInterfacedObject, IX2LogDetails, IX2LogDetailsDictionary,
IX2LogDetailsDictionaryAccess, IX2LogDetailsDictionaryWriter)
private
FValues: TX2LogValueDictionary;
protected
constructor CreateOwned(AValues: TX2LogValueDictionary);
{ IX2LogDetailsDictionaryAccess }
function GetValue(const Key: string): TX2LogDictionaryValue;
public
class function CreateIfNotEmpty(AValues: array of const): TX2LogDictionaryDetails;
constructor Create(AValues: array of const);
destructor Destroy; override;
{ IX2LogDetails }
function GetSerializerIID: TGUID;
function Clone: IX2LogDetails;
{ IX2LogDetailsDictionary }
function GetKeys: TEnumerable<string>;
function GetValueType(const Key: string): TX2LogValueType;
function GetDisplayValue(const Key: string): string;
function GetStringValue(const Key: string): string;
function GetBooleanValue(const Key: string): Boolean;
function GetIntValue(const Key: string): Int64;
function GetFloatValue(const Key: string): Extended;
function GetDateTimeValue(const Key: string): TDateTime;
{ IX2LogDetailsDictionaryWriter }
procedure SetStringValue(const Key: string; const AValue: string);
procedure SetBooleanValue(const Key: string; const AValue: Boolean);
procedure SetIntValue(const Key: string; const AValue: Int64);
procedure SetFloatValue(const Key: string; const AValue: Extended);
procedure SetDateTimeValue(const Key: string; const AValue: TDateTime);
end;
TX2LogBinaryDetails = class(TInterfacedObject, IX2LogDetails, IX2LogDetailsBinary,
IX2LogDetailsStreamable)
private
FData: TStream;
protected
property Data: TStream read FData;
public
constructor Create; overload;
constructor Create(ACopyFrom: TStream; ACount: Integer = 0); overload;
constructor Create(AData: RawByteString); overload;
destructor Destroy; override;
{ IX2LogDetails }
function GetSerializerIID: TGUID;
function Clone: IX2LogDetails;
{ IX2LogDetailsBinary }
function GetAsStream: TStream;
{ IX2LogDetailsStreamable }
procedure SaveToStream(AStream: TStream);
end;
TX2LogGraphicDetails = class(TInterfacedObject, IX2LogDetails, IX2LogDetailsGraphic,
IX2LogDetailsCopyable, IX2LogDetailsStreamable)
private
FGraphic: TGraphic;
protected
{ Dummy parameter to prevent 'Duplicate constructor inaccessible from C++' warning }
constructor CreateOwned(AGraphic: TGraphic; ADummy: Integer = 0);
public
class function CreateIfNotEmpty(AGraphic: TGraphic): TX2LogGraphicDetails;
constructor Create(AGraphic: TGraphic);
destructor Destroy; override;
{ IX2LogDetails }
function GetSerializerIID: TGUID;
function Clone: IX2LogDetails;
{ IX2LogDetailsGraphic }
function GetAsGraphic: TGraphic;
{ IX2LogDetailsCopyable }
procedure CopyToClipboard;
{ IX2LogDetailsStreamable }
procedure SaveToStream(AStream: TStream);
end;
implementation
uses
System.SysUtils,
Vcl.ClipBrd,
Winapi.Windows,
X2Log.Constants,
X2Log.Details.Registry,
X2Log.Util.Stream;
const
StringDetailsSerializerIID: TGUID = '{4223C30E-6E80-4D66-9EDC-F8688A7413D2}';
DictionaryDetailsSerializerIID: TGUID = '{1D28FF6E-8AA7-41FA-96D7-0CE921D9CA2E}';
BinaryDetailsSerializerIID: TGUID = '{05F6E8BD-118E-41B3-B626-1F190CC2A7D3}';
GraphicDetailsSerializerIID: TGUID = '{BD31E42A-83DC-4947-A862-79ABAE8D5056}';
type
TX2LogStringDetailsSerializer = class(TInterfacedObject, IX2LogDetailsSerializer)
public
{ IX2LogDetailsSerializer }
procedure Serialize(ADetails: IX2LogDetails; AStream: TStream);
function Deserialize(AStream: TStream): IX2LogDetails;
end;
TX2LogDictionaryDetailsSerializer = class(TInterfacedObject, IX2LogDetailsSerializer)
public
{ IX2LogDetailsSerializer }
procedure Serialize(ADetails: IX2LogDetails; AStream: TStream);
function Deserialize(AStream: TStream): IX2LogDetails;
end;
TX2LogBinaryDetailsSerializer = class(TInterfacedObject, IX2LogDetailsSerializer)
public
{ IX2LogDetailsSerializer }
procedure Serialize(ADetails: IX2LogDetails; AStream: TStream);
function Deserialize(AStream: TStream): IX2LogDetails;
end;
TX2LogGraphicDetailsSerializer = class(TInterfacedObject, IX2LogDetailsSerializer)
public
{ IX2LogDetailsSerializer }
procedure Serialize(ADetails: IX2LogDetails; AStream: TStream);
function Deserialize(AStream: TStream): IX2LogDetails;
end;
TX2LogDictionaryStringValue = class(TX2LogDictionaryValue)
private
FValue: string;
protected
constructor Create(const AValue: string); overload;
function Clone: TX2LogDictionaryValue; override;
procedure LoadFromStream(AStream: TStream; ASize: Cardinal); override;
procedure SaveToStream(AStream: TStream); override;
function GetDisplayValue: string; override;
property Value: string read FValue write FValue;
end;
TX2LogDictionaryBooleanValue = class(TX2LogDictionaryValue)
private
FValue: Boolean;
protected
constructor Create(AValue: Boolean); overload;
function Clone: TX2LogDictionaryValue; override;
procedure LoadFromStream(AStream: TStream; ASize: Cardinal); override;
procedure SaveToStream(AStream: TStream); override;
function GetDisplayValue: string; override;
property Value: Boolean read FValue write FValue;
end;
TX2LogDictionaryIntValue = class(TX2LogDictionaryValue)
private
FValue: Int64;
protected
constructor Create(AValue: Int64); overload;
function Clone: TX2LogDictionaryValue; override;
procedure LoadFromStream(AStream: TStream; ASize: Cardinal); override;
procedure SaveToStream(AStream: TStream); override;
function GetDisplayValue: string; override;
property Value: Int64 read FValue write FValue;
end;
TX2LogDictionaryFloatValue = class(TX2LogDictionaryValue)
private
FValue: Extended;
protected
constructor Create(AValue: Extended); overload;
function Clone: TX2LogDictionaryValue; override;
procedure LoadFromStream(AStream: TStream; ASize: Cardinal); override;
procedure SaveToStream(AStream: TStream); override;
function GetDisplayValue: string; override;
property Value: Extended read FValue write FValue;
end;
TX2LogDictionaryDateTimeValue = class(TX2LogDictionaryValue)
private
FValue: TDateTime;
protected
constructor Create(AValue: TDateTime); overload;
function Clone: TX2LogDictionaryValue; override;
procedure LoadFromStream(AStream: TStream; ASize: Cardinal); override;
procedure SaveToStream(AStream: TStream); override;
function GetDisplayValue: string; override;
property Value: TDateTime read FValue write FValue;
end;
{ TX2LogStringDetails }
class function TX2LogStringDetails.CreateIfNotEmpty(const AText: string): TX2LogStringDetails;
begin
if Length(AText) > 0 then
Result := Self.Create(AText)
else
Result := nil;
end;
constructor TX2LogStringDetails.Create(const AText: string);
begin
inherited Create;
FText := AText;
end;
function TX2LogStringDetails.GetSerializerIID: TGUID;
begin
Result := StringDetailsSerializerIID;
end;
function TX2LogStringDetails.Clone: IX2LogDetails;
begin
Result := TX2LogStringDetails.Create(FText);
end;
function TX2LogStringDetails.GetAsString: string;
begin
Result := FText;
end;
procedure TX2LogStringDetails.CopyToClipboard;
begin
Clipboard.AsText := GetAsString;
end;
procedure TX2LogStringDetails.SaveToStream(AStream: TStream);
var
writer: TStreamWriter;
begin
writer := TStreamWriter.Create(AStream, TEncoding.UTF8);
try
writer.Write(GetAsString);
finally
FreeAndNil(writer);
end;
end;
{ TX2LogDictionaryDetails }
class function TX2LogDictionaryDetails.CreateIfNotEmpty(AValues: array of const): TX2LogDictionaryDetails;
begin
if Length(AValues) > 0 then
Result := TX2LogDictionaryDetails.Create(AValues)
else
Result := nil;
end;
constructor TX2LogDictionaryDetails.CreateOwned(AValues: TX2LogValueDictionary);
begin
inherited Create;
FValues := AValues;
end;
constructor TX2LogDictionaryDetails.Create(AValues: array of const);
var
paramIndex: Integer;
param: TVarRec;
key: string;
value: TX2LogDictionaryValue;
logDateTime: IX2LogDateTime;
begin
inherited Create;
FValues := TX2LogValueDictionary.Create([doOwnsValues]);
if Length(AValues) mod 2 = 1 then
raise Exception.Create('AParams must contains a multiple of 2 number of items');
paramIndex := 0;
while paramIndex < High(AValues) do
begin
param := AValues[paramIndex];
case param.VType of
vtChar: key := string(param.VChar);
vtString: key := string(param.VString^);
vtPChar: key := string(param.VPChar);
vtAnsiString: key := string(PChar(param.VAnsiString));
vtWideChar: key := string(param.VWideChar);
vtPWideChar: key := string(param.VPWideChar);
vtWideString: key := string(WideString(param.VWideString));
{$IF CompilerVersion >= 23}
vtUnicodeString: key := string(UnicodeString(param.VUnicodeString));
{$IFEND}
else
raise Exception.CreateFmt('Parameter name at index %d is not a string value',
[paramIndex div 2]);
end;
Inc(paramIndex);
param := AValues[paramIndex];
case param.VType of
vtInteger: value := TX2LogDictionaryIntValue.Create(param.VInteger);
vtBoolean: value := TX2LogDictionaryBooleanValue.Create(param.VBoolean);
vtChar: value := TX2LogDictionaryStringValue.Create(string(param.VChar));
vtExtended: value := TX2LogDictionaryFloatValue.Create(param.VExtended^);
vtString: value := TX2LogDictionaryStringValue.Create(string(param.VString^));
vtPChar: value := TX2LogDictionaryStringValue.Create(string(param.VPChar));
vtWideChar: value := TX2LogDictionaryStringValue.Create(param.VWideChar);
vtPWideChar: value := TX2LogDictionaryStringValue.Create(param.VPWideChar);
vtAnsiString: value := TX2LogDictionaryStringValue.Create(PChar(param.VAnsiString));
vtCurrency: value := TX2LogDictionaryFloatValue.Create(param.VCurrency^);
vtInterface:
if Supports(IInterface(param.VInterface), IX2LogDateTime, logDateTime) then
value := TX2LogDictionaryDateTimeValue.Create(logDateTime.Value)
else
raise Exception.CreateFmt('Unsupported value type %d at index %d', [param.VType, paramIndex]);
vtWideString: value := TX2LogDictionaryStringValue.Create(WideString(param.VWideString));
vtInt64: value := TX2LogDictionaryIntValue.Create(param.VInt64^);
{$IF CompilerVersion >= 23}
vtUnicodeString: value := TX2LogDictionaryStringValue.Create(UnicodeString(param.VUnicodeString));
{$IFEND}
else
raise Exception.CreateFmt('Unsupported value type %d at index %d', [param.VType, paramIndex]);
end;
FValues.Add(key, value);
Inc(paramIndex);
end;
end;
destructor TX2LogDictionaryDetails.Destroy;
begin
FreeAndNil(FValues);
inherited Destroy;
end;
function TX2LogDictionaryDetails.GetSerializerIID: TGUID;
begin
Result := DictionaryDetailsSerializerIID;
end;
function TX2LogDictionaryDetails.Clone: IX2LogDetails;
var
values: TX2LogValueDictionary;
pair: TPair<string, TX2LogDictionaryValue>;
begin
values := TX2LogValueDictionary.Create([doOwnsValues]);
for pair in FValues do
values.Add(pair.Key, pair.Value.Clone);
Result := TX2LogDictionaryDetails.CreateOwned(values);
end;
function TX2LogDictionaryDetails.GetKeys: TEnumerable<string>;
begin
Result := FValues.Keys;
end;
function TX2LogDictionaryDetails.GetValueType(const Key: string): TX2LogValueType;
begin
Result := FValues[Key].ValueType;
end;
function TX2LogDictionaryDetails.GetDisplayValue(const Key: string): string;
begin
Result := FValues[Key].DisplayValue;
end;
function TX2LogDictionaryDetails.GetStringValue(const Key: string): string;
begin
Result := (FValues[Key] as TX2LogDictionaryStringValue).Value;
end;
function TX2LogDictionaryDetails.GetBooleanValue(const Key: string): Boolean;
begin
Result := (FValues[Key] as TX2LogDictionaryBooleanValue).Value;
end;
function TX2LogDictionaryDetails.GetIntValue(const Key: string): Int64;
begin
Result := (FValues[Key] as TX2LogDictionaryIntValue).Value;
end;
function TX2LogDictionaryDetails.GetFloatValue(const Key: string): Extended;
begin
Result := (FValues[Key] as TX2LogDictionaryFloatValue).Value;
end;
function TX2LogDictionaryDetails.GetDateTimeValue(const Key: string): TDateTime;
begin
Result := (FValues[Key] as TX2LogDictionaryDateTimeValue).Value;
end;
function TX2LogDictionaryDetails.GetValue(const Key: string): TX2LogDictionaryValue;
begin
Result := FValues[Key];
end;
procedure TX2LogDictionaryDetails.SetBooleanValue(const Key: string; const AValue: Boolean);
begin
FValues.Add(Key, TX2LogDictionaryBooleanValue.Create(AValue));
end;
procedure TX2LogDictionaryDetails.SetDateTimeValue(const Key: string; const AValue: TDateTime);
begin
FValues.Add(Key, TX2LogDictionaryDateTimeValue.Create(AValue));
end;
procedure TX2LogDictionaryDetails.SetFloatValue(const Key: string; const AValue: Extended);
begin
FValues.Add(Key, TX2LogDictionaryFloatValue.Create(AValue));
end;
procedure TX2LogDictionaryDetails.SetIntValue(const Key: string; const AValue: Int64);
begin
FValues.Add(Key, TX2LogDictionaryIntValue.Create(AValue));
end;
procedure TX2LogDictionaryDetails.SetStringValue(const Key, AValue: string);
begin
FValues.Add(Key, TX2LogDictionaryStringValue.Create(AValue));
end;
{ TX2LogBinaryDetails }
constructor TX2LogBinaryDetails.Create;
begin
inherited Create;
FData := TMemoryStream.Create;
end;
constructor TX2LogBinaryDetails.Create(ACopyFrom: TStream; ACount: Integer);
begin
inherited Create;
FData := TMemoryStream.Create;
FData.CopyFrom(ACopyFrom, ACount);
end;
constructor TX2LogBinaryDetails.Create(AData: RawByteString);
begin
inherited Create;
FData := TStringStream.Create(AData);
end;
destructor TX2LogBinaryDetails.Destroy;
begin
FreeAndNil(FData);
inherited Destroy;
end;
function TX2LogBinaryDetails.GetSerializerIID: TGUID;
begin
Result := BinaryDetailsSerializerIID;
end;
function TX2LogBinaryDetails.Clone: IX2LogDetails;
begin
Result := TX2LogBinaryDetails.Create(Data);
end;
function TX2LogBinaryDetails.GetAsStream: TStream;
begin
Data.Position := 0;
Result := Data;
end;
procedure TX2LogBinaryDetails.SaveToStream(AStream: TStream);
begin
AStream.CopyFrom(Data, 0);
end;
{ TX2LogGraphicDetails }
class function TX2LogGraphicDetails.CreateIfNotEmpty(AGraphic: TGraphic): TX2LogGraphicDetails;
begin
if Assigned(AGraphic) and (not AGraphic.Empty) then
Result := Self.Create(AGraphic)
else
Result := nil;
end;
constructor TX2LogGraphicDetails.Create(AGraphic: TGraphic);
begin
inherited Create;
if not Assigned(AGraphic) then
raise EInvalidGraphic.Create('AGraphic can not be nil');
FGraphic := TGraphicClass(AGraphic.ClassType).Create;
FGraphic.Assign(AGraphic);
end;
constructor TX2LogGraphicDetails.CreateOwned(AGraphic: TGraphic; ADummy: Integer);
begin
inherited Create;
FGraphic := AGraphic;
end;
destructor TX2LogGraphicDetails.Destroy;
begin
FreeAndNil(FGraphic);
inherited;
end;
function TX2LogGraphicDetails.GetSerializerIID: TGUID;
begin
Result := GraphicDetailsSerializerIID;
end;
function TX2LogGraphicDetails.Clone: IX2LogDetails;
begin
Result := TX2LogGraphicDetails.Create(FGraphic);
end;
procedure TX2LogGraphicDetails.CopyToClipboard;
var
format: Word;
data: NativeUInt;
palette: HPALETTE;
begin
GetAsGraphic.SaveToClipboardFormat(format, data, palette);
end;
procedure TX2LogGraphicDetails.SaveToStream(AStream: TStream);
begin
FGraphic.SaveToStream(AStream);
end;
function TX2LogGraphicDetails.GetAsGraphic: TGraphic;
begin
Result := FGraphic;
end;
{ TX2LogStringDetailsSerializer }
procedure TX2LogStringDetailsSerializer.Serialize(ADetails: IX2LogDetails; AStream: TStream);
begin
TStreamUtil.WriteString(AStream, (ADetails as IX2LogDetailsText).AsString);
end;
function TX2LogStringDetailsSerializer.Deserialize(AStream: TStream): IX2LogDetails;
begin
Result := TX2LogStringDetails.Create(TStreamUtil.ReadString(AStream));
end;
{ TX2LogDictionaryDetailsSerializer }
procedure TX2LogDictionaryDetailsSerializer.Serialize(ADetails: IX2LogDetails; AStream: TStream);
var
details: IX2LogDetailsDictionaryAccess;
key: string;
value: TX2LogDictionaryValue;
payload: TMemoryStream;
begin
details := (ADetails as IX2LogDetailsDictionaryAccess);
payload := TMemoryStream.Create;
try
for key in details.Keys do
begin
TStreamUtil.WriteString(AStream, key);
value := details.Value[key];
TStreamUtil.WriteByte(AStream, Ord(value.ValueType));
payload.Clear;
value.SaveToStream(payload);
TStreamUtil.WriteCardinal(AStream, payload.Size);
if payload.Size > 0 then
AStream.CopyFrom(payload, 0);
end;
finally
FreeAndNil(payload);
end;
TStreamUtil.WriteString(AStream, '');
end;
function TX2LogDictionaryDetailsSerializer.Deserialize(AStream: TStream): IX2LogDetails;
var
values: TX2LogValueDictionary;
key: string;
valueType: TX2LogValueType;
payloadSize: Cardinal;
valueClass: TX2LogDictionaryValueClass;
begin
Result := nil;
values := TX2LogValueDictionary.Create([doOwnsValues]);
try
while True do
begin
key := TStreamUtil.ReadString(AStream);
if Length(key) = 0 then
break;
valueType := TX2LogValueType(TStreamUtil.ReadByte(AStream));
payloadSize := TStreamUtil.ReadCardinal(AStream);
valueClass := nil;
case valueType of
StringValue: valueClass := TX2LogDictionaryStringValue;
BooleanValue: valueClass := TX2LogDictionaryBooleanValue;
IntValue: valueClass := TX2LogDictionaryIntValue;
FloatValue: valueClass := TX2LogDictionaryFloatValue;
DateTimeValue: valueClass := TX2LogDictionaryDateTimeValue;
else
AStream.Position := AStream.Position + payloadSize;
end;
if Assigned(valueClass) then
values.Add(key, valueClass.Create(valueType, AStream, payloadSize));
end;
Result := TX2LogDictionaryDetails.CreateOwned(values);
values := nil;
finally
FreeAndNil(values);
end;
end;
{ TX2LogBinaryDetailsSerializer }
procedure TX2LogBinaryDetailsSerializer.Serialize(ADetails: IX2LogDetails; AStream: TStream);
var
stream: TStream;
begin
stream := (ADetails as IX2LogDetailsBinary).AsStream;
TStreamUtil.WriteCardinal(AStream, stream.Size);
if stream.Size > 0 then
AStream.CopyFrom(stream, stream.Size);
end;
function TX2LogBinaryDetailsSerializer.Deserialize(AStream: TStream): IX2LogDetails;
var
streamSize: Cardinal;
begin
streamSize := TStreamUtil.ReadCardinal(AStream);
if streamSize > 0 then
Result := TX2LogBinaryDetails.Create(AStream, streamSize)
else
{ Do not return nil; the fact that Deserialize is called means an
empty Details was serialized. }
Result := TX2LogBinaryDetails.Create;
end;
{ TX2LogGraphicDetailsSerializer }
procedure TX2LogGraphicDetailsSerializer.Serialize(ADetails: IX2LogDetails; AStream: TStream);
var
graphic: TGraphic;
begin
graphic := (ADetails as IX2LogDetailsGraphic).AsGraphic;
TStreamUtil.WriteString(AStream, graphic.ClassName);
graphic.SaveToStream(AStream);
end;
function TX2LogGraphicDetailsSerializer.Deserialize(AStream: TStream): IX2LogDetails;
var
graphicClass: TGraphicClass;
graphic: TGraphic;
begin
Result := nil;
graphicClass := TGraphicClass(GetClass(TStreamUtil.ReadString(AStream)));
if Assigned(graphicClass) then
begin
graphic := graphicClass.Create;
try
graphic.LoadFromStream(AStream);
Result := TX2LogGraphicDetails.CreateOwned(graphic);
except
FreeAndNil(graphic);
raise;
end;
end;
end;
{ TX2LogDictionaryValue }
constructor TX2LogDictionaryValue.Create(AValueType: TX2LogValueType; AStream: TStream; ASize: Cardinal);
begin
inherited Create;
FValueType := AValueType;
if Assigned(AStream) then
LoadFromStream(AStream, ASize);
end;
{ TX2LogDictionaryStringValue }
constructor TX2LogDictionaryStringValue.Create(const AValue: string);
begin
inherited Create(StringValue);
Value := AValue;
end;
function TX2LogDictionaryStringValue.Clone: TX2LogDictionaryValue;
begin
Result := TX2LogDictionaryStringValue.Create(FValue);
end;
procedure TX2LogDictionaryStringValue.LoadFromStream(AStream: TStream; ASize: Cardinal);
begin
Value := TStreamUtil.ReadString(AStream, nil, False, ASize);
end;
procedure TX2LogDictionaryStringValue.SaveToStream(AStream: TStream);
begin
TStreamUtil.WriteString(AStream, Value, nil, False);
end;
function TX2LogDictionaryStringValue.GetDisplayValue: string;
begin
Result := Value;
end;
{ TX2LogDictionaryBooleanValue }
constructor TX2LogDictionaryBooleanValue.Create(AValue: Boolean);
begin
inherited Create(BooleanValue);
Value := AValue;
end;
function TX2LogDictionaryBooleanValue.Clone: TX2LogDictionaryValue;
begin
Result := TX2LogDictionaryBooleanValue.Create(FValue);
end;
procedure TX2LogDictionaryBooleanValue.LoadFromStream(AStream: TStream; ASize: Cardinal);
begin
if ASize <> SizeOf(Boolean) then
raise EInvalidOperation.CreateFmt('Size (%d) does not match Boolean', [ASize]);
AStream.ReadBuffer(FValue, ASize);
end;
procedure TX2LogDictionaryBooleanValue.SaveToStream(AStream: TStream);
begin
AStream.WriteBuffer(Value, SizeOf(Boolean));
end;
function TX2LogDictionaryBooleanValue.GetDisplayValue: string;
begin
Result := BoolToStr(Value, True);
end;
{ TX2LogDictionaryIntValue }
constructor TX2LogDictionaryIntValue.Create(AValue: Int64);
begin
inherited Create(IntValue);
Value := AValue;
end;
function TX2LogDictionaryIntValue.Clone: TX2LogDictionaryValue;
begin
Result := TX2LogDictionaryIntValue.Create(FValue);
end;
procedure TX2LogDictionaryIntValue.LoadFromStream(AStream: TStream; ASize: Cardinal);
begin
if ASize <> SizeOf(Int64) then
raise EInvalidOperation.CreateFmt('Size (%d) does not match Int64', [ASize]);
AStream.ReadBuffer(FValue, ASize);
end;
procedure TX2LogDictionaryIntValue.SaveToStream(AStream: TStream);
begin
AStream.WriteBuffer(Value, SizeOf(Int64));
end;
function TX2LogDictionaryIntValue.GetDisplayValue: string;
begin
Result := IntToStr(Value);
end;
{ TX2LogDictionaryFloatValue }
constructor TX2LogDictionaryFloatValue.Create(AValue: Extended);
begin
inherited Create(FloatValue);
Value := AValue;
end;
function TX2LogDictionaryFloatValue.Clone: TX2LogDictionaryValue;
begin
Result := TX2LogDictionaryFloatValue.Create(FValue);
end;
procedure TX2LogDictionaryFloatValue.LoadFromStream(AStream: TStream; ASize: Cardinal);
begin
if ASize <> SizeOf(Extended) then
raise EInvalidOperation.CreateFmt('Size (%d) does not match Extended', [ASize]);
AStream.ReadBuffer(FValue, ASize);
end;
procedure TX2LogDictionaryFloatValue.SaveToStream(AStream: TStream);
begin
AStream.WriteBuffer(Value, SizeOf(Extended));
end;
function TX2LogDictionaryFloatValue.GetDisplayValue: string;
begin
Result := FormatFloat('0.########', Value);
end;
{ TX2LogDictionaryDateTimeValue }
constructor TX2LogDictionaryDateTimeValue.Create(AValue: TDateTime);
begin
inherited Create(DateTimeValue);
Value := AValue;
end;
function TX2LogDictionaryDateTimeValue.Clone: TX2LogDictionaryValue;
begin
Result := TX2LogDictionaryDateTimeValue.Create(FValue);
end;
procedure TX2LogDictionaryDateTimeValue.LoadFromStream(AStream: TStream; ASize: Cardinal);
begin
if ASize <> SizeOf(TDateTime) then
raise EInvalidOperation.CreateFmt('Size (%d) does not match TDateTime', [ASize]);
AStream.ReadBuffer(FValue, ASize);
end;
procedure TX2LogDictionaryDateTimeValue.SaveToStream(AStream: TStream);
begin
AStream.WriteBuffer(Value, SizeOf(TDateTime));
end;
function TX2LogDictionaryDateTimeValue.GetDisplayValue: string;
begin
Result := DateTimeToStr(Value);
end;
initialization
TX2LogDetailsRegistry.Register(StringDetailsSerializerIID, TX2LogStringDetailsSerializer.Create);
TX2LogDetailsRegistry.Register(DictionaryDetailsSerializerIID, TX2LogDictionaryDetailsSerializer.Create);
TX2LogDetailsRegistry.Register(BinaryDetailsSerializerIID, TX2LogBinaryDetailsSerializer.Create);
TX2LogDetailsRegistry.Register(GraphicDetailsSerializerIID, TX2LogGraphicDetailsSerializer.Create);
end.