CGEM BOSS 6.6.5.g
BESIII Offline Software System
Loading...
Searching...
No Matches
Dom.cxx
Go to the documentation of this file.
1// $Header: /bes/bes/BossCvs/Calibration/xmlBase/src/Dom.cxx,v 1.2 2014/04/18 02:24:47 maqm Exp $
2// Author: J. Bogart
3//
4// Implementation of xmlBase::Dom, a convenient place to put static
5// utilities which enhance DOM api.
6
7#include "xmlBase/Dom.h"
8#include <xercesc/dom/DOMElement.hpp>
9#include <xercesc/dom/DOMNodeList.hpp>
10#include <xercesc/dom/DOMCharacterData.hpp>
11#include <xercesc/dom/DOMNamedNodeMap.hpp>
12#include <xercesc/dom/DOMDocument.hpp>
13#include <xercesc/dom/DOMException.hpp>
14#include <xercesc/dom/DOMTreeWalker.hpp>
15#include <xercesc/util/TransService.hpp>
16#include <xercesc/util/XMLString.hpp>
17#include <xercesc/util/PlatformUtils.hpp>
18
19#include "facilities/Util.h"
20//#ifdef DEFECT_NO_STRINGSTREAM
21//#include <strstream>
22//#else
23#include <sstream>
24//#endif
25
26
27#include <string>
28#include <cstring>
29#include <cassert>
30
31namespace {
32 XERCES_CPP_NAMESPACE_USE
33
34 DOMTreeWalker* makeWalker(const DOMNode* node) {
35 if (!node) return 0;
36 DOMDocument* doc = node->getOwnerDocument();
37 unsigned long whatToShow = DOMNodeFilter::SHOW_ELEMENT;
38
39 bool expand = true;
40 DOMNode* casted = const_cast<DOMNode*>(node);
41 // Show only elements; Expand entity references
42 DOMTreeWalker* walk = doc->createTreeWalker(casted, whatToShow, 0, expand);
43 return walk;
44 }
45}
46
47
48namespace xmlBase {
49 XERCES_CPP_NAMESPACE_USE
50
51 XMLLCPTranscoder* Dom::transcoder = 0;
52 char* Dom::transBuf = 0;
53
54 unsigned int Dom::transBufSize = 1000;
55 XMLCh* Dom::xmlchBuf = 0;
56
57 unsigned int Dom::xmlchBufSize = 200;
58 XMLCh* Dom::xmlchStar = 0;
59
60 DOMElement* Dom::findFirstChildByName(const DOMElement* parent,
61 const char* const name) {
62
63 if (!xmlchStar) xmlchStar = XMLString::transcode("*");
64 if (!(parent)) {
65 throw NullNode("from xmlBase::Dom::findFirstChildByName. Null parent arg.");
66 }
67
68 XMLCh* xmlchName = XMLString::transcode(name);
69
70 DOMTreeWalker* walk = makeWalker(parent);
71 DOMElement* child = static_cast<DOMElement*>(walk->firstChild());
72 if (XMLString::equals(xmlchName, xmlchStar)) return child;
73
74 if (!child) return 0;
75 // otherwise cycle through children, looking for first with right tag name
76 while (! XMLString::equals(child->getNodeName(), xmlchName)) {
77 child = static_cast<DOMElement*>(walk->nextSibling());
78 if (!child) return 0;
79 }
80
81
82 XMLString::release(&xmlchName);
83
84 walk->release();
85 return child;
86 }
87
88 DOMElement* Dom::findFirstChildByName(const DOMElement* parent,
89 const std::string name) {
90 return findFirstChildByName(parent, name.c_str());
91 }
92
93
94 // Leave this alone for now. Entities are not likely to cause
95 // trouble here.
96 DOMElement* Dom::getSiblingElement(const DOMNode* child) {
97 if (!child) {
98 throw NullNode("from xmlBase::Dom::getSiblingElement. Null argument");
99 }
100
101 DOMNode* sib = child->getNextSibling();
102
103 while (sib) {
104 if (sib->getNodeType() == DOMNode::ELEMENT_NODE) {
105 DOMElement* eltSib = static_cast<DOMElement*> (sib);
106
107 return eltSib;
108 }
109 sib = sib->getNextSibling();
110 }
111
112 return 0;
113 }
114
115 DOMElement* Dom::getFirstChildElement(const DOMNode* parent) {
116 const DOMElement* elt = static_cast<const DOMElement*>(parent);
117 return findFirstChildByName(elt, "*");
118 }
119
120 DOMElement* Dom::getElementById(const DOMDocument* doc,
121 const std::string& id) {
122 XMLCh* idChars = XMLString::transcode(id.c_str());
123 DOMElement* elt = doc->getElementById(idChars);
124 XMLString::release(&idChars);
125 return elt;
126 }
127
128 std::string Dom::getNodeName(const DOMNode* node) {
129 if (!node) {
130 throw NullNode("Null node argument supplied to xmlBase::Dom::getNodeName");
131 }
132 const XMLCh* name = node->getNodeName();
133 if (!name) return std::string("");
134
135 char* chrName = XMLString::transcode(name);
136
137 std::string strName = std::string(chrName);
138 XMLString::release(&chrName);
139 return strName;
140 }
141
142 std::string Dom::getTagName(const DOMElement* elt) {
143 return Dom::getNodeName(elt);
144 }
145
146 bool Dom::checkTagName(const DOMElement* element,
147 const std::string& tagName) {
148 if (!element) {
149 throw NullNode("Null dom element argument to xmlBase::Dom::checkTagName");
150 }
151 if (tagName == std::string("*")) return true;
152 XMLCh* xmlchTagName = XMLString::transcode(tagName.c_str());
153 bool ret = XMLString::equals(xmlchTagName, element->getTagName());
154 XMLString::release(&xmlchTagName);
155 return ret;
156 }
157
158
159
160 void Dom::getChildrenByTagName(const DOMElement* parent,
161 const std::string& tagName,
162 std::vector<DOMElement*>& children,
163 bool clear) {
164 if (!parent) {
165 throw NullNode("from xmlBase::Dom::getChildrenByTagName. Null parent arg");
166 }
167 if (clear) children.clear();
168 DOMElement* child = getFirstChildElement(parent);
169 while (child != 0) {
170 if (checkTagName(child, tagName)) {
171 children.push_back(child);
172 }
173 child = getSiblingElement(child);
174 }
175 }
176
177
178 void Dom::getDescendantsByTagName(const DOMElement* parent,
179 const std::string& tagName,
180 std::vector<DOMElement*>& children,
181 bool clear) {
182 if (parent == 0) {
183 throw NullNode("from xmlBase::Dom::getChildrenByTagName. Null parent arg");
184 }
185 if (clear) children.clear();
186 XMLCh* xmlchTagName = XMLString::transcode(tagName.c_str());;
187 DOMNodeList* list =
188 parent->getElementsByTagName(xmlchTagName);
189 XMLString::release(&xmlchTagName);
190 unsigned int nItem = list->getLength();
191 for (unsigned int iItem = 0; iItem < nItem; iItem++) {
192 children.push_back(static_cast<DOMElement *>(list->item(iItem)));
193 }
194 }
195
196 void Dom::getAttributeNodeMap(const DOMNode* node,
197 std::map<std::string, DOMNode*>& atts,
198 bool clear) {
199
200 if (clear) atts.clear();
201 DOMNamedNodeMap* nodeMap = node->getAttributes();
202 unsigned int nAtts = nodeMap->getLength();
203
204 for (unsigned iAtt = 0; iAtt < nAtts; iAtt++) {
205 DOMNode* attNode = nodeMap->item(iAtt);
206 atts[xmlBase::Dom::getNodeName(attNode)] = attNode;
207 }
208 }
209
210 bool Dom::hasAttribute(const DOMNode* node, const char* attName) {
211 bool ret = false;
212 if (node == 0) return ret;
213 if (node->getNodeType() != DOMNode::ELEMENT_NODE ) return ret;
214
215 const DOMElement* elt = static_cast<const DOMElement*>(node);
216 XMLCh* xmlchAttName = XMLString::transcode(attName);
217 ret = (elt->getAttributeNode(xmlchAttName) != 0);
218 XMLString::release(&xmlchAttName);
219 return ret;
220 }
221
222 std::string Dom::getAttribute(const DOMElement* elt, const char* attName) {
223 if (elt == 0) {
224 throw NullNode("from xmlBase::Dom::getAttribute. Null argument");
225 }
226
227 XMLCh* xmlchAttName = XMLString::transcode(attName);
228 const XMLCh* attValue = elt->getAttribute(xmlchAttName);
229 XMLString::release(&xmlchAttName);
230
231 if (attValue == 0) return std::string("");
232
233 char* chrAttValue = XMLString::transcode(attValue);
234 std::string strValue = std::string(chrAttValue);
235 XMLString::release(&chrAttValue);
236 return strValue;
237 }
238
239
240 std::string Dom::getAttribute(const DOMElement* elt,
241 std::string attName) {
242
243 return getAttribute(elt, attName.c_str());
244 }
245
246 std::string Dom::getAttribute(const DOMNode* elt, const char* attName) {
247 if (elt == 0) {
248 throw NullNode("from xmlBase::Dom::getAttribute. Null argument");
249 }
250
251 if (elt->getNodeType() != DOMNode::ELEMENT_NODE) {
252 throw NullNode("from xmlBase::Dom::getAttribute. Non-element argument");
253 }
254 return getAttribute(static_cast<const DOMElement*>(elt), attName);
255 }
256
257 std::string Dom::getAttribute(const DOMNode* elt,
258 std::string attName) {
259 return getAttribute(elt, attName.c_str());
260 }
261
262
263 double Dom::getDoubleAttribute(const DOMNode* elt, std::string attName) {
264 std::string stringValue = getAttribute(elt, attName);
265
266 if (stringValue == std::string("") ) {
267 throw
268 NullNode("from xmlBase::Dom::getDoubleAttribute. non-existent attribute");
269 }
270 try {
271 return facilities::Util::stringToDouble(stringValue);
272 }
273 catch (facilities::WrongType ex) {
274 std::cerr << ex.getMsg();
275 throw WrongAttributeType("from xmlBase::Dom::getDoubleAttribute");
276 }
277 }
278
279 unsigned Dom::getDoublesAttribute(const DOMNode* elt, std::string attName,
280 std::vector<double>& values, bool clear) {
281 unsigned nVals = 0;
282 std::vector<std::string> tokens;
283 if (clear) values.clear();
284 std::string stringValue = getAttribute(elt, attName);
285 if (stringValue.size() == 0) return nVals;
286
287 facilities::Util::stringTokenize(stringValue, std::string(" "), tokens);
288
289 try {
290 unsigned nToken = tokens.size();
291 for (unsigned iToken = 0; iToken < nToken; iToken++) {
292 values.push_back(facilities::Util::stringToDouble(tokens[iToken]));
293 nVals++;
294 }
295 }
296 catch (facilities::WrongType ex) {
297 std::cerr << ex.getMsg();
298 throw WrongAttributeType("from xmlBase::Dom::getDoublesAttribute");
299 }
300 return nVals;
301 }
302 unsigned Dom::getFloatsAttribute(const DOMNode* elt, std::string attName,
303 std::vector<float>& values, bool clear) {
304 unsigned nVals = 0;
305 std::vector<std::string> tokens;
306 if (clear) values.clear();
307 std::string stringValue = getAttribute(elt, attName);
308 if (stringValue.size() == 0) return nVals;
309
310 facilities::Util::stringTokenize(stringValue, std::string(" "), tokens);
311
312 try {
313 unsigned nToken = tokens.size();
314 for (unsigned iToken = 0; iToken < nToken; iToken++) {
315 values.push_back(facilities::Util::stringToDouble(tokens[iToken]));
316 nVals++;
317 }
318 }
319 catch (facilities::WrongType ex) {
320 std::cerr << ex.getMsg();
321 throw WrongAttributeType("from xmlBase::Dom::getDoublesAttribute");
322 }
323 return nVals;
324 }
325
326 int Dom::getIntAttribute(const DOMNode* elt, std::string attName) {
327 std::string stringValue = getAttribute(elt, attName);
328
329 if (stringValue == std::string("") ) {
330 throw
331 NullNode("from xmlBase::Dom::getIntAttribute. non-existent attribute");
332 }
333 try {
334 return facilities::Util::stringToInt(stringValue);
335 }
336 catch (facilities::WrongType ex) {
337 std::cerr << ex.getMsg();
338 throw WrongAttributeType("from xmlBase::Dom::getIntAttribute");
339 }
340 }
341
342 unsigned Dom::getIntsAttribute(const DOMNode* elt, std::string attName,
343 std::vector<int>& values, bool clear) {
344 unsigned nVals = 0;
345 std::vector<std::string> tokens;
346 if (clear) values.clear();
347 std::string stringValue = getAttribute(elt, attName);
348 if (stringValue.size() == 0) return nVals;
349
350 facilities::Util::stringTokenize(stringValue, std::string(" "), tokens);
351
352 try {
353 unsigned nToken = tokens.size();
354 for (unsigned iToken = 0; iToken < nToken; iToken++) {
355 values.push_back(facilities::Util::stringToInt(tokens[iToken]));
356 nVals++;
357 }
358 }
359 catch (facilities::WrongType ex) {
360 std::cerr << ex.getMsg();
361 throw WrongAttributeType("from xmlBase::Dom::getIntsAttribute");
362 }
363 return nVals;
364 }
365
366 std::string Dom::getText(const DOMNode* textNode) {
367 short int nType = textNode->getNodeType();
368
369 if ( (nType != DOMNode::TEXT_NODE) &&
370 (nType != DOMNode::COMMENT_NODE) &&
371 (nType != DOMNode::CDATA_SECTION_NODE))
372 {
373 throw WrongNodeType("from xmlBase::Dom::getText, argument not text node");
374 }
375 const XMLCh* t = textNode->getNodeValue();
376 if (t == 0 ) return std::string("");
377 char* chrText = XMLString::transcode(t);
378 std::string text = std::string(chrText);
379 XMLString::release(&chrText);
380
381 return text;
382 }
383
384
385 std::string Dom::getTextContent(const DOMElement* elt) {
386 if (elt->getNodeType() != DOMNode::ELEMENT_NODE) {
387 throw WrongNodeType("from xmlBase::Dom::getTextContent, argument not element node");
388 }
389 return (getText(elt->getFirstChild()));
390 }
391
392 void Dom::addAttribute(DOMElement* elt, std::string name,
393 double value) {
394 if (elt == 0) {
395 throw NullNode("from xmlBase::Dom::addAttribute. null argument");
396 }
397
398 //#ifdef DEFECT_NO_STRINGSTREAM
399 // std::strstream s;
400 // s << value << '\0';
401 //#else
402 std::ostringstream s;
403 s << value;
404 //#endif
405
406 std::string str = s.str();
407 XMLCh* xmlchValue = XMLString::transcode(str.c_str());
408 XMLCh* xmlchName = XMLString::transcode(name.c_str());
409
410 try {
411 elt->setAttribute(xmlchName, xmlchValue);
412 }
413 catch (DOMException ex) {
414 char* msg = XMLString::transcode(ex.msg);
415 std::cerr << "DOMException in xmlBase::Dom::addAttribute(double)" << std::endl;
416 std::cerr << "Msg: " << std::string(msg)
417 << "Code: " << ex.code << std::endl;
418 XMLString::release(&msg);
419 throw ex;
420 }
421 XMLString::release(&xmlchName);
422 XMLString::release(&xmlchValue);
423 }
424
425
426 void Dom::addAttribute(DOMElement* elt, std::string name,
427 int value) {
428 if (elt == 0) {
429 throw NullNode("from xmlBase::Dom::addAttribute. Null argument");
430 }
431
432
433 //#ifdef DEFECT_NO_STRINGSTREAM
434 // std::strstream s;
435 // s << value << '\0';
436 //#else
437 std::ostringstream s;
438 s << value;
439 //#endif
440
441 std::string str = s.str();
442
443 XMLCh* xmlchValue = XMLString::transcode(str.c_str());
444 XMLCh* xmlchName = XMLString::transcode(name.c_str());
445
446 try {
447 elt->setAttribute(xmlchName, xmlchValue);
448 }
449 catch (DOMException ex) {
450 char* msg = XMLString::transcode(ex.msg);
451 std::cerr << "DOMException in xmlBase::Dom::addAttribute(int)"
452 << std::endl;
453 std::cerr << "Msg: " << std::string(msg)
454 << "Code: " << ex.code << std::endl;
455 XMLString::release(&msg);
456 throw ex;
457 }
458
459 XMLString::release(&xmlchName);
460 XMLString::release(&xmlchValue);
461
462 }
463
464 void Dom::addAttribute(DOMElement* elt, std::string name,
465 unsigned int value) {
466 if (elt == 0) {
467 throw NullNode("from xmlBase::Dom::addAttribute. Null argument");
468 }
469
470 //#ifdef DEFECT_NO_STRINGSTREAM
471 // std::strstream s;
472 // s << value << '\0';
473 //#else
474 std::ostringstream s;
475 s << value;
476 //#endif
477
478 std::string str = s.str();
479
480 XMLCh* xmlchValue = XMLString::transcode(str.c_str());
481 XMLCh* xmlchName = XMLString::transcode(name.c_str());
482
483 try {
484 elt->setAttribute(xmlchName, xmlchValue);
485 }
486 catch (DOMException ex) {
487 char* msg = XMLString::transcode(ex.msg);
488 std::cerr << "DOMException in xmlBase::Dom::addAttribute(unsigned int)"
489 << std::endl;
490 std::cerr << "Msg: " << std::string(msg)
491 << "Code: " << ex.code << std::endl;
492 XMLString::release(&msg);
493 throw ex;
494 }
495 XMLString::release(&xmlchName);
496 XMLString::release(&xmlchValue);
497
498 }
499
500 void Dom::addAttribute(DOMElement* elt, std::string name,
501 const char* value) {
502
503 if (elt == 0) {
504 throw NullNode("from xmlBase::Dom::addAttribute. Null argument");
505 }
506
507 XMLCh* xmlchValue = XMLString::transcode(value);
508 XMLCh* xmlchName = XMLString::transcode(name.c_str());
509
510 try {
511 elt->setAttribute(xmlchName, xmlchValue);
512 }
513 catch (DOMException ex) {
514 char* msg = XMLString::transcode(ex.msg);
515 std::cerr << "DOMException in xmlBase::Dom::addAttribute(char*)"
516 << std::endl;
517 std::cerr << "Msg: " << std::string(msg) << "Code: "
518 << ex.code << std::endl;
519 std::cerr.flush();
520 XMLString::release(&msg);
521 throw ex;
522 }
523
524 XMLString::release(&xmlchName);
525 XMLString::release(&xmlchValue);
526
527 }
528
529 void Dom::addAttribute(DOMElement* elt, std::string name,
530 std::string value) {
531
532 if (elt == 0)
533 throw NullNode("from xmlBase::Dom::addAttribute. Null argument");
534
535 addAttribute(elt, name, value.c_str());
536 }
537
538 /*
539 Serialize a node (and any children) to the specified ostream.
540 prefix is for now ignored, but see note following.
541
542 The only node types which actually do get written are
543 element (and its attributes and children)
544 text
545 comment
546
547 NB: For this first pass, printElement outputs all the
548 supported node types just as they appeared in the
549 serialization before parsing *if* the parse was
550 non-validating. If it *was* validating (or if
551 the DOM representation was built programmatically
552 rather than by parsing a file) then ignorable
553 white space will have been thrown away (in the
554 validated case) or there won't have been any to
555 begin with (programmatically-built case)
556 so the printed version will be a horrific single
557 line except that line breaks appearing within
558 comments or text nodes will be preserved.
559
560 Ideally would like to be able to query the DOM
561 or have an argument passed in to tell us whether
562 ignorable white space has been thrown away, in which
563 case we should attempt to pretty print by putting
564 newlines in in reasonable places and keeping track
565 of a sensible indentation level.
566
567 For now, make two different functions. See
568 prettyPrintElement below.
569 */
570 void Dom::printElement(DOMNode* node, std::ostream& out) {
571
572 if (node == 0) {
573 throw NullNode("from xmlBase::Dom::printElement. Null argument");
574 }
575
576 switch(node->getNodeType()) {
577 case DOMNode::ELEMENT_NODE:
578 {
579 // output start tag
580 {
581 std::string tagName = getNodeName(node);
582 out << '<' << tagName;
583 }
584 // ...with attributes
585
586 typedef std::map<std::string, DOMNode*> AttMap;
587 AttMap atts;
588 AttMap::const_iterator it;
589 getAttributeNodeMap(node, atts);
590
591 for (it = atts.begin();
592 it != atts.end(); it++) {
593 std::string attName = (*it).first;
594 out << ' ' << attName << '=';
595 out << '"' << getAttribute(node,attName) << '"';
596 }
597
598 // iterate through children
599 DOMNode* child = node->getFirstChild();
600 if (child != 0) { // there are children
601 out << '>';
602 while (child != 0) {
603 Dom::printElement(child, out);
604 child = child->getNextSibling();
605 }
606 // output end tag, long form
607 {
608 std::string endName = getNodeName(node);
609 out << "</" << endName << ">";
610 }
611 }
612 else { // no children; use short form for the empty tag
613 out << " />";
614 }
615 }
616 break;
617 case DOMNode::TEXT_NODE:
618 // just put it out as is
619 {
620 out << getText(node);
621 }
622 break;
623
624 case DOMNode::CDATA_SECTION_NODE:
625 {
626 out << "<![CDATA[" << getText(node) << "]]>";
627 }
628 break;
629
630
631 case DOMNode::COMMENT_NODE :
632 // glast.prs doesn't have any comments (but should!)
633 {
634 out << "<!-- " << getText(node) << "-->";
635 }
636 break;
637 default:
638 // ignore anything else
639 break;
640 }
641 }
642
643 // Assume we need to do the indenting and line breaks
644 void Dom::prettyPrintElement(DOMNode* node, std::ostream& out,
645 std::string prefix) {
646
647
648 if (node == 0) {
649 throw NullNode("from xmlBase::Dom::prettyPrintElement. Null argument");
650 }
651
652 out << prefix;
653 switch(node->getNodeType()) {
654
655 case DOMNode::ELEMENT_NODE:
656 {
657 // output start tag
658 std::string tagName = getNodeName(node);
659 out << '<' << tagName;
660
661 // ...with attributes
662 typedef std::map<std::string, DOMNode*> AttMap;
663 AttMap atts;
664 AttMap::const_iterator it;
665
666 getAttributeNodeMap(node, atts);
667
668 for (it = atts.begin();
669 it != atts.end(); it++) {
670 std::string attName = (*it).first;
671 out << ' ' << attName << '=';
672 out << '"' << getAttribute(node,attName) << '"';
673 }
674
675 // iterate through children
676 DOMNode* child = node->getFirstChild();
677 if (child != 0) { // there are children
678 out << '>' << std::endl;
679 while (child != 0) {
680 // new indent level
681 Dom::prettyPrintElement(child, out, prefix + " ");
682 child = child->getNextSibling();
683 }
684 // output end tag, long form
685 {
686 std::string endName = getNodeName(node);
687 out << prefix << "</" << endName << ">" << std::endl;
688 }
689 }
690 else { // no children; use short form for the empty tag
691 out << " />" << std::endl;
692 }
693 }
694 break;
695 case DOMNode::TEXT_NODE:
696 // just put it out as is
697 // Note this won't indent correctly if the text node
698 // contains multiple lines.
699 // Similarly, it's too much work to avoid sometimes putting out
700 // an "extra" blank line in the vicinity of text.
701 // Current code puts the extra <cr> before
702 // the text node.
703 {
704 out << getText(node);
705 }
706
707 break;
708
709 case DOMNode::CDATA_SECTION_NODE:
710 {
711 // Probably need to put opening and closing sequences in by hand..
712 out << "<![CDATA[" << getText(node) << "]]>";
713 }
714 break;
715
716 case DOMNode::COMMENT_NODE :
717 // glast.prs doesn't have any comments (but should!)
718 // Note this won't indent correctly if the text node
719 // contains multiple lines. Could have utility routine
720 // to do this, to be called for comments and text nodes
721 {
722 out << "<!-- " << getText(node) << "-->" << std::endl;
723 }
724
725 break;
726 default:
727 // ignore anything else
728 break;
729 }
730 }
731
732 void Dom::prune(DOMElement* elt) {
733 DOMElement* child = findFirstChildByName(elt, "*");
734 while (child != 0) {
735 DOMElement* sib = getSiblingElement(child);
736 prune(child);
737 elt->removeChild(child);
738 child = sib;
739 }
740 }
741 char *Dom::transToChar(const XMLCh* const str) {
742 return transToChar(str, XMLString::stringLen(str) );
743 }
744
745 char *Dom::transToChar(const XMLCh* const str, unsigned int len) {
746 // Passing null argument is a fatal error.
747 // No, it's not
748 // assert(str != 0);
749 if (str == 0) return 0;
750
751 if (!transcoder) {
752 int status = initTrans();
753 if (!status) return 0;
754 }
755
756 // Find length of str to pass to transcode(..) rather than
757 // just passing output buffer size. This is important because
758 // (for Xerces 1.3 anyway) the transcode routine will try to read
759 // this many bytes from the input buffer, conceivably causing
760 // an access violation if it's more than the actual input
761 // buffer length
762
763 if (len + 1 > transBufSize) { // return old buffer; allocate a bigger one
764 char * tBuf = new char[len + 1];
765 if (!tBuf) return 0;
766 transBufSize = len + 1;
767 delete [] transBuf;
768 transBuf = tBuf;
769 }
770
771 bool ok;
772 ok = Dom::transcoder->transcode(str, transBuf, len);
773 return ( ok ? transBuf : 0);
774 }
775
776
777 XMLCh* Dom::transToXMLCh(const char* const src) {
778 // Passing null string is a fatal error
779 // No, it's not
780 if (src == 0) return 0;
781 if (!transcoder) {
782 int status = initTrans();
783 if (!status) return 0;
784 }
785 // as with transToChar above, find actual length of char*
786 // and pass that to Xerces utility for 3rd (maxChars) argument.
787 unsigned int len = strlen(src) + 1;
788 if (len > xmlchBufSize) {
789 XMLCh * tBuf = new XMLCh[len];
790 if (!tBuf) return 0;
791 xmlchBufSize = len;
792 delete [] xmlchBuf;
793 xmlchBuf = tBuf;
794 }
795
796 bool ok;
797
798 ok = transcoder->transcode(src, xmlchBuf, len);
799 return (ok ? xmlchBuf : 0);
800 }
801
802 int Dom::initTrans() {
803 transcoder = XMLPlatformUtils::fgTransService->makeNewLCPTranscoder(
804 XMLPlatformUtils::fgMemoryManager
805 );
806 if (!transcoder) return 0; // and complain?!? Shouldn't ever happen
807 transBuf = new char[transBufSize];
808 if (!transBuf) {
809 delete transcoder;
810 return 0;
811 }
812 xmlchBuf = new XMLCh[xmlchBufSize];
813 if (!xmlchBuf) {
814 delete [] transBuf;
815 delete transcoder;
816 return 0;
817 }
818 return 1;
819 }
820
821} // end namespace xmlBase
XmlRpcServer s
Definition: HelloServer.cpp:11
static double stringToDouble(const std::string &InStr)
static void stringTokenize(std::string input, const std::string &delimiters, std::vector< std::string > &tokens, bool clear=true)
static int stringToInt(const std::string &InStr)
Exception class used when converting from string to numeric type.
static std::string getTagName(const DOMElement *node)
Definition: Dom.cxx:142
static void getChildrenByTagName(const DOMElement *parent, const std::string &tagName, std::vector< DOMElement * > &children, bool clear=true)
Definition: Dom.cxx:160
static void addAttribute(DOMElement *elt, std::string name, double value)
Add attribute of type double to a DOM element, DOMString att name.
Definition: Dom.cxx:392
static int getIntAttribute(const DOMNode *elt, std::string attName)
Definition: Dom.cxx:326
static DOMElement * getSiblingElement(const DOMNode *child)
Return next element sibling, if any.
Definition: Dom.cxx:96
static unsigned getFloatsAttribute(const DOMNode *elt, std::string attName, std::vector< float > &values, bool clear=true)
Definition: Dom.cxx:302
static std::string getTextContent(const DOMElement *elt)
Definition: Dom.cxx:385
static void prettyPrintElement(DOMNode *elt, std::ostream &out, std::string prefix)
Definition: Dom.cxx:644
static void getAttributeNodeMap(const DOMNode *elt, std::map< std::string, DOMNode * > &atts, bool clear=true)
Definition: Dom.cxx:196
static void printElement(DOMNode *elt, std::ostream &out)
Definition: Dom.cxx:570
static bool hasAttribute(const DOMNode *elt, const char *attName)
Definition: Dom.cxx:210
static double getDoubleAttribute(const DOMNode *elt, std::string attName)
Definition: Dom.cxx:263
static DOMElement * getElementById(const DOMDocument *doc, const std::string &id)
Definition: Dom.cxx:120
static std::string getNodeName(const DOMNode *elt)
Definition: Dom.cxx:128
static std::string getAttribute(const DOMElement *elt, const char *attName)
Definition: Dom.cxx:222
static DOMElement * findFirstChildByName(const DOMElement *parent, const char *const name)
Definition: Dom.cxx:60
static void getDescendantsByTagName(const DOMElement *parent, const std::string &tagName, std::vector< DOMElement * > &children, bool clear=true)
Definition: Dom.cxx:178
static unsigned getDoublesAttribute(const DOMNode *elt, std::string attName, std::vector< double > &values, bool clear=true)
Definition: Dom.cxx:279
static DOMElement * getFirstChildElement(const DOMNode *parent)
Get first child which is an element node, if any.
Definition: Dom.cxx:115
static unsigned getIntsAttribute(const DOMNode *elt, std::string attName, std::vector< int > &values, bool clear=true)
Definition: Dom.cxx:342
static void prune(DOMElement *elt)
Definition: Dom.cxx:732
static std::string getText(const DOMNode *textNode)
Definition: Dom.cxx:366
static bool checkTagName(const DOMElement *element, const std::string &tagName)
Definition: Dom.cxx:146
int t()
Definition: t.c:1