1 /* "CodeWorker":	a scripting language for parsing and generating text.
2 
3 Copyright (C) 1996-1997, 1999-2002 C�dric Lemaire
4 
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9 
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 Lesser General Public License for more details.
14 
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 
19 To contact the author: codeworker@free.fr
20 */
21 
22 #ifdef WIN32
23 #pragma warning (disable : 4786)
24 #endif
25 
26 #include "UtlString.h"
27 #include "UtlDate.h"
28 #include "UtlException.h"
29 #include "ScpStream.h"
30 #include "UtlXMLStream.h"
31 
32 namespace CodeWorker {
UtlXMLStream(const std::string & sFileName,const bool bModeRead)33 	UtlXMLStream::UtlXMLStream(const std::string& sFileName, const bool bModeRead) : _bOwnerOfFileStream(true), _pInputStream(NULL), _pOutputStream(NULL) {
34 		if (!bModeRead) {
35 			_pOutputStream = CodeWorker::openOutputFile(sFileName.c_str());
36 			if (_pOutputStream == NULL) throw UtlException("unable to open file \"" + sFileName + "\" for writing");
37 				getOutputStream() << "<?xml version=\"1.0\" ?>" << std::endl;
38 		}
39 		else {
40 			_pInputStream = ScpStream::openSTLInputFile(sFileName.c_str());
41 			if (_pInputStream == NULL) throw UtlException("unable to open file \"" + sFileName + "\" for reading");
42 
43 
44 			std::string sLineVersion;
45 			if ( ! readLine(getInputStream() , sLineVersion) ) {
46 				throw UtlException("No version line in XML file: " + sFileName );
47 			}
48 		}
49 
50 		_sFileName=sFileName;
51 
52 	}
53 
54 
UtlXMLStream(std::istream & myStream)55 	UtlXMLStream::UtlXMLStream(std::istream& myStream) : _pInputStream(&myStream), _bOwnerOfFileStream(false) {
56 		std::string sLineVersion;
57 		if ( ! readLine(getInputStream() , sLineVersion) ) {
58 			throw UtlException("No version line in XML" );
59 		}
60 	}
61 
62 
UtlXMLStream(std::iostream & myStream)63 	UtlXMLStream::UtlXMLStream(std::iostream& myStream) : _pInputStream(&myStream), _pOutputStream(&myStream), _bOwnerOfFileStream(false) {
64 		std::string sLineVersion;
65 		if ( ! readLine(getInputStream() , sLineVersion) ) {
66 			throw UtlException("No version line in XML" );
67 		}
68 	}
69 
70 
71 	// write part
~UtlXMLStream()72 	UtlXMLStream::~UtlXMLStream() {
73 		if (_bOwnerOfFileStream) {
74 			if (_pOutputStream != NULL) {
75 				((std::ofstream*) _pOutputStream)->close();
76 				delete _pOutputStream;
77 			}
78 
79 			if (_pInputStream != NULL) {
80 				((std::ifstream*) _pInputStream)->close();
81 				delete _pInputStream;
82 			}
83 		}
84 	}
85 
writeStartTag(const std::string & sTag)86 	void UtlXMLStream::writeStartTag(const std::string& sTag) {
87 		getOutputStream() << _sIndentation.c_str() << "<" << sTag.c_str() << ">" << std::endl;
88 		_sIndentation += "\t";
89 	}
90 
writeEndTag(const std::string & sTag)91 	void UtlXMLStream::writeEndTag(const std::string& sTag) {
92 		_sIndentation = _sIndentation.substr(1);
93 		getOutputStream() << _sIndentation.c_str() << "</" << sTag.c_str() << ">" << std::endl;
94 	}
95 
writeTag(const std::string & sTag)96 	void UtlXMLStream::writeTag(const std::string& sTag) {
97 		getOutputStream() << _sIndentation.c_str() << "<" << sTag.c_str() << "/>" << std::endl;
98 	}
99 
writeBeginningOfObject(const std::string & sTypeName)100 	void UtlXMLStream::writeBeginningOfObject(const std::string& sTypeName) {
101 		getOutputStream() << _sIndentation.c_str() << "<" << sTypeName.c_str();
102 		_sIndentation += "\t";
103 	}
104 
writeEndOfObject(const std::string & sTypeName)105 	void UtlXMLStream::writeEndOfObject(const std::string& sTypeName) {
106 		_sIndentation = _sIndentation.substr(1);
107 		getOutputStream() << _sIndentation.c_str() << "</" << sTypeName.c_str() << ">" << std::endl;
108 	}
109 
writeEndOfObject()110 	void UtlXMLStream::writeEndOfObject() {
111 		_sIndentation = _sIndentation.substr(1);
112 		getOutputStream() << " />" << std::endl;
113 	}
114 
normalizeAttributeName(const std::string & sName) const115 	std::string UtlXMLStream::normalizeAttributeName(const std::string& sName) const {
116 		char c = sName[0];
117 		if ((c < 'A') || (c > 'Z')) return sName;
118 		if (sName.size() >= 2) {
119 			char c1 = sName[1];
120 			if ((c1 >= 'A') && (c1 <= 'Z')) return sName;
121 		}
122 		std::string sNewName = sName;
123 		sNewName[0] = c + ' ';
124 		return sNewName;
125 	}
126 
writeAttribute(const std::string & sName,int iValue)127 	void UtlXMLStream::writeAttribute(const std::string& sName, int iValue) {
128 		std::string sNormalizedName = normalizeAttributeName(sName);
129 		getOutputStream() << " " << sNormalizedName.c_str() << "=\"" << iValue << "\"";
130 	}
131 
writeAttribute(const std::string & sName,long lValue)132 	void UtlXMLStream::writeAttribute(const std::string& sName, long lValue) {
133 		std::string sNormalizedName = normalizeAttributeName(sName);
134 		getOutputStream() << " " << sNormalizedName.c_str() << "=\"" << lValue << "\"";
135 	}
136 
writeAttribute(const std::string & sName,double dValue)137 	void UtlXMLStream::writeAttribute(const std::string& sName, double dValue) {
138 		std::string sNormalizedName = normalizeAttributeName(sName);
139 		char sNumber[300];
140 		sprintf(sNumber, "%f", dValue);
141 		getOutputStream() << " " << sNormalizedName.c_str() << "=\"" << sNumber << "\"";
142 	}
143 
writeAttribute(const std::string & sName,const std::string & sValue)144 	void UtlXMLStream::writeAttribute(const std::string& sName, const std::string& sValue) {
145 		std::string sNormalizedName = normalizeAttributeName(sName);
146 		std::string sXMLText = convertToXMLText(sValue);
147 		getOutputStream() << " " << sNormalizedName.c_str() << "=\"" << sXMLText.c_str() << "\"";
148 	}
149 
writeAttribute(const std::string & sName,bool bValue)150 	void UtlXMLStream::writeAttribute(const std::string& sName, bool bValue) {
151 		std::string sNormalizedName = normalizeAttributeName(sName);
152 		getOutputStream() << " " << sNormalizedName.c_str() << "=\"";
153 		if (bValue) getOutputStream() << "True";
154 		else getOutputStream() << "False";
155 		getOutputStream() << "\"";
156 	}
157 
writeAttribute(const std::string & sName,const UtlDate & myValue)158 	void UtlXMLStream::writeAttribute(const std::string& sName, const UtlDate& myValue) {
159 		std::string sNormalizedName = normalizeAttributeName(sName);
160 		std::string sDate = myValue.getString();
161 		if (!myValue.isNull()) {
162 			getOutputStream() << " " << sNormalizedName.c_str() << "=\"" << sDate.c_str() << "\"";
163 		}
164 	}
165 
writeEndOfAttributes()166 	void UtlXMLStream::writeEndOfAttributes() {
167 		getOutputStream() << ">" << std::endl;
168 	}
169 
writeArrayElement(int iValue)170 	void UtlXMLStream::writeArrayElement(int iValue) {
171 		getOutputStream() << _sIndentation.c_str() << "<int value =\"" << iValue << "\" />" << std::endl;
172 	}
173 
writeArrayElement(double dValue)174 	void UtlXMLStream::writeArrayElement(double dValue) {
175 		getOutputStream() << _sIndentation.c_str() << "<double value =\"" << dValue << "\" />" << std::endl;
176 	}
177 
writeArrayElement(const std::string & sValue)178 	void UtlXMLStream::writeArrayElement(const std::string& sValue) {
179 		getOutputStream() << _sIndentation.c_str() << "<string value =\"" << sValue.c_str() << "\" />" << std::endl;
180 	}
181 
writeArrayElement(bool bValue)182 	void UtlXMLStream::writeArrayElement(bool bValue) {
183 		getOutputStream() << _sIndentation.c_str() << "<bool value =\"";
184 		if (bValue) getOutputStream() << "True";
185 		else getOutputStream() << "False";
186 		getOutputStream() << "\"/>" << std::endl;
187 	}
188 
writeArrayElement(const UtlDate & myValue)189 	void UtlXMLStream::writeArrayElement(const UtlDate& myValue) {
190 		std::string sDate = myValue.getString();
191 		getOutputStream() << _sIndentation.c_str() << "<date value =\"" << sDate.c_str() << "\" />" << std::endl;
192 	}
193 
writeHashtableEntry(const std::string & sKey,const std::string & sValue)194 	void UtlXMLStream::writeHashtableEntry(const std::string& sKey, const std::string& sValue) {
195 		getOutputStream() << _sIndentation.c_str() << "<pair key=\"" << sKey.c_str() << "\" value =\"" << sValue.c_str() << "\" />" << std::endl;
196 	}
197 
writeHashtableEntry(const std::string & sKey,double dValue)198 	void UtlXMLStream::writeHashtableEntry(const std::string& sKey, double dValue) {
199 		getOutputStream() << _sIndentation.c_str() << "<pair key=\"" << sKey.c_str() << "\" value =\"" << dValue << "\" />" << std::endl;
200 	}
201 
writeHashtableEntry(const std::string & sKey,const std::vector<double> & listOfValues)202 	void UtlXMLStream::writeHashtableEntry(const std::string& sKey, const std::vector<double>& listOfValues) {
203 		getOutputStream() << _sIndentation.c_str() << "<pair key=\"" << sKey.c_str() << "\" >" << std::endl;
204 		_sIndentation += "\t";
205 		for (std::vector<double>::const_iterator i = listOfValues.begin(); i != listOfValues.end(); i++) {
206 			getOutputStream() << _sIndentation.c_str() << "<double value=\"" << (*i) << "\" >" << std::endl;
207 		}
208 		_sIndentation = _sIndentation.substr(1);
209 		getOutputStream() << _sIndentation.c_str() << "</pair>" << std::endl;
210 	}
211 
writeHashtableEntry(const std::string & sKey,const std::vector<std::string> & listOfValues)212 	void UtlXMLStream::writeHashtableEntry(const std::string& sKey, const std::vector<std::string>& listOfValues) {
213 		getOutputStream() << _sIndentation.c_str() << "<pair key=\"" << sKey.c_str() << "\" >" << std::endl;
214 		_sIndentation += "\t";
215 		for (std::vector<std::string>::const_iterator i = listOfValues.begin(); i != listOfValues.end(); i++) {
216 			getOutputStream() << _sIndentation.c_str() << "<string value=\"" << i->c_str() << "\" >" << std::endl;
217 		}
218 		_sIndentation = _sIndentation.substr(1);
219 		getOutputStream() << _sIndentation.c_str() << "</pair>" << std::endl;
220 	}
221 
writeHashtableEntry(int iKey,int iValue)222 	void UtlXMLStream::writeHashtableEntry(int iKey, int iValue) {
223 		getOutputStream() << _sIndentation.c_str() << "<pair key=\"" << iKey << "\" value =\"" << iValue << "\" />" << std::endl;
224 	}
225 
writeBeginningOfAggregation(const std::string & sOwnerClass,const std::string & sName)226 	void UtlXMLStream::writeBeginningOfAggregation(const std::string& sOwnerClass, const std::string& sName) {
227 		getOutputStream() << _sIndentation.c_str() << "<" << sOwnerClass.c_str() << "_" << sName.c_str() << ">" << std::endl;
228 		_sIndentation += "\t";
229 	}
230 
writeEndOfAggregation(const std::string & sOwnerClass,const std::string & sName)231 	void UtlXMLStream::writeEndOfAggregation(const std::string& sOwnerClass, const std::string& sName) {
232 		_sIndentation = _sIndentation.substr(1);
233 		getOutputStream() << _sIndentation.c_str() << "</" << sOwnerClass.c_str() << "_" << sName.c_str() << ">" << std::endl;
234 	}
235 
writeBeginningOfAssociation(const std::string & sOwnerClass,const std::string & sName)236 	void UtlXMLStream::writeBeginningOfAssociation(const std::string& sOwnerClass, const std::string& sName) {
237 		getOutputStream() << _sIndentation.c_str() << "<" << sOwnerClass.c_str() << "_" << sName.c_str() << ">" << std::endl;
238 		_sIndentation += "\t";
239 	}
240 
writeEndOfAssociation(const std::string & sOwnerClass,const std::string & sName)241 	void UtlXMLStream::writeEndOfAssociation(const std::string& sOwnerClass, const std::string& sName) {
242 		_sIndentation = _sIndentation.substr(1);
243 		getOutputStream() << _sIndentation.c_str() << "</" << sOwnerClass.c_str() << "_" << sName.c_str() << ">" << std::endl;
244 	}
245 
writeObjectReference(const std::string & sTypeName,const std::string &,const std::string & sIdentifier)246 	void UtlXMLStream::writeObjectReference(const std::string& sTypeName, const std::string& /*sIDAttrName*/, const std::string& sIdentifier) {
247 		getOutputStream() << _sIndentation.c_str() << "<reference type=\"" << sTypeName.c_str() << "\" ID=\"" << sIdentifier.c_str() << "\" />" << std::endl;
248 	}
249 
convertToXMLText(const std::string & sText)250 	std::string UtlXMLStream::convertToXMLText(const std::string& sText) {
251 		std::string sResult;
252 		for (std::string::size_type i = 0; i < sText.size(); i++) {
253 			char a = sText[i];
254 			switch(a) {
255 				case '&': sResult += "&amp;";break;
256 				case '<': sResult += "&lt;";break;
257 				case '>': sResult += "&gt;";break;
258 				case '\"': sResult += "&quot;";break;
259 				default:
260 					sResult += a;
261 					break;
262 			}
263 		}
264 		return sResult;
265 	}
266 
267 
268 	// read part
readStartTag(std::string & sTag)269 	bool UtlXMLStream::readStartTag( std::string& sTag) {
270 		int iChar;
271 
272 		skipBlanks( getInputStream() );
273 
274 		iChar=readChar(  getInputStream() );
275 		if (iChar != '<')  {
276 			return false;
277 		}
278 
279 		if (!readWord(  getInputStream(), sTag ))
280 			return false;
281 
282 		iChar=readChar(  getInputStream() );
283 		if (iChar != '>')  {
284 			return false;
285 		}
286 
287 		return true;
288 	}
289 
readEndTag(std::string & sTag)290 	bool UtlXMLStream::readEndTag(std::string& sTag) {
291 		int iChar;
292 
293 		skipBlanks( getInputStream() );
294 
295 
296 		iChar=readChar(  getInputStream() );
297 		if (iChar != '<')  {
298 			return false;
299 		}
300 
301 		iChar=readChar(  getInputStream() );
302 		if (iChar != '/')  {
303 			return false;
304 		}
305 
306 		if (!readWord(  getInputStream(), sTag ))
307 			return false;
308 
309 		iChar=readChar(  getInputStream() );
310 		if (iChar != '>')  {
311 			return false;
312 		}
313 
314 		return true;
315 	}
316 
readTag(std::string & sTag)317 	bool UtlXMLStream::readTag(std::string& sTag) {
318 		int iChar;
319 
320 		skipBlanks( getInputStream() );
321 
322 		iChar=readChar(  getInputStream() );
323 		if (iChar != '<')  {
324 			return false;
325 		}
326 
327 		if (!readWord(  getInputStream(), sTag ))
328 			return false;
329 
330 		if (iChar != '/')  {
331 			return false;
332 		}
333 
334 		iChar=readChar(  getInputStream() );
335 		if (iChar != '>')  {
336 			return false;
337 		}
338 
339 		return true;
340 	}
341 
342 
343 
344 
readBeginningOfObject(std::string & sTypeName)345 	bool UtlXMLStream::readBeginningOfObject(std::string& sTypeName) {
346 
347 		int iChar;
348 
349 		skipBlanks( getInputStream() );
350 
351 		iChar=readChar(  getInputStream() );
352 		if (iChar != '<')  {
353 			return false;
354 		}
355 
356 		if (!readWord(  getInputStream(), sTypeName ))
357 			return false;
358 
359 		return true;
360 	}
361 
362 
readName(std::string & sName)363 	bool UtlXMLStream::readName(std::string& sName) {
364 		skipBlanks( getInputStream() );
365 
366 
367 		std::string sNonNormaliseName;
368 		if (!readWord(  getInputStream(), sNonNormaliseName ))
369 			return false;
370 
371 		sName = normalizeAttributeName(sNonNormaliseName);
372 
373 		return true;
374 	}
375 
readBeginningOfAttribute()376 	bool UtlXMLStream::readBeginningOfAttribute() {
377 		int iChar;
378 
379 		skipBlanks( getInputStream() );
380 
381 		iChar=readChar(  getInputStream() );
382 		if (iChar != '=')  {
383 			return false;
384 		}
385 
386 		iChar=readChar(  getInputStream() );
387 		if (iChar != '\"')  {
388 			return false;
389 		}
390 
391 		return true;
392 	}
393 
394 
395 
readEndOfAttribute()396 	bool UtlXMLStream::readEndOfAttribute() {
397 		int iChar;
398 		skipBlanks( getInputStream() );
399 		iChar=readChar(  getInputStream() );
400 		if (iChar != '\"')  {
401 			return false;
402 		}
403 
404 		return true;
405 	}
406 
407 
readEndOfObject(std::string & sTypeName)408 	bool UtlXMLStream::readEndOfObject( std::string& sTypeName) {
409 		int iChar;
410 		skipBlanks( getInputStream() );
411 		iChar=readChar(  getInputStream() );
412 		if (iChar != '<')  {
413 			return false;
414 		}
415 
416 		iChar=readChar(  getInputStream() );
417 		if (iChar != '/')  {
418 			return false;
419 		}
420 
421 		if (!readWord(  getInputStream(), sTypeName ))
422 			return false;
423 
424 		iChar=readChar(  getInputStream() );
425 		if (iChar != '>')  {
426 			return false;
427 		}
428 		return true;
429 	}
430 
readEndOfObject()431 	bool UtlXMLStream::readEndOfObject() {
432 
433 		int iChar;
434 		skipBlanks( getInputStream() );
435 		iChar=readChar(  getInputStream() );
436 		if (iChar != '/')  {
437 			return false;
438 		}
439 
440 		iChar=readChar(  getInputStream() );
441 		if (iChar != '>')  {
442 			return false;
443 		}
444 
445 		return true;
446 	}
447 
readAttribute(std::string & sName,int & iValue)448 	bool UtlXMLStream::readAttribute(std::string& sName, int& iValue) {
449 
450 		skipBlanks( getInputStream() );
451 		if (!readName(sName))
452 			return false;
453 
454 		if (!readBeginningOfAttribute())
455 			return false;
456 
457 		if (!readInt(  getInputStream() , iValue))
458 			return false;
459 
460 		if (!readEndOfAttribute())
461 			return false;
462 
463 		return true;
464 	}
465 
readAttribute(std::string & sName,long & lValue)466 	bool UtlXMLStream::readAttribute(std::string& sName, long& lValue) {
467 		skipBlanks( getInputStream() );
468 		if (!readName(sName))
469 			return false;
470 
471 		if (!readBeginningOfAttribute())
472 			return false;
473 
474 		if (!readLong(  getInputStream() , lValue))
475 			return false;
476 
477 		if (!readEndOfAttribute())
478 			return false;
479 
480 		return true;
481 	}
482 
readAttribute(std::string & sName,double & dValue)483 	bool UtlXMLStream::readAttribute(std::string& sName, double& dValue) {
484 		skipBlanks( getInputStream() );
485 		if (!readName(sName))
486 			return false;
487 
488 		if (!readBeginningOfAttribute())
489 			return false;
490 
491 		if (!readDouble(  getInputStream() , dValue))
492 			return false;
493 
494 		if (!readEndOfAttribute())
495 			return false;
496 
497 		return true;
498 	}
499 
readAttribute(std::string & sName,std::string & sValue)500 	bool UtlXMLStream::readAttribute(std::string& sName, std::string& sValue) {
501 		skipBlanks( getInputStream() );
502 
503 		if (!readName(sName))
504 			return false;
505 
506 
507 		// if (!readBeginningOfAttribute())
508 		//	return false;
509 
510 		// std::string sXMLText;
511 		// if (!readName( sXMLText))
512 		//	return false;
513 
514 		int iChar=readChar(  getInputStream() );
515 		if (iChar != '=')  {
516 			return false;
517 		}
518 
519 		std::string sXMLText;
520 		if (!readString( getInputStream(), sXMLText))
521 			return false;
522 
523 		sValue=convertXMLTextToClassicText( sXMLText );
524 
525 		// if (!readEndOfAttribute())
526 		//	return false;
527 
528 		return true;
529 	}
530 
readAttribute(std::string & sName,bool & bValue)531 	bool UtlXMLStream::readAttribute(std::string& sName, bool& bValue) {
532 
533 		skipBlanks( getInputStream() );
534 
535 		if (!readName(sName))
536 			return false;
537 
538 		if (!readBeginningOfAttribute())
539 			return false;
540 
541 		std::string sXMLText;
542 		if (!readString(  getInputStream() , sXMLText))
543 			return false;
544 
545 		if (stricmp(sXMLText.c_str(),"TRUE"))
546 			bValue=true;
547 		if (stricmp(sXMLText.c_str(),"FALSE"))
548 			bValue=false;
549 		else
550 			return false;
551 
552 		if (!readEndOfAttribute())
553 			return false;
554 
555 		return true;
556 	}
557 
readAttribute(std::string & sName,UtlDate & myValue)558 	bool UtlXMLStream::readAttribute(std::string& sName, UtlDate& myValue) {
559 
560 		skipBlanks( getInputStream() );
561 
562 		if (!readName(sName))
563 			return false;
564 
565 		if (!readBeginningOfAttribute())
566 			return false;
567 
568 		struct tm tmValue;
569 		if (!readDate(  getInputStream() , tmValue))
570 			return false;
571 		myValue=UtlDate( tmValue.tm_year, tmValue.tm_mon, tmValue.tm_mday, 0, 0, 0);
572 
573 
574 		if (!readEndOfAttribute())
575 			return false;
576 
577 		return true;
578 	}
579 
readEndOfAttributes()580 	bool UtlXMLStream::readEndOfAttributes() {
581 		int iChar;
582 		skipBlanks( getInputStream() );
583 		iChar=readChar(  getInputStream() );
584 		if (iChar != '>')  {
585 			return false;
586 		}
587 
588 		return true;
589 	}
590 
readArrayElement(int & iValue)591 	bool UtlXMLStream::readArrayElement(int& iValue) {
592 		skipBlanks( getInputStream() );
593 		if (!readBeginOfArrayElement("int"))
594 			return false;
595 
596 		if (!readInt(  getInputStream() , iValue))
597 			return false;
598 
599 		if (!readEndOfArrayElement())
600 			return false;
601 
602 		return true;
603 	}
604 
readArrayElement(double & dValue)605 	bool UtlXMLStream::readArrayElement(double& dValue) {
606 
607 		skipBlanks( getInputStream() );
608 		if (!readBeginOfArrayElement("double"))
609 			return false;
610 
611 		if (!readDouble(  getInputStream() , dValue))
612 			return false;
613 
614 		if (!readEndOfArrayElement())
615 			return false;
616 
617 		return true;
618 	}
619 
readArrayElement(std::string & sValue)620 	bool UtlXMLStream::readArrayElement(std::string& sValue) {
621 
622 		skipBlanks( getInputStream() );
623 
624 		if (!readBeginOfArrayElement("string"))
625 			return false;
626 
627 		std::string sXMLText;
628 		if (!readString(  getInputStream() , sXMLText))
629 			return false;
630 		sValue=convertXMLTextToClassicText( sXMLText );
631 
632 		if (!readEndOfArrayElement())
633 			return false;
634 
635 		return true;
636 	}
637 
readArrayElement(bool & bValue)638 	bool UtlXMLStream::readArrayElement(bool& bValue) {
639 
640 		skipBlanks( getInputStream() );
641 
642 		if (!readBeginOfArrayElement("bool"))
643 			return false;
644 
645 		std::string sXMLText;
646 		if (!readString(  getInputStream() , sXMLText))
647 			return false;
648 
649 		if (stricmp(sXMLText.c_str(),"TRUE"))
650 			bValue=true;
651 		if (stricmp(sXMLText.c_str(),"FALSE"))
652 			bValue=false;
653 		else
654 			return false;
655 
656 		if (!readEndOfArrayElement())
657 			return false;
658 
659 		return true;
660 	}
661 
readArrayElement(UtlDate & myValue)662 	bool UtlXMLStream::readArrayElement(UtlDate& myValue) {
663 
664 		skipBlanks( getInputStream() );
665 		if (!readBeginOfArrayElement("date"))
666 			return false;
667 
668 		struct tm tmValue;
669 		if (!readDate(  getInputStream() , tmValue))
670 			return false;
671 		myValue=UtlDate( tmValue.tm_year, tmValue.tm_mon, tmValue.tm_mday, 0, 0, 0);
672 
673 		if (!readEndOfArrayElement())
674 			return false;
675 		return true;
676 	}
677 
678 
readKeyOfHashTable(std::string & sKey)679 	bool UtlXMLStream::readKeyOfHashTable(std::string& sKey) {
680 
681 		int iChar;
682 		skipBlanks( getInputStream() );
683 
684 		iChar=readChar(  getInputStream() );
685 		if (iChar != '<')  {
686 			return false;
687 		}
688 
689 		std::string sTrash;
690 		if (!readString( getInputStream() , sTrash))
691 			return false;
692 		if (strcmp(sTrash.c_str(),"pair"))
693 			return false;
694 
695 		std::string sKeyTag;
696 		if (!readAttribute( sKeyTag , sKey))
697 			return false;
698 
699 		if (strcmp(sKeyTag.c_str(),"key"))
700 			return false;
701 
702 		return true;
703 	}
704 
705 
readEndOfHashTable()706 	bool UtlXMLStream::readEndOfHashTable() {
707 
708 		int iChar;
709 
710 		skipBlanks( getInputStream() );
711 
712 		iChar=readChar(  getInputStream() );
713 		if (iChar != '/')  {
714 			return false;
715 		}
716 
717 		iChar=readChar(  getInputStream() );
718 		if (iChar != '>')  {
719 			return false;
720 		}
721 
722 		return true;
723 	}
724 
725 
726 
readHashtableEntry(std::string & sKey,std::string & sValue)727 	bool UtlXMLStream::readHashtableEntry(std::string& sKey, std::string& sValue) {
728 		int iChar;
729 
730 		skipBlanks( getInputStream() );
731 		if (!readKeyOfHashTable(sKey))
732 			return false;
733 
734 		iChar=readChar(  getInputStream() );
735 		if (iChar != ' ')  {
736 			return false;
737 		}
738 
739 		std::string sValueTag;
740 		if (!readAttribute(  sValueTag , sValue))
741 			return false;
742 
743 		if (!readEndOfHashTable())
744 			return false;
745 
746 		return true;
747 	}
748 
749 
readBeginOfArrayElement(std::string sType)750 	bool UtlXMLStream::readBeginOfArrayElement(std::string sType) {
751 
752 		int iChar;
753 		skipBlanks( getInputStream() );
754 		iChar=readChar(  getInputStream() );
755 		if (iChar != '<')  {
756 			return false;
757 		}
758 
759 		std::string sReadType;
760 		if (!readString( getInputStream(), sReadType))
761 		if (sReadType!=sType)
762 				return false;
763 
764 		std::string sValue;
765 		if (!readString( getInputStream(), sValue))
766 			return false;
767 
768 		iChar=readChar(  getInputStream() );
769 		if (iChar != ' ')  {
770 			return false;
771 		}
772 
773 		if (strcmp(sValue.c_str(),"value") )
774 			return false;
775 
776 		return true;
777 	}
778 
readEndOfArrayElement()779 	bool UtlXMLStream::readEndOfArrayElement() {
780 		int iChar;
781 
782 
783 		skipBlanks( getInputStream() );
784 		iChar=readChar(  getInputStream() );
785 		if (iChar != '/')  {
786 			return false;
787 		}
788 
789 		iChar=readChar(  getInputStream() );
790 		if (iChar != '>')  {
791 			return false;
792 		}
793 		return true;
794 	}
795 
796 
readHashtableEntry(std::string & sKey,double & dValue)797 	bool UtlXMLStream::readHashtableEntry(std::string& sKey, double& dValue) {
798 		int iChar;
799 		skipBlanks( getInputStream() );
800 		if (!readKeyOfHashTable(sKey))
801 			return false;
802 
803 		iChar=readChar(  getInputStream() );
804 		if (iChar != '>')  {
805 			return false;
806 		}
807 
808 		std::string sValueTag;
809 		if (!readAttribute(  sValueTag , dValue))
810 			return false;
811 
812 		if (!readEndOfHashTable())
813 			return false;
814 
815 		return true;
816 	}
817 
readHashtableEntry(std::string & sKey,std::vector<double> & listOfValues)818 	bool UtlXMLStream::readHashtableEntry(std::string& sKey, std::vector<double>& listOfValues) {
819 		int iChar;
820 		skipBlanks( getInputStream() );
821 		if (!readKeyOfHashTable(sKey))
822 			return false;
823 
824 		iChar=readChar(  getInputStream() );
825 		if (iChar != ' ')  {
826 			return false;
827 		}
828 
829 		iChar=readChar(  getInputStream() );
830 		if (iChar != '>')  {
831 			return false;
832 		}
833 
834 		bool bAtLeastOne=false;
835 		bool bContinue=true;
836 
837 		listOfValues.clear();
838 
839 		while (bContinue) {
840 			double dValue;
841 
842 			int iPos = getInputStream().tellg();
843 
844 			bContinue=readArrayElement(dValue);
845 			if (bContinue) {
846 				listOfValues.push_back(dValue);
847 				bAtLeastOne=true;
848 			}
849 			else {
850 				getInputStream().seekg(iPos);
851 			}
852 		}
853 
854 		if (!bAtLeastOne) {
855 			return false;
856 		}
857 
858 		if (!readEndOfHashTable())
859 			return false;
860 
861 		return true;
862 	}
863 
readHashtableEntry(std::string & sKey,std::vector<std::string> & listOfValues)864 	bool UtlXMLStream::readHashtableEntry(std::string& sKey, std::vector<std::string>& listOfValues) {
865 		int iChar;
866 		skipBlanks( getInputStream() );
867 		if (!readKeyOfHashTable(sKey))
868 			return false;
869 
870 		iChar=readChar(  getInputStream() );
871 		if (iChar != ' ')  {
872 			return false;
873 		}
874 
875 		iChar=readChar(  getInputStream() );
876 		if (iChar != '>')  {
877 			return false;
878 		}
879 
880 		bool bAtLeastOne=false;
881 		bool bContinue=true;
882 
883 		listOfValues.clear();
884 
885 		while (bContinue) {
886 			int iPos = getInputStream().tellg();
887 			std::string sValue;
888 
889 			bContinue=readArrayElement(sValue);
890 			if (bContinue) {
891 				listOfValues.push_back(sValue);
892 				bAtLeastOne=true;
893 			}
894 			else {
895 				getInputStream().seekg(iPos);
896 			}
897 		}
898 
899 		if (!bAtLeastOne) {
900 			return false;
901 		}
902 
903 		if (!readEndOfHashTable())
904 			return false;
905 
906 		return true;
907 	}
908 
readBeginningOfAggregation(std::string & sOwnerClass,std::string & sName)909 	bool UtlXMLStream::readBeginningOfAggregation(std::string& sOwnerClass, std::string& sName) {
910 		return readBeginningOfAssociation( sOwnerClass, sName);
911 	}
912 
readEndOfAggregation(std::string & sOwnerClass,std::string & sName)913 	bool UtlXMLStream::readEndOfAggregation(std::string& sOwnerClass, std::string& sName) {
914 		return readEndOfAssociation( sOwnerClass, sName);
915 	}
916 
917 
readBeginningOfAssociation(std::string & sOwnerClass,std::string & sName)918 	bool UtlXMLStream::readBeginningOfAssociation(std::string& sOwnerClass, std::string& sName) {
919 		int iChar;
920 		skipBlanks( getInputStream() );
921 		iChar=readChar(  getInputStream() );
922 		if (iChar != '<')  {
923 			return false;
924 		}
925 
926 		// Read a string, search '_' and split the string in two
927 		std::string sCompletWord,sDebut,sFin;
928 		if (!readWord(  getInputStream(), sCompletWord ))
929 			return false;
930 
931 		if (!splitString( sCompletWord, '_', sOwnerClass, sName))
932 			return false;
933 
934 		iChar=readChar(  getInputStream() );
935 		if (iChar != '>')  {
936 			return false;
937 		}
938 
939 		return true;
940 	}
941 
readEndOfAssociation(std::string & sOwnerClass,std::string & sName)942 	bool UtlXMLStream::readEndOfAssociation(std::string& sOwnerClass, std::string& sName) {
943 
944 		int iChar;
945 		skipBlanks( getInputStream() );
946 		iChar=readChar(  getInputStream() );
947 		if (iChar != '<')  {
948 			return false;
949 		}
950 
951 		iChar=readChar(  getInputStream() );
952 		if (iChar != '/')  {
953 			return false;
954 		}
955 
956 		// Read a string, search '_' and split the string in two
957 		std::string sCompletWord,sDebut,sFin;
958 		if (!readWord(  getInputStream(), sCompletWord ))
959 			return false;
960 
961 		if (!splitString( sCompletWord, '_', sOwnerClass, sName))
962 			return false;
963 
964 		iChar=readChar(  getInputStream() );
965 		if (iChar != '>')  {
966 			return false;
967 		}
968 
969 		return true;
970 	}
971 
972 
readObjectReference(std::string & sTypeName,std::string & sIDAttrName,std::string & sIdentifier)973 	bool UtlXMLStream::readObjectReference(std::string& sTypeName, std::string& sIDAttrName, std::string& sIdentifier) {
974 
975 		int iChar;
976 		skipBlanks( getInputStream() );
977 		iChar=readChar(  getInputStream() );
978 		if (iChar != '<')  {
979 			return false;
980 		}
981 
982 		std::string sTrash;
983 		// reference
984 		if (!readString( getInputStream(), sTrash))
985 			return false;
986 		if (strcmp(sTrash.c_str(),"reference"))
987 			return false;
988 
989 		// type
990 		if (!readAttribute(sTrash, sTypeName))
991 			return false;
992 
993 		// ID
994 		if (!readAttribute( sIDAttrName, sIdentifier))
995 			return false;
996 
997 		iChar=readChar(  getInputStream() );
998 		if (iChar != '/')  {
999 			return false;
1000 		}
1001 
1002 		iChar=readChar(  getInputStream() );
1003 		if (iChar != '>')  {
1004 			return false;
1005 		}
1006 
1007 		return true;
1008 	}
1009 
convertXMLTextToClassicText(const std::string & sText)1010 	std::string UtlXMLStream::convertXMLTextToClassicText(const std::string& sText) {
1011 		std::string sResult,sResultInter;
1012 
1013 		for (std::string::size_type i = 0; i < sText.size(); i++) {
1014 			char a = sText[i];
1015 			switch(a) {
1016 				case '&': sResultInter += "&";break;
1017 				case 'a': sResultInter += "a";break;
1018 				case 'm': sResultInter += "m";break;
1019 				case 'p': sResultInter += "p";break;
1020 				case ';': if (!strcmp(sResultInter.c_str(),"&amp")) {
1021 							sResult += "&";
1022 							sResultInter = "";
1023 						}
1024 
1025 							break;
1026 				default:
1027 					if (!sResultInter.empty()) {
1028 						sResult+=sResultInter;
1029 						sResultInter = "";
1030 					}
1031 
1032 					sResult += a;
1033 					break;
1034 			}
1035 		}
1036 
1037 		if (!sResultInter.empty()) {
1038 			sResult+=sResultInter;
1039 			sResultInter = "";
1040 		}
1041 
1042 		return sResult;
1043 	}
1044 }
1045