1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Added some free functions to help make XML parsing less verbose: parseXML()

This commit is contained in:
jules 2018-10-15 16:08:25 +01:00
parent 97c100b9c1
commit 768139a298
23 changed files with 116 additions and 94 deletions

View file

@ -1030,7 +1030,7 @@ private:
// this loads the embedded database XML file into memory // this loads the embedded database XML file into memory
void loadData() void loadData()
{ {
demoData.reset (XmlDocument::parse (loadEntireAssetIntoString ("demo table data.xml"))); demoData = parseXML (loadEntireAssetIntoString ("demo table data.xml"));
dataList = demoData->getChildByName ("DATA"); dataList = demoData->getChildByName ("DATA");
columnList = demoData->getChildByName ("COLUMNS"); columnList = demoData->getChildByName ("COLUMNS");

View file

@ -84,8 +84,7 @@ struct BackgroundLogo : public AnimatedContent
</svg> </svg>
)blahblah"; )blahblah";
std::unique_ptr<XmlElement> svg (XmlDocument::parse (logoData)); logo.reset (Drawable::createFromSVG (*parseXML (logoData)));
logo.reset (Drawable::createFromSVG (*svg));
} }
String getName() const override { return "Background Image"; } String getName() const override { return "Background Image"; }

View file

@ -163,9 +163,7 @@ public:
dragOver = false; dragOver = false;
repaint(); repaint();
std::unique_ptr<XmlElement> element (XmlDocument::parse (File (files[0]))); if (auto element = parseXML (File (files[0])))
if (element != nullptr)
{ {
if (auto* ePath = element->getChildByName ("path")) if (auto* ePath = element->getChildByName ("path"))
userText.setText (ePath->getStringAttribute ("d"), true); userText.setText (ePath->getStringAttribute ("d"), true);

View file

@ -713,7 +713,7 @@ namespace
#endif #endif
auto settingsFile = userAppData.getChildFile ("Projucer").getChildFile ("Projucer.settings"); auto settingsFile = userAppData.getChildFile ("Projucer").getChildFile ("Projucer.settings");
std::unique_ptr<XmlElement> xml (XmlDocument::parse (settingsFile)); auto xml = parseXML (settingsFile);
if (xml == nullptr) if (xml == nullptr)
ConsoleApplication::fail ("Settings file not valid!"); ConsoleApplication::fail ("Settings file not valid!");

View file

@ -108,12 +108,8 @@ private:
} }
if (drawable == nullptr) if (drawable == nullptr)
{ if (auto svg = parseXML (file))
std::unique_ptr<XmlElement> svg (XmlDocument::parse (file));
if (svg != nullptr)
drawable.reset (Drawable::createFromSVG (*svg)); drawable.reset (Drawable::createFromSVG (*svg));
}
facts.removeEmptyStrings (true); facts.removeEmptyStrings (true);
} }

View file

