]>
git.saurik.com Git - wxWidgets.git/blob - src/xrc/xmlwrite.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxXmlDocument - XML text writer
4 // Author: Vaclav Slavik
7 // Copyright: (c) 2001 Vaclav Slavik
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
12 // nothing - already in xml.cpp
15 // For compilers that support precompilation, includes "wx.h".
16 #include "wx/wxprec.h"
22 #include "wx/wfstream.h"
25 #include "wx/strconv.h"
26 #include "wx/xrc/xml.h"
27 #include "wx/xrc/xmlio.h"
29 // write string to output:
30 inline static void OutputString(wxOutputStream
& stream
, const wxString
& str
,
31 wxMBConv
*convMem
, wxMBConv
*convFile
)
33 if (str
.IsEmpty()) return;
35 const wxW2MBbuf
*buf
= str
.mb_str(convFile
? *convFile
: wxConvUTF8
);
36 stream
.Write((const char*)buf
, strlen((const char*)buf
));
38 if ( convFile
== NULL
)
39 stream
.Write(str
.mb_str(), str
.Len());
42 wxString
str2(str
.wc_str(*convMem
), *convFile
);
43 stream
.Write(str2
.mb_str(), str2
.Len());
48 // Same as above, but create entities first.
49 // Translates '<' to "<", '>' to ">" and '&' to "&"
50 static void OutputStringEnt(wxOutputStream
& stream
, const wxString
& str
,
51 wxMBConv
*convMem
, wxMBConv
*convFile
)
59 for (i
= 0; i
< len
; i
++)
62 if (c
== wxT('<') || c
== wxT('>') ||
63 (c
== wxT('&') && str
.Mid(i
+1, 4) != wxT("amp;")))
65 OutputString(stream
, str
.Mid(last
, i
- last
), convMem
, convFile
);
69 OutputString(stream
, wxT("<"), NULL
, NULL
);
72 OutputString(stream
, wxT(">"), NULL
, NULL
);
75 OutputString(stream
, wxT("&"), NULL
, NULL
);
82 OutputString(stream
, str
.Mid(last
, i
- last
), convMem
, convFile
);
85 inline static void OutputIndentation(wxOutputStream
& stream
, int indent
)
87 wxString str
= wxT("\n");
88 for (int i
= 0; i
< indent
; i
++)
89 str
<< wxT(' ') << wxT(' ');
90 OutputString(stream
, str
, NULL
, NULL
);
93 static void OutputNode(wxOutputStream
& stream
, wxXmlNode
*node
, int indent
,
94 wxMBConv
*convMem
, wxMBConv
*convFile
)
99 switch (node
->GetType())
101 case wxXML_TEXT_NODE
:
102 OutputStringEnt(stream
, node
->GetContent(), convMem
, convFile
);
105 case wxXML_ELEMENT_NODE
:
106 OutputString(stream
, wxT("<"), NULL
, NULL
);
107 OutputString(stream
, node
->GetName(), NULL
, NULL
);
109 prop
= node
->GetProperties();
112 OutputString(stream
, wxT(" ") + prop
->GetName() +
113 wxT("=\"") + prop
->GetValue() + wxT("\""),
115 // FIXME - what if prop contains '"'?
116 prop
= prop
->GetNext();
119 if (node
->GetChildren())
121 OutputString(stream
, wxT(">"), NULL
, NULL
);
123 n
= node
->GetChildren();
126 if (n
&& n
->GetType() != wxXML_TEXT_NODE
)
127 OutputIndentation(stream
, indent
+ 1);
128 OutputNode(stream
, n
, indent
+ 1, convMem
, convFile
);
132 if (prev
&& prev
->GetType() != wxXML_TEXT_NODE
)
133 OutputIndentation(stream
, indent
);
134 OutputString(stream
, wxT("</"), NULL
, NULL
);
135 OutputString(stream
, node
->GetName(), NULL
, NULL
);
136 OutputString(stream
, wxT(">"), NULL
, NULL
);
139 OutputString(stream
, wxT("/>"), NULL
, NULL
);
142 case wxXML_COMMENT_NODE
:
143 OutputString(stream
, wxT("<!--"), NULL
, NULL
);
144 OutputString(stream
, node
->GetContent(), convMem
, convFile
);
145 OutputString(stream
, wxT("-->"), NULL
, NULL
);
149 wxFAIL_MSG(wxT("unsupported node type"));
153 bool wxXmlIOHandlerWriter::Save(wxOutputStream
& stream
, const wxXmlDocument
& doc
)
160 wxMBConv
*convMem
= NULL
, *convFile
= NULL
;
162 convFile
= new wxCSConv(doc
.GetFileEncoding());
164 if ( doc
.GetFileEncoding() != doc
.GetEncoding() )
166 convFile
= new wxCSConv(doc
.GetFileEncoding());
167 convMem
= new wxCSConv(doc
.GetEncoding());
171 s
.Printf(wxT("<?xml version=\"%s\" encoding=\"%s\"?>\n"),
172 doc
.GetVersion().c_str(), doc
.GetFileEncoding().c_str());
173 OutputString(stream
, s
, NULL
, NULL
);
175 OutputNode(stream
, doc
.GetRoot(), 0, convMem
, convFile
);
176 OutputString(stream
, wxT("\n"), NULL
, NULL
);