LMMS
Loading...
Searching...
No Matches
XmlElement.cpp
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the Water library.
5 Copyright (c) 2016 ROLI Ltd.
6 Copyright (C) 2017-2022 Filipe Coelho <falktx@falktx.com>
7
8 Permission is granted to use this software under the terms of the ISC license
9 http://www.isc.org/downloads/software-support-policy/isc-license/
10
11 Permission to use, copy, modify, and/or distribute this software for any
12 purpose with or without fee is hereby granted, provided that the above
13 copyright notice and this permission notice appear in all copies.
14
15 THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD
16 TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
18 OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
19 USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21 OF THIS SOFTWARE.
22
23 ==============================================================================
24*/
25
26#include "XmlElement.h"
29#include "../text/NewLine.h"
30
31namespace water {
32
33inline bool isValidXmlNameStartCharacter (const water_uchar character) noexcept
34{
35 return character == ':'
36 || character == '_'
37 || (character >= 'a' && character <= 'z')
38 || (character >= 'A' && character <= 'Z')
39 || (character >= 0xc0 && character <= 0xd6)
40 || (character >= 0xd8 && character <= 0xf6)
41 || (character >= 0xf8 && character <= 0x2ff)
42 || (character >= 0x370 && character <= 0x37d)
43 || (character >= 0x37f && character <= 0x1fff)
44 || (character >= 0x200c && character <= 0x200d)
45 || (character >= 0x2070 && character <= 0x218f)
46 || (character >= 0x2c00 && character <= 0x2fef)
47 || (character >= 0x3001 && character <= 0xd7ff)
48 || (character >= 0xf900 && character <= 0xfdcf)
49 || (character >= 0xfdf0 && character <= 0xfffd)
50 || (character >= 0x10000 && character <= 0xeffff);
51}
52
53inline bool isValidXmlNameBodyCharacter (const water_uchar character) noexcept
54{
55 return isValidXmlNameStartCharacter (character)
56 || character == '-'
57 || character == '.'
58 || character == 0xb7
59 || (character >= '0' && character <= '9')
60 || (character >= 0x300 && character <= 0x036f)
61 || (character >= 0x203f && character <= 0x2040);
62}
63
65 : name (other.name),
66 value (other.value)
67{
68}
69
75
81
82//==============================================================================
84 : tagName (tag)
85{
87}
88
89XmlElement::XmlElement (const char* tag)
90 : tagName (tag)
91{
93}
94
100
102 : tagName (tag.toString())
103{
105}
106
108 : tagName (StartEndString (tagNameStart, tagNameEnd))
109{
111}
112
113XmlElement::XmlElement (int /*dummy*/) noexcept
114{
115}
116
118 : tagName (other.tagName)
119{
121}
122
124{
125 if (this != &other)
126 {
129 tagName = other.tagName;
131 }
132
133 return *this;
134}
135
137{
138 wassert (firstChildElement.get() == nullptr);
139 firstChildElement.addCopyOfList (other.firstChildElement);
140
141 wassert (attributes.get() == nullptr);
142 attributes.addCopyOfList (other.attributes);
143}
144
146{
147 firstChildElement.deleteAll();
148 attributes.deleteAll();
149}
150
151//==============================================================================
153{
154 #if 0 // (These functions are just used to generate the lookup table used below)
155 bool isLegalXmlCharSlow (const water_uchar character) noexcept
156 {
157 if ((character >= 'a' && character <= 'z')
158 || (character >= 'A' && character <= 'Z')
159 || (character >= '0' && character <= '9'))
160 return true;
161
162 const char* t = " .,;:-()_+=?!'#@[]/\\*%~{}$|";
163
164 do
165 {
166 if (((water_uchar) (uint8) *t) == character)
167 return true;
168 }
169 while (*++t != 0);
170
171 return false;
172 }
173
174 void generateLegalCharLookupTable()
175 {
176 uint8 n[32] = { 0 };
177 for (int i = 0; i < 256; ++i)
178 if (isLegalXmlCharSlow (i))
179 n[i >> 3] |= (1 << (i & 7));
180
181 String s;
182 for (int i = 0; i < 32; ++i)
183 s << (int) n[i] << ", ";
184
185 DBG (s);
186 }
187 #endif
188
189 static bool isLegalXmlChar (const uint32 c) noexcept
190 {
191 static const unsigned char legalChars[] = { 0, 0, 0, 0, 187, 255, 255, 175, 255,
192 255, 255, 191, 254, 255, 255, 127 };
193 return c < sizeof (legalChars) * 8
194 && (legalChars [c >> 3] & (1 << (c & 7))) != 0;
195 }
196
197 static void escapeIllegalXmlChars (OutputStream& outputStream, const String& text, const bool changeNewLines)
198 {
199 CharPointer_UTF8 t (text.getCharPointer());
200
201 for (;;)
202 {
203 const uint32 character = (uint32) t.getAndAdvance();
204
205 if (character == 0)
206 break;
207
208 if (isLegalXmlChar (character))
209 {
210 outputStream << (char) character;
211 }
212 else
213 {
214 switch (character)
215 {
216 case '&': outputStream << "&amp;"; break;
217 case '"': outputStream << "&quot;"; break;
218 case '>': outputStream << "&gt;"; break;
219 case '<': outputStream << "&lt;"; break;
220
221 case '\n':
222 case '\r':
223 if (! changeNewLines)
224 {
225 outputStream << (char) character;
226 break;
227 }
228 // fall-through
229 default:
230 outputStream << "&#" << ((int) character) << ';';
231 break;
232 }
233 }
234 }
235 }
236
237 static void writeSpaces (OutputStream& out, const size_t numSpaces)
238 {
239 out.writeRepeatedByte (' ', numSpaces);
240 }
241}
242
244 const int indentationLevel,
245 const int lineWrapLength) const
246{
247 using namespace XmlOutputFunctions;
248
249 NewLine newLine;
250
251 if (indentationLevel >= 0)
252 writeSpaces (outputStream, (size_t) indentationLevel);
253
254 if (! isTextElement())
255 {
256 outputStream.writeByte ('<');
257 outputStream << tagName;
258
259 {
260 const size_t attIndent = (size_t) (indentationLevel + tagName.length() + 1);
261 int lineLen = 0;
262
263 for (const XmlAttributeNode* att = attributes; att != nullptr; att = att->nextListItem)
264 {
265 if (lineLen > lineWrapLength && indentationLevel >= 0)
266 {
267 outputStream << newLine;
268 writeSpaces (outputStream, attIndent);
269 lineLen = 0;
270 }
271
272 const int64 startPos = outputStream.getPosition();
273 outputStream.writeByte (' ');
274 outputStream << att->name;
275 outputStream.write ("=\"", 2);
276 escapeIllegalXmlChars (outputStream, att->value, true);
277 outputStream.writeByte ('"');
278 lineLen += (int) (outputStream.getPosition() - startPos);
279 }
280 }
281
282 if (firstChildElement != nullptr)
283 {
284 outputStream.writeByte ('>');
285
286 bool lastWasTextNode = false;
287
288 for (XmlElement* child = firstChildElement; child != nullptr; child = child->nextListItem)
289 {
290 if (child->isTextElement())
291 {
292 escapeIllegalXmlChars (outputStream, child->getText(), false);
293 lastWasTextNode = true;
294 }
295 else
296 {
297 if (indentationLevel >= 0 && ! lastWasTextNode)
298 outputStream << newLine;
299
300 child->writeElementAsText (outputStream,
301 lastWasTextNode ? 0 : (indentationLevel + (indentationLevel >= 0 ? 2 : 0)), lineWrapLength);
302 lastWasTextNode = false;
303 }
304 }
305
306 if (indentationLevel >= 0 && ! lastWasTextNode)
307 {
308 outputStream << newLine;
309 writeSpaces (outputStream, (size_t) indentationLevel);
310 }
311
312 outputStream.write ("</", 2);
313 outputStream << tagName;
314 outputStream.writeByte ('>');
315 }
316 else
317 {
318 outputStream.write ("/>", 2);
319 }
320 }
321 else
322 {
323 escapeIllegalXmlChars (outputStream, getText(), false);
324 }
325}
326
328 const bool allOnOneLine,
329 const bool includeXmlHeader,
330 StringRef encodingType,
331 const int lineWrapLength) const
332{
333 MemoryOutputStream mem (2048);
334 writeToStream (mem, dtdToUse, allOnOneLine, includeXmlHeader, encodingType, lineWrapLength);
335
336 return mem.toUTF8();
337}
338
340 StringRef dtdToUse,
341 const bool allOnOneLine,
342 const bool includeXmlHeader,
343 StringRef encodingType,
344 const int lineWrapLength) const
345{
346 using namespace XmlOutputFunctions;
347
348 NewLine newLine;
349
350 if (includeXmlHeader)
351 {
352 output << "<?xml version=\"1.0\" encoding=\"" << encodingType << "\"?>";
353
354 if (allOnOneLine)
355 output.writeByte (' ');
356 else
357 output << newLine << newLine;
358 }
359
360 if (dtdToUse.isNotEmpty())
361 {
362 output << dtdToUse;
363
364 if (allOnOneLine)
365 output.writeByte (' ');
366 else
367 output << newLine;
368 }
369
370 writeElementAsText (output, allOnOneLine ? -1 : 0, lineWrapLength);
371
372 if (! allOnOneLine)
373 output << newLine;
374}
375
376#if 0
377bool XmlElement::writeToFile (const File& file,
378 StringRef dtdToUse,
379 StringRef encodingType,
380 const int lineWrapLength) const
381{
382 TemporaryFile tempFile (file);
383
384 {
385 FileOutputStream out (tempFile.getFile());
386
387 if (! out.openedOk())
388 return false;
389
390 writeToStream (out, dtdToUse, false, true, encodingType, lineWrapLength);
391
392 out.flush(); // (called explicitly to force an fsync on posix)
393
394 if (out.getStatus().failed())
395 return false;
396 }
397
398 return tempFile.overwriteTargetFileWithTemporary();
399}
400#endif
401
402//==============================================================================
403bool XmlElement::hasTagName (StringRef possibleTagName) const noexcept
404{
405 const bool matches = tagName.equalsIgnoreCase (possibleTagName);
406
407 // XML tags should be case-sensitive, so although this method allows a
408 // case-insensitive match to pass, you should try to avoid this.
409 wassert ((! matches) || tagName == possibleTagName);
410
411 return matches;
412}
413
415{
416 return tagName.upToFirstOccurrenceOf (":", false, false);
417}
418
420{
421 return tagName.fromLastOccurrenceOf (":", false, false);
422}
423
425{
426 return hasTagName (possibleTagName) || getTagNameWithoutNamespace() == possibleTagName;
427}
428
430{
432
433 while (e != nullptr && ! e->hasTagName (requiredTagName))
434 e = e->nextListItem;
435
436 return e;
437}
438
439//==============================================================================
441{
442 return attributes.size();
443}
444
446{
447 static String empty;
448 return empty;
449}
450
451static const std::string& getEmptyStdStringRef() noexcept
452{
453 static std::string empty;
454 return empty;
455}
456
457const std::string& XmlElement::getAttributeName (const int index) const noexcept
458{
459 if (const XmlAttributeNode* const att = attributes [index])
460 return att->name.toString();
461
462 return getEmptyStdStringRef();
463}
464
465const String& XmlElement::getAttributeValue (const int index) const noexcept
466{
467 if (const XmlAttributeNode* const att = attributes [index])
468 return att->value;
469
470 return getEmptyStringRef();
471}
472
474{
475 for (XmlAttributeNode* att = attributes; att != nullptr; att = att->nextListItem)
476 if (att->name == attributeName)
477 return att;
478
479 return nullptr;
480}
481
482bool XmlElement::hasAttribute (StringRef attributeName) const noexcept
483{
484 return getAttribute (attributeName) != nullptr;
485}
486
487//==============================================================================
488const String& XmlElement::getStringAttribute (StringRef attributeName) const noexcept
489{
490 if (const XmlAttributeNode* att = getAttribute (attributeName))
491 return att->value;
492
493 return getEmptyStringRef();
494}
495
496String XmlElement::getStringAttribute (StringRef attributeName, const String& defaultReturnValue) const
497{
498 if (const XmlAttributeNode* att = getAttribute (attributeName))
499 return att->value;
500
501 return defaultReturnValue;
502}
503
504int XmlElement::getIntAttribute (StringRef attributeName, const int defaultReturnValue) const
505{
506 if (const XmlAttributeNode* att = getAttribute (attributeName))
507 return att->value.getIntValue();
508
509 return defaultReturnValue;
510}
511
512double XmlElement::getDoubleAttribute (StringRef attributeName, const double defaultReturnValue) const
513{
514 if (const XmlAttributeNode* att = getAttribute (attributeName))
515 return att->value.getDoubleValue();
516
517 return defaultReturnValue;
518}
519
520bool XmlElement::getBoolAttribute (StringRef attributeName, const bool defaultReturnValue) const
521{
522 if (const XmlAttributeNode* att = getAttribute (attributeName))
523 {
524 const water_uchar firstChar = *(att->value.getCharPointer().findEndOfWhitespace());
525
526 return firstChar == '1'
527 || firstChar == 't'
528 || firstChar == 'y'
529 || firstChar == 'T'
530 || firstChar == 'Y';
531 }
532
533 return defaultReturnValue;
534}
535
537 StringRef stringToCompareAgainst,
538 const bool ignoreCase) const noexcept
539{
540 if (const XmlAttributeNode* att = getAttribute (attributeName))
541 return ignoreCase ? att->value.equalsIgnoreCase (stringToCompareAgainst)
542 : att->value == stringToCompareAgainst;
543
544 return false;
545}
546
547//==============================================================================
548void XmlElement::setAttribute (const Identifier& attributeName, const String& value)
549{
550 if (attributes == nullptr)
551 {
552 attributes = new XmlAttributeNode (attributeName, value);
553 }
554 else
555 {
556 for (XmlAttributeNode* att = attributes; ; att = att->nextListItem)
557 {
558 if (att->name == attributeName)
559 {
560 att->value = value;
561 break;
562 }
563
564 if (att->nextListItem == nullptr)
565 {
566 att->nextListItem = new XmlAttributeNode (attributeName, value);
567 break;
568 }
569 }
570 }
571}
572
573void XmlElement::setAttribute (const Identifier& attributeName, const int number)
574{
575 setAttribute (attributeName, String (number));
576}
577
578void XmlElement::setAttribute (const Identifier& attributeName, const double number)
579{
580 setAttribute (attributeName, String (number, 20));
581}
582
583void XmlElement::removeAttribute (const Identifier& attributeName) noexcept
584{
586 att->get() != nullptr;
587 att = &(att->get()->nextListItem))
588 {
589 if (att->get()->name == attributeName)
590 {
591 delete att->removeNext();
592 break;
593 }
594 }
595}
596
598{
599 attributes.deleteAll();
600}
601
602//==============================================================================
607
608XmlElement* XmlElement::getChildElement (const int index) const noexcept
609{
610 return firstChildElement [index].get();
611}
612
614{
615 wassert (! childName.isEmpty());
616
617 for (XmlElement* child = firstChildElement; child != nullptr; child = child->nextListItem)
618 if (child->hasTagName (childName))
619 return child;
620
621 return nullptr;
622}
623
624XmlElement* XmlElement::getChildByAttribute (StringRef attributeName, StringRef attributeValue) const noexcept
625{
626 wassert (! attributeName.isEmpty());
627
628 for (XmlElement* child = firstChildElement; child != nullptr; child = child->nextListItem)
629 if (child->compareAttribute (attributeName, attributeValue))
630 return child;
631
632 return nullptr;
633}
634
635void XmlElement::addChildElement (XmlElement* const newNode) noexcept
636{
637 if (newNode != nullptr)
638 {
639 // The element being added must not be a child of another node!
640 wassert (newNode->nextListItem == nullptr);
641
642 firstChildElement.append (newNode);
643 }
644}
645
646void XmlElement::insertChildElement (XmlElement* const newNode, int indexToInsertAt) noexcept
647{
648 if (newNode != nullptr)
649 {
650 // The element being added must not be a child of another node!
651 wassert (newNode->nextListItem == nullptr);
652
653 firstChildElement.insertAtIndex (indexToInsertAt, newNode);
654 }
655}
656
658{
659 if (newNode != nullptr)
660 {
661 // The element being added must not be a child of another node!
662 wassert (newNode->nextListItem == nullptr);
663
664 firstChildElement.insertNext (newNode);
665 }
666}
667
669{
670 XmlElement* const newElement = new XmlElement (childTagName);
671 addChildElement (newElement);
672 return newElement;
673}
674
675bool XmlElement::replaceChildElement (XmlElement* const currentChildElement,
676 XmlElement* const newNode) noexcept
677{
678 if (newNode != nullptr)
679 {
680 if (LinkedListPointer<XmlElement>* const p = firstChildElement.findPointerTo (currentChildElement))
681 {
682 if (currentChildElement != newNode)
683 delete p->replaceNext (newNode);
684
685 return true;
686 }
687 }
688
689 return false;
690}
691
693 const bool shouldDeleteTheChild) noexcept
694{
695 if (childToRemove != nullptr)
696 {
697 firstChildElement.remove (childToRemove);
698
699 if (shouldDeleteTheChild)
700 delete childToRemove;
701 }
702}
703
704bool XmlElement::isEquivalentTo (const XmlElement* const other,
705 const bool ignoreOrderOfAttributes) const noexcept
706{
707 if (this != other)
708 {
709 if (other == nullptr || tagName != other->tagName)
710 return false;
711
712 if (ignoreOrderOfAttributes)
713 {
714 int totalAtts = 0;
715
716 for (const XmlAttributeNode* att = attributes; att != nullptr; att = att->nextListItem)
717 {
718 if (! other->compareAttribute (att->name, att->value))
719 return false;
720
721 ++totalAtts;
722 }
723
724 if (totalAtts != other->getNumAttributes())
725 return false;
726 }
727 else
728 {
729 const XmlAttributeNode* thisAtt = attributes;
730 const XmlAttributeNode* otherAtt = other->attributes;
731
732 for (;;)
733 {
734 if (thisAtt == nullptr || otherAtt == nullptr)
735 {
736 if (thisAtt == otherAtt) // both nullptr, so it's a match
737 break;
738
739 return false;
740 }
741
742 if (thisAtt->name != otherAtt->name
743 || thisAtt->value != otherAtt->value)
744 {
745 return false;
746 }
747
748 thisAtt = thisAtt->nextListItem;
749 otherAtt = otherAtt->nextListItem;
750 }
751 }
752
753 const XmlElement* thisChild = firstChildElement;
754 const XmlElement* otherChild = other->firstChildElement;
755
756 for (;;)
757 {
758 if (thisChild == nullptr || otherChild == nullptr)
759 {
760 if (thisChild == otherChild) // both 0, so it's a match
761 break;
762
763 return false;
764 }
765
766 if (! thisChild->isEquivalentTo (otherChild, ignoreOrderOfAttributes))
767 return false;
768
769 thisChild = thisChild->nextListItem;
770 otherChild = otherChild->nextListItem;
771 }
772 }
773
774 return true;
775}
776
781
783{
784 for (XmlElement* child = firstChildElement; child != nullptr;)
785 {
786 XmlElement* const nextChild = child->nextListItem;
787
788 if (child->hasTagName (name))
789 removeChildElement (child, true);
790
791 child = nextChild;
792 }
793}
794
795bool XmlElement::containsChildElement (const XmlElement* const possibleChild) const noexcept
796{
797 return firstChildElement.contains (possibleChild);
798}
799
800XmlElement* XmlElement::findParentElementOf (const XmlElement* const elementToLookFor) noexcept
801{
802 if (this == elementToLookFor || elementToLookFor == nullptr)
803 return nullptr;
804
805 for (XmlElement* child = firstChildElement; child != nullptr; child = child->nextListItem)
806 {
807 if (elementToLookFor == child)
808 return this;
809
810 if (XmlElement* const found = child->findParentElementOf (elementToLookFor))
811 return found;
812 }
813
814 return nullptr;
815}
816
818{
819 firstChildElement.copyToArray (elems);
820}
821
822void XmlElement::reorderChildElements (XmlElement** const elems, const int num) noexcept
823{
824 XmlElement* e = firstChildElement = elems[0];
825
826 for (int i = 1; i < num; ++i)
827 {
828 e->nextListItem = elems[i];
829 e = e->nextListItem;
830 }
831
832 e->nextListItem = nullptr;
833}
834
835//==============================================================================
837{
838 return tagName.isEmpty();
839}
840
841static const char* const water_xmltextContentAttributeName = "text";
842
844{
845 wassert (isTextElement()); // you're trying to get the text from an element that
846 // isn't actually a text element.. If this contains text sub-nodes, you
847 // probably want to use getAllSubText instead.
848
850}
851
857
859{
860 if (isTextElement())
861 return getText();
862
863 if (getNumChildElements() == 1)
864 return firstChildElement.get()->getAllSubText();
865
866 MemoryOutputStream mem (1024);
867
868 for (const XmlElement* child = firstChildElement; child != nullptr; child = child->nextListItem)
869 mem << child->getAllSubText();
870
871 return mem.toUTF8();
872}
873
874String XmlElement::getChildElementAllSubText (StringRef childTagName, const String& defaultReturnValue) const
875{
876 if (const XmlElement* const child = getChildByName (childTagName))
877 return child->getAllSubText();
878
879 return defaultReturnValue;
880}
881
883{
884 XmlElement* const e = new XmlElement ((int) 0);
886 return e;
887}
888
890{
891 if (text.isEmpty() || ! isValidXmlNameStartCharacter (text.text.getAndAdvance()))
892 return false;
893
894 for (;;)
895 {
896 if (text.isEmpty())
897 return true;
898
899 if (! isValidXmlNameBodyCharacter (text.text.getAndAdvance()))
900 return false;
901 }
902}
903
908
910{
911 for (XmlElement* child = firstChildElement; child != nullptr;)
912 {
913 XmlElement* const next = child->nextListItem;
914
915 if (child->isTextElement())
916 removeChildElement (child, true);
917
918 child = next;
919 }
920}
921
922}
#define CARLA_SAFE_ASSERT_RETURN(cond, ret)
Definition CarlaDefines.h:190
#define noexcept
Definition DistrhoDefines.h:72
Definition CharPointer_UTF8.h:45
Definition File.h:50
Definition FileOutputStream.h:42
Definition Identifier.h:44
Definition LinkedListPointer.h:62
Definition MemoryOutputStream.h:42
String toUTF8() const
Definition MemoryOutputStream.cpp:183
Definition NewLine.h:45
Definition OutputStream.h:44
virtual bool write(const void *dataToWrite, size_t numberOfBytes)=0
virtual int64 getPosition()=0
virtual bool writeByte(char byte)
Definition OutputStream.cpp:51
Definition String.h:48
int getIntValue() const noexcept
Definition String.cpp:1781
Definition StringRef.h:67
bool isNotEmpty() const noexcept
Definition StringRef.h:101
Definition TemporaryFile.h:73
const std::string & getAttributeName(int attributeIndex) const noexcept
Definition XmlElement.cpp:457
void copyChildrenAndAttributesFrom(const XmlElement &)
Definition XmlElement.cpp:136
XmlElement * getChildByName(StringRef tagNameToLookFor) const noexcept
Definition XmlElement.cpp:613
LinkedListPointer< XmlElement > nextListItem
Definition XmlElement.h:713
XmlElement * getChildElement(int index) const noexcept
Definition XmlElement.cpp:608
bool hasTagName(StringRef possibleTagName) const noexcept
Definition XmlElement.cpp:403
bool compareAttribute(StringRef attributeName, StringRef stringToCompareAgainst, bool ignoreCase=false) const noexcept
Definition XmlElement.cpp:536
XmlElement * createNewChildElement(StringRef tagName)
Definition XmlElement.cpp:668
XmlElement * getChildByAttribute(StringRef attributeName, StringRef attributeValue) const noexcept
Definition XmlElement.cpp:624
bool hasAttribute(StringRef attributeName) const noexcept
Definition XmlElement.cpp:482
void addChildElement(XmlElement *newChildElement) noexcept
Definition XmlElement.cpp:635
String createDocument(StringRef dtdToUse, bool allOnOneLine=false, bool includeXmlHeader=true, StringRef encodingType="UTF-8", int lineWrapLength=60) const
Definition XmlElement.cpp:327
void deleteAllTextElements() noexcept
Definition XmlElement.cpp:909
void setText(const String &newText)
Definition XmlElement.cpp:852
bool replaceChildElement(XmlElement *currentChildElement, XmlElement *newChildNode) noexcept
Definition XmlElement.cpp:675
void prependChildElement(XmlElement *newChildElement) noexcept
Definition XmlElement.cpp:657
void deleteAllChildElementsWithTagName(StringRef tagName) noexcept
Definition XmlElement.cpp:782
int getIntAttribute(StringRef attributeName, int defaultReturnValue=0) const
Definition XmlElement.cpp:504
void writeElementAsText(OutputStream &, int indentationLevel, int lineWrapLength) const
Definition XmlElement.cpp:243
XmlElement(const String &tagName)
Definition XmlElement.cpp:83
double getDoubleAttribute(StringRef attributeName, double defaultReturnValue=0.0) const
Definition XmlElement.cpp:512
XmlElement * getNextElementWithTagName(StringRef requiredTagName) const
Definition XmlElement.cpp:429
LinkedListPointer< XmlElement > firstChildElement
Definition XmlElement.h:714
int getNumChildElements() const noexcept
Definition XmlElement.cpp:603
LinkedListPointer< XmlAttributeNode > attributes
Definition XmlElement.h:715
const String & getStringAttribute(StringRef attributeName) const noexcept
Definition XmlElement.cpp:488
String getAllSubText() const
Definition XmlElement.cpp:858
void removeChildElement(XmlElement *childToRemove, bool shouldDeleteTheChild) noexcept
Definition XmlElement.cpp:692
bool isTextElement() const noexcept
Definition XmlElement.cpp:836
String tagName
Definition XmlElement.h:716
bool isEquivalentTo(const XmlElement *other, bool ignoreOrderOfAttributes) const noexcept
Definition XmlElement.cpp:704
void getChildElementsAsArray(XmlElement **) const noexcept
Definition XmlElement.cpp:817
String getChildElementAllSubText(StringRef childTagName, const String &defaultReturnValue) const
Definition XmlElement.cpp:874
void removeAttribute(const Identifier &attributeName) noexcept
Definition XmlElement.cpp:583
bool hasTagNameIgnoringNamespace(StringRef possibleTagName) const
Definition XmlElement.cpp:424
void reorderChildElements(XmlElement **, int) noexcept
Definition XmlElement.cpp:822
void insertChildElement(XmlElement *newChildElement, int indexToInsertAt) noexcept
Definition XmlElement.cpp:646
XmlAttributeNode * getAttribute(StringRef) const noexcept
Definition XmlElement.cpp:473
const String & getAttributeValue(int attributeIndex) const noexcept
Definition XmlElement.cpp:465
XmlElement & operator=(const XmlElement &)
Definition XmlElement.cpp:123
int getNumAttributes() const noexcept
Definition XmlElement.cpp:440
static XmlElement * createTextElement(const String &text)
Definition XmlElement.cpp:882
void addTextElement(const String &text)
Definition XmlElement.cpp:904
String getTagNameWithoutNamespace() const
Definition XmlElement.cpp:419
void writeToStream(OutputStream &output, StringRef dtdToUse, bool allOnOneLine=false, bool includeXmlHeader=true, StringRef encodingType="UTF-8", int lineWrapLength=60) const
Definition XmlElement.cpp:339
const String & getText() const noexcept
Definition XmlElement.cpp:843
static bool isValidXmlName(StringRef possibleName) noexcept
Definition XmlElement.cpp:889
~XmlElement() noexcept
Definition XmlElement.cpp:145
void setAttribute(const Identifier &attributeName, const String &newValue)
Definition XmlElement.cpp:548
bool getBoolAttribute(StringRef attributeName, bool defaultReturnValue=false) const
Definition XmlElement.cpp:520
void removeAllAttributes() noexcept
Definition XmlElement.cpp:597
String getNamespace() const
Definition XmlElement.cpp:414
bool containsChildElement(const XmlElement *possibleChild) const noexcept
Definition XmlElement.cpp:795
XmlElement * findParentElementOf(const XmlElement *childToSearchFor) noexcept
Definition XmlElement.cpp:800
void deleteAllChildElements() noexcept
Definition XmlElement.cpp:777
* e
Definition inflate.c:1404
struct huft * t
Definition inflate.c:943
unsigned v[N_MAX]
Definition inflate.c:1584
register unsigned i
Definition inflate.c:1575
unsigned s
Definition inflate.c:1555
static PuglViewHint int value
Definition pugl.h:1708
static const char * name
Definition pugl.h:1582
#define wassert(expression)
#define DBG(textToWrite)
float out
Definition lilv_test.c:1461
Definition XmlElement.cpp:153
static void escapeIllegalXmlChars(OutputStream &outputStream, const String &text, const bool changeNewLines)
Definition XmlElement.cpp:197
static void writeSpaces(OutputStream &out, const size_t numSpaces)
Definition XmlElement.cpp:237
static bool isLegalXmlChar(const uint32 c) noexcept
Definition XmlElement.cpp:189
Definition AudioSampleBuffer.h:33
bool isValidXmlNameBodyCharacter(const water_uchar character) noexcept
Definition XmlElement.cpp:53
unsigned int uint32
Definition water.h:98
static const char *const water_xmltextContentAttributeName
Definition XmlElement.cpp:841
static const std::string & getEmptyStdStringRef() noexcept
Definition XmlElement.cpp:451
bool isValidXmlNameStartCharacter(const water_uchar character) noexcept
Definition XmlElement.cpp:33
static const String & getEmptyStringRef() noexcept
Definition XmlElement.cpp:445
long long int64
Definition water.h:100
unsigned char uint8
Definition water.h:90
uint32 water_uchar
Definition CharacterFunctions.h:38
Definition String.h:1194
Definition XmlElement.h:694
Identifier name
Definition XmlElement.h:700
LinkedListPointer< XmlAttributeNode > nextListItem
Definition XmlElement.h:699
XmlAttributeNode(const XmlAttributeNode &) noexcept
Definition XmlElement.cpp:64
String value
Definition XmlElement.h:701
const char * text
Definition swell-functions.h:167
int n
Definition crypt.c:458
uch * p
Definition crypt.c:594
return c
Definition crypt.c:175
typedef int(UZ_EXP MsgFn)()
struct zdirent * file
Definition win32.c:1500
#define const
Definition zconf.h:137