Browse Source

* Some improvements by Sergei Gorelkin
- xmlread now detects encoding. (UTF8 and UTF16)
- xmlread now uses single pass sequential reading mechanism
- xmlwrite now uses a couple of classes, making it thread-safe


git-svn-id: trunk@3783 -

michael 19 years ago
parent
commit
faf7cba799
2 changed files with 665 additions and 805 deletions
  1. 437 481
      fcl/xml/xmlread.pp
  2. 228 324
      fcl/xml/xmlwrite.pp

File diff suppressed because it is too large
+ 437 - 481
fcl/xml/xmlread.pp


+ 228 - 324
fcl/xml/xmlwrite.pp

@@ -3,8 +3,9 @@
 
 
     XML writing routines
     XML writing routines
     Copyright (c) 1999-2000 by Sebastian Guenther, [email protected]
     Copyright (c) 1999-2000 by Sebastian Guenther, [email protected]
+    Modified in 2006 by Sergei Gorelkin, [email protected]
 
 
-    See the file COPYING.modifiedLGPL, included in this distribution,
+    See the file COPYING.FPC, included in this distribution,
     for details about the copyright.
     for details about the copyright.
 
 
     This program is distributed in the hope that it will be useful,
     This program is distributed in the hope that it will be useful,
@@ -16,8 +17,11 @@
 
 
 unit XMLWrite;
 unit XMLWrite;
 
 
+{$ifdef fpc}
 {$MODE objfpc}
 {$MODE objfpc}
+{$INLINE ON}
 {$H+}
 {$H+}
+{$endif}
 
 
 interface
 interface
 
 
@@ -39,148 +43,146 @@ implementation
 uses SysUtils;
 uses SysUtils;
 
 
 // -------------------------------------------------------------------
 // -------------------------------------------------------------------
-//   Writers for the different node types
+//   Text file and TStream support
 // -------------------------------------------------------------------
 // -------------------------------------------------------------------
 
 
-procedure WriteElement(node: TDOMNode); forward;
-procedure WriteAttribute(node: TDOMNode); forward;
-procedure WriteText(node: TDOMNode); forward;
-procedure WriteCDATA(node: TDOMNode); forward;
-procedure WriteEntityRef(node: TDOMNode); forward;
-procedure WriteEntity(node: TDOMNode); forward;
-procedure WritePI(node: TDOMNode); forward;
-procedure WriteComment(node: TDOMNode); forward;
-procedure WriteDocument(node: TDOMNode); forward;
-procedure WriteDocumentType(node: TDOMNode); forward;
-procedure WriteDocumentFragment(node: TDOMNode); forward;
-procedure WriteNotation(node: TDOMNode); forward;
-
-
 type
 type
