OpenShot Audio Library | OpenShotAudio 0.4.0
Loading...
Searching...
No Matches
juce_XmlElement.h
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23namespace juce
24{
25
26//==============================================================================
82class JUCE_API XmlElement
83{
84public:
85 //==============================================================================
87 explicit XmlElement (const String& tagName);
88
90 explicit XmlElement (const char* tagName);
91
93 explicit XmlElement (const Identifier& tagName);
94
96 explicit XmlElement (StringRef tagName);
97
99 XmlElement (String::CharPointerType tagNameBegin, String::CharPointerType tagNameEnd);
100
102 XmlElement (const XmlElement&);
103
105 XmlElement& operator= (const XmlElement&);
106
108 XmlElement& operator= (XmlElement&&) noexcept;
109
111 XmlElement (XmlElement&&) noexcept;
112
114 ~XmlElement() noexcept;
115
116 //==============================================================================
128 bool isEquivalentTo (const XmlElement* other,
129 bool ignoreOrderOfAttributes) const noexcept;
130
131 //==============================================================================
136 {
138 TextFormat();
139
143 bool addDefaultHeader = true;
144 int lineWrapLength = 60;
145 const char* newLineChars = "\r\n";
146
147 [[nodiscard]] TextFormat singleLine() const;
148 [[nodiscard]] TextFormat withoutHeader() const;
149 };
150
156 String toString (const TextFormat& format = {}) const;
157
161 void writeTo (OutputStream& output, const TextFormat& format = {}) const;
162
166 bool writeTo (const File& destinationFile, const TextFormat& format = {}) const;
167
168 //==============================================================================
173 const String& getTagName() const noexcept { return tagName; }
174
176 String getNamespace() const;
177
179 String getTagNameWithoutNamespace() const;
180
185 bool hasTagName (StringRef possibleTagName) const noexcept;
186
191 bool hasTagNameIgnoringNamespace (StringRef possibleTagName) const;
192
196 void setTagName (StringRef newTagName);
197
198 //==============================================================================
204 int getNumAttributes() const noexcept;
205
213 const String& getAttributeName (int attributeIndex) const noexcept;
214
222 const String& getAttributeValue (int attributeIndex) const noexcept;
223
224 //==============================================================================
225 // Attribute-handling methods..
226
228 bool hasAttribute (StringRef attributeName) const noexcept;
229
233 const String& getStringAttribute (StringRef attributeName) const noexcept;
234
240 String getStringAttribute (StringRef attributeName, const String& defaultReturnValue) const;
241
250 bool compareAttribute (StringRef attributeName,
251 StringRef stringToCompareAgainst,
252 bool ignoreCase = false) const noexcept;
253
264 int getIntAttribute (StringRef attributeName, int defaultReturnValue = 0) const;
265
276 double getDoubleAttribute (StringRef attributeName, double defaultReturnValue = 0.0) const;
277
288 bool getBoolAttribute (StringRef attributeName, bool defaultReturnValue = false) const;
289
303 void setAttribute (const Identifier& attributeName, const String& newValue);
304
317 void setAttribute (const Identifier& attributeName, int newValue);
318
331 void setAttribute (const Identifier& attributeName, double newValue);
332
338 void removeAttribute (const Identifier& attributeName) noexcept;
339
341 void removeAllAttributes() noexcept;
342
343 //==============================================================================
344 // Child element methods..
345
351 XmlElement* getFirstChildElement() const noexcept { return firstChildElement; }
352
379 inline XmlElement* getNextElement() const noexcept { return nextListItem; }
380
389 XmlElement* getNextElementWithTagName (StringRef requiredTagName) const;
390
394 int getNumChildElements() const noexcept;
395
404 XmlElement* getChildElement (int index) const noexcept;
405
412 XmlElement* getChildByName (StringRef tagNameToLookFor) const noexcept;
413
421 XmlElement* getChildByAttribute (StringRef attributeName,
422 StringRef attributeValue) const noexcept;
423
424 //==============================================================================
438 void addChildElement (XmlElement* newChildElement) noexcept;
439
451 void insertChildElement (XmlElement* newChildElement,
452 int indexToInsertAt) noexcept;
453
466 void prependChildElement (XmlElement* newChildElement) noexcept;
467
482 XmlElement* createNewChildElement (StringRef tagName);
483
491 bool replaceChildElement (XmlElement* currentChildElement,
492 XmlElement* newChildNode) noexcept;
493
500 void removeChildElement (XmlElement* childToRemove,
501 bool shouldDeleteTheChild) noexcept;
502
506 void deleteAllChildElements() noexcept;
507
511 void deleteAllChildElementsWithTagName (StringRef tagName) noexcept;
512
514 bool containsChildElement (const XmlElement* possibleChild) const noexcept;
515
526 XmlElement* findParentElementOf (const XmlElement* childToSearchFor) noexcept;
527
528 //==============================================================================
551 template <class ElementComparator>
552 void sortChildElements (ElementComparator& comparator,
553 bool retainOrderOfEquivalentItems = false)
554 {
555 auto num = getNumChildElements();
556
557 if (num > 1)
558 {
559 HeapBlock<XmlElement*> elems (num);
560 getChildElementsAsArray (elems);
561 sortArray (comparator, (XmlElement**) elems, 0, num - 1, retainOrderOfEquivalentItems);
562 reorderChildElements (elems, num);
563 }
564 }
565
566 //==============================================================================
574 bool isTextElement() const noexcept;
575
592 const String& getText() const noexcept;
593
600 void setText (const String& newText);
601
615 String getAllSubText() const;
616
625 String getChildElementAllSubText (StringRef childTagName,
626 const String& defaultReturnValue) const;
627
631 void addTextElement (const String& text);
632
636 void deleteAllTextElements() noexcept;
637
639 static XmlElement* createTextElement (const String& text);
640
642 static bool isValidXmlName (StringRef possibleName) noexcept;
643
644private:
645 //==============================================================================
646 struct GetNextElement
647 {
648 XmlElement* getNext (const XmlElement& e) const { return e.getNextElement(); }
649 };
650
651 struct GetNextElementWithTagName
652 {
653 GetNextElementWithTagName() = default;
654 explicit GetNextElementWithTagName (String n) : name (std::move (n)) {}
655 XmlElement* getNext (const XmlElement& e) const { return e.getNextElementWithTagName (name); }
656
657 String name;
658 };
659
660 //==============================================================================
661 template <typename Traits>
662 class Iterator : private Traits
663 {
664 public:
665 using difference_type = ptrdiff_t;
666 using value_type = XmlElement*;
667 using pointer = const value_type*;
668 using reference = value_type;
669 using iterator_category = std::input_iterator_tag;
670
671 Iterator() = default;
672
673 template <typename... Args>
674 Iterator (XmlElement* e, Args&&... args)
675 : Traits (std::forward<Args> (args)...), element (e) {}
676
677 Iterator begin() const { return *this; }
678 Iterator end() const { return Iterator{}; }
679
680 bool operator== (const Iterator& other) const { return element == other.element; }
681 bool operator!= (const Iterator& other) const { return ! operator== (other); }
682
683 reference operator*() const { return element; }
684 pointer operator->() const { return &element; }
685
686 Iterator& operator++()
687 {
688 element = Traits::getNext (*element);
689 return *this;
690 }
691
692 Iterator operator++ (int)
693 {
694 auto copy = *this;
695 ++(*this);
696 return copy;
697 }
698
699 private:
700 value_type element = nullptr;
701 };
702
703public:
704 //==============================================================================
715 Iterator<GetNextElement> getChildIterator() const
716 {
717 return Iterator<GetNextElement> { getFirstChildElement() };
718 }
719
730 Iterator<GetNextElementWithTagName> getChildWithTagNameIterator (StringRef name) const
731 {
732 return Iterator<GetNextElementWithTagName> { getChildByName (name), name };
733 }
734
735 #ifndef DOXYGEN
736 [[deprecated]] void macroBasedForLoop() const noexcept {}
737
738 [[deprecated ("This has been deprecated in favour of the toString method.")]]
739 String createDocument (StringRef dtdToUse,
740 bool allOnOneLine = false,
741 bool includeXmlHeader = true,
742 StringRef encodingType = "UTF-8",
743 int lineWrapLength = 60) const;
744
745 [[deprecated ("This has been deprecated in favour of the writeTo method.")]]
746 void writeToStream (OutputStream& output,
747 StringRef dtdToUse,
748 bool allOnOneLine = false,
749 bool includeXmlHeader = true,
750 StringRef encodingType = "UTF-8",
751 int lineWrapLength = 60) const;
752
753 [[deprecated ("This has been deprecated in favour of the writeTo method.")]]
754 bool writeToFile (const File& destinationFile,
755 StringRef dtdToUse,
756 StringRef encodingType = "UTF-8",
757 int lineWrapLength = 60) const;
758 #endif
759
760private:
761 //==============================================================================
762 struct XmlAttributeNode
763 {
764 XmlAttributeNode (const XmlAttributeNode&) noexcept;
765 XmlAttributeNode (const Identifier&, const String&) noexcept;
766 XmlAttributeNode (String::CharPointerType, String::CharPointerType);
767
768 LinkedListPointer<XmlAttributeNode> nextListItem;
769 Identifier name;
770 String value;
771
772 private:
773 XmlAttributeNode& operator= (const XmlAttributeNode&) = delete;
774 };
775
776 friend class XmlDocument;
777 friend class LinkedListPointer<XmlAttributeNode>;
778 friend class LinkedListPointer<XmlElement>;
779 friend class LinkedListPointer<XmlElement>::Appender;
780 friend class NamedValueSet;
781
782 LinkedListPointer<XmlElement> nextListItem, firstChildElement;
783 LinkedListPointer<XmlAttributeNode> attributes;
784 String tagName;
785
786 XmlElement (int) noexcept;
787 void copyChildrenAndAttributesFrom (const XmlElement&);
788 void writeElementAsText (OutputStream&, int, int, const char*) const;
789 void getChildElementsAsArray (XmlElement**) const noexcept;
790 void reorderChildElements (XmlElement**, int) noexcept;
791 XmlAttributeNode* getAttribute (StringRef) const noexcept;
792
793 // Sigh.. L"" or _T ("") string literals are problematic in general, and really inappropriate
794 // for XML tags. Use a UTF-8 encoded literal instead, or if you're really determined to use
795 // UTF-16, cast it to a String and use the other constructor.
796 XmlElement (const wchar_t*) = delete;
797
798 JUCE_LEAK_DETECTOR (XmlElement)
799};
800
801//==============================================================================
802#ifndef DOXYGEN
803
824#define forEachXmlChildElement(parentXmlElement, childElementVariableName) \
825 for (auto* (childElementVariableName) : ((parentXmlElement).macroBasedForLoop(), (parentXmlElement).getChildIterator()))
826
852#define forEachXmlChildElementWithTagName(parentXmlElement, childElementVariableName, requiredTagName) \
853 for (auto* (childElementVariableName) : ((parentXmlElement).macroBasedForLoop(), (parentXmlElement).getChildWithTagNameIterator ((requiredTagName))))
854
855#endif
856
857} // namespace juce
int getNumChildElements() const noexcept
XmlElement(const String &tagName)
XmlElement * getChildByName(StringRef tagNameToLookFor) const noexcept
XmlElement * getNextElement() const noexcept
String toString(const TextFormat &format={}) const
void sortChildElements(ElementComparator &comparator, bool retainOrderOfEquivalentItems=false)
Iterator< GetNextElementWithTagName > getChildWithTagNameIterator(StringRef name) const
bool isEquivalentTo(const XmlElement *other, bool ignoreOrderOfAttributes) const noexcept
Iterator< GetNextElement > getChildIterator() const
const String & getTagName() const noexcept
XmlElement * getFirstChildElement() const noexcept