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