|
@@ -268,7 +268,7 @@ type
|
|
|
|
|
|
TLiteralType = (ltPlain, ltPubid, ltEntity);
|
|
TLiteralType = (ltPlain, ltPubid, ltEntity);
|
|
|
|
|
|
- TXMLTextReader = class(TXMLReader)
|
|
|
|
|
|
+ TXMLTextReader = class(TXMLReader, IXmlLineInfo)
|
|
private
|
|
private
|
|
FSource: TXMLCharSource;
|
|
FSource: TXMLCharSource;
|
|
FNameTable: THashTable;
|
|
FNameTable: THashTable;
|
|
@@ -341,6 +341,9 @@ type
|
|
procedure SetNodeInfoWithValue(typ: TXMLNodeType; AName: PHashItem = nil);
|
|
procedure SetNodeInfoWithValue(typ: TXMLNodeType; AName: PHashItem = nil);
|
|
function SetupFakeLF(nextstate: TXMLToken): Boolean;
|
|
function SetupFakeLF(nextstate: TXMLToken): Boolean;
|
|
function AddId(aNodeData: PNodeData): Boolean;
|
|
function AddId(aNodeData: PNodeData): Boolean;
|
|
|
|
+ function QueryInterface(constref iid: TGUID; out obj): HRESULT; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
|
|
|
|
+ function _AddRef: Longint; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
|
|
|
|
+ function _Release: Longint; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
|
|
protected
|
|
protected
|
|
FNesting: Integer;
|
|
FNesting: Integer;
|
|
FCurrNode: PNodeData;
|
|
FCurrNode: PNodeData;
|
|
@@ -392,6 +395,7 @@ type
|
|
procedure ParseAttribute(ElDef: TElementDecl);
|
|
procedure ParseAttribute(ElDef: TElementDecl);
|
|
function ReadTopLevel: Boolean;
|
|
function ReadTopLevel: Boolean;
|
|
procedure NextAttrValueChunk;
|
|
procedure NextAttrValueChunk;
|
|
|
|
+ function GetHasLineInfo: Boolean;
|
|
function GetLineNumber: Integer;
|
|
function GetLineNumber: Integer;
|
|
function GetLinePosition: Integer;
|
|
function GetLinePosition: Integer;
|
|
public
|
|
public
|
|
@@ -1000,6 +1004,24 @@ end;
|
|
|
|
|
|
{ TXMLTextReader }
|
|
{ TXMLTextReader }
|
|
|
|
|
|
|
|
+function TXMLTextReader.QueryInterface(constref iid: TGUID; out obj): HRESULT; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
|
|
|
|
+begin
|
|
|
|
+ if GetInterface(iid,obj) then
|
|
|
|
+ result := S_OK
|
|
|
|
+ else
|
|
|
|
+ result:= E_NOINTERFACE;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TXMLTextReader._AddRef: Longint; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
|
|
|
|
+begin
|
|
|
|
+ result := -1;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TXMLTextReader._Release: Longint; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
|
|
|
|
+begin
|
|
|
|
+ result := -1;
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TXMLTextReader.ConvertSource(SrcIn: TXMLInputSource; out SrcOut: TXMLCharSource);
|
|
procedure TXMLTextReader.ConvertSource(SrcIn: TXMLInputSource; out SrcOut: TXMLCharSource);
|
|
begin
|
|
begin
|
|
SrcOut := nil;
|
|
SrcOut := nil;
|
|
@@ -1746,9 +1768,12 @@ var
|
|
start: TObject;
|
|
start: TObject;
|
|
curr: PNodeData;
|
|
curr: PNodeData;
|
|
StartPos: Integer;
|
|
StartPos: Integer;
|
|
|
|
+ StartLoc: TLocation;
|
|
entName: PHashItem;
|
|
entName: PHashItem;
|
|
begin
|
|
begin
|
|
SkipQuote(Delim);
|
|
SkipQuote(Delim);
|
|
|
|
+ AttrData^.FLoc2 := FTokenStart;
|
|
|
|
+ StartLoc := FTokenStart;
|
|
curr := AttrData;
|
|
curr := AttrData;
|
|
FValue.Length := 0;
|
|
FValue.Length := 0;
|
|
StartPos := 0;
|
|
StartPos := 0;
|
|
@@ -1767,10 +1792,16 @@ begin
|
|
if ((ent = nil) or (not FExpandEntities)) and (FSource.FEntity = start) then
|
|
if ((ent = nil) or (not FExpandEntities)) and (FSource.FEntity = start) then
|
|
begin
|
|
begin
|
|
if FValue.Length > StartPos then
|
|
if FValue.Length > StartPos then
|
|
|
|
+ begin
|
|
AllocAttributeValueChunk(curr, StartPos);
|
|
AllocAttributeValueChunk(curr, StartPos);
|
|
|
|
+ curr^.FLoc := StartLoc;
|
|
|
|
+ end;
|
|
AllocAttributeValueChunk(curr, FValue.Length);
|
|
AllocAttributeValueChunk(curr, FValue.Length);
|
|
curr^.FNodeType := ntEntityReference;
|
|
curr^.FNodeType := ntEntityReference;
|
|
curr^.FQName := entName;
|
|
curr^.FQName := entName;
|
|
|
|
+ StoreLocation(StartLoc);
|
|
|
|
+ curr^.FLoc := StartLoc;
|
|
|
|
+ Dec(curr^.FLoc.LinePos, FName.Length+1);
|
|
end;
|
|
end;
|
|
StartPos := FValue.Length;
|
|
StartPos := FValue.Length;
|
|
if Assigned(ent) then
|
|
if Assigned(ent) then
|
|
@@ -1796,7 +1827,10 @@ begin
|
|
begin
|
|
begin
|
|
FAttrCleanupFlag := True;
|
|
FAttrCleanupFlag := True;
|
|
if FValue.Length > StartPos then
|
|
if FValue.Length > StartPos then
|
|
|
|
+ begin
|
|
AllocAttributeValueChunk(curr, StartPos);
|
|
AllocAttributeValueChunk(curr, StartPos);
|
|
|
|
+ curr^.FLoc := StartLoc;
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
if nonCDATA then
|
|
if nonCDATA then
|
|
BufNormalize(FValue, attrData^.FDenormalized)
|
|
BufNormalize(FValue, attrData^.FDenormalized)
|
|
@@ -2193,6 +2227,7 @@ end;
|
|
procedure TXMLTextReader.ParseDoctypeDecl; // [28]
|
|
procedure TXMLTextReader.ParseDoctypeDecl; // [28]
|
|
var
|
|
var
|
|
Src: TXMLCharSource;
|
|
Src: TXMLCharSource;
|
|
|
|
+ DTDName: PHashItem;
|
|
begin
|
|
begin
|
|
if FState >= rsDTD then
|
|
if FState >= rsDTD then
|
|
FatalError('Markup declaration is not allowed here');
|
|
FatalError('Markup declaration is not allowed here');
|
|
@@ -2208,6 +2243,7 @@ begin
|
|
|
|
|
|
CheckName;
|
|
CheckName;
|
|
SetString(FDocType.FName, FName.Buffer, FName.Length);
|
|
SetString(FDocType.FName, FName.Buffer, FName.Length);
|
|
|
|
+ DTDName := FNameTable.FindOrAdd(FName.Buffer, FName.Length);
|
|
SkipS(True);
|
|
SkipS(True);
|
|
ParseExternalID(FDocType.FSystemID, FDocType.FPublicID, False);
|
|
ParseExternalID(FDocType.FSystemID, FDocType.FPublicID, False);
|
|
SkipS;
|
|
SkipS;
|
|
@@ -2249,7 +2285,9 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
FState := rsAfterDTD;
|
|
FState := rsAfterDTD;
|
|
- FCurrNode^.FNodeType := ntDocumentType;
|
|
|
|
|
|
+ FValue.Length := 0;
|
|
|
|
+ BufAppendString(FValue, FDocType.FInternalSubset);
|
|
|
|
+ SetNodeInfoWithValue(ntDocumentType, DTDName);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TXMLTextReader.ExpectEq; // [25]
|
|
procedure TXMLTextReader.ExpectEq; // [25]
|
|
@@ -2792,6 +2830,8 @@ end;
|
|
procedure TXMLTextReader.Close;
|
|
procedure TXMLTextReader.Close;
|
|
begin
|
|
begin
|
|
FReadState := rsClosed;
|
|
FReadState := rsClosed;
|
|
|
|
+ FTokenStart.Line := 0;
|
|
|
|
+ FTokenStart.LinePos := 0;
|
|
end;
|
|
end;
|
|
|
|
|
|
function TXMLTextReader.GetAttributeCount: Integer;
|
|
function TXMLTextReader.GetAttributeCount: Integer;
|
|
@@ -2882,14 +2922,27 @@ begin
|
|
result := FSource.SystemID;
|
|
result := FSource.SystemID;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+{ IXmlLineInfo methods }
|
|
|
|
+
|
|
|
|
+function TXMLTextReader.GetHasLineInfo: Boolean;
|
|
|
|
+begin
|
|
|
|
+ result := True;
|
|
|
|
+end;
|
|
|
|
+
|
|
function TXMLTextReader.GetLineNumber: Integer;
|
|
function TXMLTextReader.GetLineNumber: Integer;
|
|
begin
|
|
begin
|
|
- result := FCurrNode^.FLoc.Line;
|
|
|
|
|
|
+ if (FCurrNode^.FNodeType in [ntElement,ntAttribute]) or (FAttrReadState <> arsNone) then
|
|
|
|
+ result := FCurrNode^.FLoc.Line
|
|
|
|
+ else
|
|
|
|
+ result := FTokenStart.Line;
|
|
end;
|
|
end;
|
|
|
|
|
|
function TXMLTextReader.GetLinePosition: Integer;
|
|
function TXMLTextReader.GetLinePosition: Integer;
|
|
begin
|
|
begin
|
|
- result := FCurrNode^.FLoc.LinePos;
|
|
|
|
|
|
+ if (FCurrNode^.FNodeType in [ntElement,ntAttribute]) or (FAttrReadState <> arsNone) then
|
|
|
|
+ result := FCurrNode^.FLoc.LinePos
|
|
|
|
+ else
|
|
|
|
+ result := FTokenStart.LinePos;
|
|
end;
|
|
end;
|
|
|
|
|
|
function TXMLTextReader.LookupNamespace(const APrefix: XMLString): XMLString;
|
|
function TXMLTextReader.LookupNamespace(const APrefix: XMLString): XMLString;
|
|
@@ -2999,6 +3052,7 @@ begin
|
|
end;
|
|
end;
|
|
|
|
|
|
FCurrNode := @FNodeStack[FNesting+FAttrCount+1];
|
|
FCurrNode := @FNodeStack[FNesting+FAttrCount+1];
|
|
|
|
+ StoreLocation(FCurrNode^.FLoc);
|
|
FValue.Length := 0;
|
|
FValue.Length := 0;
|
|
if FAttrReadState = arsText then
|
|
if FAttrReadState = arsText then
|
|
repeat
|
|
repeat
|
|
@@ -3033,19 +3087,12 @@ begin
|
|
|
|
|
|
if tok = arsEntity then
|
|
if tok = arsEntity then
|
|
begin
|
|
begin
|
|
- FCurrNode^.FNodeType := ntEntityReference;
|
|
|
|
- FCurrNode^.FQName := FNameTable.FindOrAdd(FName.Buffer, FName.Length);
|
|
|
|
- FCurrNode^.FValueStart := nil;
|
|
|
|
- FCurrNode^.FValueLength := 0;
|
|
|
|
- FCurrNode^.FValueStr := '';
|
|
|
|
|
|
+ HandleEntityStart;
|
|
FAttrReadState := arsText;
|
|
FAttrReadState := arsText;
|
|
end
|
|
end
|
|
else if tok = arsEntityEnd then
|
|
else if tok = arsEntityEnd then
|
|
begin
|
|
begin
|
|
- ContextPop(True);
|
|
|
|
- Dec(FNesting);
|
|
|
|
- FCurrNode := @FNodeStack[FNesting+FAttrCount+1];
|
|
|
|
- FCurrNode^.FNodeType := ntEndEntity;
|
|
|
|
|
|
+ HandleEntityEnd;
|
|
FAttrReadState := arsText;
|
|
FAttrReadState := arsText;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
@@ -3219,21 +3266,26 @@ end;
|
|
|
|
|
|
procedure TXMLTextReader.HandleEntityStart;
|
|
procedure TXMLTextReader.HandleEntityStart;
|
|
begin
|
|
begin
|
|
- FCurrNode := @FNodeStack[FNesting];
|
|
|
|
|
|
+ FCurrNode := @FNodeStack[FNesting+(FAttrCount+1)*ord(FAttrReadState<>arsNone)];
|
|
FCurrNode^.FNodeType := ntEntityReference;
|
|
FCurrNode^.FNodeType := ntEntityReference;
|
|
FCurrNode^.FQName := FNameTable.FindOrAdd(FName.Buffer, FName.Length);
|
|
FCurrNode^.FQName := FNameTable.FindOrAdd(FName.Buffer, FName.Length);
|
|
|
|
+ FCurrNode^.FColonPos := -1;
|
|
FCurrNode^.FValueStart := nil;
|
|
FCurrNode^.FValueStart := nil;
|
|
FCurrNode^.FValueLength := 0;
|
|
FCurrNode^.FValueLength := 0;
|
|
|
|
+ FCurrNode^.FValueStr := '';
|
|
|
|
+ StoreLocation(FCurrNode^.FLoc);
|
|
|
|
+ { point past '&' to first char of entity name }
|
|
|
|
+ Dec(FCurrNode^.FLoc.LinePos, FName.Length+1);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TXMLTextReader.HandleEntityEnd;
|
|
procedure TXMLTextReader.HandleEntityEnd;
|
|
begin
|
|
begin
|
|
ContextPop(True);
|
|
ContextPop(True);
|
|
if FNesting > 0 then Dec(FNesting);
|
|
if FNesting > 0 then Dec(FNesting);
|
|
- FCurrNode := @FNodeStack[FNesting];
|
|
|
|
|
|
+ FCurrNode := @FNodeStack[FNesting+(FAttrCount+1)*ord(FAttrReadState<>arsNone)];
|
|
FCurrNode^.FNodeType := ntEndEntity;
|
|
FCurrNode^.FNodeType := ntEndEntity;
|
|
- // TODO: other properties of FCurrNode
|
|
|
|
- FNext := xtText;
|
|
|
|
|
|
+ { point to trailing ';' }
|
|
|
|
+ Inc(FCurrNode^.FLoc.LinePos, Length(FCurrNode^.FQName^.Key));
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TXMLTextReader.ResolveEntity;
|
|
procedure TXMLTextReader.ResolveEntity;
|
|
@@ -3252,6 +3304,7 @@ begin
|
|
if n <> FCurrNode then
|
|
if n <> FCurrNode then
|
|
n^ := FCurrNode^;
|
|
n^ := FCurrNode^;
|
|
|
|
|
|
|
|
+ ent := nil;
|
|
if Assigned(FDocType) then
|
|
if Assigned(FDocType) then
|
|
ent := FDocType.Entities.Get(PWideChar(n^.FQName^.Key),Length(n^.FQName^.Key)) as TEntityDecl;
|
|
ent := FDocType.Entities.Get(PWideChar(n^.FQName^.Key),Length(n^.FQName^.Key)) as TEntityDecl;
|
|
if ent = nil then
|
|
if ent = nil then
|
|
@@ -3754,6 +3807,8 @@ begin
|
|
|
|
|
|
FCurrNode := @FNodeStack[FNesting]; // move off the possible child
|
|
FCurrNode := @FNodeStack[FNesting]; // move off the possible child
|
|
FCurrNode^.FNodeType := ntEndElement;
|
|
FCurrNode^.FNodeType := ntEndElement;
|
|
|
|
+ Inc(FTokenStart.LinePos, 2); // move over '</' chars
|
|
|
|
+ FCurrNode^.FLoc := FTokenStart;
|
|
ElName := FCurrNode^.FQName;
|
|
ElName := FCurrNode^.FQName;
|
|
|
|
|
|
CheckName;
|
|
CheckName;
|
|
@@ -3766,7 +3821,6 @@ begin
|
|
SkipS;
|
|
SkipS;
|
|
ExpectChar('>');
|
|
ExpectChar('>');
|
|
end;
|
|
end;
|
|
- Inc(FTokenStart.LinePos, 2); // move over '</' chars
|
|
|
|
FNext := xtPopElement;
|
|
FNext := xtPopElement;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -3822,7 +3876,6 @@ begin
|
|
|
|
|
|
ExpectEq;
|
|
ExpectEq;
|
|
ExpectAttValue(attrData, Assigned(AttDef) and (AttDef.DataType <> dtCDATA));
|
|
ExpectAttValue(attrData, Assigned(AttDef) and (AttDef.DataType <> dtCDATA));
|
|
- attrData^.FLoc2 := FTokenStart;
|
|
|
|
|
|
|
|
if Assigned(attrData^.FNsUri) then
|
|
if Assigned(attrData^.FNsUri) then
|
|
begin
|
|
begin
|