* xmlread.pp: refactoring, no function chages:

* Renamed ParseElement to ParseStartTag to reflect its actual functionality
  * Changed ParseQuantity into function returning a enumeration type
  * Simplified TXMLDecodingSource.NewLine
  * Changed the main loop (ParseContent) so that multiple calls to DoText() are replaced by a single call.
  - Removed "if FCDSectinsAsText" branch in DoCDSect. It is obsolete since this case is handled in ParseContent.

git-svn-id: trunk@15975 -
This commit is contained in:
sergei 2010-09-13 16:07:50 +00:00
parent 06c1413fb0
commit cc82844a9d

View File

@ -362,7 +362,7 @@ type
function ContextPush(AEntity: TDOMEntityEx): Boolean; function ContextPush(AEntity: TDOMEntityEx): Boolean;
function ContextPop(Forced: Boolean = False): Boolean; function ContextPop(Forced: Boolean = False): Boolean;
procedure XML11_BuildTables; procedure XML11_BuildTables;
procedure ParseQuantity(CP: TContentParticle); function ParseQuantity: TCPQuant;
procedure StoreLocation(out Loc: TLocation); procedure StoreLocation(out Loc: TLocation);
function ValidateAttrSyntax(AttrDef: TDOMAttrDef; const aValue: WideString): Boolean; function ValidateAttrSyntax(AttrDef: TDOMAttrDef; const aValue: WideString): Boolean;
procedure ValidateAttrValue(Attr: TDOMAttr; const aValue: WideString); procedure ValidateAttrValue(Attr: TDOMAttr; const aValue: WideString);
@ -405,7 +405,7 @@ type
procedure ExpectEq; procedure ExpectEq;
procedure ParseDoctypeDecl; // [28] procedure ParseDoctypeDecl; // [28]
procedure ParseMarkupDecl; // [29] procedure ParseMarkupDecl; // [29]
procedure ParseElement; // [39] procedure ParseStartTag; // [39]
procedure ParseEndTag; // [42] procedure ParseEndTag; // [42]
procedure DoEndElement(ErrOffset: Integer); procedure DoEndElement(ErrOffset: Integer);
procedure ParseAttribute(Elem: TDOMElement; ElDef: TDOMElementDef); procedure ParseAttribute(Elem: TDOMElement; ElDef: TDOMElementDef);
@ -881,31 +881,25 @@ end;
procedure TXMLDecodingSource.NewLine; procedure TXMLDecodingSource.NewLine;
begin begin
case FBuf^ of case FBuf^ of
#10: begin #10: ;
Inc(FLineNo);
LFPos := FBuf;
end;
#13: begin #13: begin
Inc(FLineNo);
LFPos := FBuf;
// Reload trashes the buffer, it should be consumed beforehand // Reload trashes the buffer, it should be consumed beforehand
if (FBufEnd >= FBuf+2) or Reload then if (FBufEnd >= FBuf+2) or Reload then
begin begin
if (FBuf[1] = #10) or (FXML11Rules and (FBuf[1] = #$85)) then if (FBuf[1] = #10) or (FXML11Rules and (FBuf[1] = #$85)) then
begin
Inc(FBuf); Inc(FBuf);
Inc(LFPos);
end;
end; end;
FBuf^ := #10; FBuf^ := #10;
end; end;
#$85, #$2028: if FXML11Rules then #$85, #$2028: if FXML11Rules then
begin FBuf^ := #10
FBuf^ := #10; else
Exit;
else
Exit;
end;
Inc(FLineNo); Inc(FLineNo);
LFPos := FBuf; LFPos := FBuf;
end;
end;
end; end;
{ TXMLStreamInputSource } { TXMLStreamInputSource }
@ -2166,13 +2160,14 @@ begin
ValidationError('Standalone constriant violation', [], LineOffs); ValidationError('Standalone constriant violation', [], LineOffs);
end; end;
procedure TXMLReader.ParseQuantity(CP: TContentParticle); function TXMLReader.ParseQuantity: TCPQuant;
begin begin
case FSource.FBuf^ of case FSource.FBuf^ of
'?': CP.CPQuant := cqZeroOrOnce; '?': Result := cqZeroOrOnce;
'*': CP.CPQuant := cqZeroOrMore; '*': Result := cqZeroOrMore;
'+': CP.CPQuant := cqOnceOrMore; '+': Result := cqOnceOrMore;
else else
Result := cqOnce;
Exit; Exit;
end; end;
FSource.NextChar; FSource.NextChar;
@ -2214,7 +2209,7 @@ begin
else else
CurrentCP.Def := FindOrCreateElDef; CurrentCP.Def := FindOrCreateElDef;
ParseQuantity(CurrentCP); CurrentCP.CPQuant := ParseQuantity;
SkipWhitespace; SkipWhitespace;
if FSource.FBuf^ = ')' then if FSource.FBuf^ = ')' then
Break; Break;
@ -2296,7 +2291,7 @@ begin
if CurrentEntity <> FSource.FEntity then if CurrentEntity <> FSource.FEntity then
BadPENesting; BadPENesting;
FSource.NextChar; FSource.NextChar;
ParseQuantity(CP); CP.CPQuant := ParseQuantity;
end; end;
except except
CP.Free; CP.Free;
@ -2735,12 +2730,16 @@ const
[#0, '>'] [#0, '>']
); );
type
TXMLToken = (xtNone, xtText, xtElement, xtEndElement, xtCDSect, xtComment, xtPI, xtDoctype, xtEntity, xtEntityEnd);
procedure TXMLReader.ParseContent; procedure TXMLReader.ParseContent;
var var
nonWs: Boolean; nonWs: Boolean;
wc: WideChar; wc: WideChar;
ent: TDOMEntityEx; ent: TDOMEntityEx;
InCDATA: Boolean; InCDATA: Boolean;
tok: TXMLToken;
begin begin
InCDATA := False; InCDATA := False;
StoreLocation(FTokenStart); StoreLocation(FTokenStart);
@ -2754,18 +2753,9 @@ begin
if FSource.FBufEnd < FSource.FBuf + 2 then if FSource.FBufEnd < FSource.FBuf + 2 then
FSource.Reload; FSource.Reload;
if FSource.FBuf^ = '/' then if FSource.FBuf^ = '/' then
begin tok := xtEndElement
DoText(FValue.Buffer, FValue.Length, not nonWs);
if FNesting <= FSource.FStartNesting then
FatalError('End-tag is not allowed here');
Inc(FSource.FBuf);
ParseEndTag;
end
else if CheckName([cnOptional]) then else if CheckName([cnOptional]) then
begin tok := xtElement
DoText(FValue.Buffer, FValue.Length, not nonWs);
ParseElement;
end
else if FSource.FBuf^ = '!' then else if FSource.FBuf^ = '!' then
begin begin
Inc(FSource.FBuf); Inc(FSource.FBuf);
@ -2776,30 +2766,24 @@ begin
FatalError('Illegal at document level'); FatalError('Illegal at document level');
StoreLocation(FTokenStart); StoreLocation(FTokenStart);
InCDATA := True; InCDATA := True;
if not FCDSectionsAsText then if FCDSectionsAsText then
DoText(FValue.Buffer, FValue.Length, not nonWs)
else
Continue; Continue;
tok := xtCDSect;
end end
else if FSource.FBuf^ = '-' then else if FSource.FBuf^ = '-' then
begin begin
if not FIgnoreComments then
DoText(FValue.Buffer, FValue.Length, not nonWs);
ParseComment;
if FIgnoreComments then if FIgnoreComments then
begin
ParseComment;
Continue; Continue;
end;
tok := xtComment;
end end
else else
begin tok := xtDoctype;
DoText(FValue.Buffer, FValue.Length, not nonWs);
ParseDoctypeDecl;
end;
end end
else if FSource.FBuf^ = '?' then else if FSource.FBuf^ = '?' then
begin tok := xtPI
DoText(FValue.Buffer, FValue.Length, not nonWs);
ParsePI;
end
else else
RaiseNameNotFound; RaiseNameNotFound;
end end
@ -2826,7 +2810,7 @@ begin
InCDATA := False; InCDATA := False;
if FCDSectionsAsText then if FCDSectionsAsText then
Continue; Continue;
DoCDSect(FValue.Buffer, FValue.Length); tok := xtText;
end end
else else
FatalError('Literal '']]>'' is not allowed in text', 3); FatalError('Literal '']]>'' is not allowed in text', 3);
@ -2847,18 +2831,27 @@ begin
else else
begin begin
ent := EntityCheck; ent := EntityCheck;
if (ent = nil) or (not FExpandEntities) then if Assigned(ent) and FExpandEntities then
begin
DoText(FValue.Buffer, FValue.Length, not nonWs);
AppendReference(ent);
end
else
begin begin
ContextPush(ent); ContextPush(ent);
Continue; Continue;
end; end;
tok := xtEntity;
end; end;
end; end;
// flush text accumulated this far
if tok = xtText then
DoCDSect(FValue.Buffer, FValue.Length)
else
DoText(FValue.Buffer, FValue.Length, not nonWs);
case tok of
xtEntity: AppendReference(ent);
xtElement: ParseStartTag;
xtEndElement: ParseEndTag;
xtPI: ParsePI;
xtDoctype: ParseDoctypeDecl;
xtComment: ParseComment;
end;
StoreLocation(FTokenStart); StoreLocation(FTokenStart);
FValue.Length := 0; FValue.Length := 0;
nonWs := False; nonWs := False;
@ -2882,7 +2875,7 @@ begin
end; end;
// Element name already in FNameBuffer // Element name already in FNameBuffer
procedure TXMLReader.ParseElement; // [39] [40] [44] procedure TXMLReader.ParseStartTag; // [39] [40] [44]
var var
NewElem: TDOMElement; NewElem: TDOMElement;
ElDef: TDOMElementDef; ElDef: TDOMElementDef;
@ -2968,6 +2961,10 @@ procedure TXMLReader.ParseEndTag; // [42]
var var
ElName: PHashItem; ElName: PHashItem;
begin begin
if FNesting <= FSource.FStartNesting then
FatalError('End-tag is not allowed here');
Inc(FSource.FBuf);
ElName := FValidator[FNesting].FElement.NSI.QName; ElName := FValidator[FNesting].FElement.NSI.QName;
CheckName; CheckName;
@ -3382,19 +3379,13 @@ procedure TXMLReader.DoCDSect(ch: PWideChar; Count: Integer);
var var
s: WideString; s: WideString;
begin begin
Assert(not FCDSectionsAsText, 'Should not be called when CDSectionsAsText=True');
if FCurrContentType = ctChildren then if FCurrContentType = ctChildren then
ValidationError('CDATA sections are not allowed in element-only content',[]); ValidationError('CDATA sections are not allowed in element-only content',[]);
if not FCDSectionsAsText then
begin
SetString(s, ch, Count); SetString(s, ch, Count);
// SAX: LexicalHandler.StartCDATA;
// SAX: ContentHandler.Characters(...);
FCursor.AppendChild(doc.CreateCDATASection(s)); FCursor.AppendChild(doc.CreateCDATASection(s));
// SAX: LexicalHandler.EndCDATA;
end
else
FCursor.AppendChild(doc.CreateTextNodeBuf(ch, Count, False));
end; end;
procedure TXMLReader.DoNotationDecl(const aName, aPubID, aSysID: WideString); procedure TXMLReader.DoNotationDecl(const aName, aPubID, aSysID: WideString);