* xmlread.pp, remove FCursorStack and resort back to a single cursor node. But this time it is simply a local variable.

git-svn-id: trunk@16962 -
This commit is contained in:
sergei 2011-02-21 16:11:38 +00:00
parent 547a1b289c
commit 9ca12c0377

View File

@ -254,7 +254,6 @@ type
end;
TNodeDataDynArray = array of TNodeData;
TDOMNodeDynArray = array of TDOMNode_WithChildren;
TValidatorDynArray = array of TElementValidator;
TXMLReadState = (rsProlog, rsDTD, rsAfterDTD, rsRoot, rsEpilog);
@ -348,7 +347,6 @@ type
FPrefixedAttrs: Integer;
FSpecifiedAttrs: Integer;
FNodeStack: TNodeDataDynArray;
FCursorStack: TDOMNodeDynArray;
FValidators: TValidatorDynArray;
FAttrChunks: TFPList;
FFreeAttrChunk: PNodeData;
@ -378,20 +376,20 @@ type
procedure ExpectAttValue(attrData: PNodeData; NonCDATA: Boolean); // [10]
procedure ParseComment(discard: Boolean); // [15]
procedure ParsePI; // [16]
procedure CreatePINode;
function CreatePINode: TDOMNode;
procedure ParseXmlOrTextDecl(TextDecl: Boolean);
procedure ExpectEq;
procedure ParseDoctypeDecl; // [28]
procedure ParseMarkupDecl; // [29]
procedure ParseStartTag; // [39]
procedure ParseEndTag; // [42]
procedure DoStartElement;
function DoStartElement: TDOMElement;
procedure HandleEntityStart;
procedure HandleEntityEnd;
procedure ResolveEntity;
procedure DoStartEntity;
procedure ParseAttribute(ElDef: TElementDecl);
procedure ParseContent; // [43]
procedure ParseContent(parent: TDOMNode_WithChildren); // [43]
function Read: Boolean;
function ResolvePredefined: Boolean;
function EntityCheck(NoExternals: Boolean = False): TEntityDecl;
@ -422,12 +420,8 @@ type
procedure ValidationErrorWithName(const Msg: string; LineOffs: Integer = -1);
procedure DTDReloadHook;
procedure ConvertSource(SrcIn: TXMLInputSource; out SrcOut: TXMLCharSource);
// Some SAX-alike stuff (at a very early stage)
procedure DoText(ch: PWideChar; Count: Integer; Whitespace: Boolean=False);
procedure DoComment(ch: PWideChar; Count: Integer);
procedure DoCDSect(ch: PWideChar; Count: Integer);
function DoCDSect(ch: PWideChar; Count: Integer): TDOMNode;
procedure DoNotationDecl(const aName, aPubID, aSysID: WideString);
procedure DoEntityReference;
public
doc: TDOMDocument;
constructor Create; overload;
@ -1248,7 +1242,6 @@ begin
FNamePages := @NamePages;
SetLength(FNodeStack, 16);
SetLength(FValidators, 16);
SetLength(FCursorStack, 16);
end;
constructor TXMLReader.Create(AParser: TDOMParser);
@ -1324,14 +1317,14 @@ begin
FState := rsProlog;
FNesting := 0;
FCurrNode := @FNodeStack[0];
FCursorStack[0] := doc;
FFragmentMode := False;
NSPrepare;
Initialize(ASource);
if FSource.FXMLVersion <> xmlVersionUnknown then
TDOMTopNodeEx(TDOMNode(doc)).FXMLVersion := FSource.FXMLVersion;
TDOMTopNodeEx(TDOMNode(doc)).FXMLEncoding := FSource.FXMLEncoding;
ParseContent;
FNext := xtText;
ParseContent(doc);
if FState < rsRoot then
FatalError('Root element is missing');
@ -1352,7 +1345,6 @@ begin
FState := rsRoot;
FNesting := 0;
FCurrNode := @FNodeStack[0];
FCursorStack[0] := AOwner as TDOMNode_WithChildren;
FFragmentMode := True;
FXML11 := doc.InheritsFrom(TXMLDocument) and (TXMLDocument(doc).XMLVersion = '1.1');
NSPrepare;
@ -1369,7 +1361,8 @@ begin
TDOMTopNodeEx(AOwner).FXMLVersion := FSource.FXMLVersion;
TDOMTopNodeEx(AOwner).FXMLEncoding := FSource.FXMLEncoding;
end;
ParseContent;
FNext := xtText;
ParseContent(aOwner as TDOMNode_WithChildren);
end;
function TXMLReader.CheckName(aFlags: TCheckNameFlags): Boolean;
@ -1929,17 +1922,13 @@ begin
FNameTable.FindOrAdd(FName.Buffer, FName.Length));
end;
procedure TXMLReader.CreatePINode;
function TXMLReader.CreatePINode: TDOMNode;
var
NameStr, ValueStr: WideString;
PINode: TDOMProcessingInstruction;
begin
SetString(NameStr, FName.Buffer, FName.Length);
SetString(ValueStr, FValue.Buffer, FValue.Length);
// SAX: ContentHandler.ProcessingInstruction(Name, Value);
PINode := Doc.CreateProcessingInstruction(NameStr, ValueStr);
FCursorStack[FNesting].InternalAppend(PINode);
result := Doc.CreateProcessingInstruction(NameStr, ValueStr);
end;
const
@ -2550,7 +2539,7 @@ begin
if FSource.FBuf^ = '?' then
begin
ParsePI;
CreatePINode;
doc.AppendChild(CreatePINode);
end
else
begin
@ -2764,11 +2753,6 @@ begin
end;
end;
procedure TXMLReader.DoEntityReference;
begin
FCursorStack[FNesting].AppendChild(doc.CreateEntityReference(FCurrNode^.FQName^.Key));
end;
procedure TXMLReader.HandleEntityStart;
begin
{ FNesting+1 is available due to overallocation in AllocNodeData() }
@ -2782,7 +2766,6 @@ end;
procedure TXMLReader.HandleEntityEnd;
begin
FValidators[FNesting-1] := FValidators[FNesting];
FCursorStack[FNesting-1] := FCursorStack[FNesting];
ContextPop(True);
PopVC;
FCurrNode := @FNodeStack[FNesting+1];
@ -2817,31 +2800,27 @@ begin
{ Compensate for an extra entry in node stack }
FValidators[FNesting] := FValidators[FNesting-1];
FCursorStack[FNesting] := FCursorStack[FNesting-1];
UpdateConstraints;
FNext := xtText;
end;
procedure TXMLReader.DoStartElement;
function TXMLReader.DoStartElement: TDOMElement;
var
NewElem: TDOMElement;
Attr: TDOMAttr;
i: Integer;
begin
with FCurrNode^.FQName^ do
NewElem := doc.CreateElementBuf(PWideChar(Key), Length(Key));
FCursorStack[FNesting-1].InternalAppend(NewElem);
FCursorStack[FNesting] := NewElem;
Result := doc.CreateElementBuf(PWideChar(Key), Length(Key));
if Assigned(FCurrNode^.FNsUri) then
NewElem.SetNSI(FCurrNode^.FNsUri^.Key, FCurrNode^.FColonPos+1);
Result.SetNSI(FCurrNode^.FNsUri^.Key, FCurrNode^.FColonPos+1);
for i := 1 to FAttrCount do
begin
Attr := LoadAttribute(doc, @FNodeStack[FNesting+i]);
NewElem.SetAttributeNode(Attr);
Result.SetAttributeNode(Attr);
// Attach element to ID map entry if necessary
if Assigned(FNodeStack[FNesting+i].FIDEntry) then
FNodeStack[FNesting+i].FIDEntry^.Data := NewElem;
FNodeStack[FNesting+i].FIDEntry^.Data := Result;
end;
end;
@ -2898,33 +2877,57 @@ const
ntText
);
procedure TXMLReader.ParseContent;
procedure TXMLReader.ParseContent(parent: TDOMNode_WithChildren);
var
cursor: TDOMNode_WithChildren;
element: TDOMElement;
begin
FNext := xtText;
cursor := parent;
while Read do
begin
if FValidate then
ValidateCurrentNode;
case FCurrNode^.FNodeType of
ntText, ntWhitespace:
DoText(FValue.Buffer, FValue.Length, FCurrNode^.FNodeType = ntWhitespace);
ntText:
cursor.InternalAppend(doc.CreateTextNodeBuf(FValue.Buffer, FValue.Length, False));
ntWhitespace:
if FPreserveWhitespace then
cursor.InternalAppend(doc.CreateTextNodeBuf(FValue.Buffer, FValue.Length, FCurrContentType = ctChildren))
else
Continue;
ntCDATA:
DoCDSect(FValue.Buffer, FValue.Length);
cursor.InternalAppend(DoCDSect(FValue.Buffer, FValue.Length));
ntProcessingInstruction:
CreatePINode;
cursor.InternalAppend(CreatePINode);
ntComment:
DoComment(FCurrNode^.FValueStart, FCurrNode^.FValueLength);
if FIgnoreComments then
Continue
else
cursor.InternalAppend(doc.CreateCommentBuf(FCurrNode^.FValueStart, FCurrNode^.FValueLength));
ntElement:
DoStartElement;
ntEndElement:
;
ntDocumentType:
begin
if not FCanonical then
doc.AppendChild(TDOMDocumentType.Create(doc, FDocType));
element := DoStartElement;
cursor.InternalAppend(element);
cursor := element;
Continue;
end;
ntEndElement:
cursor := TDOMNode_WithChildren(cursor.ParentNode);
ntDocumentType:
if FCanonical then
Continue
else
cursor.InternalAppend(TDOMDocumentType.Create(doc, FDocType));
ntEntityReference:
DoEntityReference;
cursor.InternalAppend(doc.CreateEntityReference(FCurrNode^.FQName^.Key));
end;
end;
end;
@ -3080,6 +3083,12 @@ begin
end;
if FValue.Length <> 0 then
begin
if FState <> rsRoot then
if nonWs then
FatalError('Illegal at document level', -1)
else
Break;
SetNodeInfoWithValue(textNodeTypes[nonWs]);
FNext := tok;
Result := True;
@ -3538,42 +3547,15 @@ begin
DoErrorPos(esError, 'Notation ''%s'' is not declared', [Value], Loc);
end;
procedure TXMLReader.DoText(ch: PWideChar; Count: Integer; Whitespace: Boolean);
var
TextNode: TDOMText;
begin
if FState <> rsRoot then
if not Whitespace then
FatalError('Illegal at document level', -1)
else
Exit;
if (Whitespace and (not FPreserveWhitespace)) or (Count = 0) then
Exit;
TextNode := Doc.CreateTextNodeBuf(ch, Count, Whitespace and (FCurrContentType = ctChildren));
FCursorStack[FNesting].InternalAppend(TextNode);
end;
procedure TXMLReader.DoComment(ch: PWideChar; Count: Integer);
var
Node: TDOMComment;
begin
if (not FIgnoreComments) and (FState <> rsDTD) then
begin
Node := Doc.CreateCommentBuf(ch, Count);
FCursorStack[FNesting].InternalAppend(Node);
end;
end;
procedure TXMLReader.DoCDSect(ch: PWideChar; Count: Integer);
function TXMLReader.DoCDSect(ch: PWideChar; Count: Integer): TDOMNode;
var
s: WideString;
begin
Assert(not FCDSectionsAsText, 'Should not be called when CDSectionsAsText=True');
SetString(s, ch, Count);
FCursorStack[FNesting].InternalAppend(doc.CreateCDATASection(s));
result := doc.CreateCDATASection(s);
end;
procedure TXMLReader.DoNotationDecl(const aName, aPubID, aSysID: WideString);
@ -3695,9 +3677,8 @@ begin
FCurrNode^.FNsUri := nil;
FCurrNode^.FIDEntry := nil;
if FNesting >= Length(FCursorStack) then
if FNesting >= Length(FValidators) then
begin
SetLength(FCursorStack, FNesting * 2);
SetLength(FValidators, FNesting * 2);
end;