GammaLib 2.2.0.dev
Loading...
Searching...
No Matches
GXmlElement.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GXmlElement.cpp - XML element node class implementation *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2010-2026 by Juergen Knoedlseder *
5 * ----------------------------------------------------------------------- *
6 * *
7 * This program is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 3 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19 * *
20 ***************************************************************************/
21/**
22 * @file GXmlElement.cpp
23 * @brief XML element node class implementation
24 * @author Juergen Knoedlseder
25 */
26
27/* __ Includes ___________________________________________________________ */
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include "GTools.hpp"
32#include "GException.hpp"
33#include "GFilename.hpp"
34#include "GXmlDocument.hpp"
35#include "GXmlElement.hpp"
36#include "GXmlText.hpp"
37
38/* __ Method name definitions ____________________________________________ */
39#define G_VALUE "GXmlElement::value()"
40#define G_ATTRIBUTE "GXmlElement::attribute(int&)"
41#define G_PARSE_START "GXmlElement::parse_start(std::string&)"
42#define G_PARSE_STOP "GXmlElement::parse_stop(std::string&)"
43#define G_PARSE_ATTRIBUTE "GXmlElement::parse_attribute(size_t*, "\
44 "std::string&)"
45
46/* __ Constants __________________________________________________________ */
47const int g_indent = 2; //!< Indent for XML file writing
48
49/* __ Macros _____________________________________________________________ */
50
51/* __ Coding definitions _________________________________________________ */
52
53/* __ Debug definitions __________________________________________________ */
54
55
56/*==========================================================================
57 = =
58 = Constructors/destructors =
59 = =
60 ==========================================================================*/
61
62/***********************************************************************//**
63 * @brief Void constructor
64 ***************************************************************************/
66{
67 // Initialise members
69
70 // Return
71 return;
72}
73
74
75/***********************************************************************//**
76 * @brief Copy constructor
77 *
78 * @param[in] node XML element.
79 ***************************************************************************/
81{
82 // Initialise members
84
85 // Copy members
86 copy_members(node);
87
88 // Return
89 return;
90}
91
92
93/***********************************************************************//**
94 * @brief Segment constructor
95 *
96 * @param[in] segment XML segment.
97 *
98 * Constructs a XML element from a text @p segment. The text segment is
99 * parsed and the element name and attributes are extracted using the
100 * parse_start() method.
101 ***************************************************************************/
102GXmlElement::GXmlElement(const std::string& segment) : GXmlNode()
103{
104 // Initialise members
105 init_members();
106
107 // Parse start element
108 parse_start(segment);
109
110 // Return
111 return;
112}
113
114
115/***********************************************************************//**
116 * @brief Integer value constructor
117 *
118 * @param[in] name Element name.
119 * @param[in] value Integer value.
120 *
121 * Constructs a XML value element of the form
122 *
123 * <name>value</name>
124 ***************************************************************************/
125GXmlElement::GXmlElement(const std::string& name,
126 const int& value) : GXmlNode()
127{
128 // Initialise members
129 init_members();
130
131 // Set element name
132 m_name = name;
133
134 // Append text element with value
136
137 // Return
138 return;
139}
140
141
142/***********************************************************************//**
143 * @brief Floating point value constructor
144 *
145 * @param[in] name Element name.
146 * @param[in] value Floating point value.
147 *
148 * Constructs a XML value element of the form
149 *
150 * <name>value</name>
151 ***************************************************************************/
152GXmlElement::GXmlElement(const std::string& name,
153 const double& value) : GXmlNode()
154{
155 // Initialise members
156 init_members();
157
158 // Set element name
159 m_name = name;
160
161 // Append text element with value
163
164 // Return
165 return;
166}
167
168
169/***********************************************************************//**
170 * @brief String value constructor
171 *
172 * @param[in] name Element name.
173 * @param[in] value String value.
174 *
175 * Constructs a XML value element of the form
176 *
177 * <name>value</name>
178 ***************************************************************************/
179GXmlElement::GXmlElement(const std::string& name,
180 const std::string& value) : GXmlNode()
181{
182 // Initialise members
183 init_members();
184
185 // Set element name
186 m_name = name;
187
188 // Append text element with value
189 this->append(GXmlText(value));
190
191 // Return
192 return;
193}
194
195
196/***********************************************************************//**
197 * @brief Destructor
198 ***************************************************************************/
200{
201 // Free members
202 free_members();
203
204 // Return
205 return;
206}
207
208
209/*==========================================================================
210 = =
211 = Operators =
212 = =
213 ==========================================================================*/
214
215/***********************************************************************//**
216 * @brief Assignment operator
217 *
218 * @param[in] node XML element.
219 * @return XML element.
220 ***************************************************************************/
222{
223 // Execute only if object is not identical
224 if (this != &node) {
225
226 // Copy base class members
227 this->GXmlNode::operator=(node);
228
229 // Free members
230 free_members();
231
232 // Initialise members
233 init_members();
234
235 // Copy members
236 copy_members(node);
237
238 } // endif: object was not identical
239
240 // Return
241 return *this;
242}
243
244
245/*==========================================================================
246 = =
247 = Public methods =
248 = =
249 ==========================================================================*/
250
251 /***********************************************************************//**
252 * @brief Clear XML element
253 *
254 * Resets the XML element to a clean initial state.
255 ***************************************************************************/
257{
258 // Free class members (base and derived classes, derived class first)
259 free_members();
261
262 // Initialise members
264 init_members();
265
266 // Return
267 return;
268}
269
270
271/***********************************************************************//**
272 * @brief Clone XML element
273 *
274 * @return Pointer to deep copy of XML element.
275 ***************************************************************************/
277{
278 // Clone element
279 return new GXmlElement(*this);
280}
281
282
283/***********************************************************************//**
284 * @brief Return string value
285 *
286 * @return String value.
287 *
288 * @exception GException::invalid_value
289 * Element does not contain a single text element.
290 *
291 * Returns the string value of the text element in case that the element
292 * contains one text element. An exception is returned in case that the
293 * element does not contain a text element.
294 ***************************************************************************/
295std::string GXmlElement::value(void) const
296{
297 // Throw an exception if the element does not contain a single element
298 if (size() != 1) {
299 std::string msg = "Method requires a XML element instance that "
300 "contains a single child, but this instance "
301 "contains "+gammalib::str(size())+" childs. "
302 "Please specify a valid XML element.";
304 }
305
306 // Throw an exception if the element does not contain a text element
307 const GXmlText *text = dynamic_cast<const GXmlText*>((*this)[0]);
308 if (text == NULL) {
309 std::string msg = "XML element instance does not contain a text "
310 "element. Please specify a valid XML element.";
312 }
313
314 // Return text string as value
315 return (text->text());
316}
317
318
319/***********************************************************************//**
320 * @brief Return attribute
321 *
322 * @param[in] index Attribute index [0,...,attributes()-1].
323 * @return Pointer to attribute.
324 *
325 * @exception GException::out_of_range
326 * Index out of range.
327 ***************************************************************************/
328const GXmlAttribute* GXmlElement::attribute(const int& index) const
329{
330 // Throw exception if index is out of range
331 #if defined(G_RANGE_CHECK)
332 if (index < 0 || index >= attributes()) {
333 throw GException::out_of_range(G_ATTRIBUTE, "Attribute index",
334 index, attributes());
335 }
336 #endif
337
338 // Return pointer to attribute
339 return (&(m_attr[index]));
340}
341
342
343/***********************************************************************//**
344 * @brief Return attribute value
345 *
346 * @param[in] name Attribute name.
347 * @return String containing attribute value.
348 *
349 * Returns the value of the attribute @p name. If the requested attribute was
350 * not found an empty string is returned.
351 ***************************************************************************/
352std::string GXmlElement::attribute(const std::string& name) const
353{
354 // Initialise empty value (i.e. attribute not found)
355 std::string value = "";
356
357 // Search attribute value in list of attributes
358 for (int i = 0; i < m_attr.size(); ++i) {
359 if (m_attr[i].name() == name) {
360 value = m_attr[i].value();
361 break;
362 }
363 }
364
365 // Return value
366 return value;
367}
368
369
370/***********************************************************************//**
371 * @brief Set attribute value
372 *
373 * @param[in] name Attribute name.
374 * @param[in] value Attribute value.
375 *
376 * Sets an attribute of the element. If the attribute name exists the value
377 * is modified. If the attribute does not yet exist it is created and
378 * added to the list of attributes.
379 *
380 * Note that this logical assures that only one attribute with a given name
381 * will exist in the element.
382 ***************************************************************************/
383void GXmlElement::attribute(const std::string& name, const std::string& value)
384{
385 // Initialise found flag
386 bool found = false;
387
388 // If attribute exists already then set it's value
389 for (int i = 0; i < m_attr.size(); ++i) {
390 if (m_attr[i].name() == name) {
391 m_attr[i].value(value);
392 found = true;
393 break;
394 }
395 }
396
397 // ... otherwise add attribute
398 if (!found) {
399 GXmlAttribute attr(name, value);
400 m_attr.push_back(attr);
401 }
402
403 // Return
404 return;
405}
406
407
408/***********************************************************************//**
409 * @brief Check if element has a given attribute
410 *
411 * @param[in] name Attribute name.
412 * @return True if attribute exists, false otherwise.
413 *
414 * Checks whether the element contains an attribute with @p name. If the
415 * attribute was found true is returned, false otherwise.
416 ***************************************************************************/
417bool GXmlElement::has_attribute(const std::string& name) const
418{
419 // Initialise found flag
420 bool found = false;
421
422 // Search attribute value in list of attributes
423 for (int i = 0; i < m_attr.size(); ++i) {
424 if (m_attr[i].name() == name) {
425 found = true;
426 break;
427 }
428 }
429
430 // Return found flag
431 return found;
432}
433
434
435/***********************************************************************//**
436 * @brief Remove attribute from element
437 *
438 * @param[in] name Attribute name.
439 *
440 * Remove the attribute with @p name from the XML element. If the requested
441 * attribute was not found the method does nothing.
442 ***************************************************************************/
443void GXmlElement::remove_attribute(const std::string& name)
444{
445 // Do nothing if there are no attributes
446 if (!m_attr.empty()) {
447
448 // Store number of attributes.
449 int num = m_attr.size();
450
451 // Search attribute name in list of attributes and erase attribute
452 // when it has been found. Note that if several attributes with the
453 // same name exist (which should never be the case!), only the
454 // first attribute is removed
455 for (int i = 0; i < num; ++i) {
456 if (m_attr[i].name() == name) {
457 m_attr.erase(m_attr.begin() + i);
458 break;
459 }
460 }
461
462 } // endif: there were attributes
463
464 // Return
465 return;
466}
467
468
469/***********************************************************************//**
470 * @brief Write element into URL
471 *
472 * @param[in] url Unified Resource Locator.
473 * @param[in] indent Text indentation.
474 *
475 * Writes the element into a Unified Resource Locator.
476 ***************************************************************************/
477void GXmlElement::write(GUrl& url, const int& indent) const
478{
479 // Prepend indentation
480 for (int k = 0; k < indent; ++k) {
481 url.printf(" ");
482 }
483
484 // Write element name into URL
485 url.printf("<%s", m_name.c_str());
486
487 // Write attributes into URL
488 for (int k = 0; k < m_attr.size(); ++k) {
489 m_attr[k].write(url);
490 }
491
492 // If there are no children then write an empty tag
493 if (is_empty()) {
494 url.printf(" />\n");
495 }
496
497 // ... otherwise finish start tag, write children and write end tag
498 else {
499
500 // Case A: The element contains a single text leaf
501 if ((m_nodes.size() == 1) && (m_nodes[0]->type() == NT_TEXT)) {
502
503 // Finish start tag
504 url.printf(">");
505
506 // Write text leaf
507 m_nodes[0]->write(url, 0);
508
509 // Write end tag
510 url.printf("</%s>\n", m_name.c_str());
511 }
512
513 // Case B: ... otherwise it contains markup
514 else {
515
516 // Finish start tag
517 url.printf(">\n");
518
519 // Write children in file
520 for (int i = 0; i < m_nodes.size(); ++i) {
521 m_nodes[i]->write(url, indent+g_indent);
522 if (m_nodes[i]->type() == NT_TEXT) {
523 url.printf("\n");
524 }
525 }
526
527 // Write end tag
528 for (int k = 0; k < indent; ++k) {
529 url.printf(" ");
530 }
531 url.printf("</%s>\n", m_name.c_str());
532
533 } // endelse: element contained markup
534
535 } // endelse: finished start tag
536
537 // Return
538 return;
539}
540
541
542/***********************************************************************//**
543 * @brief Print XML element
544 *
545 * @param[in] chatter Chattiness.
546 * @param[in] indent Text indentation.
547 * @return String containing XML element
548 ***************************************************************************/
549std::string GXmlElement::print(const GChatter& chatter,
550 const int& indent) const
551{
552 // Allocate result string
553 std::string result;
554
555 // Continue only if chatter is not silent
556 if (chatter != SILENT) {
557
558 // Initialise result string
559 result = gammalib::fill(" ", indent);
560
561 // Append element to string
562 result.append("GXmlElement::"+m_name);
563 for (int k = 0; k < m_attr.size(); ++k) {
564 result.append(m_attr[k].print(chatter));
565 }
566
567 // Append children
568 for (int i = 0; i < m_nodes.size(); ++i) {
569 result.append("\n" + m_nodes[i]->print(chatter, indent+g_indent));
570 }
571
572 } // endif: chatter was not silent
573
574 // Return
575 return result;
576}
577
578
579/*==========================================================================
580 = =
581 = Private methods =
582 = =
583 ==========================================================================*/
584
585/***********************************************************************//**
586 * @brief Initialise class members
587 ***************************************************************************/
589{
590 // Initialise members
591 m_name.clear();
592 m_attr.clear();
593
594 // Return
595 return;
596}
597
598
599/***********************************************************************//**
600 * @brief Copy class members
601 *
602 * @param[in] node XML element.
603 *
604 * This method copies all class members.
605 ***************************************************************************/
607{
608 // Copy members
609 m_name = node.m_name;
610 m_attr = node.m_attr;
611
612 // Return
613 return;
614}
615
616
617/***********************************************************************//**
618 * @brief Delete class members
619 ***************************************************************************/
621{
622 // Return
623 return;
624}
625
626
627/***********************************************************************//**
628 * @brief Parse element start segment string
629 *
630 * @param[in] segment Segment string.
631 *
632 * @exception GException::xml_syntax_error
633 * XML syntax error.
634 *
635 * Parse the segment string and set class members based on the information
636 * that is found. The method also performs syntax checking. It does not
637 * require brackets to be set.
638 ***************************************************************************/
639void GXmlElement::parse_start(const std::string& segment)
640{
641 // Initialize position check
642 std::size_t pos_start = 0;
643
644 // Get length of segment
645 int n = segment.length();
646
647 // Throw an error is segment is empty
648 if (n < 1) {
649 std::string msg = "Empty XML segment encountered. Please verify the "
650 "XML format.";
652 }
653
654 // If string starts with brackets then check that the brackets are
655 // valid comment brackets
656 if (segment[0] == '<') {
657 if (n < 2 || (segment.compare(0,1,"<") != 0) ||
658 (segment.compare(n-1,1,">") != 0)) {
659 std::string msg = "Invalid tag brackets encountered in XML "
660 "segment \""+segment+"\". Please verify the "
661 "XML format.";
663 }
664 pos_start = 1;
665 } // endif: there were brackets
666
667 // Extract element name
668 std::size_t pos = segment.find_first_of("\x20\x09\x0d\x0a>", 1);
669 if (pos == pos_start) {
670 std::string msg = "Whitespace before element name encountered in XML "
671 "segment \""+segment+"\". Please verify the "
672 "XML format.";
674 }
675 if (pos == std::string::npos) {
676 if (pos_start == 1) {
677 std::string msg = "No element name found in XML segment \""+
678 segment+"\". Please verify the XML format.";
680 }
681 }
682 m_name = segment.substr(pos_start, pos-pos_start);
683
684 // Extract attributes
685 while (pos != std::string::npos) {
686 parse_attribute(&pos, segment);
687 }
688
689 // Return
690 return;
691}
692
693
694/***********************************************************************//**
695 * @brief Parse element stop segment string
696 *
697 * @param[in] segment Segment string.
698 *
699 * @exception GException::xml_syntax_error
700 * XML syntax error.
701 *
702 * Parse the stop segment string and verify the syntax.
703 ***************************************************************************/
704void GXmlElement::parse_stop(const std::string& segment)
705{
706 // Get length of segment
707 int n = segment.length();
708
709 // Check on existence of brackets
710 if (n < 3 || (segment.compare(0,2,"</") != 0) ||
711 (segment.compare(n-1,1,">") != 0)) {
712 std::string msg = "Incorrect or missing tag brackets encountered in "
713 "XML segment \""+segment+"\". Please verify the "
714 "XML format.";
716 }
717
718 // Extract and verify element name
719 size_t pos = segment.find_first_of("\x20\x09\x0d\x0a>", 2);
720 if (pos == 2) {
721 std::string msg = "Whitespace encountered after \"</\" in XML "
722 "segment \""+segment+"\". Please verify the XML "
723 "format.";
725 }
726 if (pos == std::string::npos) {
727 std::string msg = "No element name found in XML segment \""+
728 segment+"\". Please verify the XML format.";
730 }
731 std::string name = segment.substr(2, pos-2);
732 if (name != m_name) {
733 std::string msg = "Element name \""+name+"\" found in stop tag in XML "
734 "segment \""+segment+"\" while start tag has name "
735 "\""+m_name+"\". Please verify the XML format.";
737 }
738
739 // Verify that no further characters exist in element stop tag
740 size_t pos2 = segment.find_first_of("\x20\x09\x0d\x0a>", pos);
741 if (pos2 != n-1) {
742 std::string msg = "Invalid characters encountered after element name "
743 "in XML segment \""+segment+"\". Please verify the "
744 "XML format.";
746 }
747
748 // Return
749 return;
750}
751
752
753/***********************************************************************//**
754 * @brief Parse element attribute
755 *
756 * @param[in] pos Start position in string.
757 * @param[in] segment Segment string.
758 *
759 * @exception GException::invalid_value
760 * XML syntax error.
761 *
762 * Parse the segment string for one attribute, and if attribute was found,
763 * attach it to element.
764 *
765 * @todo Verify XML validity of attribute name and value
766 ***************************************************************************/
767void GXmlElement::parse_attribute(size_t* pos, const std::string& segment)
768{
769 // Main loop
770 do {
771 // Get substring for error message
772 std::string error = segment.substr(*pos, segment.length()-*pos);
773
774 // Find first character of name substring
775 std::size_t pos_name_start = segment.find_first_not_of("\x20\x09\x0d\x0a/>?", *pos);
776 if (pos_name_start == std::string::npos) {
777 *pos = std::string::npos;
778 continue;
779 }
780
781 // Find end of name substring
782 std::size_t pos_name_end = segment.find_first_of("\x20\x09\x0d\x0a=", pos_name_start);
783 if (pos_name_end == std::string::npos) {
784 std::string msg = "Invalid or missing attribute name encountered "
785 "in XML segment \""+error+"\". Please verify "
786 "the XML format.";
788 }
789
790 // Find '=' character
791 std::size_t pos_equal = segment.find_first_of("=", pos_name_end);
792 if (pos_equal == std::string::npos) {
793 std::string msg = "Missing \"=\" sign for attribute encountered "
794 "in XML segment \""+error+"\". Please verify "
795 "the XML format.";
797 }
798
799 // Find start of value substring
800 std::size_t pos_value_start = segment.find_first_of("\x22\x27", pos_equal);
801 if (pos_value_start == std::string::npos) {
802 std::string msg = "Invalid or missing attribute value start "
803 "hyphen encountered in XML segment \""+
804 error+"\". Please verify the XML format.";
806 }
807
808 // Save hyphen character and step forward one character
809 std::string hyphen = segment.substr(pos_value_start, 1);
810 pos_value_start++;
811 if (pos_value_start >= segment.length()) {
812 std::string msg = "Invalid or missing attribute value encountered "
813 "in XML segment \""+error+"\". Please verify "
814 "the XML format.";
816 }
817
818 // Find end of value substring
819 std::size_t pos_value_end = segment.find_first_of(hyphen, pos_value_start);
820 if (pos_value_end == std::string::npos) {
821 std::string msg = "Invalid or missing attribute value end hyphen "
822 "encountered in XML segment \""+error+
823 "\". Please verify the XML format.";
825 }
826
827 // Get name substring
828 std::size_t n_name = pos_name_end - pos_name_start;
829 if (n_name < 1) {
830 std::string msg = "Invalid or missing attribute name encountered "
831 "in XML segment \""+error+"\". Please verify "
832 "the XML format.";
834 }
835 std::string name = segment.substr(pos_name_start, n_name);
836
837 //@todo Check XML validity of attribute name
838
839 // Get value substring length
840 std::size_t n_value = pos_value_end - pos_value_start;
841 std::string value = segment.substr(pos_value_start-1, n_value+2);
842
843 //@todo Check XML validity of attribute value
844
845 // Allocate, set and append new attribute to element
846 GXmlAttribute attr(name, value);
847 m_attr.push_back(attr);
848
849 // Update segment pointer
850 pos_value_end++;
851 if (pos_value_end >= segment.length()) {
852 pos_value_end = std::string::npos;
853 }
854 *pos = pos_value_end;
855
856 } while (0);
857
858 // Return
859 return;
860}
Exception handler interface definition.
Filename class interface definition.
#define G_VALUE
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
XML document node class interface definition.
#define G_PARSE_STOP
const int g_indent
Indent for XML file writing.
#define G_PARSE_START
#define G_ATTRIBUTE
#define G_PARSE_ATTRIBUTE
XML element node class interface definition.
XML text node class interface definition.
Abstract URL base class.
Definition GUrl.hpp:44
virtual void printf(const char *format,...)=0
XML attribute class.
XML element node class.
void parse_stop(const std::string &segment)
Parse element stop segment string.
std::string m_name
Element name.
virtual void clear(void)
Clear XML element.
std::vector< GXmlAttribute > m_attr
Attributes.
void parse_start(const std::string &segment)
Parse element start segment string.
const GXmlAttribute * attribute(const int &index) const
Return attribute.
virtual ~GXmlElement(void)
Destructor.
void free_members(void)
Delete class members.
virtual void write(GUrl &url, const int &indent=0) const
Write element into URL.
GXmlElement(void)
Void constructor.
GXmlElement & operator=(const GXmlElement &node)
Assignment operator.
void copy_members(const GXmlElement &node)
Copy class members.
bool has_attribute(const std::string &name) const
Check if element has a given attribute.
void parse_attribute(size_t *pos, const std::string &segment)
Parse element attribute.
std::string value(void) const
Return string value.
void remove_attribute(const std::string &name)
Remove attribute from element.
virtual GXmlElement * clone(void) const
Clone XML element.
const std::string & name(void) const
Return XML element name.
virtual NodeType type(void) const
Return XML node type.
int attributes(void) const
Return number of attributes.
virtual std::string print(const GChatter &chatter=NORMAL, const int &indent=0) const
Print XML element.
void init_members(void)
Initialise class members.
Abstract XML node base class.
Definition GXmlNode.hpp:57
virtual GXmlNode * append(const GXmlNode &node)
Append XML child node.
Definition GXmlNode.cpp:287
GXmlNode & operator=(const GXmlNode &node)
Assignment operator.
Definition GXmlNode.cpp:118
std::vector< GXmlNode * > m_nodes
Pointer to child nodes.
Definition GXmlNode.hpp:123
void free_members(void)
Delete class members.
Definition GXmlNode.cpp:921
virtual bool is_empty(void) const
Signals if node has no child nodes.
Definition GXmlNode.hpp:145
virtual int size(void) const
Return number of child nodes.
Definition GXmlNode.hpp:133
void init_members(void)
Initialise class members.
Definition GXmlNode.cpp:880
XML text node class.
Definition GXmlText.hpp:43
const std::string & text(void) const
Return text.
Definition GXmlText.hpp:97
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:508
std::string fill(const std::string &s, const int &n)
Fill string with n strings of same type.
Definition GTools.cpp:1037