From 0fb8c8e82a17dfd81bee4e4ed189301539cca936 Mon Sep 17 00:00:00 2001 From: jules Date: Sun, 19 May 2019 08:13:20 +0100 Subject: [PATCH] Added handy new function parseXMLIfTagMatches(), and refactored a lot of old code that was parsing XML in a more clunky way --- examples/Plugins/AudioPluginDemo.h | 4 +- .../Plugins/InterAppAudioEffectPluginDemo.h | 4 +- examples/Utilities/AnalyticsCollectionDemo.h | 76 +++++++++---------- .../Source/Filters/FilterGraph.cpp | 26 +++---- .../Application/jucer_ProjucerAnalytics.cpp | 12 ++- .../ComponentEditor/jucer_ComponentLayout.cpp | 5 +- .../ComponentEditor/jucer_JucerDocument.cpp | 8 +- .../ComponentEditor/jucer_PaintRoutine.cpp | 5 +- .../jucer_ProjectExport_Android.h | 2 +- .../ProjectSaving/jucer_ProjectExport_CLion.h | 3 +- .../format_types/juce_VST3PluginFormat.cpp | 4 +- .../processors/juce_AudioProcessor.cpp | 4 +- .../juce_core/containers/juce_PropertySet.cpp | 2 +- modules/juce_core/network/juce_URL.cpp | 2 +- modules/juce_core/xml/juce_XmlDocument.cpp | 33 ++++++-- modules/juce_core/xml/juce_XmlDocument.h | 30 ++++++-- modules/juce_core/xml/juce_XmlElement.h | 2 +- .../app_properties/juce_PropertiesFile.cpp | 39 +++------- .../drawables/juce_Drawable.cpp | 10 +-- .../drawables/juce_SVGParser.cpp | 17 +---- 20 files changed, 135 insertions(+), 153 deletions(-) diff --git a/examples/Plugins/AudioPluginDemo.h b/examples/Plugins/AudioPluginDemo.h index 1ecfacd01e..c1b39f9e74 100644 --- a/examples/Plugins/AudioPluginDemo.h +++ b/examples/Plugins/AudioPluginDemo.h @@ -293,9 +293,7 @@ public: { // Restore our plug-in's state from the xml representation stored in the above // method. - std::unique_ptr xmlState (getXmlFromBinary (data, sizeInBytes)); - - if (xmlState.get() != nullptr) + if (auto xmlState = getXmlFromBinary (data, sizeInBytes)) state.replaceState (ValueTree::fromXml (*xmlState)); } diff --git a/examples/Plugins/InterAppAudioEffectPluginDemo.h b/examples/Plugins/InterAppAudioEffectPluginDemo.h index bf4442e284..821476c4fe 100644 --- a/examples/Plugins/InterAppAudioEffectPluginDemo.h +++ b/examples/Plugins/InterAppAudioEffectPluginDemo.h @@ -236,9 +236,7 @@ public: void setStateInformation (const void* data, int sizeInBytes) override { - auto xmlState = std::unique_ptr (getXmlFromBinary (data, sizeInBytes)); - - if (xmlState.get() != nullptr) + if (auto xmlState = getXmlFromBinary (data, sizeInBytes)) if (xmlState->hasTagName (parameters.state.getType())) parameters.state = ValueTree::fromXml (*xmlState); } diff --git a/examples/Utilities/AnalyticsCollectionDemo.h b/examples/Utilities/AnalyticsCollectionDemo.h index cb43cf5065..52269207f3 100644 --- a/examples/Utilities/AnalyticsCollectionDemo.h +++ b/examples/Utilities/AnalyticsCollectionDemo.h @@ -212,11 +212,10 @@ private: // a binary format may be more suitable if it is faster - remember that this // method is called on app shutdown so it needs to complete quickly! - XmlDocument previouslySavedEvents (savedEventsFile); - std::unique_ptr xml (previouslySavedEvents.getDocumentElement()); + auto xml = parseXMLIfTagMatches (savedEventsFile, "events"); - if (xml.get() == nullptr || xml->getTagName() != "events") - xml.reset (new XmlElement ("events")); + if (xml == nullptr) + xml = std::make_unique ("events"); for (auto& event : eventsToSave) { @@ -248,45 +247,42 @@ private: void restoreUnloggedEvents (std::deque& restoredEventQueue) override { - XmlDocument savedEvents (savedEventsFile); - std::unique_ptr xml (savedEvents.getDocumentElement()); - - if (xml.get() == nullptr || xml->getTagName() != "events") - return; + if (auto xml = parseXMLIfTagMatches (savedEventsFile, "events")) + { + auto numEvents = xml->getNumChildElements(); - auto numEvents = xml->getNumChildElements(); + for (auto iEvent = 0; iEvent < numEvents; ++iEvent) + { + auto* xmlEvent = xml->getChildElement (iEvent); + + StringPairArray parameters; + auto* xmlParameters = xmlEvent->getChildByName ("parameters"); + auto numParameters = xmlParameters->getNumAttributes(); + + for (auto iParam = 0; iParam < numParameters; ++iParam) + parameters.set (xmlParameters->getAttributeName (iParam), + xmlParameters->getAttributeValue (iParam)); + + StringPairArray userProperties; + auto* xmlUserProperties = xmlEvent->getChildByName ("user_properties"); + auto numUserProperties = xmlUserProperties->getNumAttributes(); + + for (auto iProp = 0; iProp < numUserProperties; ++iProp) + userProperties.set (xmlUserProperties->getAttributeName (iProp), + xmlUserProperties->getAttributeValue (iProp)); + + restoredEventQueue.push_back ({ + xmlEvent->getStringAttribute ("name"), + xmlEvent->getIntAttribute ("type"), + static_cast (xmlEvent->getIntAttribute ("timestamp")), + parameters, + xmlEvent->getStringAttribute ("user_id"), + userProperties + }); + } - for (auto iEvent = 0; iEvent < numEvents; ++iEvent) - { - auto* xmlEvent = xml->getChildElement (iEvent); - - StringPairArray parameters; - auto* xmlParameters = xmlEvent->getChildByName ("parameters"); - auto numParameters = xmlParameters->getNumAttributes(); - - for (auto iParam = 0; iParam < numParameters; ++iParam) - parameters.set (xmlParameters->getAttributeName (iParam), - xmlParameters->getAttributeValue (iParam)); - - StringPairArray userProperties; - auto* xmlUserProperties = xmlEvent->getChildByName ("user_properties"); - auto numUserProperties = xmlUserProperties->getNumAttributes(); - - for (auto iProp = 0; iProp < numUserProperties; ++iProp) - userProperties.set (xmlUserProperties->getAttributeName (iProp), - xmlUserProperties->getAttributeValue (iProp)); - - restoredEventQueue.push_back ({ - xmlEvent->getStringAttribute ("name"), - xmlEvent->getIntAttribute ("type"), - static_cast (xmlEvent->getIntAttribute ("timestamp")), - parameters, - xmlEvent->getStringAttribute ("user_id"), - userProperties - }); + savedEventsFile.deleteFile(); } - - savedEventsFile.deleteFile(); } const int initialPeriodMs = 1000; diff --git a/extras/AudioPluginHost/Source/Filters/FilterGraph.cpp b/extras/AudioPluginHost/Source/Filters/FilterGraph.cpp index 914d9e4b59..395caf1661 100644 --- a/extras/AudioPluginHost/Source/Filters/FilterGraph.cpp +++ b/extras/AudioPluginHost/Source/Filters/FilterGraph.cpp @@ -221,26 +221,26 @@ void FilterGraph::newDocument() Result FilterGraph::loadDocument (const File& file) { - XmlDocument doc (file); - std::unique_ptr xml (doc.getDocumentElement()); - - if (xml == nullptr || ! xml->hasTagName ("FILTERGRAPH")) - return Result::fail ("Not a valid filter graph file"); + if (auto xml = parseXMLIfTagMatches (file, "FILTERGRAPH")) + { + graph.removeChangeListener (this); + restoreFromXml (*xml); - graph.removeChangeListener (this); - restoreFromXml (*xml); + MessageManager::callAsync ([this] + { + setChangedFlag (false); + graph.addChangeListener (this); + }); - MessageManager::callAsync ([this] () { - setChangedFlag (false); - graph.addChangeListener (this); - } ); + return Result::ok(); + } - return Result::ok(); + return Result::fail ("Not a valid filter graph file"); } Result FilterGraph::saveDocument (const File& file) { - std::unique_ptr xml (createXml()); + auto xml = createXml(); if (! xml->writeTo (file, {})) return Result::fail ("Couldn't write to the file"); diff --git a/extras/Projucer/Source/Application/jucer_ProjucerAnalytics.cpp b/extras/Projucer/Source/Application/jucer_ProjucerAnalytics.cpp index f5dfc1e43a..d616a86124 100644 --- a/extras/Projucer/Source/Application/jucer_ProjucerAnalytics.cpp +++ b/extras/Projucer/Source/Application/jucer_ProjucerAnalytics.cpp @@ -178,11 +178,10 @@ void ProjucerAnalyticsDestination::stopLoggingEvents() //============================================================================== void ProjucerAnalyticsDestination::saveUnloggedEvents (const std::deque& eventsToSave) { - XmlDocument previouslySavedEvents (savedEventsFile); - std::unique_ptr xml (previouslySavedEvents.getDocumentElement()); + auto xml = parseXMLIfTagMatches (savedEventsFile, "events"); - if (xml.get() == nullptr || xml->getTagName() != "events") - xml.reset (new XmlElement ("events")); + if (xml == nullptr) + xml = std::make_unique ("events"); for (auto& event : eventsToSave) { @@ -214,10 +213,9 @@ void ProjucerAnalyticsDestination::saveUnloggedEvents (const std::deque& restoredEventQueue) { - XmlDocument savedEvents (savedEventsFile); - std::unique_ptr xml (savedEvents.getDocumentElement()); + auto xml = parseXMLIfTagMatches (savedEventsFile, "events"); - if (xml.get() == nullptr || xml->getTagName() != "events") + if (xml == nullptr) return; auto numEvents = xml->getNumChildElements(); diff --git a/extras/Projucer/Source/ComponentEditor/jucer_ComponentLayout.cpp b/extras/Projucer/Source/ComponentEditor/jucer_ComponentLayout.cpp index b0f4f9ad2c..1ced1baf8b 100644 --- a/extras/Projucer/Source/ComponentEditor/jucer_ComponentLayout.cpp +++ b/extras/Projucer/Source/ComponentEditor/jucer_ComponentLayout.cpp @@ -271,10 +271,7 @@ void ComponentLayout::copySelectedToClipboard() void ComponentLayout::paste() { - XmlDocument clip (SystemClipboard::getTextFromClipboard()); - std::unique_ptr doc (clip.getDocumentElement()); - - if (doc != nullptr && doc->hasTagName (clipboardXmlTag)) + if (auto doc = parseXMLIfTagMatches (SystemClipboard::getTextFromClipboard(), clipboardXmlTag)) { selected.deselectAll(); diff --git a/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp b/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp index 137da8deee..dea80bcde3 100644 --- a/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp +++ b/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp @@ -624,16 +624,14 @@ void JucerDocument::extractCustomPaintSnippetsFromCppFile (const String& cppCont std::unique_ptr JucerDocument::pullMetaDataFromCppFile (const String& cpp) { auto lines = StringArray::fromLines (cpp); - - const int startLine = indexOfLineStartingWith (lines, "BEGIN_JUCER_METADATA", 0); + auto startLine = indexOfLineStartingWith (lines, "BEGIN_JUCER_METADATA", 0); if (startLine > 0) { - const int endLine = indexOfLineStartingWith (lines, "END_JUCER_METADATA", startLine); + auto endLine = indexOfLineStartingWith (lines, "END_JUCER_METADATA", startLine); if (endLine > startLine) - return XmlDocument::parse (lines.joinIntoString ("\n", startLine + 1, - endLine - startLine - 1)); + return parseXML (lines.joinIntoString ("\n", startLine + 1, endLine - startLine - 1)); } return nullptr; diff --git a/extras/Projucer/Source/ComponentEditor/jucer_PaintRoutine.cpp b/extras/Projucer/Source/ComponentEditor/jucer_PaintRoutine.cpp index 62add31939..fd59d2b59c 100644 --- a/extras/Projucer/Source/ComponentEditor/jucer_PaintRoutine.cpp +++ b/extras/Projucer/Source/ComponentEditor/jucer_PaintRoutine.cpp @@ -302,10 +302,7 @@ void PaintRoutine::copySelectedToClipboard() void PaintRoutine::paste() { - XmlDocument clip (SystemClipboard::getTextFromClipboard()); - std::unique_ptr doc (clip.getDocumentElement()); - - if (doc != nullptr && doc->hasTagName (clipboardXmlTag)) + if (auto doc = parseXMLIfTagMatches (SystemClipboard::getTextFromClipboard(), clipboardXmlTag)) { selectedElements.deselectAll(); selectedPoints.deselectAll(); diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h index 03b888e3d7..d421eec077 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h @@ -1543,7 +1543,7 @@ private: std::unique_ptr createManifestElement() const { - auto manifest = XmlDocument::parse (androidManifestCustomXmlElements.get()); + auto manifest = parseXML (androidManifestCustomXmlElements.get()); if (manifest == nullptr) manifest = std::make_unique ("manifest"); diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CLion.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CLion.h index 48213db58d..7a780de6db 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CLion.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CLion.h @@ -1013,9 +1013,8 @@ private: if (targetAttributeKeys.contains ("INFOPLIST_FILE")) { auto plistFile = exporter.getTargetFolder().getChildFile (targetAttributes["INFOPLIST_FILE"]); - XmlDocument infoPlistData (plistFile); - if (auto plist = std::unique_ptr (infoPlistData.getDocumentElement())) + if (auto plist = parseXML (plistFile)) { if (auto* dict = plist->getChildByName ("dict")) { diff --git a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp index c717cbf6f0..c901656b03 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp @@ -2292,9 +2292,7 @@ public: void setStateInformation (const void* data, int sizeInBytes) override { - std::unique_ptr head (AudioProcessor::getXmlFromBinary (data, sizeInBytes)); - - if (head != nullptr) + if (auto head = AudioProcessor::getXmlFromBinary (data, sizeInBytes)) { auto componentStream (createMemoryStreamForState (*head, "IComponent")); diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp index c42ba07dd3..81460cfeb8 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp @@ -1121,8 +1121,8 @@ std::unique_ptr AudioProcessor::getXmlFromBinary (const void* data, auto stringLength = (int) ByteOrder::littleEndianInt (addBytesToPointer (data, 4)); if (stringLength > 0) - return XmlDocument::parse (String::fromUTF8 (static_cast (data) + 8, - jmin ((sizeInBytes - 8), stringLength))); + return parseXML (String::fromUTF8 (static_cast (data) + 8, + jmin ((sizeInBytes - 8), stringLength))); } return {}; diff --git a/modules/juce_core/containers/juce_PropertySet.cpp b/modules/juce_core/containers/juce_PropertySet.cpp index cbb93ec7e7..fe3712721c 100644 --- a/modules/juce_core/containers/juce_PropertySet.cpp +++ b/modules/juce_core/containers/juce_PropertySet.cpp @@ -112,7 +112,7 @@ bool PropertySet::getBoolValue (StringRef keyName, bool defaultValue) const noex std::unique_ptr PropertySet::getXmlValue (StringRef keyName) const { - return XmlDocument::parse (getValue (keyName)); + return parseXML (getValue (keyName)); } void PropertySet::setValue (const String& keyName, const var& v) diff --git a/modules/juce_core/network/juce_URL.cpp b/modules/juce_core/network/juce_URL.cpp index 9bfdd2d462..73fa4f8371 100644 --- a/modules/juce_core/network/juce_URL.cpp +++ b/modules/juce_core/network/juce_URL.cpp @@ -790,7 +790,7 @@ String URL::readEntireTextStream (bool usePostCommand) const std::unique_ptr URL::readEntireXmlStream (bool usePostCommand) const { - return XmlDocument::parse (readEntireTextStream (usePostCommand)); + return parseXML (readEntireTextStream (usePostCommand)); } //============================================================================== diff --git a/modules/juce_core/xml/juce_XmlDocument.cpp b/modules/juce_core/xml/juce_XmlDocument.cpp index 3b1ef37ef2..a7f9d99560 100644 --- a/modules/juce_core/xml/juce_XmlDocument.cpp +++ b/modules/juce_core/xml/juce_XmlDocument.cpp @@ -30,24 +30,32 @@ XmlDocument::~XmlDocument() {} std::unique_ptr XmlDocument::parse (const File& file) { - XmlDocument doc (file); - return doc.getDocumentElement(); + return XmlDocument (file).getDocumentElement(); } -std::unique_ptr XmlDocument::parse (const String& xmlData) +std::unique_ptr XmlDocument::parse (const String& textToParse) { - XmlDocument doc (xmlData); - return doc.getDocumentElement(); + return XmlDocument (textToParse).getDocumentElement(); } std::unique_ptr parseXML (const String& textToParse) { - return std::unique_ptr (XmlDocument::parse (textToParse)); + return XmlDocument (textToParse).getDocumentElement(); } -std::unique_ptr parseXML (const File& fileToParse) +std::unique_ptr parseXML (const File& file) { - return std::unique_ptr (XmlDocument::parse (fileToParse)); + return XmlDocument (file).getDocumentElement(); +} + +std::unique_ptr parseXMLIfTagMatches (const String& textToParse, StringRef requiredTag) +{ + return XmlDocument (textToParse).getDocumentElementIfTagMatches (requiredTag); +} + +std::unique_ptr parseXMLIfTagMatches (const File& file, StringRef requiredTag) +{ + return XmlDocument (file).getDocumentElementIfTagMatches (requiredTag); } void XmlDocument::setInputSource (InputSource* newSource) noexcept @@ -139,6 +147,15 @@ std::unique_ptr XmlDocument::getDocumentElement (const bool onlyRead return parseDocumentElement (originalText.getCharPointer(), onlyReadOuterDocumentElement); } +std::unique_ptr XmlDocument::getDocumentElementIfTagMatches (StringRef requiredTag) +{ + if (auto xml = getDocumentElement (true)) + if (xml->hasTagName (requiredTag)) + return getDocumentElement (false); + + return {}; +} + const String& XmlDocument::getLastParseError() const noexcept { return lastError; diff --git a/modules/juce_core/xml/juce_XmlDocument.h b/modules/juce_core/xml/juce_XmlDocument.h index e763a2d412..fe5a4c4300 100644 --- a/modules/juce_core/xml/juce_XmlDocument.h +++ b/modules/juce_core/xml/juce_XmlDocument.h @@ -98,12 +98,17 @@ public: tag, without having to parse the entire file @returns a new XmlElement which the caller will need to delete, or null if there was an error. - @see getLastParseError + @see getLastParseError, getDocumentElementIfTagMatches */ std::unique_ptr getDocumentElement (bool onlyReadOuterDocumentElement = false); - /** Returns the parsing error that occurred the last time getDocumentElement was called. + /** Does an inexpensive check to see whether the outer element has the given tag name, and + then does a full parse if it matches. + If the tag is different, or the XML parse fails, this will return nullptr. + */ + std::unique_ptr getDocumentElementIfTagMatches (StringRef requiredTag); + /** Returns the parsing error that occurred the last time getDocumentElement was called. @returns the error, or an empty string if there was no error. */ const String& getLastParseError() const noexcept; @@ -178,18 +183,31 @@ private: //============================================================================== /** Attempts to parse some XML text, returning a new XmlElement if it was valid. If the parse fails, this will return a nullptr - if you need more information about - errors or more parsing options, see the XmlDocument instead. - @see XmlDocument + errors or more parsing options, see the XmlDocument class instead. + @see XmlDocument, parseXMLIfTagMatches */ std::unique_ptr parseXML (const String& textToParse); /** Attempts to parse some XML text, returning a new XmlElement if it was valid. If the parse fails, this will return a nullptr - if you need more information about - errors or more parsing options, see the XmlDocument instead. - @see XmlDocument + errors or more parsing options, see the XmlDocument class instead. + @see XmlDocument, parseXMLIfTagMatches */ std::unique_ptr parseXML (const File& fileToParse); +/** Does an inexpensive check to see whether the top-level element has the given tag + name, and if that's true, does a full parse and returns the result. + If the outer tag doesn't match, or the XML has errors, this will return nullptr; + @see parseXML +*/ +std::unique_ptr parseXMLIfTagMatches (const String& textToParse, StringRef requiredTag); + +/** Does an inexpensive check to see whether the top-level element has the given tag + name, and if that's true, does a full parse and returns the result. + If the outer tag doesn't match, or the XML has errors, this will return nullptr; + @see parseXML +*/ +std::unique_ptr parseXMLIfTagMatches (const File& fileToParse, StringRef requiredTag); } // namespace juce diff --git a/modules/juce_core/xml/juce_XmlElement.h b/modules/juce_core/xml/juce_XmlElement.h index ac632a4433..edd142f091 100644 --- a/modules/juce_core/xml/juce_XmlElement.h +++ b/modules/juce_core/xml/juce_XmlElement.h @@ -130,7 +130,7 @@ namespace juce auto xmlString = animalsList.toString(); @endcode - @see XmlDocument + @see parseXML, parseXMLIfTagMatches, XmlDocument @tags{Core} */ diff --git a/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp b/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp index bbe788b0fc..39b85dc6a4 100644 --- a/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp +++ b/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp @@ -186,35 +186,20 @@ bool PropertiesFile::save() bool PropertiesFile::loadAsXml() { - XmlDocument parser (file); - - if (auto doc = parser.getDocumentElement (true)) + if (auto doc = parseXMLIfTagMatches (file, PropertyFileConstants::fileTag)) { - if (doc->hasTagName (PropertyFileConstants::fileTag)) + forEachXmlChildElementWithTagName (*doc, e, PropertyFileConstants::valueTag) { - doc = parser.getDocumentElement(); - - if (doc != nullptr) - { - forEachXmlChildElementWithTagName (*doc, e, PropertyFileConstants::valueTag) - { - auto name = e->getStringAttribute (PropertyFileConstants::nameAttribute); - - if (name.isNotEmpty()) - getAllProperties().set (name, - e->getFirstChildElement() != nullptr - ? e->getFirstChildElement()->toString (XmlElement::TextFormat().singleLine().withoutHeader()) - : e->getStringAttribute (PropertyFileConstants::valueAttribute)); - } - - return true; - } - - // must be a pretty broken XML file we're trying to parse here, - // or a sign that this object needs an InterProcessLock, - // or just a failure reading the file. This last reason is why - // we don't jassertfalse here. + auto name = e->getStringAttribute (PropertyFileConstants::nameAttribute); + + if (name.isNotEmpty()) + getAllProperties().set (name, + e->getFirstChildElement() != nullptr + ? e->getFirstChildElement()->toString (XmlElement::TextFormat().singleLine().withoutHeader()) + : e->getStringAttribute (PropertyFileConstants::valueAttribute)); } + + return true; } return false; @@ -231,7 +216,7 @@ bool PropertiesFile::saveAsXml() e->setAttribute (PropertyFileConstants::nameAttribute, props.getAllKeys() [i]); // if the value seems to contain xml, store it as such.. - if (auto childElement = XmlDocument::parse (props.getAllValues() [i])) + if (auto childElement = parseXML (props.getAllValues() [i])) e->addChildElement (childElement.release()); else e->setAttribute (PropertyFileConstants::valueAttribute, props.getAllValues() [i]); diff --git a/modules/juce_gui_basics/drawables/juce_Drawable.cpp b/modules/juce_gui_basics/drawables/juce_Drawable.cpp index e1f1f81c8b..06fdbe0001 100644 --- a/modules/juce_gui_basics/drawables/juce_Drawable.cpp +++ b/modules/juce_gui_basics/drawables/juce_Drawable.cpp @@ -180,14 +180,8 @@ std::unique_ptr Drawable::createFromImageData (const void* data, const } else { - auto asString = String::createStringFromData (data, (int) numBytes); - - XmlDocument doc (asString); - std::unique_ptr outer (doc.getDocumentElement (true)); - - if (outer != nullptr && outer->hasTagName ("svg")) - if (auto svg = doc.getDocumentElement()) - result = Drawable::createFromSVG (*svg); + if (auto svg = parseXMLIfTagMatches (String::createStringFromData (data, (int) numBytes), "svg")) + result = Drawable::createFromSVG (*svg); } return result; diff --git a/modules/juce_gui_basics/drawables/juce_SVGParser.cpp b/modules/juce_gui_basics/drawables/juce_SVGParser.cpp index 2049668dbb..a1e7dd01d1 100644 --- a/modules/juce_gui_basics/drawables/juce_SVGParser.cpp +++ b/modules/juce_gui_basics/drawables/juce_SVGParser.cpp @@ -1702,24 +1702,13 @@ std::unique_ptr Drawable::createFromSVG (const XmlElement& svgDocument return {}; SVGState state (&svgDocument); - return std::unique_ptr (state.parseSVGElement (SVGState::XmlPath (&svgDocument, nullptr))); + return std::unique_ptr (state.parseSVGElement (SVGState::XmlPath (&svgDocument, {}))); } std::unique_ptr Drawable::createFromSVGFile (const File& svgFile) { - XmlDocument doc (svgFile); - - if (auto outer = doc.getDocumentElement (true)) - { - if (outer->hasTagName ("svg")) - { - if (auto svgDocument = doc.getDocumentElement()) - { - SVGState state (svgDocument.get(), svgFile); - return std::unique_ptr (state.parseSVGElement (SVGState::XmlPath (svgDocument.get(), nullptr))); - } - } - } + if (auto xml = parseXMLIfTagMatches (svgFile, "svg")) + return createFromSVG (*xml); return {}; }