0024284: Some trivial warnings produced by ICC 14
[occt.git] / src / LDOM / LDOM_XmlWriter.cxx
CommitLineData
b311480e 1// Created on: 2001-06-28
2// Created by: Alexander GRIGORIEV
3// Copyright (c) 2001-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
7fd59977 20
21
22#include <LDOM_XmlWriter.hxx>
23#include <LDOM_Document.hxx>
24#include <LDOM_CharReference.hxx>
25
26#define chOpenAngle '<'
27#define chCloseAngle '>'
28#define chOpenSquare '['
29#define chCloseSquare ']'
30#define chQuestion '?'
31#define chForwardSlash '/'
32#define chLF '\n'
33#define chNull '\0'
34#define chEqual '='
35#define chDash '-'
36#define chBang '!'
37#define chSpace ' '
38#define chDoubleQuote '\"'
39#define chZero '0'
40#define chOne '1'
41#define chTwo '2'
42#define chThree '3'
43#define chFour '4'
44#define chFive '5'
45#define chSix '6'
46#define chSeven '7'
47#define chEight '8'
48#define chNine '9'
49#define chLatin_a 'a'
50#define chLatin_b 'b'
51#define chLatin_c 'c'
52#define chLatin_d 'd'
53#define chLatin_e 'e'
54#define chLatin_f 'f'
55#define chLatin_g 'g'
56#define chLatin_h 'h'
57#define chLatin_i 'i'
58#define chLatin_j 'j'
59#define chLatin_k 'k'
60#define chLatin_l 'l'
61#define chLatin_m 'm'
62#define chLatin_n 'n'
63#define chLatin_o 'o'
64#define chLatin_p 'p'
65#define chLatin_q 'q'
66#define chLatin_r 'r'
67#define chLatin_s 's'
68#define chLatin_t 't'
69#define chLatin_u 'u'
70#define chLatin_v 'v'
71#define chLatin_w 'w'
72#define chLatin_x 'x'
73#define chLatin_y 'y'
74#define chLatin_z 'z'
75#define chLatin_A 'A'
76#define chLatin_B 'B'
77#define chLatin_C 'C'
78#define chLatin_D 'D'
79#define chLatin_E 'E'
80#define chLatin_F 'F'
81#define chLatin_G 'G'
82#define chLatin_H 'H'
83#define chLatin_I 'I'
84#define chLatin_J 'J'
85#define chLatin_K 'K'
86#define chLatin_L 'L'
87#define chLatin_M 'M'
88#define chLatin_N 'N'
89#define chLatin_O 'O'
90#define chLatin_P 'P'
91#define chLatin_Q 'Q'
92#define chLatin_R 'R'
93#define chLatin_S 'S'
94#define chLatin_T 'T'
95#define chLatin_U 'U'
96#define chLatin_V 'V'
97#define chLatin_W 'W'
98#define chLatin_X 'X'
99#define chLatin_Y 'Y'
100#define chLatin_Z 'Z'
101
102static const LXMLCh gEndElement[] = { chOpenAngle, chForwardSlash, chNull };
103static const LXMLCh gEndElement1[]= { chForwardSlash, chNull };
f24125b9 104//static const LXMLCh gEndPI[] = { chQuestion, chCloseAngle, chNull };
105//static const LXMLCh gStartPI[] = { chOpenAngle, chQuestion, chNull };
7fd59977 106static const LXMLCh gXMLDecl1[] =
107{ chOpenAngle, chQuestion, chLatin_x, chLatin_m, chLatin_l
108 , chSpace, chLatin_v, chLatin_e, chLatin_r, chLatin_s, chLatin_i
109 , chLatin_o, chLatin_n, chEqual, chDoubleQuote, chNull
110};
111static const LXMLCh gXMLDecl2[] =
112{ chDoubleQuote, chSpace, chLatin_e, chLatin_n, chLatin_c
113 , chLatin_o, chLatin_d, chLatin_i, chLatin_n, chLatin_g, chEqual
114 , chDoubleQuote, chNull
115};
f24125b9 116/*
7fd59977 117static const LXMLCh gXMLDecl3[] =
118{ chDoubleQuote, chSpace, chLatin_s, chLatin_t, chLatin_a
119 , chLatin_n, chLatin_d, chLatin_a, chLatin_l, chLatin_o
120 , chLatin_n, chLatin_e, chEqual, chDoubleQuote, chNull
121};
f24125b9 122*/
7fd59977 123static const LXMLCh gXMLDecl4[] =
124{ chDoubleQuote, chQuestion, chCloseAngle
125 , chLF, chNull
126};
127static const LXMLCh gStartCDATA[] =
128{ chOpenAngle, chBang, chOpenSquare, chLatin_C, chLatin_D,
129 chLatin_A, chLatin_T, chLatin_A, chOpenSquare, chNull
130};
131static const LXMLCh gEndCDATA[] =
132{ chCloseSquare, chCloseSquare, chCloseAngle, chNull };
133static const LXMLCh gStartComment[] =
134{ chOpenAngle, chBang, chDash, chDash, chNull };
135static const LXMLCh gEndComment[] =
136{ chDash, chDash, chCloseAngle, chNull };
f24125b9 137/*
7fd59977 138static const LXMLCh gStartDoctype[] =
139{ chOpenAngle, chBang, chLatin_D, chLatin_O, chLatin_C, chLatin_T,
140 chLatin_Y, chLatin_P, chLatin_E, chSpace, chNull
141};
142static const LXMLCh gPublic[] =
143{ chLatin_P, chLatin_U, chLatin_B, chLatin_L, chLatin_I,
144 chLatin_C, chSpace, chDoubleQuote, chNull
145};
146static const LXMLCh gSystem[] =
147{ chLatin_S, chLatin_Y, chLatin_S, chLatin_T, chLatin_E,
148 chLatin_M, chSpace, chDoubleQuote, chNull
149};
150static const LXMLCh gStartEntity[] =
151{ chOpenAngle, chBang, chLatin_E, chLatin_N, chLatin_T, chLatin_I,
152 chLatin_T, chLatin_Y, chSpace, chNull
153};
154static const LXMLCh gNotation[] =
155{ chLatin_N, chLatin_D, chLatin_A, chLatin_T, chLatin_A,
156 chSpace, chDoubleQuote, chNull
157};
f24125b9 158*/
7fd59977 159
160static LXMLCh * getEncodingName (const LXMLCh * theEncodingName)
161{
162 const LXMLCh * anEncoding = theEncodingName;
163 if (theEncodingName == NULL)
164 {
165// anEncoding = // US-ASCII
166// { chLatin_U, chLatin_S, chDash, chLatin_A, chLatin_S, chLatin_C, chLatin_I,
167// chLatin_I, chNull };
168 static const LXMLCh anUTFEncoding [] = // UTF-8
169 { chLatin_U, chLatin_T, chLatin_F, chDash, chEight, chNull };
170 anEncoding = anUTFEncoding;
171 }
172 Standard_Integer aLen = 0;
173 while (anEncoding[aLen++] != chNull);
174 LXMLCh * aResult = new LXMLCh [aLen];
175 memcpy (aResult, anEncoding, aLen * sizeof (LXMLCh));
176 return aResult;
177}
178
179//=======================================================================
180//function : LH3D_LXMLWriter()
181//purpose : Constructor
182//=======================================================================
183LDOM_XmlWriter::LDOM_XmlWriter (FILE * aFile,
184 const LXMLCh * theEncoding)
185 : myFile (aFile),
186 myEncodingName (::getEncodingName (theEncoding)),
187 myIndent (0),
188 myCurIndent (0),
189 myABuffer (NULL),
190 myABufferLen (0)
191{}
192
193//=======================================================================
194//function : ~LDOM_XmlWriter
195//purpose : Destructor
196//=======================================================================
197
198LDOM_XmlWriter::~LDOM_XmlWriter ()
199{
200 delete [] myEncodingName;
201 if (myABuffer != NULL) delete [] myABuffer;
202}
203
204//=======================================================================
205//function : operator <<
206//purpose :
207//=======================================================================
208
209LDOM_XmlWriter& LDOM_XmlWriter::operator << (const LDOM_Document& aDoc)
210{
211 const char * anXMLversion = "1.0";
212 * this << gXMLDecl1 << anXMLversion
213 << gXMLDecl2 << myEncodingName << gXMLDecl4;
214
215 return (* this << aDoc.getDocumentElement());
216}
217
218//=======================================================================
219//function : operator <<
220//purpose : Stream out an LDOMString
221//=======================================================================
222
223inline LDOM_XmlWriter& LDOM_XmlWriter::operator <<
224 (const LDOMBasicString& aString)
225{
226 switch (aString.Type()) {
227 case LDOMBasicString::LDOM_Integer:
228 {
229 Standard_Integer aValue;
230 aString.GetInteger (aValue);
231 fprintf (myFile, "%d", aValue);
232 break;
233 }
234 case LDOMBasicString::LDOM_AsciiHashed: // attr names and element tags
235 case LDOMBasicString::LDOM_AsciiDocClear:
236 {
237 const char * str = aString.GetString();
238 if (str) {
60be1f9b 239 const Standard_Size aLen = strlen (str);
7fd59977 240 if (aLen > 0) fwrite (str, aLen, 1, myFile);
241 }
242 }
243 break;
244 case LDOMBasicString::LDOM_AsciiFree:
245 case LDOMBasicString::LDOM_AsciiDoc:
246 {
247 const char * str = aString.GetString();
248 if (str) {
249 Standard_Integer aLen;
250 char * encStr = LDOM_CharReference::Encode(str, aLen, Standard_False);
251 if (aLen > 0) fwrite (encStr, aLen, 1, myFile);
252 if (encStr != str) delete [] encStr;
253 }
254 }
255 default: ;
256 }
257 return * this;
258}
259
260//=======================================================================
261//function : operator<<()
262//purpose : Stream out a char *.
263//=======================================================================
264inline LDOM_XmlWriter& LDOM_XmlWriter::operator << (const LXMLCh * aString)
265{
60be1f9b 266 Standard_Size aLength = strlen (aString);
7fd59977 267 if (aLength > 0) fwrite ((void *) aString, aLength, 1, myFile);
268 return * this;
269}
270
271//=======================================================================
272//function : operator<<()
273//purpose : Stream out a character.
274//=======================================================================
275inline LDOM_XmlWriter& LDOM_XmlWriter::operator << (const LXMLCh aChar)
276{
277 fputc (aChar, myFile);
278 return * this;
279}
280
281//=======================================================================
282//function : WriteAttribute()
283//purpose : Stream out an XML attribute.
284//=======================================================================
285void LDOM_XmlWriter::WriteAttribute (const LDOM_Node& theAtt)
286{
287 int aLength;
288 const char * aName = theAtt.getNodeName().GetString();
289 const LDOMString aValueStr = theAtt.getNodeValue();
290
291 // Integer attribute value
292 if (aValueStr.Type() == LDOMBasicString::LDOM_Integer) {
293 Standard_Integer anIntValue;
294 aValueStr.GetInteger (anIntValue);
60be1f9b 295 aLength = (Standard_Integer) (20 + strlen (aName));
7fd59977 296 if (aLength > myABufferLen) {
297 if (myABuffer != NULL) delete [] myABuffer;
298 myABuffer = new char [aLength+1];
299 myABufferLen = aLength;
300 }
301 sprintf (myABuffer, "%c%s%c%c%d%c", chSpace, aName,
302 chEqual, chDoubleQuote, anIntValue, chDoubleQuote);
60be1f9b 303 aLength = (Standard_Integer) strlen (myABuffer);
7fd59977 304
305 // String attribute value
306 } else {
307 const char * aValue = aValueStr.GetString();
308 char * encStr;
309 if (aValueStr.Type() == LDOMBasicString::LDOM_AsciiDocClear) {
310 encStr = (char *) aValue;
60be1f9b 311 aLength = (Standard_Integer) (4 + strlen (aValue) + strlen (aName));
7fd59977 312 } else {
313 encStr = LDOM_CharReference::Encode (aValue, aLength, Standard_True);
60be1f9b 314 aLength += (Standard_Integer) (4 + strlen (aName));
7fd59977 315 }
316 if (aLength > myABufferLen) {
317 if (myABuffer != NULL) delete [] myABuffer;
318 myABuffer = new char [aLength+1];
319 myABufferLen = aLength;
320 }
321 sprintf (myABuffer, "%c%s%c%c%s%c", chSpace, aName,
322 chEqual, chDoubleQuote, encStr, chDoubleQuote);
323 if (encStr != aValue) delete [] encStr;
324 }
325 fwrite ((void *) myABuffer, aLength, 1, myFile);
326}
327
328//=======================================================================
329//function : operator<<()
330//purpose : Stream out a DOM node, and, recursively, all of its children.
331// This function is the heart of writing a DOM tree out as XML source.
332// Give it a document node and it will do the whole thing.
333//=======================================================================
334LDOM_XmlWriter& LDOM_XmlWriter::operator<< (const LDOM_Node& theNodeToWrite)
335{
336 // Get the name and value out for convenience
337 LDOMString aNodeName = theNodeToWrite.getNodeName();
338 LDOMString aNodeValue = theNodeToWrite.getNodeValue();
339// unsigned long dwLent = aNodeValue.length();
340
341 switch (theNodeToWrite.getNodeType())
342 {
343 case LDOM_Node::TEXT_NODE :
344 * this << aNodeValue;
345 break;
346 case LDOM_Node::ELEMENT_NODE :
347 {
348 const int aMaxNSpaces = 40;
349 static LXMLCh aSpaces [] = {
350 chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace,
351 chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace,
352 chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace,
353 chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace,
354 chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace,
355 chOpenAngle, chNull };
356 const LXMLCh * anIndentString = &aSpaces [aMaxNSpaces - myCurIndent];
357 if (anIndentString < &aSpaces[0]) anIndentString = &aSpaces[0];
358
359 // Output the element start tag.
360 * this << anIndentString << aNodeName.GetString();
361
362 // Output any attributes of this element
363 const LDOM_Element& anElemToWrite = (const LDOM_Element&) theNodeToWrite;
364 LDOM_NodeList aListAtt = anElemToWrite.GetAttributesList ();
365 Standard_Integer aListInd = aListAtt.getLength();
366 while (aListInd--) {
367 LDOM_Node aChild = aListAtt.item (aListInd);
368 WriteAttribute (aChild);
369 }
370
371 // Test for the presence of children
372 LDOM_Node aChild = theNodeToWrite.getFirstChild();
373 if (aChild != 0)
374 {
375 // There are children. Close start-tag, and output children.
376 * this << chCloseAngle;
377 if (aChild.getNodeType() == LDOM_Node::ELEMENT_NODE && myIndent > 0)
378 * this << chLF;
379 Standard_Boolean isChildElem = Standard_False;
380 while( aChild != 0)
381 {
382 isChildElem = (aChild.getNodeType() == LDOM_Node::ELEMENT_NODE);
383 if (isChildElem) myCurIndent += myIndent;
384 *this << aChild;
385 if (isChildElem) myCurIndent -= myIndent;
386 do aChild = aChild.getNextSibling();
387 while (aChild.getNodeType() == LDOM_Node::ATTRIBUTE_NODE);
388 }
389 // Done with children. Output the end tag.
390 //
391 if (isChildElem)
392 * this << anIndentString
393 << gEndElement1 << aNodeName.GetString() << chCloseAngle;
394 else
395 * this << gEndElement << aNodeName.GetString() << chCloseAngle;
396 }
397 else
398 {
399 // There were no children. Output the short form close of
400 // the element start tag, making it an empty-element tag.
401 * this << chForwardSlash << chCloseAngle;
402 }
403 if (myIndent > 0)
404 * this << chLF;
405 break;
406 }
407 case LDOM_Node::CDATA_SECTION_NODE:
408 {
409 * this << gStartCDATA << aNodeValue << gEndCDATA;
410 break;
411 }
412 case LDOM_Node::COMMENT_NODE:
413 {
414 * this << gStartComment << aNodeValue << gEndComment;
415 break;
416 }
417 default:
418#ifndef WNT
419 cerr << "Unrecognized node type = "
420 << (long)theNodeToWrite.getNodeType() << endl
421#endif
422 ; }
423 return *this;
424}