Browse Source

Added handy new function parseXMLIfTagMatches(), and refactored a lot of old code that was parsing XML in a more clunky way

tags/2021-05-28
jules 6 years ago
parent
commit
0fb8c8e82a
20 changed files with 135 additions and 153 deletions
  1. +1
    -3
      examples/Plugins/AudioPluginDemo.h
  2. +1
    -3
      examples/Plugins/InterAppAudioEffectPluginDemo.h
  3. +36
    -40
      examples/Utilities/AnalyticsCollectionDemo.h
  4. +13
    -13
      extras/AudioPluginHost/Source/Filters/FilterGraph.cpp
  5. +5
    -7
      extras/Projucer/Source/Application/jucer_ProjucerAnalytics.cpp
  6. +1
    -4
      extras/Projucer/Source/ComponentEditor/jucer_ComponentLayout.cpp
  7. +3
    -5
      extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp
  8. +1
    -4
      extras/Projucer/Source/ComponentEditor/jucer_PaintRoutine.cpp
  9. +1
    -1
      extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h
  10. +1
    -2
      extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CLion.h
  11. +1
    -3
      modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp
  12. +2
    -2
      modules/juce_audio_processors/processors/juce_AudioProcessor.cpp
  13. +1
    -1
      modules/juce_core/containers/juce_PropertySet.cpp
  14. +1
    -1
      modules/juce_core/network/juce_URL.cpp
  15. +25
    -8
      modules/juce_core/xml/juce_XmlDocument.cpp
  16. +24
    -6
      modules/juce_core/xml/juce_XmlDocument.h
  17. +1
    -1
      modules/juce_core/xml/juce_XmlElement.h
  18. +12
    -27
      modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp
  19. +2
    -8
      modules/juce_gui_basics/drawables/juce_Drawable.cpp
  20. +3
    -14
      modules/juce_gui_basics/drawables/juce_SVGParser.cpp

+ 1
- 3
examples/Plugins/AudioPluginDemo.h View File

@@ -293,9 +293,7 @@ public:
{ {
// Restore our plug-in's state from the xml representation stored in the above // Restore our plug-in's state from the xml representation stored in the above
// method. // method.
std::unique_ptr<XmlElement> xmlState (getXmlFromBinary (data, sizeInBytes));
if (xmlState.get() != nullptr)
if (auto xmlState = getXmlFromBinary (data, sizeInBytes))
state.replaceState (ValueTree::fromXml (*xmlState)); state.replaceState (ValueTree::fromXml (*xmlState));
} }


+ 1
- 3
examples/Plugins/InterAppAudioEffectPluginDemo.h View File

@@ -236,9 +236,7 @@ public:
void setStateInformation (const void* data, int sizeInBytes) override void setStateInformation (const void* data, int sizeInBytes) override
{ {
auto xmlState = std::unique_ptr<XmlElement> (getXmlFromBinary (data, sizeInBytes));
if (xmlState.get() != nullptr)
if (auto xmlState = getXmlFromBinary (data, sizeInBytes))
if (xmlState->hasTagName (parameters.state.getType())) if (xmlState->hasTagName (parameters.state.getType()))
parameters.state = ValueTree::fromXml (*xmlState); parameters.state = ValueTree::fromXml (*xmlState);
} }


+ 36
- 40
examples/Utilities/AnalyticsCollectionDemo.h View File

