1 
2 #include "studiox_includes.h"
3 
4 #ifdef _DEBUG
5 #define new DEBUG_NEW
6 #endif
7 
8 ///////////////////////////////////////////////////////////////////////////////
xml_writer()9 xml_writer::xml_writer()
10 {
11     mpFile = NULL;
12     UsingMemFile = FALSE;
13 }
14 
15 ///////////////////////////////////////////////////////////////////////////////
~xml_writer()16 xml_writer::~xml_writer()
17 {
18     if (mpFile)
19     {
20         CloseFile();
21     }
22 }
23 
24 ///////////////////////////////////////////////////////////////////////////////
OpenFile(const CString & pathname)25 BOOL xml_writer::OpenFile(const CString &pathname)
26 {
27     CStdioFile *ofile = new CStdioFile();
28     if (!ofile->Open(pathname,
29         CFile::modeCreate|CFile::modeWrite|CFile::typeText))
30     {
31         delete ofile;
32         return FALSE;
33     }
34     mpFile = ofile;
35     UsingMemFile = FALSE;
36     return TRUE;
37 }
38 
39 ///////////////////////////////////////////////////////////////////////////////
OpenMemFile(CFile * file)40 void xml_writer::OpenMemFile(CFile *file)
41 {
42     mpFile = file;
43     UsingMemFile = TRUE;
44 }
45 
46 ///////////////////////////////////////////////////////////////////////////////
CloseFile(void)47 void xml_writer::CloseFile(void)
48 {
49     if (mpFile)
50     {
51         if (!UsingMemFile)
52         {
53             mpFile->Flush();
54             mpFile->Close();
55             delete mpFile;
56         }
57         mpFile = NULL;
58     }
59 }
60 
61 ///////////////////////////////////////////////////////////////////////////////
WriteHeader(const char * docType)62 void xml_writer::WriteHeader(const char *docType)
63 {
64     StringToFile(_T("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"));
65 
66     if (docType)
67     {
68         CString cs(docType);
69 
70         StringToFile(_T("<!DOCTYPE "));
71         StringToFile(cs);
72         StringToFile(_T(">\n"));
73     }
74 }
75 
76 ///////////////////////////////////////////////////////////////////////////////
WriteInt(const char * name,int val)77 void xml_writer::WriteInt(const char *name, int val)
78 {
79     CString cVal;
80     cVal.Format(_T("%d"), val);
81     WriteString(name, cVal);
82 }
83 
84 ///////////////////////////////////////////////////////////////////////////////
WriteUnsigned(const char * name,ULONG val)85 void xml_writer::WriteUnsigned(const char *name, ULONG val)
86 {
87     CString cVal;
88     cVal.Format(_T("%u"), val);
89     WriteString(name, cVal);
90 }
91 
92 ///////////////////////////////////////////////////////////////////////////////
WriteUByte(const char * name,GX_UBYTE val)93 void xml_writer::WriteUByte(const char *name, GX_UBYTE val)
94 {
95     CString cVal;
96     cVal.Format(_T("%u"), val);
97     WriteString(name, cVal);
98 }
99 
100 
101 ///////////////////////////////////////////////////////////////////////////////
WriteHex(const char * name,ULONG val)102 void xml_writer::WriteHex(const char *name, ULONG val)
103 {
104     CString cVal;
105     cVal.Format(_T("%08x"), val);
106     WriteString(name, cVal);
107 }
108 
109 ///////////////////////////////////////////////////////////////////////////////
WriteRect(const char * name,GX_RECTANGLE & rect)110 void xml_writer::WriteRect(const char *name, GX_RECTANGLE &rect)
111 {
112     OpenTag(name);
113     WriteInt("left", rect.gx_rectangle_left);
114     WriteInt("top", rect.gx_rectangle_top);
115     WriteInt("right", rect.gx_rectangle_right);
116     WriteInt("bottom", rect.gx_rectangle_bottom);
117     CloseTag(name);
118 }
119 
120 ///////////////////////////////////////////////////////////////////////////////
WriteBool(const char * name,BOOL val)121 void xml_writer::WriteBool(const char *name, BOOL val)
122 {
123     OpenTag(name, TRUE);
124 
125     if (val)
126     {
127         StringToFile(_T("TRUE"));
128     }
129     else
130     {
131         StringToFile(_T("FALSE"));
132     }
133     CloseTag(name);
134 }
135 
136 ///////////////////////////////////////////////////////////////////////////////
WriteString(const char * name,const char * val,BOOL bForce)137 void xml_writer::WriteString(const char *name, const char *val, BOOL bForce)
138 {
139     CString cVal(val);
140     WriteString(name, cVal, bForce);
141 }
142 
143 ///////////////////////////////////////////////////////////////////////////////
WriteString(const char * name,const CString & cVal,BOOL bForce)144 void xml_writer::WriteString(const char *name, const CString &cVal, BOOL bForce)
145 {
146     if (!bForce && cVal.IsEmpty())
147     {
148         return;
149     }
150 
151     // escape out the special characters
152     // " &quot
153     // ' &apos
154     // < &lt
155     // > &gt
156     // & &amp
157     CString escaped(cVal);
158     escaped.Replace(_T("&"), _T("&amp;"));
159     escaped.Replace(_T("\""), _T("&quot;"));
160     escaped.Replace(_T("\'"), _T("&apos;"));
161     escaped.Replace(_T("<"), _T("&lt;"));
162     escaped.Replace(_T(">"), _T("&gt;"));
163 
164     OpenTag(name, TRUE);
165     if (!escaped.IsEmpty())
166     {
167         // convert unicode to utf8
168         // The maximun UTF8 character is 6 bytes, calculate the maximun utf8 buffer size needed for the string.
169         int buffer_size = escaped.GetLength() * 6 + 1;
170         char *utf8buf = new char[buffer_size];
171         strcpy_s(utf8buf, buffer_size, CT2A(escaped.GetString(), CP_UTF8));
172         mpFile->Write(utf8buf, strlen(utf8buf));
173         delete[] utf8buf;
174 
175     }
176     CloseTag(name);
177 }
178 
179 ///////////////////////////////////////////////////////////////////////////////
WritePathInfo(const PATHINFO & info)180 void xml_writer::WritePathInfo(const PATHINFO &info)
181 {
182     OpenTag("pathinfo");
183     if (!info.pathname.IsEmpty())
184     {
185         WriteString("pathname", info.pathname);
186     }
187     switch(info.pathtype)
188     {
189     case PATH_TYPE_PROJECT_RELATIVE:
190         WriteString("pathtype", "project_relative");
191         break;
192 
193     case PATH_TYPE_INSTALL_RELATIVE:
194         WriteString("pathtype", "studio_relative");
195         break;
196 
197     default:
198         WriteString("pathtype", "absolute");
199         break;
200     }
201     CloseTag("pathinfo");
202 }
203 
204 ///////////////////////////////////////////////////////////////////////////////
OpenTag(const char * tag,BOOL has_content)205 void xml_writer::OpenTag(const char *tag, BOOL has_content)
206 {
207     CString cTag(tag);
208     StringToFile(_T("<"));
209     StringToFile(cTag);
210 
211     if (has_content)
212     {
213         StringToFile(_T(">"));
214     }
215     else
216     {
217         StringToFile(_T(">\n"));
218     }
219 }
220 
221 ///////////////////////////////////////////////////////////////////////////////
OpenTag(const char * tag,CString & content)222 void xml_writer::OpenTag(const char *tag, CString &content)
223 {
224     CString cTag(tag);
225     StringToFile(_T("<"));
226     StringToFile(cTag);
227 
228     if (!content.IsEmpty())
229     {
230         cTag = " ";
231         cTag += content;
232         StringToFile(cTag);
233     }
234     StringToFile(_T(">\n"));
235 }
236 
237 ///////////////////////////////////////////////////////////////////////////////
CloseTag(const char * tag)238 void xml_writer::CloseTag(const char *tag)
239 {
240     CString cTag(tag);
241     StringToFile(_T("</"));
242     StringToFile(cTag);
243     StringToFile(_T(">\n"));
244 }
245 
246 ///////////////////////////////////////////////////////////////////////////////
StringToFile(LPCTSTR str)247 void xml_writer::StringToFile(LPCTSTR str)
248 {
249     if (mpFile && str)
250     {
251         // Convert Unicode string to UTF8 string:
252 
253         // The maximun UTF8 character is 6 bytes, calculate the maximun utf8 buffer size needed for the string.
254         int char_count = _tcslen(str) * 6 + 1;
255         char *utf8buf = new char[char_count];
256         strcpy_s(utf8buf, char_count, CT2A(str, CP_UTF8));
257         mpFile->Write(utf8buf, strlen(utf8buf));
258         delete[] utf8buf;
259     }
260 }
261