@ -938,9 +938,7 @@ void JucerDocumentEditor::getCommandInfo (const CommandID commandID, Application
bool canPaste = false; bool canPaste = false;
std::unique_ptr<XmlElement> doc (XmlDocument::parse (SystemClipboard::getTextFromClipboard())); if (auto doc = parseXML (SystemClipboard::getTextFromClipboard()))
if (doc != nullptr)
{ {
if (doc->hasTagName (ComponentLayout::clipboardXmlTag)) if (doc->hasTagName (ComponentLayout::clipboardXmlTag))
canPaste = (currentLayout != nullptr); canPaste = (currentLayout != nullptr);
@ -1156,9 +1154,7 @@ bool JucerDocumentEditor::perform (const InvocationInfo& info)
case StandardApplicationCommandIDs::paste: case StandardApplicationCommandIDs::paste:
{ {
std::unique_ptr<XmlElement> doc (XmlDocument::parse (SystemClipboard::getTextFromClipboard())); if (auto doc = parseXML (SystemClipboard::getTextFromClipboard()))
if (doc != nullptr)
{ {
if (doc->hasTagName (ComponentLayout::clipboardXmlTag)) if (doc->hasTagName (ComponentLayout::clipboardXmlTag))
{ {

View file

@ -422,7 +422,7 @@ private:
{ {
auto liveModules = project.getProjectRoot().getChildWithName (Ids::MODULES); auto liveModules = project.getProjectRoot().getChildWithName (Ids::MODULES);
std::unique_ptr<XmlElement> xml (XmlDocument::parse (project.getFile())); auto xml = parseXML (project.getFile());
if (xml == nullptr || ! xml->hasTagName (Ids::JUCERPROJECT.toString())) if (xml == nullptr || ! xml->hasTagName (Ids::JUCERPROJECT.toString()))
return false; return false;

View file

@ -39,8 +39,10 @@ struct LogoComponent : public Component
{ {
LogoComponent() LogoComponent()
{ {
std::unique_ptr<XmlElement> svg (XmlDocument::parse (BinaryData::background_logo_svg)); if (auto svg = parseXML (BinaryData::background_logo_svg))
logo.reset (Drawable::createFromSVG (*svg)); logo.reset (Drawable::createFromSVG (*svg));
else
jassertfalse;
} }
void paint (Graphics& g) override void paint (Graphics& g) override

View file

@ -552,7 +552,7 @@ static void forgetRecentFile (const File& file)
//============================================================================== //==============================================================================
Result Project::loadDocument (const File& file) Result Project::loadDocument (const File& file)
{ {
std::unique_ptr<XmlElement> xml (XmlDocument::parse (file)); auto xml = parseXML (file);
if (xml == nullptr || ! xml->hasTagName (Ids::JUCERPROJECT.toString())) if (xml == nullptr || ! xml->hasTagName (Ids::JUCERPROJECT.toString()))
return Result::fail ("Not a valid Jucer project!"); return Result::fail ("Not a valid Jucer project!");

View file

@ -1404,12 +1404,17 @@ private:
customStringsXmlContent << cfg.getCustomStringsXml(); customStringsXmlContent << cfg.getCustomStringsXml();
customStringsXmlContent << "\n</resources>"; customStringsXmlContent << "\n</resources>";
std::unique_ptr<XmlElement> strings (XmlDocument::parse (customStringsXmlContent)); if (auto strings = parseXML (customStringsXmlContent))
{
String dir = cfg.isDebug() ? "debug" : "release";
String subPath = "app/src/" + dir + "/res/values/string.xml";
String dir = cfg.isDebug() ? "debug" : "release"; writeXmlOrThrow (*strings, folder.getChildFile (subPath), "utf-8", 100, true);
String subPath = "app/src/" + dir + "/res/values/string.xml"; }
else
writeXmlOrThrow (*strings, folder.getChildFile (subPath), "utf-8", 100, true); {
jassertfalse; // needs handling?
}
} }
} }

View file

@ -1345,7 +1345,7 @@ public:
if (! shouldCreatePList()) if (! shouldCreatePList())
return; return;
std::unique_ptr<XmlElement> plist (XmlDocument::parse (owner.getPListToMergeString())); auto plist = parseXML (owner.getPListToMergeString());
if (plist == nullptr || ! plist->hasTagName ("plist")) if (plist == nullptr || ! plist->hasTagName ("plist"))
plist.reset (new XmlElement ("plist")); plist.reset (new XmlElement ("plist"));
@ -3195,9 +3195,7 @@ private:
bool xcschemeManagementPlistMatchesTargets (const File& plist) const bool xcschemeManagementPlistMatchesTargets (const File& plist) const
{ {
std::unique_ptr<XmlElement> xml (XmlDocument::parse (plist)); if (auto xml = parseXML (plist))
if (xml != nullptr)
if (auto* dict = xml->getChildByName ("dict")) if (auto* dict = xml->getChildByName ("dict"))
return parseNamesOfTargetsFromPlist (*dict) == getNamesOfTargets(); return parseNamesOfTargetsFromPlist (*dict) == getNamesOfTargets();

View file

@ -64,13 +64,11 @@ File AppearanceSettings::getSchemesFolder()
void AppearanceSettings::writeDefaultSchemeFile (const String& xmlString, const String& name) void AppearanceSettings::writeDefaultSchemeFile (const String& xmlString, const String& name)
{ {
const File file (getSchemesFolder().getChildFile (name).withFileExtension (getSchemeFileSuffix())); auto file = getSchemesFolder().getChildFile (name).withFileExtension (getSchemeFileSuffix());
AppearanceSettings settings (false); AppearanceSettings settings (false);
std::unique_ptr<XmlElement> xml (XmlDocument::parse (xmlString)); if (auto xml = parseXML (xmlString))
if (xml != nullptr)
settings.readFromXML (*xml); settings.readFromXML (*xml);
settings.writeToFile (file); settings.writeToFile (file);
@ -132,8 +130,10 @@ bool AppearanceSettings::readFromXML (const XmlElement& xml)
bool AppearanceSettings::readFromFile (const File& file) bool AppearanceSettings::readFromFile (const File& file)
{ {
const std::unique_ptr<XmlElement> xml (XmlDocument::parse (file)); if (auto xml = parseXML (file))
return xml != nullptr && readFromXML (*xml); return readFromXML (*xml);
return false;
} }
bool AppearanceSettings::writeToFile (const File& file) const bool AppearanceSettings::writeToFile (const File& file) const

View file

@ -39,15 +39,13 @@ public:
: DrawableButton (buttonName, buttonStyle) : DrawableButton (buttonName, buttonStyle)
{ {
// svg for thumbnail icon // svg for thumbnail icon
std::unique_ptr<XmlElement> svg (XmlDocument::parse (thumbSvg)); auto svg = parseXML (thumbSvg);
jassert (svg != nullptr); jassert (svg != nullptr);
thumb.reset (Drawable::createFromSVG (*svg)); thumb.reset (Drawable::createFromSVG (*svg));
// svg for thumbnail background highlight // svg for thumbnail background highlight
std::unique_ptr<XmlElement> backSvg (XmlDocument::parse (BinaryData::wizard_Highlight_svg)); auto backSvg = parseXML (BinaryData::wizard_Highlight_svg);
jassert (backSvg != nullptr); jassert (backSvg != nullptr);
hoverBackground.reset (Drawable::createFromSVG (*backSvg)); hoverBackground.reset (Drawable::createFromSVG (*backSvg));
name = buttonName; name = buttonName;

View file

@ -849,20 +849,21 @@ namespace WavFileHelpers
{ {
static void addToMetadata (StringPairArray& destValues, const String& source) static void addToMetadata (StringPairArray& destValues, const String& source)
{ {
std::unique_ptr<XmlElement> xml (XmlDocument::parse (source)); if (auto xml = parseXML (source))
if (xml != nullptr && xml->hasTagName ("ebucore:ebuCoreMain"))
{ {
if (auto* xml2 = xml->getChildByName ("ebucore:coreMetadata")) if (xml->hasTagName ("ebucore:ebuCoreMain"))
{ {
if (auto* xml3 = xml2->getChildByName ("ebucore:identifier")) if (auto xml2 = xml->getChildByName ("ebucore:coreMetadata"))
{ {
if (auto* xml4 = xml3->getChildByName ("dc:identifier")) if (auto xml3 = xml2->getChildByName ("ebucore:identifier"))
{ {
auto ISRCCode = xml4->getAllSubText().fromFirstOccurrenceOf ("ISRC:", false, true); if (auto xml4 = xml3->getChildByName ("dc:identifier"))
{
auto ISRCCode = xml4->getAllSubText().fromFirstOccurrenceOf ("ISRC:", false, true);
if (ISRCCode.isNotEmpty()) if (ISRCCode.isNotEmpty())
destValues.set (WavAudioFormat::ISRC, ISRCCode); destValues.set (WavAudioFormat::ISRC, ISRCCode);
}
} }
} }
} }

View file

@ -661,11 +661,11 @@ struct ModuleHandle : public ReferenceCountedObject
if (moduleMain != nullptr) if (moduleMain != nullptr)
{ {
vstXml.reset (XmlDocument::parse (file.withFileExtension ("vstxml"))); vstXml = parseXML (file.withFileExtension ("vstxml"));
#if JUCE_WINDOWS #if JUCE_WINDOWS
if (vstXml == nullptr) if (vstXml == nullptr)
vstXml.reset (XmlDocument::parse (getDLLResource (file, "VSTXML", 1))); vstXml = parseXML (getDLLResource (file, "VSTXML", 1));
#endif #endif
} }
@ -772,7 +772,7 @@ struct ModuleHandle : public ReferenceCountedObject
.findChildFiles (File::findFiles, false, "*.vstxml"); .findChildFiles (File::findFiles, false, "*.vstxml");
if (! vstXmlFiles.isEmpty()) if (! vstXmlFiles.isEmpty())
vstXml.reset (XmlDocument::parse (vstXmlFiles.getReference(0))); vstXml = parseXML (vstXmlFiles.getReference(0));
} }
} }

View file

@ -40,6 +40,16 @@ XmlElement* XmlDocument::parse (const String& xmlData)
return doc.getDocumentElement(); return doc.getDocumentElement();
} }
std::unique_ptr<XmlElement> parseXML (const String& textToParse)
{
return std::unique_ptr<XmlElement> (XmlDocument::parse (textToParse));
}
std::unique_ptr<XmlElement> parseXML (const File& fileToParse)
{
return std::unique_ptr<XmlElement> (XmlDocument::parse (fileToParse));
}
void XmlDocument::setInputSource (InputSource* newSource) noexcept void XmlDocument::setInputSource (InputSource* newSource) noexcept
{ {
inputSource.reset (newSource); inputSource.reset (newSource);

View file

@ -47,14 +47,15 @@ namespace juce
@endcode @endcode
Or you can use the static helper methods for quick parsing.. Or you can use the helper functions for much less verbose parsing..
@code @code
std::unique_ptr<XmlElement> xml (XmlDocument::parse (myXmlFile)); if (auto xml = parseXML (myXmlFile))
if (xml != nullptr && xml->hasTagName ("foobar"))
{ {
...etc if (xml->hasTagName ("foobar"))
{
...etc
}
} }
@endcode @endcode
@ -132,12 +133,14 @@ public:
//============================================================================== //==============================================================================
/** A handy static method that parses a file. /** A handy static method that parses a file.
This is a shortcut for creating an XmlDocument object and calling getDocumentElement() on it. This is a shortcut for creating an XmlDocument object and calling getDocumentElement() on it.
An even better shortcut is the juce::parseXML() function, which returns a std::unique_ptr<XmlElement>!
@returns a new XmlElement which the caller will need to delete, or null if there was an error. @returns a new XmlElement which the caller will need to delete, or null if there was an error.
*/ */
static XmlElement* parse (const File& file); static XmlElement* parse (const File& file);
/** A handy static method that parses some XML data. /** A handy static method that parses some XML data.
This is a shortcut for creating an XmlDocument object and calling getDocumentElement() on it. This is a shortcut for creating an XmlDocument object and calling getDocumentElement() on it.
An even better shortcut is the juce::parseXML() function, which returns a std::unique_ptr<XmlElement>!
@returns a new XmlElement which the caller will need to delete, or null if there was an error. @returns a new XmlElement which the caller will need to delete, or null if there was an error.
*/ */
static XmlElement* parse (const String& xmlData); static XmlElement* parse (const String& xmlData);
@ -172,4 +175,21 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (XmlDocument) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (XmlDocument)
}; };
//==============================================================================
/** 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
*/
std::unique_ptr<XmlElement> 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
*/
std::unique_ptr<XmlElement> parseXML (const File& fileToParse);
} // namespace juce } // namespace juce

View file

@ -46,7 +46,7 @@ namespace WindowsMessageHelpers
void dispatchMessageFromLParam (LPARAM lParam) void dispatchMessageFromLParam (LPARAM lParam)
{ {
if (MessageManager::MessageBase* message = reinterpret_cast<MessageManager::MessageBase*> (lParam)) if (auto message = reinterpret_cast<MessageManager::MessageBase*> (lParam))
{ {
JUCE_TRY JUCE_TRY
{ {
@ -154,7 +154,7 @@ bool MessageManager::dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMes
{ {
// if it's someone else's window being clicked on, and the focus is // if it's someone else's window being clicked on, and the focus is
// currently on a juce window, pass the kb focus over.. // currently on a juce window, pass the kb focus over..
HWND currentFocus = GetFocus(); auto currentFocus = GetFocus();
if (currentFocus == 0 || JuceWindowIdentifier::isJUCEWindow (currentFocus)) if (currentFocus == 0 || JuceWindowIdentifier::isJUCEWindow (currentFocus))
SetFocus (m.hwnd); SetFocus (m.hwnd);
@ -175,14 +175,14 @@ bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* cons
#if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client && JucePlugin_Build_Unity #if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client && JucePlugin_Build_Unity
if (juce_isRunningInUnity()) if (juce_isRunningInUnity())
return SendNotifyMessage (juce_messageWindowHandle, WindowsMessageHelpers::customMessageID, 0, (LPARAM) message) != 0; return SendNotifyMessage (juce_messageWindowHandle, WindowsMessageHelpers::customMessageID, 0, (LPARAM) message) != 0;
else
#endif #endif
return PostMessage (juce_messageWindowHandle, WindowsMessageHelpers::customMessageID, 0, (LPARAM) message) != 0; return PostMessage (juce_messageWindowHandle, WindowsMessageHelpers::customMessageID, 0, (LPARAM) message) != 0;
} }
void MessageManager::broadcastMessage (const String& value) void MessageManager::broadcastMessage (const String& value)
{ {
const String localCopy (value); auto localCopy = value;
Array<HWND> windows; Array<HWND> windows;
EnumWindows (&WindowsMessageHelpers::broadcastEnumWindowProc, (LPARAM) &windows); EnumWindows (&WindowsMessageHelpers::broadcastEnumWindowProc, (LPARAM) &windows);

View file

@ -27,16 +27,16 @@
namespace juce namespace juce
{ {
static XmlElement* findFontsConfFile() static std::unique_ptr<XmlElement> findFontsConfFile()
{ {
static const char* pathsToSearch[] = { "/etc/fonts/fonts.conf", static const char* pathsToSearch[] = { "/etc/fonts/fonts.conf",
"/usr/share/fonts/fonts.conf" }; "/usr/share/fonts/fonts.conf" };
for (auto* path : pathsToSearch) for (auto* path : pathsToSearch)
if (auto* xml = XmlDocument::parse (File (path))) if (auto xml = parseXML (File (path)))
return xml; return xml;
return nullptr; return {};
} }
StringArray FTTypefaceList::getDefaultFontDirectories() StringArray FTTypefaceList::getDefaultFontDirectories()
@ -48,9 +48,7 @@ StringArray FTTypefaceList::getDefaultFontDirectories()
if (fontDirs.isEmpty()) if (fontDirs.isEmpty())
{ {
std::unique_ptr<XmlElement> fontsInfo (findFontsConfFile()); if (auto fontsInfo = findFontsConfFile())
if (fontsInfo != nullptr)
{ {
forEachXmlChildElementWithTagName (*fontsInfo, e, "dir") forEachXmlChildElementWithTagName (*fontsInfo, e, "dir")
{ {

View file

@ -2655,7 +2655,7 @@ void LookAndFeel_V2::layoutFileBrowserComponent (FileBrowserComponent& browserCo
//============================================================================== //==============================================================================
static Drawable* createDrawableFromSVG (const char* data) static Drawable* createDrawableFromSVG (const char* data)
{ {
std::unique_ptr<XmlElement> xml (XmlDocument::parse (data)); auto xml = parseXML (data);
jassert (xml != nullptr); jassert (xml != nullptr);
return Drawable::createFromSVG (*xml); return Drawable::createFromSVG (*xml);
} }

View file

@ -294,7 +294,8 @@ std::unique_ptr<Drawable> JUCESplashScreen::getSplashScreenLogo()
</svg> </svg>
)JUCESPLASHSCREEN"; )JUCESPLASHSCREEN";
std::unique_ptr<XmlElement> svgXml (XmlDocument::parse (svgData)); auto svgXml = parseXML (svgData);
jassert (svgXml != nullptr);
return std::unique_ptr<Drawable> (Drawable::createFromSVG (*svgXml)); return std::unique_ptr<Drawable> (Drawable::createFromSVG (*svgXml));
} }

View file

@ -436,40 +436,42 @@ String TableHeaderComponent::toString() const
void TableHeaderComponent::restoreFromString (const String& storedVersion) void TableHeaderComponent::restoreFromString (const String& storedVersion)
{ {
std::unique_ptr<XmlElement> storedXml (XmlDocument::parse (storedVersion)); if (auto storedXML = parseXML (storedVersion))
int index = 0;
if (storedXml != nullptr && storedXml->hasTagName ("TABLELAYOUT"))
{ {
forEachXmlChildElement (*storedXml, col) if (storedXML->hasTagName ("TABLELAYOUT"))
{ {
auto tabId = col->getIntAttribute ("id"); int index = 0;
if (auto* ci = getInfoForId (tabId)) forEachXmlChildElement (*storedXML, col)
{ {
columns.move (columns.indexOf (ci), index); auto tabId = col->getIntAttribute ("id");
ci->width = col->getIntAttribute ("width");
setColumnVisible (tabId, col->getBoolAttribute ("visible")); if (auto* ci = getInfoForId (tabId))
{
columns.move (columns.indexOf (ci), index);
ci->width = col->getIntAttribute ("width");
setColumnVisible (tabId, col->getBoolAttribute ("visible"));
}
++index;
} }
++index; columnsResized = true;
sendColumnsChanged();
setSortColumnId (storedXML->getIntAttribute ("sortedCol"),
storedXML->getBoolAttribute ("sortForwards", true));
} }
columnsResized = true;
sendColumnsChanged();
setSortColumnId (storedXml->getIntAttribute ("sortedCol"),
storedXml->getBoolAttribute ("sortForwards", true));
} }
} }
//============================================================================== //==============================================================================
void TableHeaderComponent::addListener (Listener* const newListener) void TableHeaderComponent::addListener (Listener* newListener)
{ {
listeners.addIfNotAlreadyThere (newListener); listeners.addIfNotAlreadyThere (newListener);
} }
void TableHeaderComponent::removeListener (Listener* const listenerToRemove) void TableHeaderComponent::removeListener (Listener* listenerToRemove)
{ {
listeners.removeFirstMatchingValue (listenerToRemove); listeners.removeFirstMatchingValue (listenerToRemove);
} }

View file

@ -120,10 +120,10 @@ struct KeyFileUtils
{ {
key.applyToValue (val); key.applyToValue (val);
const MemoryBlock mb (val.toMemoryBlock()); auto mb = val.toMemoryBlock();
if (CharPointer_UTF8::isValidString (static_cast<const char*> (mb.getData()), (int) mb.getSize())) if (CharPointer_UTF8::isValidString (static_cast<const char*> (mb.getData()), (int) mb.getSize()))
xml.reset (XmlDocument::parse (mb.toString())); xml = parseXML (mb.toString());
} }
return xml != nullptr ? *xml : XmlElement("key"); return xml != nullptr ? *xml : XmlElement("key");
@ -465,9 +465,7 @@ OnlineUnlockStatus::UnlockResult OnlineUnlockStatus::attemptWebserverUnlock (con
DBG ("Reply from server: " << reply); DBG ("Reply from server: " << reply);
std::unique_ptr<XmlElement> xml (XmlDocument::parse (reply)); if (auto xml = parseXML (reply))
if (xml != nullptr)
return handleXmlReply (*xml); return handleXmlReply (*xml);
return handleFailedConnection(); return handleFailedConnection();