@@ -212,11 +212,10 @@ private:
// a binary format may be more suitable if it is faster - remember that this // 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! // method is called on app shutdown so it needs to complete quickly!
XmlDocument previouslySavedEvents (savedEventsFile);
std::unique_ptr<XmlElement> 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<XmlElement> ("events");
for (auto& event : eventsToSave) for (auto& event : eventsToSave)
{ {
@@ -248,45 +247,42 @@ private:
void restoreUnloggedEvents (std::deque<AnalyticsEvent>& restoredEventQueue) override void restoreUnloggedEvents (std::deque<AnalyticsEvent>& restoredEventQueue) override
{ {
XmlDocument savedEvents (savedEventsFile);
std::unique_ptr<XmlElement> 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<uint32> (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<uint32> (xmlEvent->getIntAttribute ("timestamp")),
parameters,
xmlEvent->getStringAttribute ("user_id"),
userProperties
});
savedEventsFile.deleteFile();
} }
savedEventsFile.deleteFile();
} }
const int initialPeriodMs = 1000; const int initialPeriodMs = 1000;


+ 13
- 13
extras/AudioPluginHost/Source/Filters/FilterGraph.cpp View File

@@ -221,26 +221,26 @@ void FilterGraph::newDocument()
Result FilterGraph::loadDocument (const File& file) Result FilterGraph::loadDocument (const File& file)
{ {
XmlDocument doc (file);
std::unique_ptr<XmlElement> 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) Result FilterGraph::saveDocument (const File& file)
{ {
std::unique_ptr<XmlElement> xml (createXml());
auto xml = createXml();
if (! xml->writeTo (file, {})) if (! xml->writeTo (file, {}))
return Result::fail ("Couldn't write to the file"); return Result::fail ("Couldn't write to the file");


+ 5
- 7
extras/Projucer/Source/Application/jucer_ProjucerAnalytics.cpp View File

@@ -178,11 +178,10 @@ void ProjucerAnalyticsDestination::stopLoggingEvents()
//============================================================================== //==============================================================================
void ProjucerAnalyticsDestination::saveUnloggedEvents (const std::deque<AnalyticsEvent>& eventsToSave) void ProjucerAnalyticsDestination::saveUnloggedEvents (const std::deque<AnalyticsEvent>& eventsToSave)
{ {
XmlDocument previouslySavedEvents (savedEventsFile);
std::unique_ptr<XmlElement> 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<XmlElement> ("events");
for (auto& event : eventsToSave) for (auto& event : eventsToSave)
{ {
@@ -214,10 +213,9 @@ void ProjucerAnalyticsDestination::saveUnloggedEvents (const std::deque<Analytic
void ProjucerAnalyticsDestination::restoreUnloggedEvents (std::deque<AnalyticsEvent>& restoredEventQueue) void ProjucerAnalyticsDestination::restoreUnloggedEvents (std::deque<AnalyticsEvent>& restoredEventQueue)
{ {
XmlDocument savedEvents (savedEventsFile);
std::unique_ptr<XmlElement> xml (savedEvents.getDocumentElement());
auto xml = parseXMLIfTagMatches (savedEventsFile, "events");
if (xml.get() == nullptr || xml->getTagName() != "events")
if (xml == nullptr)
return; return;
auto numEvents = xml->getNumChildElements(); auto numEvents = xml->getNumChildElements();


+ 1
- 4
extras/Projucer/Source/ComponentEditor/jucer_ComponentLayout.cpp View File

@@ -271,10 +271,7 @@ void ComponentLayout::copySelectedToClipboard()
void ComponentLayout::paste() void ComponentLayout::paste()
{ {
XmlDocument clip (SystemClipboard::getTextFromClipboard());
std::unique_ptr<XmlElement> doc (clip.getDocumentElement());
if (doc != nullptr && doc->hasTagName (clipboardXmlTag))
if (auto doc = parseXMLIfTagMatches (SystemClipboard::getTextFromClipboard(), clipboardXmlTag))
{ {
selected.deselectAll(); selected.deselectAll();


+ 3
- 5
extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp View File

@@ -624,16 +624,14 @@ void JucerDocument::extractCustomPaintSnippetsFromCppFile (const String& cppCont
std::unique_ptr<XmlElement> JucerDocument::pullMetaDataFromCppFile (const String& cpp) std::unique_ptr<XmlElement> JucerDocument::pullMetaDataFromCppFile (const String& cpp)
{ {
auto lines = StringArray::fromLines (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) if (startLine > 0)
{ {
const int endLine = indexOfLineStartingWith (lines, "END_JUCER_METADATA", startLine);
auto endLine = indexOfLineStartingWith (lines, "END_JUCER_METADATA", startLine);
if (endLine > 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; return nullptr;


+ 1
- 4
extras/Projucer/Source/ComponentEditor/jucer_PaintRoutine.cpp View File

@@ -302,10 +302,7 @@ void PaintRoutine::copySelectedToClipboard()
void PaintRoutine::paste() void PaintRoutine::paste()
{ {
XmlDocument clip (SystemClipboard::getTextFromClipboard());
std::unique_ptr<XmlElement> doc (clip.getDocumentElement());
if (doc != nullptr && doc->hasTagName (clipboardXmlTag))
if (auto doc = parseXMLIfTagMatches (SystemClipboard::getTextFromClipboard(), clipboardXmlTag))
{ {
selectedElements.deselectAll(); selectedElements.deselectAll();
selectedPoints.deselectAll(); selectedPoints.deselectAll();


+ 1
- 1
extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h View File

@@ -1543,7 +1543,7 @@ private:
std::unique_ptr<XmlElement> createManifestElement() const std::unique_ptr<XmlElement> createManifestElement() const
{ {
auto manifest = XmlDocument::parse (androidManifestCustomXmlElements.get());
auto manifest = parseXML (androidManifestCustomXmlElements.get());
if (manifest == nullptr) if (manifest == nullptr)
manifest = std::make_unique<XmlElement> ("manifest"); manifest = std::make_unique<XmlElement> ("manifest");


+ 1
- 2
extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CLion.h View File

@@ -1013,9 +1013,8 @@ private:
if (targetAttributeKeys.contains ("INFOPLIST_FILE")) if (targetAttributeKeys.contains ("INFOPLIST_FILE"))
{ {
auto plistFile = exporter.getTargetFolder().getChildFile (targetAttributes["INFOPLIST_FILE"]); auto plistFile = exporter.getTargetFolder().getChildFile (targetAttributes["INFOPLIST_FILE"]);
XmlDocument infoPlistData (plistFile);
if (auto plist = std::unique_ptr<XmlElement> (infoPlistData.getDocumentElement()))
if (auto plist = parseXML (plistFile))
{ {
if (auto* dict = plist->getChildByName ("dict")) if (auto* dict = plist->getChildByName ("dict"))
{ {


+ 1
- 3
modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp View File

@@ -2292,9 +2292,7 @@ public:
void setStateInformation (const void* data, int sizeInBytes) override void setStateInformation (const void* data, int sizeInBytes) override
{ {
std::unique_ptr<XmlElement> head (AudioProcessor::getXmlFromBinary (data, sizeInBytes));
if (head != nullptr)
if (auto head = AudioProcessor::getXmlFromBinary (data, sizeInBytes))
{ {
auto componentStream (createMemoryStreamForState (*head, "IComponent")); auto componentStream (createMemoryStreamForState (*head, "IComponent"));


+ 2
- 2
modules/juce_audio_processors/processors/juce_AudioProcessor.cpp View File

@@ -1121,8 +1121,8 @@ std::unique_ptr<XmlElement> AudioProcessor::getXmlFromBinary (const void* data,
auto stringLength = (int) ByteOrder::littleEndianInt (addBytesToPointer (data, 4)); auto stringLength = (int) ByteOrder::littleEndianInt (addBytesToPointer (data, 4));
if (stringLength > 0) if (stringLength > 0)
return XmlDocument::parse (String::fromUTF8 (static_cast<const char*> (data) + 8,
jmin ((sizeInBytes - 8), stringLength)));
return parseXML (String::fromUTF8 (static_cast<const char*> (data) + 8,
jmin ((sizeInBytes - 8), stringLength)));
} }
return {}; return {};


+ 1
- 1
modules/juce_core/containers/juce_PropertySet.cpp View File

@@ -112,7 +112,7 @@ bool PropertySet::getBoolValue (StringRef keyName, bool defaultValue) const noex
std::unique_ptr<XmlElement> PropertySet::getXmlValue (StringRef keyName) const std::unique_ptr<XmlElement> PropertySet::getXmlValue (StringRef keyName) const
{ {
return XmlDocument::parse (getValue (keyName));
return parseXML (getValue (keyName));
} }
void PropertySet::setValue (const String& keyName, const var& v) void PropertySet::setValue (const String& keyName, const var& v)


+ 1
- 1
modules/juce_core/network/juce_URL.cpp View File

@@ -790,7 +790,7 @@ String URL::readEntireTextStream (bool usePostCommand) const
std::unique_ptr<XmlElement> URL::readEntireXmlStream (bool usePostCommand) const std::unique_ptr<XmlElement> URL::readEntireXmlStream (bool usePostCommand) const
{ {
return XmlDocument::parse (readEntireTextStream (usePostCommand));
return parseXML (readEntireTextStream (usePostCommand));
} }
//============================================================================== //==============================================================================


+ 25
- 8
modules/juce_core/xml/juce_XmlDocument.cpp View File

@@ -30,24 +30,32 @@ XmlDocument::~XmlDocument() {}
std::unique_ptr<XmlElement> XmlDocument::parse (const File& file) std::unique_ptr<XmlElement> XmlDocument::parse (const File& file)
{ {
XmlDocument doc (file);
return doc.getDocumentElement();
return XmlDocument (file).getDocumentElement();
} }
std::unique_ptr<XmlElement> XmlDocument::parse (const String& xmlData)
std::unique_ptr<XmlElement> XmlDocument::parse (const String& textToParse)
{ {
XmlDocument doc (xmlData);
return doc.getDocumentElement();
return XmlDocument (textToParse).getDocumentElement();
} }
std::unique_ptr<XmlElement> parseXML (const String& textToParse) std::unique_ptr<XmlElement> parseXML (const String& textToParse)
{ {
return std::unique_ptr<XmlElement> (XmlDocument::parse (textToParse));
return XmlDocument (textToParse).getDocumentElement();
} }
std::unique_ptr<XmlElement> parseXML (const File& fileToParse)
std::unique_ptr<XmlElement> parseXML (const File& file)
{ {
return std::unique_ptr<XmlElement> (XmlDocument::parse (fileToParse));
return XmlDocument (file).getDocumentElement();
}
std::unique_ptr<XmlElement> parseXMLIfTagMatches (const String& textToParse, StringRef requiredTag)
{
return XmlDocument (textToParse).getDocumentElementIfTagMatches (requiredTag);
}
std::unique_ptr<XmlElement> parseXMLIfTagMatches (const File& file, StringRef requiredTag)
{
return XmlDocument (file).getDocumentElementIfTagMatches (requiredTag);
} }
void XmlDocument::setInputSource (InputSource* newSource) noexcept void XmlDocument::setInputSource (InputSource* newSource) noexcept
@@ -139,6 +147,15 @@ std::unique_ptr<XmlElement> XmlDocument::getDocumentElement (const bool onlyRead
return parseDocumentElement (originalText.getCharPointer(), onlyReadOuterDocumentElement); return parseDocumentElement (originalText.getCharPointer(), onlyReadOuterDocumentElement);
} }
std::unique_ptr<XmlElement> XmlDocument::getDocumentElementIfTagMatches (StringRef requiredTag)
{
if (auto xml = getDocumentElement (true))
if (xml->hasTagName (requiredTag))
return getDocumentElement (false);
return {};
}
const String& XmlDocument::getLastParseError() const noexcept const String& XmlDocument::getLastParseError() const noexcept
{ {
return lastError; return lastError;


+ 24
- 6
modules/juce_core/xml/juce_XmlDocument.h View File

@@ -98,12 +98,17 @@ public:
tag, without having to parse the entire file tag, without having to parse the entire file
@returns a new XmlElement which the caller will need to delete, or null if @returns a new XmlElement which the caller will need to delete, or null if
there was an error. there was an error.
@see getLastParseError
@see getLastParseError, getDocumentElementIfTagMatches
*/ */
std::unique_ptr<XmlElement> getDocumentElement (bool onlyReadOuterDocumentElement = false); std::unique_ptr<XmlElement> 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<XmlElement> 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. @returns the error, or an empty string if there was no error.
*/ */
const String& getLastParseError() const noexcept; const String& getLastParseError() const noexcept;
@@ -178,18 +183,31 @@ private:
//============================================================================== //==============================================================================
/** Attempts to parse some XML text, returning a new XmlElement if it was valid. /** 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 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<XmlElement> parseXML (const String& textToParse); std::unique_ptr<XmlElement> parseXML (const String& textToParse);
/** Attempts to parse some XML text, returning a new XmlElement if it was valid. /** 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 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<XmlElement> parseXML (const File& fileToParse); std::unique_ptr<XmlElement> 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<XmlElement> 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<XmlElement> parseXMLIfTagMatches (const File& fileToParse, StringRef requiredTag);
} // namespace juce } // namespace juce

+ 1
- 1
modules/juce_core/xml/juce_XmlElement.h View File

@@ -130,7 +130,7 @@ namespace juce
auto xmlString = animalsList.toString(); auto xmlString = animalsList.toString();
@endcode @endcode
@see XmlDocument
@see parseXML, parseXMLIfTagMatches, XmlDocument
@tags{Core} @tags{Core}
*/ */


+ 12
- 27
modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp View File

@@ -186,35 +186,20 @@ bool PropertiesFile::save()
bool PropertiesFile::loadAsXml() 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; return false;
@@ -231,7 +216,7 @@ bool PropertiesFile::saveAsXml()
e->setAttribute (PropertyFileConstants::nameAttribute, props.getAllKeys() [i]); e->setAttribute (PropertyFileConstants::nameAttribute, props.getAllKeys() [i]);
// if the value seems to contain xml, store it as such.. // 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()); e->addChildElement (childElement.release());
else else
e->setAttribute (PropertyFileConstants::valueAttribute, props.getAllValues() [i]); e->setAttribute (PropertyFileConstants::valueAttribute, props.getAllValues() [i]);


+ 2
- 8
modules/juce_gui_basics/drawables/juce_Drawable.cpp View File

@@ -180,14 +180,8 @@ std::unique_ptr<Drawable> Drawable::createFromImageData (const void* data, const
} }
else else
{ {
auto asString = String::createStringFromData (data, (int) numBytes);
XmlDocument doc (asString);
std::unique_ptr<XmlElement> 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; return result;


+ 3
- 14
modules/juce_gui_basics/drawables/juce_SVGParser.cpp View File

@@ -1702,24 +1702,13 @@ std::unique_ptr<Drawable> Drawable::createFromSVG (const XmlElement& svgDocument
return {}; return {};
SVGState state (&svgDocument); SVGState state (&svgDocument);
return std::unique_ptr<Drawable> (state.parseSVGElement (SVGState::XmlPath (&svgDocument, nullptr)));
return std::unique_ptr<Drawable> (state.parseSVGElement (SVGState::XmlPath (&svgDocument, {})));
} }
std::unique_ptr<Drawable> Drawable::createFromSVGFile (const File& svgFile) std::unique_ptr<Drawable> 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<Drawable> (state.parseSVGElement (SVGState::XmlPath (svgDocument.get(), nullptr)));
}
}
}
if (auto xml = parseXMLIfTagMatches (svgFile, "svg"))
return createFromSVG (*xml);
return {}; return {};
} }


Loading…
Cancel
Save