Componentes.Terceros.jcl/official/2.1.1/source/windows/JclDebugSerialization.pas
2010-01-18 16:51:36 +00:00

761 lines
27 KiB
ObjectPascal

{**************************************************************************************************}
{ }
{ Project JEDI Code Library (JCL) }
{ }
{ The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); }
{ you may not use this file except in compliance with the License. You may obtain a copy of the }
{ License at http://www.mozilla.org/MPL/ }
{ }
{ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF }
{ ANY KIND, either express or implied. See the License for the specific language governing rights }
{ and limitations under the License. }
{ }
{ The Original Code is JclDebugSerialization.pas. }
{ }
{ The Initial Developer of the Original Code is Uwe Schuster. }
{ Portions created by Uwe Schuster are Copyright (C) 2009 Uwe Schuster. All rights reserved. }
{ }
{ Contributor(s): }
{ Uwe Schuster (uschuster) }
{ }
{**************************************************************************************************}
{ }
{ Last modified: $Date:: 2009-08-10 23:20:25 +0200 (lun., 10 août 2009) $ }
{ Revision: $Rev:: 2943 $ }
{ Author: $Author:: outchy $ }
{ }
{**************************************************************************************************}
unit JclDebugSerialization;
{$I jcl.inc}
interface
uses
SysUtils, Classes, Contnrs,
{$IFDEF UNITVERSIONING}
JclUnitVersioning,
{$ENDIF UNITVERSIONING}
JclDebug;
type
TJclCustomSimpleSerializer = class(TObject)
protected
FItems: TObjectList;
FName: string;
FValues: TStringList;
function GetCount: Integer;
function GetItems(AIndex: Integer): TJclCustomSimpleSerializer;
public
constructor Create(const AName: string);
destructor Destroy; override;
function AddChild(ASender: TObject; const AName: string): TJclCustomSimpleSerializer;
procedure Clear;
function ReadString(ASender: TObject; const AName: string): string;
procedure WriteString(ASender: TObject; const AName: string; const AValue: string);
property Count: Integer read GetCount;
property Items[AIndex: Integer]: TJclCustomSimpleSerializer read GetItems; default;
property Name: string read FName;
property Values: TStringList read FValues;
end;
TJclSerializableLocationInfo = class(TJclLocationInfoEx)
public
procedure Deserialize(ASerializer: TJclCustomSimpleSerializer);
procedure Serialize(ASerializer: TJclCustomSimpleSerializer);
end;
TJclSerializableLocationInfoList = class(TJclCustomLocationInfoList)
private
function GetItems(AIndex: Integer): TJclSerializableLocationInfo;
public
constructor Create; override;
function Add(Addr: Pointer): TJclSerializableLocationInfo;
procedure Deserialize(ASerializer: TJclCustomSimpleSerializer);
procedure Serialize(ASerializer: TJclCustomSimpleSerializer);
property Items[AIndex: Integer]: TJclSerializableLocationInfo read GetItems; default;
end;
TJclSerializableThreadInfo = class(TJclCustomThreadInfo)
private
function GetStack(const AIndex: Integer): TJclSerializableLocationInfoList;
protected
function GetStackClass: TJclCustomLocationInfoListClass; override;
public
constructor Create;
destructor Destroy; override;
procedure Deserialize(ASerializer: TJclCustomSimpleSerializer);
procedure Serialize(ASerializer: TJclCustomSimpleSerializer);
property CreationStack: TJclSerializableLocationInfoList index 1 read GetStack;
property Stack: TJclSerializableLocationInfoList index 2 read GetStack;
end;
TJclSerializableThreadInfoList = class(TPersistent)
private
FItems: TObjectList;
function GetItems(AIndex: Integer): TJclSerializableThreadInfo;
function GetCount: Integer;
public
constructor Create;
destructor Destroy; override;
function Add: TJclSerializableThreadInfo;
procedure Assign(Source: TPersistent); override;
procedure Clear;
procedure Deserialize(ASerializer: TJclCustomSimpleSerializer);
procedure Serialize(ASerializer: TJclCustomSimpleSerializer);
property Count: Integer read GetCount;
property Items[AIndex: Integer]: TJclSerializableThreadInfo read GetItems; default;
end;
TJclSerializableException = class(TPersistent)
private
FExceptionClassName: string;
FExceptionMessage: string;
protected
procedure AssignTo(Dest: TPersistent); override;
public
procedure Clear;
procedure Deserialize(ASerializer: TJclCustomSimpleSerializer);
procedure Serialize(ASerializer: TJclCustomSimpleSerializer);
property ExceptionClassName: string read FExceptionClassName write FExceptionClassName;
property ExceptionMessage: string read FExceptionMessage write FExceptionMessage;
end;
TJclSerializableModuleInfo = class(TPersistent)
private
FStartStr: string;
FEndStr: string;
FSystemModuleStr: string;
FModuleName: string;
FBinFileVersion: string;
FFileVersion: string;
FFileDescription: string;
protected
procedure AssignTo(Dest: TPersistent); override;
public
procedure Deserialize(ASerializer: TJclCustomSimpleSerializer);
procedure Serialize(ASerializer: TJclCustomSimpleSerializer);
property StartStr: string read FStartStr write FStartStr;
property EndStr: string read FEndStr write FEndStr;
property SystemModuleStr: string read FSystemModuleStr write FSystemModuleStr;
property ModuleName: string read FModuleName write FModuleName;
property BinFileVersion: string read FBinFileVersion write FBinFileVersion;
property FileVersion: string read FFileVersion write FFileVersion;
property FileDescription: string read FFileDescription write FFileDescription;
end;
TJclSerializableModuleInfoList = class(TPersistent)
private
FItems: TObjectList;
function GetCount: Integer;
function GetItems(AIndex: Integer): TJclSerializableModuleInfo;
protected
procedure AssignTo(Dest: TPersistent); override;
public
constructor Create;
destructor Destroy; override;
function Add: TJclSerializableModuleInfo;
procedure Clear;
procedure Deserialize(ASerializer: TJclCustomSimpleSerializer);
procedure Serialize(ASerializer: TJclCustomSimpleSerializer);
property Count: Integer read GetCount;
property Items[AIndex: Integer]: TJclSerializableModuleInfo read GetItems; default;
end;
TJclSerializableExceptionInfo = class(TObject)
private
FException: TJclSerializableException;
FThreadInfoList: TJclSerializableThreadInfoList;
FModules: TJclSerializableModuleInfoList;
public
constructor Create;
destructor Destroy; override;
procedure Deserialize(ASerializer: TJclCustomSimpleSerializer);
procedure Serialize(ASerializer: TJclCustomSimpleSerializer);
property ThreadInfoList: TJclSerializableThreadInfoList read FThreadInfoList;
property Exception: TJclSerializableException read FException;
property Modules: TJclSerializableModuleInfoList read FModules;
end;
{$IFDEF UNITVERSIONING}
const
UnitVersioning: TUnitVersionInfo = (
RCSfile: '$URL: https://jcl.svn.sourceforge.net/svnroot/jcl/tags/JCL-2.1-Build3536/jcl/source/windows/JclDebugSerialization.pas $';
Revision: '$Revision: 2943 $';
Date: '$Date: 2009-08-10 23:20:25 +0200 (lun., 10 août 2009) $';
LogPath: 'JCL\source\windows';
Extra: '';
Data: nil
);
{$ENDIF UNITVERSIONING}
implementation
uses
JclDateTime;
const
MinutesPerDay = 60 * 24;
{ TODO -oUSc : move to JclDateTime }
function ISOFormatStrToDateTime(const AISOFormatTimeStampStr: string; ADefault: TDateTime): TDateTime;
var
Year, Month, Day, Hour, Minute, Second: Word;
begin
Result := ADefault;
{ TODO -oUSc : make it more generics to accept for exam. milliseconds }
if (Length(AISOFormatTimeStampStr) = 25) or ((Length(AISOFormatTimeStampStr) = 20) and
(AISOFormatTimeStampStr[20] = 'Z')) then
begin
if (AISOFormatTimeStampStr[5] = '-') and (AISOFormatTimeStampStr[8] = '-') and
(AISOFormatTimeStampStr[11] = 'T') and (AISOFormatTimeStampStr[14] = ':') and
(AISOFormatTimeStampStr[17] = ':') then
begin
Year := StrToInt(Copy(AISOFormatTimeStampStr, 1, 4));
Month := StrToInt(Copy(AISOFormatTimeStampStr, 6, 2));
Day := StrToInt(Copy(AISOFormatTimeStampStr, 9, 2));
Hour := StrToInt(Copy(AISOFormatTimeStampStr, 12, 2));
Minute := StrToInt(Copy(AISOFormatTimeStampStr, 15, 2));
Second := StrToInt(Copy(AISOFormatTimeStampStr, 18, 2));
Result := EncodeDate(Year, Month, Day) + EncodeTime(Hour, Minute, Second, 0);
end;
end;
end;
function ISOFormatStrToLocalDateTime(const AISOFormatTimeStampStr: string; ADefault: TDateTime): TDateTime;
begin
Result := ISOFormatStrToDateTime(AISOFormatTimeStampStr, ADefault);
Result := DateTimeToLocalDateTime(Result);
end;
function DateTimeToISOFormatStr(ATimeStamp: TDateTime; ABias: Longint): string;
var
TimeZoneAsDateTime: TDateTime;
S: string;
begin
Result := FormatDateTime('yyyy-mm-dd"T"hh:nn:ss', ATimeStamp);
TimeZoneAsDateTime := ABias / MinutesPerDay;
S := FormatDateTime('hh:nn', Abs(TimeZoneAsDateTime));
if ABias > 0 then
Result := Result + '+' + S
else
if ABias = 0 then
Result := Result + 'Z'
else
Result := Result + '-' + S;
end;
function LocalDateTimeToISOFormatStr(ATimeStamp: TDateTime): string;
var
UTCTimeStamp, TimeZoneAsDateTime: TDateTime;
begin
UTCTimeStamp := LocalDateTimeToDateTime(ATimeStamp);
TimeZoneAsDateTime := ATimeStamp - UTCTimeStamp;
Result := DateTimeToISOFormatStr(UTCTimeStamp, Round(TimeZoneAsDateTime * MinutesPerDay));
end;
//=== { TJclCustomSimpleSerializer } =========================================
constructor TJclCustomSimpleSerializer.Create(const AName: string);
begin
inherited Create;
FItems := TObjectList.Create;
FName := AName;
FValues := TStringList.Create;
end;
destructor TJclCustomSimpleSerializer.Destroy;
begin
FValues.Free;
FItems.Free;
inherited Destroy;
end;
function TJclCustomSimpleSerializer.AddChild(ASender: TObject; const AName: string): TJclCustomSimpleSerializer;
begin
FItems.Add(TJclCustomSimpleSerializer.Create(AName));
Result := TJclCustomSimpleSerializer(FItems.Last);
end;
procedure TJclCustomSimpleSerializer.Clear;
begin
FItems.Clear;
FValues.Clear;
FName := '';
end;
function TJclCustomSimpleSerializer.GetCount: Integer;
begin
Result := FItems.Count;
end;
function TJclCustomSimpleSerializer.GetItems(AIndex: Integer): TJclCustomSimpleSerializer;
begin
Result := TJclCustomSimpleSerializer(FItems[AIndex]);
end;
function TJclCustomSimpleSerializer.ReadString(ASender: TObject; const AName: string): string;
begin
Result := FValues.Values[AName];
end;
procedure TJclCustomSimpleSerializer.WriteString(ASender: TObject; const AName: string; const AValue: string);
begin
FValues.Add(Format('%s=%s', [AName, AValue]));
end;
//=== { TJclSerializableThreadInfoList } =====================================
constructor TJclSerializableThreadInfoList.Create;
begin
inherited Create;
FItems := TObjectList.Create;
end;
destructor TJclSerializableThreadInfoList.Destroy;
begin
FItems.Free;
inherited Destroy;
end;
function TJclSerializableThreadInfoList.Add: TJclSerializableThreadInfo;
begin
FItems.Add(TJclSerializableThreadInfo.Create);
Result := TJclSerializableThreadInfo(FItems.Last);
end;
procedure TJclSerializableThreadInfoList.Assign(Source: TPersistent);
var
I: Integer;
begin
if Source is TJclThreadInfoList then
begin
Clear;
for I := 0 to TJclThreadInfoList(Source).Count - 1 do
Add.Assign(TJclThreadInfoList(Source)[I]);
end
else
inherited Assign(Source);
end;
procedure TJclSerializableThreadInfoList.Clear;
begin
FItems.Clear;
end;
function TJclSerializableThreadInfoList.GetCount: Integer;
begin
Result := FItems.Count;
end;
function TJclSerializableThreadInfoList.GetItems(AIndex: Integer): TJclSerializableThreadInfo;
begin
Result := TJclSerializableThreadInfo(FItems[AIndex]);
end;
procedure TJclSerializableThreadInfoList.Deserialize(ASerializer: TJclCustomSimpleSerializer);
var
I: Integer;
begin
Clear;
for I := 0 to ASerializer.Count - 1 do
if ASerializer[I].Name = 'ThreadInfo' then
Add.Deserialize(ASerializer[I]);
end;
procedure TJclSerializableThreadInfoList.Serialize(ASerializer: TJclCustomSimpleSerializer);
var
I: Integer;
begin
for I := 0 to Count - 1 do
Items[I].Serialize(ASerializer.AddChild(Self, 'ThreadInfo'));
end;
//=== { TJclSerializableLocationInfo } =======================================
procedure TJclSerializableLocationInfo.Deserialize(ASerializer: TJclCustomSimpleSerializer);
var
S, SOffsetFromProcName, SLineNumberOffsetFromProcedureStart: string;
begin
Values := [];
SOffsetFromProcName := ASerializer.ReadString(Self, 'OffsetFromProcName');
if SOffsetFromProcName <> '' then
Values := Values + [lievLocationInfo];
SLineNumberOffsetFromProcedureStart := ASerializer.ReadString(Self, 'LineNumberOffsetFromProcedureStart');
if SLineNumberOffsetFromProcedureStart <> '' then
Values := Values + [lievProcedureStartLocationInfo];
S := ASerializer.ReadString(Self, 'VAddress');
VAddress := Pointer(StrToIntDef('$' + S, 0));
ModuleName := ASerializer.ReadString(Self, 'ModuleName');
S := ASerializer.ReadString(Self, 'Address');
Address := Pointer(StrToIntDef('$' + S, 0));
OffsetFromProcName := StrToIntDef('$' + SOffsetFromProcName, 0);
SourceUnitName := ASerializer.ReadString(Self, 'UnitName');
ProcedureName := ASerializer.ReadString(Self, 'ProcedureName');
SourceName := ASerializer.ReadString(Self, 'SourceName');
S := ASerializer.ReadString(Self, 'LineNumber');
LineNumber := StrToIntDef(S, -1);
S := ASerializer.ReadString(Self, 'OffsetFromLineNumber');
OffsetFromLineNumber := StrToIntDef(S, -1);
LineNumberOffsetFromProcedureStart := StrToIntDef(SLineNumberOffsetFromProcedureStart, -1);
UnitVersionDateTime := ISOFormatStrToDateTime(ASerializer.ReadString(Self, 'UnitVersionDateTime'), 0);
UnitVersionExtra := ASerializer.ReadString(Self, 'UnitVersionExtra');
UnitVersionLogPath := ASerializer.ReadString(Self, 'UnitVersionLogPath');
UnitVersionRCSfile := ASerializer.ReadString(Self, 'UnitVersionRCSfile');
UnitVersionRevision := ASerializer.ReadString(Self, 'UnitVersionRevision');
end;
procedure TJclSerializableLocationInfo.Serialize(ASerializer: TJclCustomSimpleSerializer);
var
S: string;
begin
S := '';
ASerializer.WriteString(Self, 'VAddress', Format('%p', [VAddress]));
ASerializer.WriteString(Self, 'ModuleName', ModuleName);
ASerializer.WriteString(Self, 'Address', Format('%p', [Address]));
if lievLocationInfo in Values then
begin
ASerializer.WriteString(Self, 'OffsetFromProcName', Format('+ $%x', [OffsetFromProcName]));
ASerializer.WriteString(Self, 'UnitName', SourceUnitName);
ASerializer.WriteString(Self, 'ProcedureName', ProcedureName);
ASerializer.WriteString(Self, 'SourceName', SourceName);
if LineNumber > 0 then
begin
ASerializer.WriteString(Self, 'LineNumber', IntToStr(LineNumber));
if OffsetFromLineNumber >= 0 then
S := S + Format('+ $%x', [OffsetFromLineNumber])
else
S := S + Format('- $%x', [-OffsetFromLineNumber]);
ASerializer.WriteString(Self, 'OffsetFromLineNumber', S);
end;
if lievProcedureStartLocationInfo in Values then
ASerializer.WriteString(Self, 'LineNumberOffsetFromProcedureStart', IntToStr(LineNumberOffsetFromProcedureStart));
end;
if lievUnitVersionInfo in Values then
begin
ASerializer.WriteString(Self, 'UnitVersionDateTime', DateTimeToISOFormatStr(UnitVersionDateTime, 0));
ASerializer.WriteString(Self, 'UnitVersionExtra', UnitVersionExtra);
ASerializer.WriteString(Self, 'UnitVersionLogPath', UnitVersionLogPath);
ASerializer.WriteString(Self, 'UnitVersionRCSfile', UnitVersionRCSfile);
ASerializer.WriteString(Self, 'UnitVersionRevision', UnitVersionRevision);
end;
end;
//=== { TJclSerializableLocationInfoList } ===================================
function TJclSerializableLocationInfoList.Add(Addr: Pointer): TJclSerializableLocationInfo;
begin
Result := TJclSerializableLocationInfo(InternalAdd(Addr));
end;
constructor TJclSerializableLocationInfoList.Create;
begin
inherited Create;
FItemClass := TJclSerializableLocationInfo;
FOptions := [];
end;
function TJclSerializableLocationInfoList.GetItems(AIndex: Integer): TJclSerializableLocationInfo;
begin
Result := TJclSerializableLocationInfo(FItems[AIndex]);
end;
procedure TJclSerializableLocationInfoList.Deserialize(ASerializer: TJclCustomSimpleSerializer);
var
I: Integer;
begin
Clear;
for I := 0 to ASerializer.Count - 1 do
if ASerializer[I].Name = 'LocationInfo' then
Add(nil).Deserialize(ASerializer[I]);
end;
procedure TJclSerializableLocationInfoList.Serialize(ASerializer: TJclCustomSimpleSerializer);
var
I: Integer;
begin
for I := 0 to Count - 1 do
Items[I].Serialize(ASerializer.AddChild(Self, 'LocationInfo'));
end;
//=== { TJclSerializableThreadInfo } =========================================
constructor TJclSerializableThreadInfo.Create;
begin
inherited Create;
end;
destructor TJclSerializableThreadInfo.Destroy;
begin
inherited Destroy;
end;
function TJclSerializableThreadInfo.GetStack(const AIndex: Integer): TJclSerializableLocationInfoList;
begin
case AIndex of
1: Result := TJclSerializableLocationInfoList(FCreationStack);
2: Result := TJclSerializableLocationInfoList(FStack);
else
Result := nil;
end;
end;
function TJclSerializableThreadInfo.GetStackClass: TJclCustomLocationInfoListClass;
begin
Result := TJclSerializableLocationInfoList;
end;
procedure TJclSerializableThreadInfo.Deserialize(ASerializer: TJclCustomSimpleSerializer);
var
S: string;
I: Integer;
begin
Values := [];
S := ASerializer.ReadString(Self, 'ThreadID');
ThreadID := StrToIntDef(S, 0);
if ASerializer.ReadString(Self, 'MainThread') = '1' then
Values := Values + [tioIsMainThread];
S := ASerializer.ReadString(Self, 'Name');
if S <> '' then
begin
Name := S;
Values := Values + [tioName];
end;
S := ASerializer.ReadString(Self, 'CreationTime');
if S <> '' then
begin
CreationTime := ISOFormatStrToLocalDateTime(S, 0);
if CreationTime > 0 then
Values := Values + [tioCreationTime];
end;
S := ASerializer.ReadString(Self, 'ParentThreadID');
if S <> '' then
begin
ParentThreadID := StrToIntDef(S, 0);
if ParentThreadID <> 0 then
Values := Values + [tioParentThreadID];
end;
for I := 0 to ASerializer.Count - 1 do
if ASerializer[I].Name = 'Stack' then
begin
Stack.Deserialize(ASerializer[I]);
Values := Values + [tioStack];
end
else
if ASerializer[I].Name = 'CreationStack' then
begin
CreationStack.Deserialize(ASerializer[I]);
Values := Values + [tioCreationStack];
end;
end;
procedure TJclSerializableThreadInfo.Serialize(ASerializer: TJclCustomSimpleSerializer);
begin
ASerializer.WriteString(Self, 'ThreadID', IntToStr(ThreadID));
if tioIsMainThread in Values then
ASerializer.WriteString(Self, 'MainThread', '1');
if tioName in Values then
ASerializer.WriteString(Self, 'Name', Name);
if tioCreationTime in Values then
ASerializer.WriteString(Self, 'CreationTime', LocalDateTimeToISOFormatStr(CreationTime));
if tioParentThreadID in Values then
ASerializer.WriteString(Self, 'ParentThreadID', IntToStr(ParentThreadID));
if tioStack in Values then
Stack.Serialize(ASerializer.AddChild(Self, 'Stack'));
if tioCreationStack in Values then
CreationStack.Serialize(ASerializer.AddChild(Self, 'CreationStack'));
end;
//=== { TExceptionInfo } =====================================================
constructor TJclSerializableExceptionInfo.Create;
begin
inherited Create;
FException := TJclSerializableException.Create;
FThreadInfoList := TJclSerializableThreadInfoList.Create;
FModules := TJclSerializableModuleInfoList.Create;
end;
destructor TJclSerializableExceptionInfo.Destroy;
begin
FModules.Free;
FException.Free;
FThreadInfoList.Free;
inherited Destroy;
end;
procedure TJclSerializableExceptionInfo.Deserialize(ASerializer: TJclCustomSimpleSerializer);
var
I: Integer;
begin
FThreadInfoList.Clear;
FException.Clear;
FModules.Clear;
for I := 0 to ASerializer.Count - 1 do
if ASerializer[I].Name = 'ThreadInfo' then
FThreadInfoList.Deserialize(ASerializer[I])
else
if ASerializer[I].Name = 'Exception' then
FException.Deserialize(ASerializer[I])
else
if ASerializer[I].Name = 'Modules' then
FModules.Deserialize(ASerializer[I]);
end;
procedure TJclSerializableExceptionInfo.Serialize(ASerializer: TJclCustomSimpleSerializer);
begin
FThreadInfoList.Serialize(ASerializer.AddChild(Self, 'ThreadInfo'));
FException.Serialize(ASerializer.AddChild(Self, 'Exception'));
FModules.Serialize(ASerializer.AddChild(Self, 'Modules'));
end;
//=== { TException } =========================================================
procedure TJclSerializableException.AssignTo(Dest: TPersistent);
begin
if Dest is TJclSerializableException then
begin
TJclSerializableException(Dest).FExceptionClassName := FExceptionClassName;
TJclSerializableException(Dest).FExceptionMessage := FExceptionMessage;
end
else
inherited AssignTo(Dest);
end;
procedure TJclSerializableException.Clear;
begin
FExceptionClassName := '';
FExceptionMessage := '';
end;
procedure TJclSerializableException.Deserialize(ASerializer: TJclCustomSimpleSerializer);
begin
Clear;
FExceptionClassName := ASerializer.ReadString(Self, 'ClassName');
FExceptionMessage := ASerializer.ReadString(Self, 'Message');
end;
procedure TJclSerializableException.Serialize(ASerializer: TJclCustomSimpleSerializer);
begin
ASerializer.WriteString(Self, 'ClassName', FExceptionClassName);
ASerializer.WriteString(Self, 'Message', FExceptionMessage);
end;
//=== { TModule } ============================================================
procedure TJclSerializableModuleInfo.AssignTo(Dest: TPersistent);
begin
if Dest is TJclSerializableModuleInfo then
begin
TJclSerializableModuleInfo(Dest).FStartStr := FStartStr;
TJclSerializableModuleInfo(Dest).FEndStr := FEndStr;
TJclSerializableModuleInfo(Dest).FSystemModuleStr := FSystemModuleStr;
TJclSerializableModuleInfo(Dest).FModuleName := FModuleName;
TJclSerializableModuleInfo(Dest).FBinFileVersion := FBinFileVersion;
TJclSerializableModuleInfo(Dest).FFileVersion := FFileVersion;
TJclSerializableModuleInfo(Dest).FFileDescription := FFileDescription;
end
else
inherited AssignTo(Dest);
end;
procedure TJclSerializableModuleInfo.Deserialize(ASerializer: TJclCustomSimpleSerializer);
begin
FStartStr := ASerializer.ReadString(Self, 'StartAddr');
FEndStr := ASerializer.ReadString(Self, 'EndAddr');
FSystemModuleStr := ASerializer.ReadString(Self, 'SystemModule');
FModuleName := ASerializer.ReadString(Self, 'FileName');
FBinFileVersion := ASerializer.ReadString(Self, 'BinFileVersion');
FFileVersion := ASerializer.ReadString(Self, 'FileVersion');
FFileDescription := ASerializer.ReadString(Self, 'FileDescription');
end;
procedure TJclSerializableModuleInfo.Serialize(ASerializer: TJclCustomSimpleSerializer);
begin
ASerializer.WriteString(Self, 'StartAddr', FStartStr);
ASerializer.WriteString(Self, 'EndAddr', FEndStr);
ASerializer.WriteString(Self, 'SystemModule', FSystemModuleStr);
ASerializer.WriteString(Self, 'FileName', FModuleName);
ASerializer.WriteString(Self, 'BinFileVersion', FBinFileVersion);
ASerializer.WriteString(Self, 'FileVersion', FFileVersion);
ASerializer.WriteString(Self, 'FileDescription', FFileDescription);
end;
//=== { TModuleList } ========================================================
constructor TJclSerializableModuleInfoList.Create;
begin
inherited Create;
FItems := TObjectList.Create;
end;
destructor TJclSerializableModuleInfoList.Destroy;
begin
FItems.Free;
inherited Destroy;
end;
function TJclSerializableModuleInfoList.Add: TJclSerializableModuleInfo;
begin
FItems.Add(TJclSerializableModuleInfo.Create);
Result := TJclSerializableModuleInfo(FItems.Last);
end;
procedure TJclSerializableModuleInfoList.AssignTo(Dest: TPersistent);
var
I: Integer;
begin
if Dest is TJclSerializableModuleInfoList then
begin
TJclSerializableModuleInfoList(Dest).Clear;
for I := 0 to Count - 1 do
TJclSerializableModuleInfoList(Dest).Add.Assign(TJclSerializableModuleInfo(FItems[I]));
end
else
inherited AssignTo(Dest);
end;
procedure TJclSerializableModuleInfoList.Clear;
begin
FItems.Clear;
end;
function TJclSerializableModuleInfoList.GetCount: Integer;
begin
Result := FItems.Count;
end;
function TJclSerializableModuleInfoList.GetItems(AIndex: Integer): TJclSerializableModuleInfo;
begin
Result := TJclSerializableModuleInfo(FItems[AIndex]);
end;
procedure TJclSerializableModuleInfoList.Deserialize(ASerializer: TJclCustomSimpleSerializer);
var
I: Integer;
begin
Clear;
for I := 0 to ASerializer.Count - 1 do
if ASerializer[I].Name = 'Module' then
Add.Deserialize(ASerializer[I]);
end;
procedure TJclSerializableModuleInfoList.Serialize(ASerializer: TJclCustomSimpleSerializer);
var
I: Integer;
begin
for I := 0 to Count - 1 do
Items[I].Serialize(ASerializer.AddChild(Self, 'Module'));
end;
{$IFDEF UNITVERSIONING}
initialization
RegisterUnitVersion(HInstance, UnitVersioning);
finalization
UnregisterUnitVersion(HInstance);
{$ENDIF UNITVERSIONING}
end.