mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-05 06:19:41 +01:00
improved some lfm error handling
git-svn-id: trunk@7679 -
This commit is contained in:
parent
a641b3fe25
commit
c2deb580ce
@ -137,6 +137,7 @@ type
|
|||||||
{ TLFMValueNodeSymbol - a LFM value of type symbol }
|
{ TLFMValueNodeSymbol - a LFM value of type symbol }
|
||||||
|
|
||||||
TLFMSymbolType = (
|
TLFMSymbolType = (
|
||||||
|
lfmsNone,
|
||||||
lfmsTrue,
|
lfmsTrue,
|
||||||
lfmsFalse,
|
lfmsFalse,
|
||||||
lfmsNil,
|
lfmsNil,
|
||||||
@ -201,7 +202,8 @@ type
|
|||||||
lfmeObjectIncompatible,
|
lfmeObjectIncompatible,
|
||||||
lfmePropertyNameMissing,
|
lfmePropertyNameMissing,
|
||||||
lfmePropertyHasNoSubProperties,
|
lfmePropertyHasNoSubProperties,
|
||||||
lfmeIdentifierNotPublished
|
lfmeIdentifierNotPublished,
|
||||||
|
lfmeEndNotFound
|
||||||
);
|
);
|
||||||
TLFMErrorTypes = set of TLFMErrorType;
|
TLFMErrorTypes = set of TLFMErrorType;
|
||||||
|
|
||||||
@ -273,7 +275,8 @@ const
|
|||||||
'ObjectIncompatible',
|
'ObjectIncompatible',
|
||||||
'PropertyNameMissing',
|
'PropertyNameMissing',
|
||||||
'PropertyHasNoSubProperties',
|
'PropertyHasNoSubProperties',
|
||||||
'IdentifierNotPublished'
|
'IdentifierNotPublished',
|
||||||
|
'EndNotFound'
|
||||||
);
|
);
|
||||||
|
|
||||||
procedure FreeListOfPInstancePropInfo(List: TFPList);
|
procedure FreeListOfPInstancePropInfo(List: TFPList);
|
||||||
@ -442,7 +445,9 @@ begin
|
|||||||
SymbolNode:=TLFMValueNodeSymbol(CurNode);
|
SymbolNode:=TLFMValueNodeSymbol(CurNode);
|
||||||
if SymbolNode=nil then ;
|
if SymbolNode=nil then ;
|
||||||
s := Parser.TokenString;
|
s := Parser.TokenString;
|
||||||
if CompareText(s, 'True') = 0 then
|
if CompareText(s, 'End') = 0 then
|
||||||
|
SymbolNode.SymbolType:=lfmsNone
|
||||||
|
else if CompareText(s, 'True') = 0 then
|
||||||
SymbolNode.SymbolType:=lfmsTrue
|
SymbolNode.SymbolType:=lfmsTrue
|
||||||
else if CompareText(s, 'False') = 0 then
|
else if CompareText(s, 'False') = 0 then
|
||||||
SymbolNode.SymbolType:=lfmsFalse
|
SymbolNode.SymbolType:=lfmsFalse
|
||||||
@ -453,7 +458,8 @@ begin
|
|||||||
SymbolNode.SymbolType:=lfmsIdentifier;
|
SymbolNode.SymbolType:=lfmsIdentifier;
|
||||||
Parser.TokenComponentIdent;
|
Parser.TokenComponentIdent;
|
||||||
end;
|
end;
|
||||||
Parser.NextToken;
|
if SymbolNode.SymbolType<>lfmsNone then
|
||||||
|
Parser.NextToken;
|
||||||
CloseChildNode;
|
CloseChildNode;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -553,6 +559,7 @@ end;
|
|||||||
procedure TLFMTree.ProcessObject;
|
procedure TLFMTree.ProcessObject;
|
||||||
var
|
var
|
||||||
ObjectNode: TLFMObjectNode;
|
ObjectNode: TLFMObjectNode;
|
||||||
|
ObjectStartLine: LongInt;
|
||||||
begin
|
begin
|
||||||
CreateChildNode(TLFMObjectNode);
|
CreateChildNode(TLFMObjectNode);
|
||||||
ObjectNode:=TLFMObjectNode(CurNode);
|
ObjectNode:=TLFMObjectNode(CurNode);
|
||||||
@ -565,6 +572,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
Parser.NextToken;
|
Parser.NextToken;
|
||||||
Parser.CheckToken(toSymbol);
|
Parser.CheckToken(toSymbol);
|
||||||
|
ObjectStartLine:=Parser.SourceLine;
|
||||||
ObjectNode.Name := '';
|
ObjectNode.Name := '';
|
||||||
ObjectNode.TypeName := Parser.TokenString;
|
ObjectNode.TypeName := Parser.TokenString;
|
||||||
ObjectNode.TypeNamePosition:=Parser.SourcePos+1;
|
ObjectNode.TypeNamePosition:=Parser.SourcePos+1;
|
||||||
@ -586,7 +594,14 @@ begin
|
|||||||
ProcessProperty;
|
ProcessProperty;
|
||||||
|
|
||||||
// read child objects
|
// read child objects
|
||||||
while not Parser.TokenSymbolIs('END') do ProcessObject;
|
while not Parser.TokenSymbolIs('END') do begin
|
||||||
|
if Parser.Token=toEOF then begin
|
||||||
|
Parser.Error('END not found for'
|
||||||
|
+' object='+ObjectNode.Name+':'+ObjectNode.TypeName
|
||||||
|
+' starting at line '+IntToStr(ObjectStartLine));
|
||||||
|
end;
|
||||||
|
ProcessObject;
|
||||||
|
end;
|
||||||
Parser.NextToken; // Skip 'END' token
|
Parser.NextToken; // Skip 'END' token
|
||||||
|
|
||||||
CloseChildNode;
|
CloseChildNode;
|
||||||
|
|||||||
@ -80,6 +80,7 @@ type
|
|||||||
FComponentPrefix: string;
|
FComponentPrefix: string;
|
||||||
FCurUnknownClass: string;
|
FCurUnknownClass: string;
|
||||||
FCurUnknownProperty: string;
|
FCurUnknownProperty: string;
|
||||||
|
FErrors: TLRPositionLinks;
|
||||||
FOnPropertyNotFound: TJITPropertyNotFoundEvent;
|
FOnPropertyNotFound: TJITPropertyNotFoundEvent;
|
||||||
procedure SetComponentPrefix(const AValue: string);
|
procedure SetComponentPrefix(const AValue: string);
|
||||||
protected
|
protected
|
||||||
@ -164,8 +165,8 @@ type
|
|||||||
read FOnReaderError write FOnReaderError;
|
read FOnReaderError write FOnReaderError;
|
||||||
property OnPropertyNotFound: TJITPropertyNotFoundEvent
|
property OnPropertyNotFound: TJITPropertyNotFoundEvent
|
||||||
read FOnPropertyNotFound write FOnPropertyNotFound;
|
read FOnPropertyNotFound write FOnPropertyNotFound;
|
||||||
property CurReadJITComponent:TComponent read FCurReadJITComponent;
|
property CurReadJITComponent: TComponent read FCurReadJITComponent;
|
||||||
property CurReadClass:TClass read FCurReadClass;
|
property CurReadClass: TClass read FCurReadClass;
|
||||||
property CurReadChild: TComponent read FCurReadChild;
|
property CurReadChild: TComponent read FCurReadChild;
|
||||||
property CurReadChildClass: TComponentClass read FCurReadChildClass;
|
property CurReadChildClass: TComponentClass read FCurReadChildClass;
|
||||||
property CurReadErrorMsg: string read FCurReadErrorMsg;
|
property CurReadErrorMsg: string read FCurReadErrorMsg;
|
||||||
@ -173,6 +174,7 @@ type
|
|||||||
property CurUnknownClass: string read FCurUnknownClass;
|
property CurUnknownClass: string read FCurUnknownClass;
|
||||||
property ComponentPrefix: string read FComponentPrefix
|
property ComponentPrefix: string read FComponentPrefix
|
||||||
write SetComponentPrefix;
|
write SetComponentPrefix;
|
||||||
|
property Errors: TLRPositionLinks read FErrors;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -501,12 +503,14 @@ begin
|
|||||||
inherited Create;
|
inherited Create;
|
||||||
FComponentPrefix:='Form';
|
FComponentPrefix:='Form';
|
||||||
FJITComponents:=TList.Create;
|
FJITComponents:=TList.Create;
|
||||||
|
FErrors:=TLRPositionLinks.Create;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TJITComponentList.Destroy;
|
destructor TJITComponentList.Destroy;
|
||||||
begin
|
begin
|
||||||
while FJITComponents.Count>0 do DestroyJITComponent(FJITComponents.Count-1);
|
while FJITComponents.Count>0 do DestroyJITComponent(FJITComponents.Count-1);
|
||||||
FJITComponents.Free;
|
FJITComponents.Free;
|
||||||
|
FErrors.Free;
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -548,7 +552,13 @@ var
|
|||||||
OldClass: TClass;
|
OldClass: TClass;
|
||||||
begin
|
begin
|
||||||
OldClass:=Items[Index].ClassType;
|
OldClass:=Items[Index].ClassType;
|
||||||
Items[Index].Free;
|
try
|
||||||
|
Items[Index].Free;
|
||||||
|
except
|
||||||
|
on E: Exception do begin
|
||||||
|
DebugLn('[TJITComponentList.DestroyJITComponent] ERROR destroying component ',E.Message);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
FreeJITClass(OldClass);
|
FreeJITClass(OldClass);
|
||||||
FJITComponents.Delete(Index);
|
FJITComponents.Delete(Index);
|
||||||
end;
|
end;
|
||||||
@ -558,7 +568,7 @@ function TJITComponentList.FindComponentByClassName(
|
|||||||
begin
|
begin
|
||||||
Result:=FJITComponents.Count-1;
|
Result:=FJITComponents.Count-1;
|
||||||
while (Result>=0)
|
while (Result>=0)
|
||||||
and (AnsiCompareText(Items[Result].ClassName,AClassName)<>0) do
|
and (CompareText(Items[Result].ClassName,AClassName)<>0) do
|
||||||
dec(Result);
|
dec(Result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -566,7 +576,7 @@ function TJITComponentList.FindComponentByName(const AName:shortstring):integer;
|
|||||||
begin
|
begin
|
||||||
Result:=FJITComponents.Count-1;
|
Result:=FJITComponents.Count-1;
|
||||||
while (Result>=0)
|
while (Result>=0)
|
||||||
and (AnsiCompareText(Items[Result].Name,AName)<>0) do
|
and (CompareText(Items[Result].Name,AName)<>0) do
|
||||||
dec(Result);
|
dec(Result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -680,17 +690,11 @@ begin
|
|||||||
on E: Exception do begin
|
on E: Exception do begin
|
||||||
DebugLn('[TJITComponentList.AddJITChildComponentFromStream] ERROR reading form stream'
|
DebugLn('[TJITComponentList.AddJITChildComponentFromStream] ERROR reading form stream'
|
||||||
+' of Class ''',NewClassName,''' Error: ',E.Message);
|
+' of Class ''',NewClassName,''' Error: ',E.Message);
|
||||||
Result:=-1;
|
if Result>=0 then begin
|
||||||
if FCurReadJITComponent<>nil then begin
|
|
||||||
// try freeing the unfinished thing
|
// try freeing the unfinished thing
|
||||||
try
|
|
||||||
FCurReadJITComponent.Free;
|
|
||||||
except
|
|
||||||
on E: Exception do begin
|
|
||||||
DebugLn('[TJITComponentList.AddJITChildComponentFromStream] ERROR destroying component ',E.Message);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
FCurReadJITComponent:=nil;
|
FCurReadJITComponent:=nil;
|
||||||
|
DestroyJITComponent(Result);
|
||||||
|
Result:=-1;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1299,6 +1303,7 @@ const
|
|||||||
var
|
var
|
||||||
ErrorType: TJITFormError;
|
ErrorType: TJITFormError;
|
||||||
Action: TModalResult;
|
Action: TModalResult;
|
||||||
|
ErrorBinPos: Int64;
|
||||||
begin
|
begin
|
||||||
ErrorType:=jfeReaderError;
|
ErrorType:=jfeReaderError;
|
||||||
Action:=mrCancel;
|
Action:=mrCancel;
|
||||||
@ -1309,10 +1314,16 @@ begin
|
|||||||
ErrorType:=jfeUnknownProperty;
|
ErrorType:=jfeUnknownProperty;
|
||||||
Action:=mrIgnore;
|
Action:=mrIgnore;
|
||||||
end;
|
end;
|
||||||
|
if Reader.Driver is TLRSObjectReader then begin
|
||||||
|
// save error position
|
||||||
|
ErrorBinPos:=TLRSObjectReader(Reader.Driver).Stream.Position;
|
||||||
|
FErrors.Add(-1,ErrorBinPos,nil);
|
||||||
|
end;
|
||||||
if Assigned(OnReaderError) then
|
if Assigned(OnReaderError) then
|
||||||
OnReaderError(Self,ErrorType,Action);
|
OnReaderError(Self,ErrorType,Action);
|
||||||
Handled:=Action in [mrIgnore];
|
Handled:=Action in [mrIgnore];
|
||||||
FCurUnknownProperty:='';
|
FCurUnknownProperty:='';
|
||||||
|
|
||||||
DebugLn('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>');
|
DebugLn('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>');
|
||||||
DebugLn('[TJITComponentList.ReaderError] "'+ErrorMsg+'" ignoring=',BoolToStr(Handled));
|
DebugLn('[TJITComponentList.ReaderError] "'+ErrorMsg+'" ignoring=',BoolToStr(Handled));
|
||||||
DebugLn('<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<');
|
DebugLn('<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<');
|
||||||
|
|||||||
@ -117,6 +117,8 @@ type
|
|||||||
function ReadWideString: WideString;override;
|
function ReadWideString: WideString;override;
|
||||||
procedure SkipComponent(SkipComponentInfos: Boolean); override;
|
procedure SkipComponent(SkipComponentInfos: Boolean); override;
|
||||||
procedure SkipValue; override;
|
procedure SkipValue; override;
|
||||||
|
public
|
||||||
|
property Stream: TStream read FStream;
|
||||||
end;
|
end;
|
||||||
TLRSObjectReaderClass = class of TLRSObjectReader;
|
TLRSObjectReaderClass = class of TLRSObjectReader;
|
||||||
|
|
||||||
@ -172,6 +174,43 @@ type
|
|||||||
end;
|
end;
|
||||||
TLRSObjectWriterClass = class of TLRSObjectWriter;
|
TLRSObjectWriterClass = class of TLRSObjectWriter;
|
||||||
|
|
||||||
|
TLRPositionLink = record
|
||||||
|
LFMPosition: int64;
|
||||||
|
LRSPosition: int64;
|
||||||
|
Data: Pointer;
|
||||||
|
end;
|
||||||
|
PLRPositionLink = ^TLRPositionLink;
|
||||||
|
|
||||||
|
{ TLRPositionLinks }
|
||||||
|
|
||||||
|
TLRPositionLinks = class
|
||||||
|
private
|
||||||
|
FItems: TFPList;
|
||||||
|
FCount: integer;
|
||||||
|
function GetData(Index: integer): Pointer;
|
||||||
|
function GetLFM(Index: integer): Int64;
|
||||||
|
function GetLRS(Index: integer): Int64;
|
||||||
|
procedure SetCount(const AValue: integer);
|
||||||
|
procedure SetData(Index: integer; const AValue: Pointer);
|
||||||
|
procedure SetLFM(Index: integer; const AValue: Int64);
|
||||||
|
procedure SetLRS(Index: integer; const AValue: Int64);
|
||||||
|
public
|
||||||
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
|
procedure Sort(LFMPositions: Boolean);
|
||||||
|
function IndexOf(const Position: int64; LFMPositions: Boolean): integer;
|
||||||
|
function IndexOfRange(const FromPos, ToPos: int64;
|
||||||
|
LFMPositions: Boolean): integer;
|
||||||
|
procedure SetPosition(const FromPos, ToPos, MappedPos: int64;
|
||||||
|
LFMtoLRSPositions: Boolean);
|
||||||
|
procedure Add(const LFMPos, LRSPos: Int64; Data: Pointer);
|
||||||
|
public
|
||||||
|
property LFM[Index: integer]: int64 read GetLFM write SetLFM;
|
||||||
|
property LRS[Index: integer]: int64 read GetLRS write SetLRS;
|
||||||
|
property Data[Index: integer]: Pointer read GetData write SetData;
|
||||||
|
property Count: integer read FCount write SetCount;
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
LazarusResources: TLResourceList;
|
LazarusResources: TLResourceList;
|
||||||
|
|
||||||
@ -185,10 +224,8 @@ function CreateLRSWriter(s: TStream; var DestroyDriver: boolean): TWriter;
|
|||||||
|
|
||||||
procedure BinaryToLazarusResourceCode(BinStream, ResStream: TStream;
|
procedure BinaryToLazarusResourceCode(BinStream, ResStream: TStream;
|
||||||
const ResourceName, ResourceType: String);
|
const ResourceName, ResourceType: String);
|
||||||
function LFMtoLRSfile(const LFMfilename: string): boolean;
|
function LFMtoLRSfile(const LFMfilename: string): boolean;// true on success
|
||||||
// returns true if successful
|
function LFMtoLRSstream(LFMStream, LRSStream: TStream): boolean;// true on success
|
||||||
function LFMtoLRSstream(LFMStream, LRSStream: TStream): boolean;
|
|
||||||
// returns true if successful
|
|
||||||
function FindLFMClassName(LFMStream: TStream):AnsiString;
|
function FindLFMClassName(LFMStream: TStream):AnsiString;
|
||||||
function CreateLFMFile(AComponent: TComponent; LFMStream: TStream): integer;
|
function CreateLFMFile(AComponent: TComponent; LFMStream: TStream): integer;
|
||||||
|
|
||||||
@ -196,7 +233,8 @@ type
|
|||||||
TLRSStreamOriginalFormat = (sofUnknown, sofBinary, sofText);
|
TLRSStreamOriginalFormat = (sofUnknown, sofBinary, sofText);
|
||||||
|
|
||||||
procedure LRSObjectBinaryToText(Input, Output: TStream);
|
procedure LRSObjectBinaryToText(Input, Output: TStream);
|
||||||
procedure LRSObjectTextToBinary(Input, Output: TStream);
|
procedure LRSObjectTextToBinary(Input, Output: TStream;
|
||||||
|
Links: TLRPositionLinks = nil);
|
||||||
procedure LRSObjectToText(Input, Output: TStream;
|
procedure LRSObjectToText(Input, Output: TStream;
|
||||||
var OriginalFormat: TLRSStreamOriginalFormat);
|
var OriginalFormat: TLRSStreamOriginalFormat);
|
||||||
|
|
||||||
@ -245,6 +283,10 @@ procedure WriteLRSEndianBigDoubleAsEndianLittleExtended(s: TStream;
|
|||||||
procedure WriteLRSReversedWords(s: TStream; p: Pointer; Count: integer);
|
procedure WriteLRSReversedWords(s: TStream; p: Pointer; Count: integer);
|
||||||
|
|
||||||
|
|
||||||
|
function CompareLRPositionLinkWithLFMPosition(Item1, Item2: Pointer): integer;
|
||||||
|
function CompareLRPositionLinkWithLRSPosition(Item1, Item2: Pointer): integer;
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
|
||||||
@ -1568,7 +1610,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure LRSObjectTextToBinary(Input, Output: TStream);
|
procedure LRSObjectTextToBinary(Input, Output: TStream;
|
||||||
|
Links: TLRPositionLinks);
|
||||||
var
|
var
|
||||||
parser: TParser;
|
parser: TParser;
|
||||||
OldDecimalSeparator: Char;
|
OldDecimalSeparator: Char;
|
||||||
@ -1657,6 +1700,16 @@ var
|
|||||||
for i:=1 to length(Result) do
|
for i:=1 to length(Result) do
|
||||||
Result[i]:=chr(ord(s[i]));
|
Result[i]:=chr(ord(s[i]));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure ParserNextToken;
|
||||||
|
var
|
||||||
|
OldSourcePos: LongInt;
|
||||||
|
begin
|
||||||
|
OldSourcePos:=Parser.SourcePos;
|
||||||
|
Parser.NextToken;
|
||||||
|
if Links<>nil then
|
||||||
|
Links.SetPosition(OldSourcePos,Parser.SourcePos,Output.Position,true);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure ProcessProperty; forward;
|
procedure ProcessProperty; forward;
|
||||||
|
|
||||||
@ -1860,6 +1913,10 @@ var
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
if Links<>nil then begin
|
||||||
|
// sort links for LFM positions
|
||||||
|
Links.Sort(true);
|
||||||
|
end;
|
||||||
parser := TParser.Create(Input);
|
parser := TParser.Create(Input);
|
||||||
OldDecimalSeparator:=DecimalSeparator;
|
OldDecimalSeparator:=DecimalSeparator;
|
||||||
DecimalSeparator:='.';
|
DecimalSeparator:='.';
|
||||||
@ -1971,7 +2028,7 @@ begin
|
|||||||
Result:=TReader.Create(s,4096);
|
Result:=TReader.Create(s,4096);
|
||||||
{$IFDEF TRANSLATESTRING}
|
{$IFDEF TRANSLATESTRING}
|
||||||
if Assigned(LRSTranslator) then
|
if Assigned(LRSTranslator) then
|
||||||
Result.OnReadStringProperty:=@(LRSTranslator.TranslateStringProperty);
|
Result.OnReadStringProperty:=@(LRSTranslator.TranslateStringProperty);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
DestroyDriver:=false;
|
DestroyDriver:=false;
|
||||||
if Result.Driver.ClassType=LRSObjectReaderClass then exit;
|
if Result.Driver.ClassType=LRSObjectReaderClass then exit;
|
||||||
@ -2256,6 +2313,36 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function CompareLRPositionLinkWithLFMPosition(Item1, Item2: Pointer): integer;
|
||||||
|
var
|
||||||
|
p1: Int64;
|
||||||
|
p2: Int64;
|
||||||
|
begin
|
||||||
|
p1:=PLRPositionLink(Item1)^.LFMPosition;
|
||||||
|
p2:=PLRPositionLink(Item2)^.LFMPosition;
|
||||||
|
if p1<p2 then
|
||||||
|
Result:=1
|
||||||
|
else if p1>p2 then
|
||||||
|
Result:=-1
|
||||||
|
else
|
||||||
|
Result:=0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function CompareLRPositionLinkWithLRSPosition(Item1, Item2: Pointer): integer;
|
||||||
|
var
|
||||||
|
p1: Int64;
|
||||||
|
p2: Int64;
|
||||||
|
begin
|
||||||
|
p1:=PLRPositionLink(Item1)^.LRSPosition;
|
||||||
|
p2:=PLRPositionLink(Item2)^.LRSPosition;
|
||||||
|
if p1<p2 then
|
||||||
|
Result:=1
|
||||||
|
else if p1>p2 then
|
||||||
|
Result:=-1
|
||||||
|
else
|
||||||
|
Result:=0;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure WriteLRSNull(s: TStream; Count: integer);
|
procedure WriteLRSNull(s: TStream; Count: integer);
|
||||||
var
|
var
|
||||||
c: char;
|
c: char;
|
||||||
@ -3133,6 +3220,167 @@ begin
|
|||||||
LazarusResources:=TLResourceList.Create;
|
LazarusResources:=TLResourceList.Create;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TLRPositionLinks }
|
||||||
|
|
||||||
|
function TLRPositionLinks.GetLFM(Index: integer): Int64;
|
||||||
|
begin
|
||||||
|
Result:=PLRPositionLink(FItems[Index])^.LFMPosition;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLRPositionLinks.GetData(Index: integer): Pointer;
|
||||||
|
begin
|
||||||
|
Result:=PLRPositionLink(FItems[Index])^.Data;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLRPositionLinks.GetLRS(Index: integer): Int64;
|
||||||
|
begin
|
||||||
|
Result:=PLRPositionLink(FItems[Index])^.LRSPosition;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLRPositionLinks.SetCount(const AValue: integer);
|
||||||
|
var
|
||||||
|
i: LongInt;
|
||||||
|
Item: PLRPositionLink;
|
||||||
|
begin
|
||||||
|
if FCount=AValue then exit;
|
||||||
|
// free old items
|
||||||
|
for i:=AValue to FCount-1 do begin
|
||||||
|
Item:=PLRPositionLink(FItems[i]);
|
||||||
|
Dispose(Item);
|
||||||
|
end;
|
||||||
|
// create new items
|
||||||
|
FItems.Count:=AValue;
|
||||||
|
for i:=FCount to AValue-1 do begin
|
||||||
|
New(Item);
|
||||||
|
Item^.LFMPosition:=-1;
|
||||||
|
Item^.LRSPosition:=-1;
|
||||||
|
Item^.Data:=nil;
|
||||||
|
FItems[i]:=Item;
|
||||||
|
end;
|
||||||
|
FCount:=AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLRPositionLinks.SetData(Index: integer; const AValue: Pointer);
|
||||||
|
begin
|
||||||
|
PLRPositionLink(FItems[Index])^.Data:=AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLRPositionLinks.SetLFM(Index: integer; const AValue: Int64);
|
||||||
|
begin
|
||||||
|
PLRPositionLink(FItems[Index])^.LFMPosition:=AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLRPositionLinks.SetLRS(Index: integer; const AValue: Int64);
|
||||||
|
begin
|
||||||
|
PLRPositionLink(FItems[Index])^.LRSPosition:=AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TLRPositionLinks.Create;
|
||||||
|
begin
|
||||||
|
FItems:=TFPList.Create;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TLRPositionLinks.Destroy;
|
||||||
|
begin
|
||||||
|
Count:=0;
|
||||||
|
FItems.Free;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLRPositionLinks.Sort(LFMPositions: Boolean);
|
||||||
|
begin
|
||||||
|
if LFMPositions then
|
||||||
|
FItems.Sort(@CompareLRPositionLinkWithLFMPosition)
|
||||||
|
else
|
||||||
|
FItems.Sort(@CompareLRPositionLinkWithLRSPosition)
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLRPositionLinks.IndexOf(const Position: int64; LFMPositions: Boolean
|
||||||
|
): integer;
|
||||||
|
var
|
||||||
|
l, r, m: integer;
|
||||||
|
p: Int64;
|
||||||
|
begin
|
||||||
|
// binary search for the line
|
||||||
|
l:=0;
|
||||||
|
r:=FCount-1;
|
||||||
|
while r>=l do begin
|
||||||
|
m:=(l+r) shr 1;
|
||||||
|
if LFMPositions then
|
||||||
|
p:=PLRPositionLink(FItems[m])^.LFMPosition
|
||||||
|
else
|
||||||
|
p:=PLRPositionLink(FItems[m])^.LRSPosition;
|
||||||
|
if p>Position then begin
|
||||||
|
// too high, search lower
|
||||||
|
r:=m-1;
|
||||||
|
end else if p<Position then begin
|
||||||
|
// too low, search higher
|
||||||
|
l:=m+1;
|
||||||
|
end else begin
|
||||||
|
// position found
|
||||||
|
Result:=m;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Result:=-1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLRPositionLinks.IndexOfRange(const FromPos, ToPos: int64;
|
||||||
|
LFMPositions: Boolean): integer;
|
||||||
|
var
|
||||||
|
l, r, m: integer;
|
||||||
|
p: Int64;
|
||||||
|
Item: PLRPositionLink;
|
||||||
|
begin
|
||||||
|
// binary search for the line
|
||||||
|
l:=0;
|
||||||
|
r:=FCount-1;
|
||||||
|
while r>=l do begin
|
||||||
|
m:=(l+r) shr 1;
|
||||||
|
Item:=PLRPositionLink(FItems[m]);
|
||||||
|
if LFMPositions then
|
||||||
|
p:=Item^.LFMPosition
|
||||||
|
else
|
||||||
|
p:=Item^.LRSPosition;
|
||||||
|
if p>=ToPos then begin
|
||||||
|
// too high, search lower
|
||||||
|
r:=m-1;
|
||||||
|
end else if p<FromPos then begin
|
||||||
|
// too low, search higher
|
||||||
|
l:=m+1;
|
||||||
|
end else begin
|
||||||
|
// position found
|
||||||
|
Result:=m;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Result:=-1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLRPositionLinks.SetPosition(const FromPos, ToPos, MappedPos: int64;
|
||||||
|
LFMtoLRSPositions: Boolean);
|
||||||
|
var
|
||||||
|
i: LongInt;
|
||||||
|
begin
|
||||||
|
i:=IndexOfRange(FromPos,ToPos,LFMtoLRSPositions);
|
||||||
|
if i>=0 then
|
||||||
|
if LFMtoLRSPositions then
|
||||||
|
PLRPositionLink(FItems[i])^.LRSPosition:=MappedPos
|
||||||
|
else
|
||||||
|
PLRPositionLink(FItems[i])^.LFMPosition:=MappedPos;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLRPositionLinks.Add(const LFMPos, LRSPos: Int64; Data: Pointer);
|
||||||
|
var
|
||||||
|
Item: PLRPositionLink;
|
||||||
|
begin
|
||||||
|
Count:=Count+1;
|
||||||
|
Item:=PLRPositionLink(FItems[Count-1]);
|
||||||
|
Item^.LFMPosition:=LFMPos;
|
||||||
|
Item^.LRSPosition:=LRSPos;
|
||||||
|
Item^.Data:=Data;
|
||||||
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
InternalInit;
|
InternalInit;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user