-  TWriteNodeProc = procedure(node: TDOMNode);
+  TOutputProc = procedure(const Buffer; Count: Longint) of object;
+  TCharacters = set of Char;
+  TSpecialCharCallback = procedure(c: Char) of object;
+
+  TXMLWriter = class(TObject)  // (TAbstractDOMVisitor)?
+  private
+    FInsideTextNode: Boolean;
+    FIndent: string;
+    FIndentCount: Integer;
+    procedure IncIndent; {$IFDEF FPC} inline; {$ENDIF}
+    procedure DecIndent; {$IFDEF FPC} inline; {$ENDIF}
+    procedure wrtStr(const s: string);
+    procedure wrtChr(c: char);
+    procedure wrtLineEnd; {$IFDEF FPC} inline; {$ENDIF}
+    procedure wrtIndent;
+    procedure ConvWrite(const s: String; const SpecialChars: TCharacters;
+      const SpecialCharCallback: TSpecialCharCallback);
+    procedure AttrSpecialCharCallback(c: Char);
+    procedure TextNodeSpecialCharCallback(c: Char);
+  protected
+    Procedure Write(Const Buffer; Count : Longint); virtual;Abstract;
+    Procedure Writeln(Const Buffer; Count : Longint); virtual;
+    procedure WriteNode(Node: TDOMNode);
+    procedure VisitDocument(Node: TDOMNode);  // override;
+    procedure VisitElement(Node: TDOMNode);
+    procedure VisitText(Node: TDOMNode);
+    procedure VisitCDATA(Node: TDOMNode);
+    procedure VisitComment(Node: TDOMNode);
+    procedure VisitFragment(Node: TDOMNode);
+    procedure VisitAttribute(Node: TDOMNode);
+    procedure VisitEntity(Node: TDOMNode);
+    procedure VisitEntityRef(Node: TDOMNode);
+    procedure VisitDocumentType(Node: TDOMNode);
+    procedure VisitPI(Node: TDOMNode);
+    procedure VisitNotation(Node: TDOMNode);
+  end;
 
 
-const
-  WriteProcs: array[ELEMENT_NODE..NOTATION_NODE] of TWriteNodeProc =
-    (@WriteElement, @WriteAttribute, @WriteText, @WriteCDATA, @WriteEntityRef,
-     @WriteEntity, @WritePI, @WriteComment, @WriteDocument, @WriteDocumentType,
-     @WriteDocumentFragment, @WriteNotation);
+  TTextXMLWriter = Class(TXMLWriter)
+  Private
+    F : ^Text;
+  Protected  
+    Procedure Write(Const Buffer; Count : Longint);override;
+  Public  
+    procedure WriteXML(Root: TDomNode; var AFile: Text); overload;
+  end;
+  
+  TStreamXMLWriter = Class(TXMLWriter)
+  Private
+    F : TStream;
+  Protected  
+    Procedure Write(Const Buffer; Count : Longint);override;
+  Public  
+    procedure WriteXML(Root: TDomNode; AStream : TStream); overload;
+  end;
 
 
-procedure WriteNode(node: TDOMNode);
+{ ---------------------------------------------------------------------
+    TTextXMLWriter
+  ---------------------------------------------------------------------}
+  
+
+procedure TTextXMLWriter.Write(const Buffer; Count: Longint);
+var
+  s: string;
 begin
 begin
-  WriteProcs[node.NodeType](node);
+  if Count>0 then
+    begin
+    SetString(s, PChar(Buffer), Count);
+    system.Write(f^, s);
+    end;
 end;
 end;
 
 
+{ ---------------------------------------------------------------------
+    TStreamXMLWriter
+  ---------------------------------------------------------------------}
 
 
-// -------------------------------------------------------------------
-//   Text file and TStream support
-// -------------------------------------------------------------------
-
-type
-  TOutputProc = procedure(const Buffer; Count: Longint);
-
-threadvar
-  f: ^Text;
-  stream: TStream;
-  wrt, wrtln: TOutputProc;
-  InsideTextNode: Boolean;
-
-procedure Text_Write(const Buffer; Count: Longint);
-var s: string;
+procedure TStreamXMLWriter.Write(const Buffer; Count: Longint);
 begin
 begin
-  if Count>0 then begin
-    SetLength(s,Count);
-    System.Move(Buffer,s[1],Count);
-    Write(f^, s);
-  end;
+  if Count > 0 then
+    F.Write(Buffer, Count);
 end;
 end;
 
 
-procedure Text_WriteLn(const Buffer; Count: Longint);
-var s: string;
-begin
-  if Count>0 then begin
-    SetLength(s,Count);
-    System.Move(Buffer,s[1],Count);
-    writeln(f^, s);
-  end;
-end;
 
 
-procedure Stream_Write(const Buffer; Count: Longint);
-begin
-  if Count > 0 then begin
-    stream.Write(Buffer, Count);
-  end;
-end;
+{ ---------------------------------------------------------------------
+    TXMLWriter
+  ---------------------------------------------------------------------}
 
 
-procedure Stream_WriteLn(const Buffer; Count: Longint);
-begin
-  if Count > 0 then begin
-    stream.Write(Buffer, Count);
-    stream.WriteByte(10);
-  end;
-end;
+Procedure TXMLWriter.Writeln(Const Buffer; Count : Longint); 
 
 
-procedure wrtStr(const s: string);
+var
+  eol: byte;
 begin
 begin
-  if s<>'' then
-    wrt(s[1],length(s));
+  eol:=10;
+  Write(buffer,count);
+  Write(eol,sizeof(eol));
 end;
 end;
 
 
-procedure wrtStrLn(const s: string);
+
+procedure TXMLWriter.wrtStr(const s: string);
 begin
 begin
   if s<>'' then
   if s<>'' then
-    wrtln(s[1],length(s));
+    write(s[1],length(s));
 end;
 end;
 
 
-procedure wrtChr(c: char);
+procedure TXMLWriter.wrtChr(c: char);
 begin
 begin
-  wrt(c,1);
+  write(c,1);
 end;
 end;
 
 
-procedure wrtLineEnd;
+procedure TXMLWriter.wrtLineEnd;
 begin
 begin
-  wrt(#10,1);
+  wrtChr(#10);
 end;
 end;
 
 
-// -------------------------------------------------------------------
-//   Indent handling
-// -------------------------------------------------------------------
-
-threadvar
-  Indent: String;
-  IndentCount: integer;
-
-procedure wrtIndent;
-var i: integer;
+procedure TXMLWriter.wrtIndent;
+var
+  I: Integer;
 begin
 begin
-  for i:=1 to IndentCount do
-    wrtStr(Indent);
+  for I:=1 to FIndentCount do
+    wrtStr(FIndent);
 end;
 end;
 
 
-procedure IncIndent;
+procedure TXMLWriter.IncIndent;
 begin
 begin
-  inc(IndentCount);
+  Inc(FIndentCount);
 end;
 end;
 
 
-procedure DecIndent;
+procedure TXMLWriter.DecIndent;
 begin
 begin
-  if IndentCount>0 then dec(IndentCount);
+  if FIndentCount>0 then dec(FIndentCount);
 end;
 end;
 
 
-
-// -------------------------------------------------------------------
-//   String conversion
-// -------------------------------------------------------------------
-
-type
-  TCharacters = set of Char;
-  TSpecialCharCallback = procedure(c: Char);
-
 const
 const
   AttrSpecialChars = ['<', '>', '"', '&'];
   AttrSpecialChars = ['<', '>', '"', '&'];
   TextSpecialChars = ['<', '>', '&'];
   TextSpecialChars = ['<', '>', '&'];
 
 
-
-procedure ConvWrite(const s: String; const SpecialChars: TCharacters;
+procedure TXMLWriter.ConvWrite(const s: String; const SpecialChars: TCharacters;
   const SpecialCharCallback: TSpecialCharCallback);
   const SpecialCharCallback: TSpecialCharCallback);
 var
 var
   StartPos, EndPos: Integer;
   StartPos, EndPos: Integer;
@@ -191,30 +193,33 @@ begin
   begin
   begin
     if s[EndPos] in SpecialChars then
     if s[EndPos] in SpecialChars then
     begin
     begin
-      wrt(s[StartPos],EndPos - StartPos);
+      write(s[StartPos],EndPos - StartPos);
       SpecialCharCallback(s[EndPos]);
       SpecialCharCallback(s[EndPos]);
       StartPos := EndPos + 1;
       StartPos := EndPos + 1;
     end;
     end;
     Inc(EndPos);
     Inc(EndPos);
   end;
   end;
   if StartPos <= length(s) then
   if StartPos <= length(s) then
-    wrt(s[StartPos], EndPos - StartPos);
+    write(s[StartPos], EndPos - StartPos);
 end;
 end;
 
 
-procedure AttrSpecialCharCallback(c: Char);
+procedure TXMLWriter.AttrSpecialCharCallback(c: Char);
 const
 const
   QuotStr = '&quot;';
   QuotStr = '&quot;';
   AmpStr = '&amp;';
   AmpStr = '&amp;';
+  ltStr = '&lt;';
 begin
 begin
   if c = '"' then
   if c = '"' then
     wrtStr(QuotStr)
     wrtStr(QuotStr)
   else if c = '&' then
   else if c = '&' then
     wrtStr(AmpStr)
     wrtStr(AmpStr)
+  else if c = '<' then
+    wrtStr(ltStr)
   else
   else
-    wrt(c,1);
+    write(c,1);
 end;
 end;
 
 
-procedure TextnodeSpecialCharCallback(c: Char);
+procedure TXMLWriter.TextnodeSpecialCharCallback(c: Char);
 const
 const
   ltStr = '&lt;';
   ltStr = '&lt;';
   gtStr = '&gt;';
   gtStr = '&gt;';
@@ -227,362 +232,261 @@ begin
   else if c = '&' then
   else if c = '&' then
     wrtStr(AmpStr)
     wrtStr(AmpStr)
   else
   else
-    wrt(c,1);
+    write(c,1);
+end;
+
+procedure TXMLWriter.WriteNode(node: TDOMNode);
+begin
+  // Must be: node.Accept(Self);
+  case node.NodeType of
+    ELEMENT_NODE:                VisitElement(node);
+    ATTRIBUTE_NODE:              VisitAttribute(node);
+    TEXT_NODE:                   VisitText(node);
+    CDATA_SECTION_NODE:          VisitCDATA(node);
+    ENTITY_REFERENCE_NODE:       VisitEntityRef(node);
+    ENTITY_NODE:                 VisitEntity(node);
+    PROCESSING_INSTRUCTION_NODE: VisitPI(node);
+    COMMENT_NODE:                VisitComment(node);
+    DOCUMENT_NODE:               VisitDocument(node);
+    DOCUMENT_TYPE_NODE:          VisitDocumentType(node);
+    DOCUMENT_FRAGMENT_NODE:      VisitFragment(node);
+    NOTATION_NODE:               VisitNotation(node);
+  end;
 end;
 end;
 
 
 
 
-// -------------------------------------------------------------------
-//   Node writers implementations
-// -------------------------------------------------------------------
-
-procedure WriteElement(node: TDOMNode);
+procedure TXMLWriter.VisitElement(node: TDOMNode);
 var
 var
   i: Integer;
   i: Integer;
   attr, child: TDOMNode;
   attr, child: TDOMNode;
   SavedInsideTextNode: Boolean;
   SavedInsideTextNode: Boolean;
-  s: String;
+  s: DOMString;
 begin
 begin
-  if not InsideTextNode then
+  if not FInsideTextNode then
     wrtIndent;
     wrtIndent;
   wrtChr('<');
   wrtChr('<');
-  wrtStr(node.NodeName);
+  wrtStr(UTF8Encode(node.NodeName));
   for i := 0 to node.Attributes.Length - 1 do
   for i := 0 to node.Attributes.Length - 1 do
   begin
   begin
     attr := node.Attributes.Item[i];
     attr := node.Attributes.Item[i];
     wrtChr(' ');
     wrtChr(' ');
-    wrtStr(attr.NodeName);
+    wrtStr(UTF8Encode(attr.NodeName));
     wrtChr('=');
     wrtChr('=');
     s := attr.NodeValue;
     s := attr.NodeValue;
     // !!!: Replace special characters in "s" such as '&', '<', '>'
     // !!!: Replace special characters in "s" such as '&', '<', '>'
     wrtChr('"');
     wrtChr('"');
-    ConvWrite(s, AttrSpecialChars, @AttrSpecialCharCallback);
+    ConvWrite(UTF8Encode(s), AttrSpecialChars, {$IFDEF FPC}@{$ENDIF}AttrSpecialCharCallback);
     wrtChr('"');
     wrtChr('"');
   end;
   end;
   Child := node.FirstChild;
   Child := node.FirstChild;
   if Child = nil then begin
   if Child = nil then begin
     wrtChr('/');
     wrtChr('/');
     wrtChr('>');
     wrtChr('>');
-    if not InsideTextNode then wrtLineEnd;
+    if not FInsideTextNode then wrtLineEnd;
   end else
   end else
   begin
   begin
-    SavedInsideTextNode := InsideTextNode;
+    SavedInsideTextNode := FInsideTextNode;
     wrtChr('>');
     wrtChr('>');
-    if not (InsideTextNode or Child.InheritsFrom(TDOMText)) then
+    if not (FInsideTextNode or Child.InheritsFrom(TDOMText)) then
       wrtLineEnd;
       wrtLineEnd;
     IncIndent;
     IncIndent;
     repeat
     repeat
       if Child.InheritsFrom(TDOMText) then
       if Child.InheritsFrom(TDOMText) then
-        InsideTextNode := True;
+        FInsideTextNode := True
+      else                      // <-- fix case when CDATA is first child
+        FInsideTextNode := False;
       WriteNode(Child);
       WriteNode(Child);
       Child := Child.NextSibling;
       Child := Child.NextSibling;
     until child = nil;
     until child = nil;
     DecIndent;
     DecIndent;
-    if not InsideTextNode then
+    if not FInsideTextNode then
       wrtIndent;
       wrtIndent;
-    InsideTextNode := SavedInsideTextNode;
+    FInsideTextNode := SavedInsideTextNode;
     wrtChr('<');
     wrtChr('<');
     wrtChr('/');
     wrtChr('/');
-    wrtStr(node.NodeName);
+    wrtStr(UTF8Encode(node.NodeName));
     wrtChr('>');
     wrtChr('>');
-    if not InsideTextNode then
+    if not FInsideTextNode then
       wrtLineEnd;
       wrtLineEnd;
   end;
   end;
 end;
 end;
 
 
-procedure WriteAttribute(node: TDOMNode);
+procedure TXMLWriter.VisitText(node: TDOMNode);
 begin
 begin
-  if node=nil then ;
+  ConvWrite(UTF8Encode(node.NodeValue), TextSpecialChars, {$IFDEF FPC}@{$ENDIF}TextnodeSpecialCharCallback);
 end;
 end;
 
 
-procedure WriteText(node: TDOMNode);
+procedure TXMLWriter.VisitCDATA(node: TDOMNode);
 begin
 begin
-  ConvWrite(node.NodeValue, TextSpecialChars, @TextnodeSpecialCharCallback);
-  if node=nil then ;
-end;
-
-procedure WriteCDATA(node: TDOMNode);
-begin
-  if not InsideTextNode then
-    wrtStr('<![CDATA[' + node.NodeValue + ']]>')
+  if not FInsideTextNode then
+    wrtStr('<![CDATA[' + UTF8Encode(node.NodeValue) + ']]>')
   else begin
   else begin
     wrtIndent;
     wrtIndent;
-    wrtStrln('<![CDATA[' + node.NodeValue + ']]>')
+    wrtStr('<![CDATA[' + UTF8Encode(node.NodeValue) + ']]>');
+    wrtLineEnd;
   end;
   end;
 end;
 end;
 
 
-procedure WriteEntityRef(node: TDOMNode);
+procedure TXMLWriter.VisitEntityRef(node: TDOMNode);
 begin
 begin
   wrtChr('&');
   wrtChr('&');
-  wrtStr(node.NodeName);
+  wrtStr(UTF8Encode(node.NodeName));
   wrtChr(';');
   wrtChr(';');
 end;
 end;
 
 
-procedure WriteEntity(node: TDOMNode);
+procedure TXMLWriter.VisitEntity(node: TDOMNode);
 begin
 begin
-  if node=nil then ;
+
 end;
 end;
 
 
-procedure WritePI(node: TDOMNode);
+procedure TXMLWriter.VisitPI(node: TDOMNode);
 begin
 begin
-  if not InsideTextNode then wrtIndent;
-  wrtChr('<'); wrtChr('!');
-  wrtStr(TDOMProcessingInstruction(node).Target);
+  if not FInsideTextNode then wrtIndent;
+  wrtChr('<'); wrtChr('?');
+  wrtStr(UTF8Encode(TDOMProcessingInstruction(node).Target));
   wrtChr(' ');
   wrtChr(' ');
-  wrtStr(TDOMProcessingInstruction(node).Data);
-  wrtChr('>');
-  if not InsideTextNode then wrtLineEnd;
+  wrtStr(UTF8Encode(TDOMProcessingInstruction(node).Data));
+  wrtChr('?'); wrtChr('>');
+  if not FInsideTextNode then wrtLineEnd;
 end;
 end;
 
 
-procedure WriteComment(node: TDOMNode);
+procedure TXMLWriter.VisitComment(node: TDOMNode);
 begin
 begin
-  if not InsideTextNode then wrtIndent;
+  if not FInsideTextNode then wrtIndent;
   wrtStr('<!--');
   wrtStr('<!--');
-  wrtStr(node.NodeValue);
+  wrtStr(UTF8Encode(node.NodeValue));
   wrtStr('-->');
   wrtStr('-->');
-  if not InsideTextNode then wrtLineEnd;
+  if not FInsideTextNode then wrtLineEnd;
 end;
 end;
 
 
-procedure WriteDocument(node: TDOMNode);
-begin
-  if node=nil then ;
-end;
-
-procedure WriteDocumentType(node: TDOMNode);
-begin
-  if node=nil then ;
-end;
-
-procedure WriteDocumentFragment(node: TDOMNode);
-begin
-  if node=nil then ;
-end;
-
-procedure WriteNotation(node: TDOMNode);
-begin
-  if node=nil then ;
-end;
-
-
-procedure InitWriter;
-begin
-  InsideTextNode := False;
-  SetLength(Indent, 0);
-end;
-
-procedure RootWriter(doc: TXMLDocument);
+procedure TXMLWriter.VisitDocument(node: TDOMNode);
 var
 var
-  Child: TDOMNode;
+  child: TDOMNode;
 begin
 begin
-  InitWriter;
   wrtStr('<?xml version="');
   wrtStr('<?xml version="');
-  if Length(doc.XMLVersion) > 0 then
-    ConvWrite(doc.XMLVersion, AttrSpecialChars, @AttrSpecialCharCallback)
+  if Length(TXMLDocument(node).XMLVersion) > 0 then
+    ConvWrite(TXMLDocument(node).XMLVersion, AttrSpecialChars, {$IFDEF FPC}@{$ENDIF}AttrSpecialCharCallback)
   else
   else
     wrtStr('1.0');
     wrtStr('1.0');
   wrtChr('"');
   wrtChr('"');
-  if Length(doc.Encoding) > 0 then
+  if Length(TXMLDocument(node).Encoding) > 0 then
   begin
   begin
     wrtStr(' encoding="');
     wrtStr(' encoding="');
-    ConvWrite(doc.Encoding, AttrSpecialChars, @AttrSpecialCharCallback);
+    ConvWrite(TXMLDocument(node).Encoding, AttrSpecialChars, {$IFDEF FPC}@{$ENDIF}AttrSpecialCharCallback);
     wrtStr('"');
     wrtStr('"');
   end;
   end;
-  wrtStrln('?>');
+  wrtStr('?>');
+  wrtLineEnd;
 
 
-  if Length(doc.StylesheetType) > 0 then
+  if Length(TXMLDocument(node).StylesheetType) > 0 then
   begin
   begin
     wrtStr('<?xml-stylesheet type="');
     wrtStr('<?xml-stylesheet type="');
-    ConvWrite(doc.StylesheetType, AttrSpecialChars, @AttrSpecialCharCallback);
+    ConvWrite(TXMLDocument(node).StylesheetType, AttrSpecialChars, {$IFDEF FPC}@{$ENDIF}AttrSpecialCharCallback);
     wrtStr('" href="');
     wrtStr('" href="');
-    ConvWrite(doc.StylesheetHRef, AttrSpecialChars, @AttrSpecialCharCallback);
-    wrtStrln('"?>');
+    ConvWrite(TXMLDocument(node).StylesheetHRef, AttrSpecialChars, {$IFDEF FPC}@{$ENDIF}AttrSpecialCharCallback);
+    wrtStr('"?>');
+    wrtLineEnd;
   end;
   end;
 
 
-  Indent := '  ';
-  IndentCount := 0;
+  FIndent := '  ';
+  FIndentCount := 0;
 
 
-  child := doc.FirstChild;
+  child := node.FirstChild;
   while Assigned(Child) do
   while Assigned(Child) do
   begin
   begin
     WriteNode(Child);
     WriteNode(Child);
     Child := Child.NextSibling;
     Child := Child.NextSibling;
   end;
   end;
+
+  if node=nil then ;
 end;
 end;
 
 
+procedure TXMLWriter.VisitAttribute(Node: TDOMNode);
+begin
+
+end;
 
 
-procedure WriteXMLMemStream(doc: TXMLDocument);
-// internally used by the WriteXMLFile procedures
+procedure TXMLWriter.VisitDocumentType(Node: TDOMNode);
 begin
 begin
-  Stream:=TMemoryStream.Create;
-  WriteXMLFile(doc,Stream);
-  Stream.Position:=0;
+
 end;
 end;
 
 
-// -------------------------------------------------------------------
-//   Interface implementation
-// -------------------------------------------------------------------
+procedure TXMLWriter.VisitFragment(Node: TDOMNode);
+begin
+  VisitElement(Node);
+end;
 
 
-{$IFDEF FPC}
-    {$DEFINE UsesFPCWidestrings}
-{$ENDIF}
+procedure TXMLWriter.VisitNotation(Node: TDOMNode);
+begin
 
 
-{$IFDEF UsesFPCWidestrings}
+end;
 
 
-{procedure SimpleWide2AnsiMove(source:pwidechar;dest:pchar;len:sizeint);
-var
-  i : sizeint;
+
+procedure TStreamXMLWriter.WriteXML(Root: TDOMNode; AStream: TStream);
 begin
 begin
-  for i:=1 to len do
-   begin
-     if word(source^)<256 then
-      dest^:=char(word(source^))
-     else
-      dest^:='?';
-     inc(dest);
-     inc(source);
-   end;
+  F:=AStream;
+  WriteNode(Root);
 end;
 end;
 
 
-procedure SimpleAnsi2WideMove(source:pchar;dest:pwidechar;len:sizeint);
-var
-  i : sizeint;
+procedure TTextXMLWriter.WriteXML(Root: TDOMNode; var AFile: Text);
 begin
 begin
-  for i:=1 to len do
-   begin
-     dest^:=widechar(byte(source^));
-     inc(dest);
-     inc(source);
-   end;
-end;}
+  f := @AFile;
+  WriteNode(Root);
+end;
 
 
-{$ENDIF}
+// -------------------------------------------------------------------
+//   Interface implementation
+// -------------------------------------------------------------------
 
 
 procedure WriteXMLFile(doc: TXMLDocument; const AFileName: String);
 procedure WriteXMLFile(doc: TXMLDocument; const AFileName: String);
+
 var
 var
   fs: TFileStream;
   fs: TFileStream;
+  
 begin
 begin
-  // write first to memory buffer and then as one whole block to file
-  WriteXMLMemStream(doc);
+  fs := TFileStream.Create(AFileName, fmCreate);
   try
   try
-    fs := TFileStream.Create(AFileName, fmCreate);
-    fs.CopyFrom(Stream,Stream.Size);
-    fs.Free;
+     WriteXMLFile(doc, fs);
   finally
   finally
-    Stream.Free;
+    fs.Free;
   end;
   end;
 end;
 end;
 
 
 procedure WriteXMLFile(doc: TXMLDocument; var AFile: Text);
 procedure WriteXMLFile(doc: TXMLDocument; var AFile: Text);
-{$IFDEF UsesFPCWidestrings}
-var
-  MyWideStringManager,OldWideStringManager: TWideStringManager;
-{$ENDIF}
 begin
 begin
-  {$IFDEF UsesFPCWidestrings}
-  GetWideStringManager(MyWideStringManager);
-
-  MyWideStringManager.Wide2AnsiMoveProc:=@defaultWide2AnsiMove;
-  MyWideStringManager.Ansi2WideMoveProc:=@defaultAnsi2WideMove;
-  SetWideStringManager(MyWideStringManager, OldWideStringManager);
+  with TTextXMLWriter.Create do
   try
   try
-  {$ENDIF}
-    f := @AFile;
-    wrt := @Text_Write;
-    wrtln := @Text_WriteLn;
-    RootWriter(doc);
-  {$IFDEF UsesFPCWidestrings}
+    WriteXML(doc, AFile);
   finally
   finally
-    SetWideStringManager(OldWideStringManager);
+    Free;
   end;
   end;
-  {$ENDIF}
 end;
 end;
 
 
 procedure WriteXMLFile(doc: TXMLDocument; AStream: TStream);
 procedure WriteXMLFile(doc: TXMLDocument; AStream: TStream);
-{$IFDEF UsesFPCWidestrings}
-var
-  OldWideStringManager: TWideStringManager;
-{$ENDIF}
 begin
 begin
-  {$IFDEF UsesFPCWidestrings}
-  SetWideStringManager(WideStringManager, OldWideStringManager);
+  with TStreamXMLWriter.Create do
   try
   try
-  {$ENDIF}
-    Stream := AStream;
-    wrt := @Stream_Write;
-    wrtln := @Stream_WriteLn;
-    RootWriter(doc);
-  {$IFDEF UsesFPCWidestrings}
+    WriteXML(doc, AStream);
   finally
   finally
-    SetWideStringManager(OldWideStringManager);
+    Free;
   end;
   end;
-  {$ENDIF}
 end;
 end;
 
 
-
 procedure WriteXML(Element: TDOMNode; const AFileName: String);
 procedure WriteXML(Element: TDOMNode; const AFileName: String);
-{$IFDEF UsesFPCWidestrings}
-var
-  OldWideStringManager: TWideStringManager;
-{$ENDIF}
 begin
 begin
-  {$IFDEF UsesFPCWidestrings}
-  SetWideStringManager(WideStringManager, OldWideStringManager);
-  try
-  {$ENDIF}
-    Stream := TFileStream.Create(AFileName, fmCreate);
-    wrt := @Stream_Write;
-    wrtln := @Stream_WriteLn;
-    InitWriter;
-    WriteNode(Element);
-    Stream.Free;
-  {$IFDEF UsesFPCWidestrings}
-  finally
-    SetWideStringManager(OldWideStringManager);
-  end;
-  {$ENDIF}
+  WriteXML(TXMLDocument(Element), AFileName);
 end;
 end;
 
 
 procedure WriteXML(Element: TDOMNode; var AFile: Text);
 procedure WriteXML(Element: TDOMNode; var AFile: Text);
-{$IFDEF UsesFPCWidestrings}
-var
-  OldWideStringManager: TWideStringManager;
-{$ENDIF}
 begin
 begin
-  {$IFDEF UsesFPCWidestrings}
-  SetWideStringManager(WideStringManager, OldWideStringManager);
-  try
-  {$ENDIF}
-    f := @AFile;
-    wrt := @Text_Write;
-    wrtln := @Text_WriteLn;
-    InitWriter;
-    WriteNode(Element);
-  {$IFDEF UsesFPCWidestrings}
-  finally
-    SetWideStringManager(OldWideStringManager);
-  end;
-  {$ENDIF}
+  WriteXML(TXMLDocument(Element), AFile);
 end;
 end;
 
 
 procedure WriteXML(Element: TDOMNode; AStream: TStream);
 procedure WriteXML(Element: TDOMNode; AStream: TStream);
-{$IFDEF UsesFPCWidestrings}
-var
-  OldWideStringManager: TWideStringManager;
-{$ENDIF}
 begin
 begin
-  {$IFDEF UsesFPCWidestrings}
-  SetWideStringManager(WideStringManager, OldWideStringManager);
-  try
-  {$ENDIF}
-    stream := AStream;
-    wrt := @Stream_Write;
-    wrtln := @Stream_WriteLn;
-    InitWriter;
-    WriteNode(Element);
-  {$IFDEF UsesFPCWidestrings}
-  finally
-    SetWideStringManager(OldWideStringManager);
-  end;
-  {$ENDIF}
+  WriteXML(TXMLDocument(Element), AStream);
 end;
 end;
 
 
+
+
 end.
 end.

Some files were not shown because too many files changed in this diff