diff --git a/examples/Plugins/AudioPluginDemo.h b/examples/Plugins/AudioPluginDemo.h index 41760a3099..1ecfacd01e 100644 --- a/examples/Plugins/AudioPluginDemo.h +++ b/examples/Plugins/AudioPluginDemo.h @@ -285,9 +285,7 @@ public: void getStateInformation (MemoryBlock& destData) override { // Store an xml representation of our state. - std::unique_ptr xmlState (state.copyState().createXml()); - - if (xmlState.get() != nullptr) + if (auto xmlState = state.copyState().createXml()) copyXmlToBinary (*xmlState, destData); } diff --git a/examples/Plugins/InterAppAudioEffectPluginDemo.h b/examples/Plugins/InterAppAudioEffectPluginDemo.h index 46e8af1244..bf4442e284 100644 --- a/examples/Plugins/InterAppAudioEffectPluginDemo.h +++ b/examples/Plugins/InterAppAudioEffectPluginDemo.h @@ -230,8 +230,8 @@ public: //============================================================================== void getStateInformation (MemoryBlock& destData) override { - auto xml = std::unique_ptr (parameters.state.createXml()); - copyXmlToBinary (*xml, destData); + if (auto xml = parameters.state.createXml()) + copyXmlToBinary (*xml, destData); } void setStateInformation (const void* data, int sizeInBytes) override diff --git a/examples/Utilities/AnalyticsCollectionDemo.h b/examples/Utilities/AnalyticsCollectionDemo.h index 7074cc7420..cb43cf5065 100644 --- a/examples/Utilities/AnalyticsCollectionDemo.h +++ b/examples/Utilities/AnalyticsCollectionDemo.h @@ -243,7 +243,7 @@ private: xml->addChildElement (xmlEvent); } - xml->writeToFile (savedEventsFile, {}); + xml->writeTo (savedEventsFile, {}); } void restoreUnloggedEvents (std::deque& restoredEventQueue) override diff --git a/examples/Utilities/ChildProcessDemo.h b/examples/Utilities/ChildProcessDemo.h index c1c629bcef..bab208e201 100644 --- a/examples/Utilities/ChildProcessDemo.h +++ b/examples/Utilities/ChildProcessDemo.h @@ -69,10 +69,8 @@ static MemoryBlock valueTreeToMemoryBlock (const ValueTree& v) static String valueTreeToString (const ValueTree& v) { - std::unique_ptr xml (v.createXml()); - - if (xml.get() != nullptr) - return xml->createDocument ({}, true, false); + if (auto xml = v.createXml()) + return xml->toString (XmlElement::TextFormat().singleLine().withoutHeader()); return {}; } diff --git a/examples/Utilities/XMLandJSONDemo.h b/examples/Utilities/XMLandJSONDemo.h index 0231fa3019..42a9cec877 100644 --- a/examples/Utilities/XMLandJSONDemo.h +++ b/examples/Utilities/XMLandJSONDemo.h @@ -314,7 +314,7 @@ private: std::unique_ptr openness; if (rootItem.get() != nullptr) - openness.reset (rootItem->getOpennessState()); + openness = rootItem->getOpennessState(); createNewRootNode(); @@ -351,7 +351,7 @@ private: parsedXml.reset(); XmlDocument doc (codeDocument.getAllContent()); - parsedXml.reset (doc.getDocumentElement()); + parsedXml = doc.getDocumentElement(); if (parsedXml.get() == nullptr) { diff --git a/extras/AudioPluginHost/Source/Filters/FilterGraph.cpp b/extras/AudioPluginHost/Source/Filters/FilterGraph.cpp index 07ee7c67bf..5e1bc9d1ea 100644 --- a/extras/AudioPluginHost/Source/Filters/FilterGraph.cpp +++ b/extras/AudioPluginHost/Source/Filters/FilterGraph.cpp @@ -242,7 +242,7 @@ Result FilterGraph::saveDocument (const File& file) { std::unique_ptr xml (createXml()); - if (! xml->writeToFile (file, {})) + if (! xml->writeTo (file, {})) return Result::fail ("Couldn't write to the file"); return Result::ok(); diff --git a/extras/AudioPluginHost/Source/UI/MainHostWindow.cpp b/extras/AudioPluginHost/Source/UI/MainHostWindow.cpp index 4b3522b150..d8aa6827be 100644 --- a/extras/AudioPluginHost/Source/UI/MainHostWindow.cpp +++ b/extras/AudioPluginHost/Source/UI/MainHostWindow.cpp @@ -85,10 +85,8 @@ MainHostWindow::MainHostWindow() RuntimePermissions::request (RuntimePermissions::recordAudio, [safeThis] (bool granted) mutable { - std::unique_ptr savedAudioState (getAppProperties().getUserSettings() - ->getXmlValue ("audioDeviceState")); - - safeThis->deviceManager.initialise (granted ? 256 : 0, 256, savedAudioState.get(), true); + auto savedState = getAppProperties().getUserSettings()->getXmlValue ("audioDeviceState"); + safeThis->deviceManager.initialise (granted ? 256 : 0, 256, savedState.get(), true); }); #if JUCE_IOS || JUCE_ANDROID @@ -110,9 +108,7 @@ MainHostWindow::MainHostWindow() InternalPluginFormat internalFormat; internalFormat.getAllTypes (internalTypes); - std::unique_ptr savedPluginList (getAppProperties().getUserSettings()->getXmlValue ("pluginList")); - - if (savedPluginList != nullptr) + if (auto savedPluginList = getAppProperties().getUserSettings()->getXmlValue ("pluginList")) knownPluginList.recreateFromXml (*savedPluginList); for (auto* t : internalTypes) @@ -221,9 +217,7 @@ void MainHostWindow::changeListenerCallback (ChangeBroadcaster* changed) // save the plugin list every time it gets changed, so that if we're scanning // and it crashes, we've still saved the previous ones - std::unique_ptr savedPluginList (knownPluginList.createXml()); - - if (savedPluginList != nullptr) + if (auto savedPluginList = std::unique_ptr (knownPluginList.createXml())) { getAppProperties().getUserSettings()->setValue ("pluginList", savedPluginList.get()); getAppProperties().saveIfNeeded(); diff --git a/extras/Projucer/Source/Application/jucer_MainWindow.cpp b/extras/Projucer/Source/Application/jucer_MainWindow.cpp index 641fcf5108..68d2ddab0a 100644 --- a/extras/Projucer/Source/Application/jucer_MainWindow.cpp +++ b/extras/Projucer/Source/Application/jucer_MainWindow.cpp @@ -60,9 +60,7 @@ MainWindow::MainWindow() { commandManager.getKeyMappings()->resetToDefaultMappings(); - std::unique_ptr keys (getGlobalProperties().getXmlValue ("keyMappings")); - - if (keys != nullptr) + if (auto keys = getGlobalProperties().getXmlValue ("keyMappings")) commandManager.getKeyMappings()->restoreFromXml (*keys); addKeyListener (commandManager.getKeyMappings()); diff --git a/extras/Projucer/Source/Application/jucer_ProjucerAnalytics.cpp b/extras/Projucer/Source/Application/jucer_ProjucerAnalytics.cpp index 438fcd6784..f5dfc1e43a 100644 --- a/extras/Projucer/Source/Application/jucer_ProjucerAnalytics.cpp +++ b/extras/Projucer/Source/Application/jucer_ProjucerAnalytics.cpp @@ -209,7 +209,7 @@ void ProjucerAnalyticsDestination::saveUnloggedEvents (const std::dequeaddChildElement (xmlEvent); } - xml->writeToFile (savedEventsFile, {}); + xml->writeTo (savedEventsFile, {}); } void ProjucerAnalyticsDestination::restoreUnloggedEvents (std::deque& restoredEventQueue) diff --git a/extras/Projucer/Source/ComponentEditor/UI/jucer_JucerDocumentEditor.cpp b/extras/Projucer/Source/ComponentEditor/UI/jucer_JucerDocumentEditor.cpp index ca86c37dfe..de2c5fa0e8 100644 --- a/extras/Projucer/Source/ComponentEditor/UI/jucer_JucerDocumentEditor.cpp +++ b/extras/Projucer/Source/ComponentEditor/UI/jucer_JucerDocumentEditor.cpp @@ -609,7 +609,7 @@ void JucerDocumentEditor::saveLastSelectedTab() const { auto& projectProps = project->getStoredProperties(); - std::unique_ptr root (projectProps.getXmlValue ("GUIComponentsLastTab")); + auto root = projectProps.getXmlValue ("GUIComponentsLastTab"); if (root == nullptr) root.reset (new XmlElement ("FILES")); @@ -631,20 +631,10 @@ void JucerDocumentEditor::saveLastSelectedTab() const void JucerDocumentEditor::restoreLastSelectedTab() { if (document != nullptr) - { if (auto* project = document->getCppDocument().getProject()) - { - std::unique_ptr root (project->getStoredProperties().getXmlValue ("GUIComponentsLastTab")); - - if (root != nullptr) - { - auto* child = root->getChildByName (document->getCppFile().getFileName()); - - if (child != nullptr) + if (auto root = project->getStoredProperties().getXmlValue ("GUIComponentsLastTab")) + if (auto child = root->getChildByName (document->getCppFile().getFileName())) tabbedComponent.setCurrentTabIndex (child->getIntAttribute ("tab")); - } - } - } } //============================================================================== diff --git a/extras/Projucer/Source/ComponentEditor/UI/jucer_PaintRoutinePanel.cpp b/extras/Projucer/Source/ComponentEditor/UI/jucer_PaintRoutinePanel.cpp index 078dcd14de..d9796b751f 100644 --- a/extras/Projucer/Source/ComponentEditor/UI/jucer_PaintRoutinePanel.cpp +++ b/extras/Projucer/Source/ComponentEditor/UI/jucer_PaintRoutinePanel.cpp @@ -109,7 +109,7 @@ public: void updateList() { - std::unique_ptr state (propsPanel->getOpennessState()); + auto state = propsPanel->getOpennessState(); clear(); diff --git a/extras/Projucer/Source/ComponentEditor/jucer_ComponentLayout.cpp b/extras/Projucer/Source/ComponentEditor/jucer_ComponentLayout.cpp index d2542911b4..b0f4f9ad2c 100644 --- a/extras/Projucer/Source/ComponentEditor/jucer_ComponentLayout.cpp +++ b/extras/Projucer/Source/ComponentEditor/jucer_ComponentLayout.cpp @@ -254,19 +254,19 @@ void ComponentLayout::copySelectedToClipboard() for (int i = 0; i < components.size(); ++i) { - Component* const c = components.getUnchecked(i); + auto c = components.getUnchecked(i); if (selected.isSelected (c)) { - if (ComponentTypeHandler* const type = ComponentTypeHandler::getHandlerFor (*c)) + if (auto type = ComponentTypeHandler::getHandlerFor (*c)) { - XmlElement* const e = type->createXmlFor (c, this); + auto e = type->createXmlFor (c, this); clip.addChildElement (e); } } } - SystemClipboard::copyTextToClipboard (clip.createDocument ("", false, false)); + SystemClipboard::copyTextToClipboard (clip.toString()); } void ComponentLayout::paste() diff --git a/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp b/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp index b1e1355ac7..e5a096e36d 100644 --- a/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp +++ b/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp @@ -426,7 +426,7 @@ void JucerDocument::fillInGeneratedCode (GeneratedCode& code) const std::unique_ptr e (createXml()); jassert (e != nullptr); - code.jucerMetadata = e->createDocument ("", false, false); + code.jucerMetadata = e->toString (XmlElement::TextFormat().withoutHeader()); resources.fillInGeneratedCode (code); @@ -621,7 +621,7 @@ void JucerDocument::extractCustomPaintSnippetsFromCppFile (const String& cppCont applyCustomPaintSnippets (customPaintSnippets); } -XmlElement* JucerDocument::pullMetaDataFromCppFile (const String& cpp) +std::unique_ptr JucerDocument::pullMetaDataFromCppFile (const String& cpp) { auto lines = StringArray::fromLines (cpp); diff --git a/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.h b/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.h index c059562663..7bbe60c674 100644 --- a/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.h +++ b/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.h @@ -43,7 +43,7 @@ public: ~JucerDocument() override; static bool isValidJucerCppFile (const File&); - static XmlElement* pullMetaDataFromCppFile (const String& cpp); + static std::unique_ptr pullMetaDataFromCppFile (const String& cpp); static JucerDocument* createForCppFile (Project*, const File&); void changed(); diff --git a/extras/Projucer/Source/ComponentEditor/jucer_PaintRoutine.cpp b/extras/Projucer/Source/ComponentEditor/jucer_PaintRoutine.cpp index f7957da525..62add31939 100644 --- a/extras/Projucer/Source/ComponentEditor/jucer_PaintRoutine.cpp +++ b/extras/Projucer/Source/ComponentEditor/jucer_PaintRoutine.cpp @@ -297,7 +297,7 @@ void PaintRoutine::copySelectedToClipboard() if (selectedElements.isSelected (pe)) clip.addChildElement (pe->createXml()); - SystemClipboard::copyTextToClipboard (clip.createDocument ("", false, false)); + SystemClipboard::copyTextToClipboard (clip.toString()); } void PaintRoutine::paste() diff --git a/extras/Projucer/Source/Licenses/jucer_LicenseController.cpp b/extras/Projucer/Source/Licenses/jucer_LicenseController.cpp index 681a0263fb..c73d734579 100644 --- a/extras/Projucer/Source/Licenses/jucer_LicenseController.cpp +++ b/extras/Projucer/Source/Licenses/jucer_LicenseController.cpp @@ -293,9 +293,7 @@ LicenseState LicenseController::licenseStateFromOldSettings (XmlElement* license LicenseState LicenseController::licenseStateFromSettings (PropertiesFile& props) { - std::unique_ptr licenseXml (props.getXmlValue ("license")); - - if (licenseXml != nullptr) + if (auto licenseXml = props.getXmlValue ("license")) { // this is here for backwards compatibility with old-style settings files using XML text elements if (licenseXml->getChildElementAllSubText ("type", {}) != String()) diff --git a/extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.cpp b/extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.cpp index 75219aaee8..e9fb6807fd 100644 --- a/extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.cpp +++ b/extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.cpp @@ -315,9 +315,7 @@ void ProjectContentComponent::reloadLastOpenDocuments() { if (project != nullptr) { - std::unique_ptr xml (project->getStoredProperties().getXmlValue ("lastDocs")); - - if (xml != nullptr) + if (auto xml = project->getStoredProperties().getXmlValue ("lastDocs")) { recentDocumentList.restoreFromXML (*project, *xml); showDocument (recentDocumentList.getCurrentDocument(), true); diff --git a/extras/Projucer/Source/Project/jucer_Project.cpp b/extras/Projucer/Source/Project/jucer_Project.cpp index 8d0c8adf33..0bf27f9acd 100644 --- a/extras/Projucer/Source/Project/jucer_Project.cpp +++ b/extras/Projucer/Source/Project/jucer_Project.cpp @@ -697,18 +697,15 @@ void Project::moveTemporaryDirectory (const File& newParentDirectory) bool Project::saveProjectRootToFile() { - std::unique_ptr xml (projectRoot.createXml()); - - if (xml == nullptr) + if (auto xml = projectRoot.createXml()) { - jassertfalse; - return false; + MemoryOutputStream mo; + xml->writeTo (mo, {}); + return FileHelpers::overwriteFileWithNewDataIfDifferent (getFile(), mo); } - MemoryOutputStream mo; - xml->writeToStream (mo, {}); - - return FileHelpers::overwriteFileWithNewDataIfDifferent (getFile(), mo); + jassertfalse; + return false; } //============================================================================== diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h index e576c588a1..82037c24d7 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h @@ -1510,9 +1510,9 @@ private: } //============================================================================== - XmlElement* createManifestXML() const + std::unique_ptr createManifestXML() const { - auto* manifest = createManifestElement(); + auto manifest = createManifestElement(); createSupportsScreensElement (*manifest); createPermissionElements (*manifest); @@ -1532,12 +1532,12 @@ private: return manifest; } - XmlElement* createManifestElement() const + std::unique_ptr createManifestElement() const { - auto* manifest = XmlDocument::parse (androidManifestCustomXmlElements.get()); + auto manifest = XmlDocument::parse (androidManifestCustomXmlElements.get()); if (manifest == nullptr) - manifest = new XmlElement ("manifest"); + manifest = std::make_unique ("manifest"); setAttributeIfNotPresent (*manifest, "xmlns:android", "http://schemas.android.com/apk/res/android"); setAttributeIfNotPresent (*manifest, "android:versionCode", androidVersionCode.get()); diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CLion.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CLion.h index ba9eaf90d9..48213db58d 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CLion.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CLion.h @@ -1014,9 +1014,8 @@ private: { auto plistFile = exporter.getTargetFolder().getChildFile (targetAttributes["INFOPLIST_FILE"]); XmlDocument infoPlistData (plistFile); - std::unique_ptr plist (infoPlistData.getDocumentElement()); - if (plist != nullptr) + if (auto plist = std::unique_ptr (infoPlistData.getDocumentElement())) { if (auto* dict = plist->getChildByName ("dict")) { @@ -1039,7 +1038,11 @@ private: } auto updatedPlist = getTargetFolder().getChildFile (config.getName() + "-" + plistFile.getFileName()); - plist->writeToFile (updatedPlist, ""); + + XmlElement::TextFormat format; + format.dtd = ""; + plist->writeTo (updatedPlist, format); + targetAttributes.set ("INFOPLIST_FILE", ("${CMAKE_CURRENT_SOURCE_DIR}/" + updatedPlist.getFileName()).quoted()); } else diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h index 362c7af0d2..81efee8d70 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h @@ -1607,8 +1607,9 @@ public: dict->addChildElement (new XmlElement (e)); MemoryOutputStream mo; - plist->writeToStream (mo, ""); - + XmlElement::TextFormat format; + format.dtd = ""; + plist->writeTo (mo, format); overwriteFileIfDifferentOrThrow (infoPlistFile, mo); } diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.h index 2fa735a2d9..4fae76432c 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.h @@ -443,14 +443,16 @@ protected: throw SaveError ("Can't create folder: " + dirToCreate.getFullPathName()); } - static void writeXmlOrThrow (const XmlElement& xml, const File& file, const String& encoding, int maxCharsPerLine, bool useUnixNewLines = false) + static void writeXmlOrThrow (const XmlElement& xml, const File& file, const String& encoding, + int maxCharsPerLine, bool useUnixNewLines = false) { - MemoryOutputStream mo; + XmlElement::TextFormat format; + format.customEncoding = encoding; + format.lineWrapLength = maxCharsPerLine; + format.newLineChars = useUnixNewLines ? "\r\n" : "\n"; - if (useUnixNewLines) - mo.setNewLineString ("\n"); - - xml.writeToStream (mo, String(), false, true, encoding, maxCharsPerLine); + MemoryOutputStream mo (8192); + xml.writeTo (mo, format); overwriteFileIfDifferentOrThrow (file, mo); } diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectSaver.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectSaver.h index 31322935b4..b21a1aff77 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectSaver.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectSaver.h @@ -314,8 +314,8 @@ private: { static const char* filesToKeep[] = { ".svn", ".cvs", "CMakeLists.txt" }; - for (int i = 0; i < numElementsInArray (filesToKeep); ++i) - if (filename == filesToKeep[i]) + for (auto* f : filesToKeep) + if (filename == f) return true; return false; @@ -323,25 +323,27 @@ private: void writeMainProjectFile() { - std::unique_ptr xml (project.getProjectRoot().createXml()); - jassert (xml != nullptr); - - if (xml != nullptr) + if (auto xml = project.getProjectRoot().createXml()) { - MemoryOutputStream mo; - mo.setNewLineString (projectLineFeed); + XmlElement::TextFormat format; + format.newLineChars = projectLineFeed.toRawUTF8(); - xml->writeToStream (mo, String()); + MemoryOutputStream mo (8192); + xml->writeTo (mo, format); replaceFileIfDifferent (projectFile, mo); } + else + { + jassertfalse; + } } static int findLongestModuleName (const OwnedArray& modules) { int longest = 0; - for (int i = modules.size(); --i >= 0;) - longest = jmax (longest, modules.getUnchecked(i)->getID().length()); + for (auto& m : modules) + longest = jmax (longest, m->getID().length()); return longest; } @@ -352,8 +354,8 @@ private: { StringArray userContent; bool foundCodeSection = false; - auto lines = StringArray::fromLines (getAppConfigFile().loadFileAsString()); + for (int i = 0; i < lines.size(); ++i) { if (lines[i].contains ("[BEGIN_USER_CODE_SECTION]")) @@ -385,7 +387,7 @@ private: return; } - for (LibraryModule** moduleIter = modules.begin(); moduleIter != modules.end(); ++moduleIter) + for (auto moduleIter = modules.begin(); moduleIter != modules.end(); ++moduleIter) { if (auto* module = *moduleIter) { @@ -463,18 +465,14 @@ private: auto longestName = findLongestModuleName (modules); - for (int k = 0; k < modules.size(); ++k) - { - auto* m = modules.getUnchecked(k); + for (auto& m : modules) out << "#define JUCE_MODULE_AVAILABLE_" << m->getID() << String::repeatedString (" ", longestName + 5 - m->getID().length()) << " 1" << newLine; - } out << newLine << "#define JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED 1" << newLine; - for (int j = 0; j < modules.size(); ++j) + for (auto& m : modules) { - auto* m = modules.getUnchecked(j); OwnedArray flags; m->getConfigFlags (project, flags); @@ -619,6 +617,7 @@ private: if (resourceFile.getNumFiles() > 0) { auto dataNamespace = project.getBinaryDataNamespaceString().trim(); + if (dataNamespace.isEmpty()) dataNamespace = "BinaryData"; @@ -627,6 +626,7 @@ private: Array binaryDataFiles; auto maxSize = project.getMaxBinaryFileSize(); + if (maxSize <= 0) maxSize = 10 * 1024 * 1024; @@ -636,10 +636,8 @@ private: { hasBinaryData = true; - for (int i = 0; i < binaryDataFiles.size(); ++i) + for (auto& f : binaryDataFiles) { - auto& f = binaryDataFiles.getReference(i); - filesCreated.add (f); generatedFilesGroup.addFileRetainingSortOrder (f, ! f.hasFileExtension (".h")); } diff --git a/extras/Projucer/Source/Settings/jucer_AppearanceSettings.cpp b/extras/Projucer/Source/Settings/jucer_AppearanceSettings.cpp index e43d035125..33c68f90f4 100644 --- a/extras/Projucer/Source/Settings/jucer_AppearanceSettings.cpp +++ b/extras/Projucer/Source/Settings/jucer_AppearanceSettings.cpp @@ -138,8 +138,10 @@ bool AppearanceSettings::readFromFile (const File& file) bool AppearanceSettings::writeToFile (const File& file) const { - const std::unique_ptr xml (settings.createXml()); - return xml != nullptr && xml->writeToFile (file, String()); + if (auto xml = settings.createXml()) + return xml->writeTo (file, {}); + + return false; } Font AppearanceSettings::getDefaultCodeFont() diff --git a/extras/Projucer/Source/Settings/jucer_StoredSettings.cpp b/extras/Projucer/Source/Settings/jucer_StoredSettings.cpp index 49ea0e1eab..f4a01795db 100644 --- a/extras/Projucer/Source/Settings/jucer_StoredSettings.cpp +++ b/extras/Projucer/Source/Settings/jucer_StoredSettings.cpp @@ -136,14 +136,10 @@ void StoredSettings::reload() propertyFiles.clear(); propertyFiles.add (createPropsFile ("Projucer", false)); - std::unique_ptr projectDefaultsXml (propertyFiles.getFirst()->getXmlValue ("PROJECT_DEFAULT_SETTINGS")); - - if (projectDefaultsXml != nullptr) + if (auto projectDefaultsXml = propertyFiles.getFirst()->getXmlValue ("PROJECT_DEFAULT_SETTINGS")) projectDefaults = ValueTree::fromXml (*projectDefaultsXml); - std::unique_ptr fallbackPathsXml (propertyFiles.getFirst()->getXmlValue ("FALLBACK_PATHS")); - - if (fallbackPathsXml != nullptr) + if (auto fallbackPathsXml = propertyFiles.getFirst()->getXmlValue ("FALLBACK_PATHS")) fallbackPaths = ValueTree::fromXml (*fallbackPathsXml); // recent files... diff --git a/extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.cpp b/extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.cpp index 8a46dee955..368e7a974c 100644 --- a/extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.cpp +++ b/extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.cpp @@ -146,10 +146,9 @@ Result PIPGenerator::createJucerFile() auto outputFile = outputDirectory.getChildFile (metadata[Ids::name].toString() + ".jucer"); - std::unique_ptr xml (root.createXml()); - - if (xml->writeToFile (outputFile, {})) - return Result::ok(); + if (auto xml = root.createXml()) + if (xml->writeTo (outputFile, {})) + return Result::ok(); return Result::fail ("Failed to create .jucer file in " + outputDirectory.getFullPathName()); } diff --git a/extras/Projucer/Source/Utility/UI/jucer_JucerTreeViewBase.cpp b/extras/Projucer/Source/Utility/UI/jucer_JucerTreeViewBase.cpp index 861f490d2a..617f3b693e 100644 --- a/extras/Projucer/Source/Utility/UI/jucer_JucerTreeViewBase.cpp +++ b/extras/Projucer/Source/Utility/UI/jucer_JucerTreeViewBase.cpp @@ -37,14 +37,12 @@ void TreePanelBase::setRoot (JucerTreeViewBase* root) if (project != nullptr) { - const std::unique_ptr treeOpenness (project->getStoredProperties() - .getXmlValue (opennessStateKey)); - if (treeOpenness != nullptr) + if (auto treeOpenness = project->getStoredProperties().getXmlValue (opennessStateKey)) { tree.restoreOpennessState (*treeOpenness, true); for (int i = tree.getNumSelectedItems(); --i >= 0;) - if (JucerTreeViewBase* item = dynamic_cast (tree.getSelectedItem (i))) + if (auto item = dynamic_cast (tree.getSelectedItem (i))) item->cancelDelayedSelectionTimer(); } } diff --git a/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h b/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h index 04fa8099c5..a5a6889d68 100644 --- a/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h +++ b/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h @@ -314,7 +314,7 @@ public: if (settings != nullptr) { - savedState.reset (settings->getXmlValue ("audioSetup")); + savedState = settings->getXmlValue ("audioSetup"); #if ! (JUCE_IOS || JUCE_ANDROID) shouldMuteInput.setValue (settings->getBoolValue ("shouldMuteInput", true)); diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp index 9b694d57b3..c42ba07dd3 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp @@ -1105,7 +1105,7 @@ void AudioProcessor::copyXmlToBinary (const XmlElement& xml, juce::MemoryBlock& MemoryOutputStream out (destData, false); out.writeInt (magicXmlNumber); out.writeInt (0); - xml.writeToStream (out, String(), true, false); + xml.writeTo (out, XmlElement::TextFormat().singleLine()); out.writeByte (0); } @@ -1114,10 +1114,9 @@ void AudioProcessor::copyXmlToBinary (const XmlElement& xml, juce::MemoryBlock& = ByteOrder::swapIfBigEndian ((uint32) destData.getSize() - 9); } -XmlElement* AudioProcessor::getXmlFromBinary (const void* data, const int sizeInBytes) +std::unique_ptr AudioProcessor::getXmlFromBinary (const void* data, const int sizeInBytes) { - if (sizeInBytes > 8 - && ByteOrder::littleEndianInt (data) == magicXmlNumber) + if (sizeInBytes > 8 && ByteOrder::littleEndianInt (data) == magicXmlNumber) { auto stringLength = (int) ByteOrder::littleEndianInt (addBytesToPointer (data, 4)); @@ -1126,7 +1125,7 @@ XmlElement* AudioProcessor::getXmlFromBinary (const void* data, const int sizeIn jmin ((sizeInBytes - 8), stringLength))); } - return nullptr; + return {}; } bool AudioProcessor::canApplyBusCountChange (bool isInput, bool isAdding, diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.h b/modules/juce_audio_processors/processors/juce_AudioProcessor.h index 18f2ebecc6..d89ab3ce03 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.h @@ -1477,11 +1477,9 @@ public: juce::MemoryBlock& destData); /** Retrieves an XML element that was stored as binary with the copyXmlToBinary() method. - - This might return nullptr if the data's unsuitable or corrupted. Otherwise it will return - an XmlElement object that the caller must delete when no longer needed. + This might return nullptr if the data's unsuitable or corrupted. */ - static XmlElement* getXmlFromBinary (const void* data, int sizeInBytes); + static std::unique_ptr getXmlFromBinary (const void* data, int sizeInBytes); /** @internal */ static void JUCE_CALLTYPE setTypeOfNextNewPlugin (WrapperType); diff --git a/modules/juce_core/containers/juce_PropertySet.cpp b/modules/juce_core/containers/juce_PropertySet.cpp index b1938de478..cbb93ec7e7 100644 --- a/modules/juce_core/containers/juce_PropertySet.cpp +++ b/modules/juce_core/containers/juce_PropertySet.cpp @@ -23,7 +23,7 @@ namespace juce { -PropertySet::PropertySet (const bool ignoreCaseOfKeyNames) +PropertySet::PropertySet (bool ignoreCaseOfKeyNames) : properties (ignoreCaseOfKeyNames), fallbackProperties (nullptr), ignoreCaseOfKeys (ignoreCaseOfKeyNames) @@ -65,8 +65,7 @@ void PropertySet::clear() String PropertySet::getValue (StringRef keyName, const String& defaultValue) const noexcept { const ScopedLock sl (lock); - - const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys); + auto index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys); if (index >= 0) return properties.getAllValues() [index]; @@ -75,10 +74,10 @@ String PropertySet::getValue (StringRef keyName, const String& defaultValue) con : defaultValue; } -int PropertySet::getIntValue (StringRef keyName, const int defaultValue) const noexcept +int PropertySet::getIntValue (StringRef keyName, int defaultValue) const noexcept { const ScopedLock sl (lock); - const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys); + auto index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys); if (index >= 0) return properties.getAllValues() [index].getIntValue(); @@ -87,10 +86,10 @@ int PropertySet::getIntValue (StringRef keyName, const int defaultValue) const n : defaultValue; } -double PropertySet::getDoubleValue (StringRef keyName, const double defaultValue) const noexcept +double PropertySet::getDoubleValue (StringRef keyName, double defaultValue) const noexcept { const ScopedLock sl (lock); - const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys); + auto index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys); if (index >= 0) return properties.getAllValues()[index].getDoubleValue(); @@ -99,10 +98,10 @@ double PropertySet::getDoubleValue (StringRef keyName, const double defaultValue : defaultValue; } -bool PropertySet::getBoolValue (StringRef keyName, const bool defaultValue) const noexcept +bool PropertySet::getBoolValue (StringRef keyName, bool defaultValue) const noexcept { const ScopedLock sl (lock); - const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys); + auto index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys); if (index >= 0) return properties.getAllValues() [index].getIntValue() != 0; @@ -111,7 +110,7 @@ bool PropertySet::getBoolValue (StringRef keyName, const bool defaultValue) cons : defaultValue; } -XmlElement* PropertySet::getXmlValue (StringRef keyName) const +std::unique_ptr PropertySet::getXmlValue (StringRef keyName) const { return XmlDocument::parse (getValue (keyName)); } @@ -122,10 +121,9 @@ void PropertySet::setValue (const String& keyName, const var& v) if (keyName.isNotEmpty()) { - const String value (v.toString()); + auto value = v.toString(); const ScopedLock sl (lock); - - const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys); + auto index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys); if (index < 0 || properties.getAllValues() [index] != value) { @@ -140,7 +138,7 @@ void PropertySet::removeValue (StringRef keyName) if (keyName.isNotEmpty()) { const ScopedLock sl (lock); - const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys); + auto index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys); if (index >= 0) { @@ -150,10 +148,10 @@ void PropertySet::removeValue (StringRef keyName) } } -void PropertySet::setValue (const String& keyName, const XmlElement* const xml) +void PropertySet::setValue (const String& keyName, const XmlElement* xml) { setValue (keyName, xml == nullptr ? var() - : var (xml->createDocument ("", true))); + : var (xml->toString (XmlElement::TextFormat().singleLine().withoutHeader()))); } bool PropertySet::containsKey (StringRef keyName) const noexcept @@ -177,14 +175,15 @@ void PropertySet::setFallbackPropertySet (PropertySet* fallbackProperties_) noex fallbackProperties = fallbackProperties_; } -XmlElement* PropertySet::createXml (const String& nodeName) const +std::unique_ptr PropertySet::createXml (const String& nodeName) const { + auto xml = std::make_unique (nodeName); + const ScopedLock sl (lock); - XmlElement* const xml = new XmlElement (nodeName); for (int i = 0; i < properties.getAllKeys().size(); ++i) { - XmlElement* const e = xml->createNewChildElement ("VALUE"); + auto e = xml->createNewChildElement ("VALUE"); e->setAttribute ("name", properties.getAllKeys()[i]); e->setAttribute ("val", properties.getAllValues()[i]); } diff --git a/modules/juce_core/containers/juce_PropertySet.h b/modules/juce_core/containers/juce_PropertySet.h index de4f4247f5..de83ba21a2 100644 --- a/modules/juce_core/containers/juce_PropertySet.h +++ b/modules/juce_core/containers/juce_PropertySet.h @@ -113,7 +113,7 @@ public: @param keyName the name of the property to retrieve */ - XmlElement* getXmlValue (StringRef keyName) const; + std::unique_ptr getXmlValue (StringRef keyName) const; //============================================================================== /** Sets a named property. @@ -161,7 +161,7 @@ public: The string parameter is the tag name that should be used for the node. @see restoreFromXml */ - XmlElement* createXml (const String& nodeName) const; + std::unique_ptr createXml (const String& nodeName) const; /** Reloads a set of properties that were previously stored as XML. The node passed in must have been created by the createXml() method. diff --git a/modules/juce_core/network/juce_URL.cpp b/modules/juce_core/network/juce_URL.cpp index f68180f162..9bfdd2d462 100644 --- a/modules/juce_core/network/juce_URL.cpp +++ b/modules/juce_core/network/juce_URL.cpp @@ -788,7 +788,7 @@ String URL::readEntireTextStream (bool usePostCommand) const return {}; } -XmlElement* URL::readEntireXmlStream (bool usePostCommand) const +std::unique_ptr URL::readEntireXmlStream (bool usePostCommand) const { return XmlDocument::parse (readEntireTextStream (usePostCommand)); } @@ -797,14 +797,14 @@ XmlElement* URL::readEntireXmlStream (bool usePostCommand) const URL URL::withParameter (const String& parameterName, const String& parameterValue) const { - URL u (*this); + auto u = *this; u.addParameter (parameterName, parameterValue); return u; } URL URL::withParameters (const StringPairArray& parametersToAdd) const { - URL u (*this); + auto u = *this; for (int i = 0; i < parametersToAdd.size(); ++i) u.addParameter (parametersToAdd.getAllKeys()[i], @@ -820,7 +820,7 @@ URL URL::withPOSTData (const String& newPostData) const URL URL::withPOSTData (const MemoryBlock& newPostData) const { - URL u (*this); + auto u = *this; u.postData = newPostData; return u; } @@ -834,7 +834,7 @@ URL::Upload::Upload (const String& param, const String& name, URL URL::withUpload (Upload* const f) const { - URL u (*this); + auto u = *this; for (int i = u.filesToUpload.size(); --i >= 0;) if (u.filesToUpload.getObjectPointerUnchecked(i)->parameterName == f->parameterName) diff --git a/modules/juce_core/network/juce_URL.h b/modules/juce_core/network/juce_URL.h index abfc456ca1..dae57513d8 100644 --- a/modules/juce_core/network/juce_URL.h +++ b/modules/juce_core/network/juce_URL.h @@ -487,7 +487,7 @@ public: @see readEntireBinaryStream, readEntireTextStream */ - XmlElement* readEntireXmlStream (bool usePostCommand = false) const; + std::unique_ptr readEntireXmlStream (bool usePostCommand = false) const; //============================================================================== /** Adds escape sequences to a string to encode any characters that aren't diff --git a/modules/juce_core/xml/juce_XmlDocument.cpp b/modules/juce_core/xml/juce_XmlDocument.cpp index 3132841587..3b1ef37ef2 100644 --- a/modules/juce_core/xml/juce_XmlDocument.cpp +++ b/modules/juce_core/xml/juce_XmlDocument.cpp @@ -28,13 +28,13 @@ XmlDocument::XmlDocument (const File& file) : inputSource (new FileInputSource XmlDocument::~XmlDocument() {} -XmlElement* XmlDocument::parse (const File& file) +std::unique_ptr XmlDocument::parse (const File& file) { XmlDocument doc (file); return doc.getDocumentElement(); } -XmlElement* XmlDocument::parse (const String& xmlData) +std::unique_ptr XmlDocument::parse (const String& xmlData) { XmlDocument doc (xmlData); return doc.getDocumentElement(); @@ -99,7 +99,7 @@ namespace XmlIdentifierChars } } -XmlElement* XmlDocument::getDocumentElement (const bool onlyReadOuterDocumentElement) +std::unique_ptr XmlDocument::getDocumentElement (const bool onlyReadOuterDocumentElement) { if (originalText.isEmpty() && inputSource != nullptr) { @@ -176,8 +176,8 @@ juce_wchar XmlDocument::readNextChar() noexcept return c; } -XmlElement* XmlDocument::parseDocumentElement (String::CharPointerType textToParse, - const bool onlyReadOuterDocumentElement) +std::unique_ptr XmlDocument::parseDocumentElement (String::CharPointerType textToParse, + bool onlyReadOuterDocumentElement) { input = textToParse; errorOccurred = false; @@ -202,10 +202,10 @@ XmlElement* XmlDocument::parseDocumentElement (String::CharPointerType textToPar std::unique_ptr result (readNextElement (! onlyReadOuterDocumentElement)); if (! errorOccurred) - return result.release(); + return result; } - return nullptr; + return {}; } bool XmlDocument::parseHeader() diff --git a/modules/juce_core/xml/juce_XmlDocument.h b/modules/juce_core/xml/juce_XmlDocument.h index 267d565c3f..e763a2d412 100644 --- a/modules/juce_core/xml/juce_XmlDocument.h +++ b/modules/juce_core/xml/juce_XmlDocument.h @@ -100,7 +100,7 @@ public: there was an error. @see getLastParseError */ - XmlElement* getDocumentElement (bool onlyReadOuterDocumentElement = false); + std::unique_ptr getDocumentElement (bool onlyReadOuterDocumentElement = false); /** Returns the parsing error that occurred the last time getDocumentElement was called. @@ -136,14 +136,14 @@ public: An even better shortcut is the juce::parseXML() function, which returns a std::unique_ptr! @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 std::unique_ptr parse (const File& file); /** A handy static method that parses some XML data. 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! @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 std::unique_ptr parse (const String& xmlData); //============================================================================== @@ -156,7 +156,7 @@ private: bool needToLoadDTD = false, ignoreEmptyTextElements = true; std::unique_ptr inputSource; - XmlElement* parseDocumentElement (String::CharPointerType, bool outer); + std::unique_ptr parseDocumentElement (String::CharPointerType, bool outer); void setLastError (const String&, bool carryOn); bool parseHeader(); bool parseDTD(); diff --git a/modules/juce_core/xml/juce_XmlElement.cpp b/modules/juce_core/xml/juce_XmlElement.cpp index b03b9d025d..f5eacfccd8 100644 --- a/modules/juce_core/xml/juce_XmlElement.cpp +++ b/modules/juce_core/xml/juce_XmlElement.cpp @@ -167,50 +167,46 @@ XmlElement::~XmlElement() noexcept //============================================================================== namespace XmlOutputFunctions { - #if 0 // (These functions are just used to generate the lookup table used below) - bool isLegalXmlCharSlow (const juce_wchar character) noexcept + namespace LegalCharLookupTable { - if ((character >= 'a' && character <= 'z') - || (character >= 'A' && character <= 'Z') - || (character >= '0' && character <= '9')) - return true; - - const char* t = " .,;:-()_+=?!'#@[]/\\*%~{}$|"; - - do + template + struct Bit { - if (((juce_wchar) (uint8) *t) == character) - return true; - } - while (*++t != 0); - - return false; - } - - void generateLegalCharLookupTable() - { - uint8 n[32] = { 0 }; - for (int i = 0; i < 256; ++i) - if (isLegalXmlCharSlow (i)) - n[i >> 3] |= (1 << (i & 7)); - - String s; - for (int i = 0; i < 32; ++i) - s << (int) n[i] << ", "; + enum { v = ((c >= 'a' && c <= 'z') + || (c >= 'A' && c <= 'Z') + || (c >= '0' && c <= '9') + || c == ' ' || c == '.' || c == ',' || c == ';' + || c == ':' || c == '-' || c == '(' || c == ')' + || c == '_' || c == '+' || c == '=' || c == '?' + || c == '!' || c == '$' || c == '#' || c == '@' + || c == '[' || c == ']' || c == '/' || c == '|' + || c == '*' || c == '%' || c == '~' || c == '{' + || c == '}' || c == '\'' || c == '\\') + ? (1 << (c & 7)) : 0 }; + }; + + template + struct Byte + { + enum { v = Bit::v | Bit::v + | Bit::v | Bit::v + | Bit::v | Bit::v + | Bit::v | Bit::v }; + }; - DBG (s); - } - #endif + static bool isLegal (uint32 c) noexcept + { + static const unsigned char legalChars[] = { Byte< 0>::v, Byte< 1>::v, Byte< 2>::v, Byte< 3>::v, + Byte< 4>::v, Byte< 5>::v, Byte< 6>::v, Byte< 7>::v, + Byte< 8>::v, Byte< 9>::v, Byte<10>::v, Byte<11>::v, + Byte<12>::v, Byte<13>::v, Byte<14>::v, Byte<15>::v }; - static bool isLegalXmlChar (const uint32 c) noexcept - { - static const unsigned char legalChars[] = { 0, 0, 0, 0, 187, 255, 255, 175, 255, - 255, 255, 191, 254, 255, 255, 127 }; - return c < sizeof (legalChars) * 8 - && (legalChars [c >> 3] & (1 << (c & 7))) != 0; + return c < sizeof (legalChars) * 8 + && (legalChars[c >> 3] & (1 << (c & 7))) != 0; + } } - static void escapeIllegalXmlChars (OutputStream& outputStream, const String& text, const bool changeNewLines) + static void escapeIllegalXmlChars (OutputStream& outputStream, const String& text, bool changeNewLines) { auto t = text.getCharPointer(); @@ -221,7 +217,7 @@ namespace XmlOutputFunctions if (character == 0) break; - if (isLegalXmlChar (character)) + if (LegalCharLookupTable::isLegal (character)) { outputStream << (char) character; } @@ -257,13 +253,12 @@ namespace XmlOutputFunctions } void XmlElement::writeElementAsText (OutputStream& outputStream, - const int indentationLevel, - const int lineWrapLength) const + int indentationLevel, + int lineWrapLength, + const char* newLineChars) const { - using namespace XmlOutputFunctions; - if (indentationLevel >= 0) - writeSpaces (outputStream, (size_t) indentationLevel); + XmlOutputFunctions::writeSpaces (outputStream, (size_t) indentationLevel); if (! isTextElement()) { @@ -278,8 +273,8 @@ void XmlElement::writeElementAsText (OutputStream& outputStream, { if (lineLen > lineWrapLength && indentationLevel >= 0) { - outputStream << newLine; - writeSpaces (outputStream, attIndent); + outputStream << newLineChars; + XmlOutputFunctions::writeSpaces (outputStream, attIndent); lineLen = 0; } @@ -287,7 +282,7 @@ void XmlElement::writeElementAsText (OutputStream& outputStream, outputStream.writeByte (' '); outputStream << att->name; outputStream.write ("=\"", 2); - escapeIllegalXmlChars (outputStream, att->value, true); + XmlOutputFunctions::escapeIllegalXmlChars (outputStream, att->value, true); outputStream.writeByte ('"'); lineLen += (int) (outputStream.getPosition() - startPos); } @@ -302,24 +297,25 @@ void XmlElement::writeElementAsText (OutputStream& outputStream, { if (child->isTextElement()) { - escapeIllegalXmlChars (outputStream, child->getText(), false); + XmlOutputFunctions::escapeIllegalXmlChars (outputStream, child->getText(), false); lastWasTextNode = true; } else { if (indentationLevel >= 0 && ! lastWasTextNode) - outputStream << newLine; + outputStream << newLineChars; child->writeElementAsText (outputStream, - lastWasTextNode ? 0 : (indentationLevel + (indentationLevel >= 0 ? 2 : 0)), lineWrapLength); + lastWasTextNode ? 0 : (indentationLevel + (indentationLevel >= 0 ? 2 : 0)), lineWrapLength, + newLineChars); lastWasTextNode = false; } } if (indentationLevel >= 0 && ! lastWasTextNode) { - outputStream << newLine; - writeSpaces (outputStream, (size_t) indentationLevel); + outputStream << newLineChars; + XmlOutputFunctions::writeSpaces (outputStream, (size_t) indentationLevel); } outputStream.write (""; + output << ""; + + if (options.newLineChars == nullptr) output.writeByte (' '); else - output << newLine << newLine; + output << options.newLineChars + << options.newLineChars; } - if (dtdToUse.isNotEmpty()) + if (options.dtd.isNotEmpty()) { - output << dtdToUse; + output << options.dtd; - if (allOnOneLine) + if (options.newLineChars == nullptr) output.writeByte (' '); else - output << newLine; + output << options.newLineChars; } - writeElementAsText (output, allOnOneLine ? -1 : 0, lineWrapLength); + writeElementAsText (output, options.newLineChars == nullptr ? -1 : 0, + options.lineWrapLength, + options.newLineChars); - if (! allOnOneLine) - output << newLine; + if (options.newLineChars != nullptr) + output << options.newLineChars; } -bool XmlElement::writeToFile (const File& file, StringRef dtdToUse, - StringRef encodingType, int lineWrapLength) const +bool XmlElement::writeTo (const File& destinationFile, const TextFormat& options) const { - TemporaryFile tempFile (file); + TemporaryFile tempFile (destinationFile); { FileOutputStream out (tempFile.getFile()); @@ -392,7 +414,7 @@ bool XmlElement::writeToFile (const File& file, StringRef dtdToUse, if (! out.openedOk()) return false; - writeToStream (out, dtdToUse, false, true, encodingType, lineWrapLength); + writeTo (out, options); out.flush(); // (called explicitly to force an fsync on posix) if (out.getStatus().failed()) @@ -402,6 +424,48 @@ bool XmlElement::writeToFile (const File& file, StringRef dtdToUse, return tempFile.overwriteTargetFileWithTemporary(); } +String XmlElement::createDocument (StringRef dtdToUse, bool allOnOneLine, bool includeXmlHeader, + StringRef encodingType, int lineWrapLength) const +{ + TextFormat options; + options.dtd = dtdToUse; + options.customEncoding = encodingType; + options.addDefaultHeader = includeXmlHeader; + options.lineWrapLength = lineWrapLength; + + if (allOnOneLine) + options.newLineChars = nullptr; + + return toString (options); +} + +void XmlElement::writeToStream (OutputStream& output, StringRef dtdToUse, + bool allOnOneLine, bool includeXmlHeader, + StringRef encodingType, int lineWrapLength) const +{ + TextFormat options; + options.dtd = dtdToUse; + options.customEncoding = encodingType; + options.addDefaultHeader = includeXmlHeader; + options.lineWrapLength = lineWrapLength; + + if (allOnOneLine) + options.newLineChars = nullptr; + + writeTo (output, options); +} + +bool XmlElement::writeToFile (const File& file, StringRef dtdToUse, + StringRef encodingType, int lineWrapLength) const +{ + TextFormat options; + options.dtd = dtdToUse; + options.customEncoding = encodingType; + options.lineWrapLength = lineWrapLength; + + return writeTo (file, options); +} + //============================================================================== bool XmlElement::hasTagName (StringRef possibleTagName) const noexcept { @@ -608,7 +672,7 @@ int XmlElement::getNumChildElements() const noexcept XmlElement* XmlElement::getChildElement (const int index) const noexcept { - return firstChildElement [index].get(); + return firstChildElement[index].get(); } XmlElement* XmlElement::getChildByName (StringRef childName) const noexcept diff --git a/modules/juce_core/xml/juce_XmlElement.h b/modules/juce_core/xml/juce_XmlElement.h index 91de12781d..ac632a4433 100644 --- a/modules/juce_core/xml/juce_XmlElement.h +++ b/modules/juce_core/xml/juce_XmlElement.h @@ -126,8 +126,8 @@ namespace juce animalsList.addChildElement (giraffe); } - // now we can turn the whole thing into a text document.. - String myXmlDoc = animalsList.createDocument (String()); + // now we can turn the whole thing into textual XML + auto xmlString = animalsList.toString(); @endcode @see XmlDocument @@ -184,74 +184,37 @@ public: bool ignoreOrderOfAttributes) const noexcept; //============================================================================== - /** Returns an XML text document that represents this element. - - The string returned can be parsed to recreate the same XmlElement that - was used to create it. - - @param dtdToUse the DTD to add to the document - @param allOnOneLine if true, this means that the document will not contain any - linefeeds, so it'll be smaller but not very easy to read. - @param includeXmlHeader whether to add the "::Appender; friend class NamedValueSet; - LinkedListPointer nextListItem; - LinkedListPointer firstChildElement; + LinkedListPointer nextListItem, firstChildElement; LinkedListPointer attributes; String tagName; XmlElement (int) noexcept; void copyChildrenAndAttributesFrom (const XmlElement&); - void writeElementAsText (OutputStream&, int indentationLevel, int lineWrapLength) const; + void writeElementAsText (OutputStream&, int, int, const char*) const; void getChildElementsAsArray (XmlElement**) const noexcept; void reorderChildElements (XmlElement**, int) noexcept; XmlAttributeNode* getAttribute (StringRef) const noexcept; diff --git a/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp b/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp index c9a63f0da3..bbe788b0fc 100644 --- a/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp +++ b/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp @@ -187,32 +187,34 @@ bool PropertiesFile::save() bool PropertiesFile::loadAsXml() { XmlDocument parser (file); - std::unique_ptr doc (parser.getDocumentElement (true)); - if (doc != nullptr && doc->hasTagName (PropertyFileConstants::fileTag)) + if (auto doc = parser.getDocumentElement (true)) { - doc.reset (parser.getDocumentElement()); - - if (doc != nullptr) + if (doc->hasTagName (PropertyFileConstants::fileTag)) { - forEachXmlChildElementWithTagName (*doc, e, PropertyFileConstants::valueTag) - { - auto name = e->getStringAttribute (PropertyFileConstants::nameAttribute); + doc = parser.getDocumentElement(); - if (name.isNotEmpty()) - getAllProperties().set (name, - e->getFirstChildElement() != nullptr - ? e->getFirstChildElement()->createDocument ("", true) - : e->getStringAttribute (PropertyFileConstants::valueAttribute)); + 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; } - 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. } - - // 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. } return false; @@ -229,8 +231,8 @@ 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])) - e->addChildElement (childElement); + if (auto childElement = XmlDocument::parse (props.getAllValues() [i])) + e->addChildElement (childElement.release()); else e->setAttribute (PropertyFileConstants::valueAttribute, props.getAllValues() [i]); } @@ -240,7 +242,7 @@ bool PropertiesFile::saveAsXml() if (pl != nullptr && ! pl->isLocked()) return false; // locking failure.. - if (doc.writeToFile (file, {})) + if (doc.writeTo (file, {})) { needsWriting = false; return true; diff --git a/modules/juce_data_structures/values/juce_ValueTree.cpp b/modules/juce_data_structures/values/juce_ValueTree.cpp index 8d5aa02f8d..76d0d6f461 100644 --- a/modules/juce_data_structures/values/juce_ValueTree.cpp +++ b/modules/juce_data_structures/values/juce_ValueTree.cpp @@ -992,9 +992,9 @@ void ValueTree::sendPropertyChangeMessage (const Identifier& property) } //============================================================================== -XmlElement* ValueTree::createXml() const +std::unique_ptr ValueTree::createXml() const { - return object != nullptr ? object->createXml() : nullptr; + return std::unique_ptr (object != nullptr ? object->createXml() : nullptr); } ValueTree ValueTree::fromXml (const XmlElement& xml) @@ -1015,12 +1015,10 @@ ValueTree ValueTree::fromXml (const XmlElement& xml) return {}; } -String ValueTree::toXmlString() const +String ValueTree::toXmlString (const XmlElement::TextFormat& format) const { - std::unique_ptr xml (createXml()); - - if (xml != nullptr) - return xml->createDocument ({}); + if (auto xml = createXml()) + return xml->toString (format); return {}; } @@ -1188,8 +1186,8 @@ public: } expect (v1.isEquivalentTo (ValueTree::readFromGZIPData (zipped.getData(), zipped.getDataSize()))); - std::unique_ptr xml1 (v1.createXml()); - std::unique_ptr xml2 (v2.createCopy().createXml()); + auto xml1 = v1.createXml(); + auto xml2 = v2.createCopy().createXml(); expect (xml1->isEquivalentTo (xml2.get(), false)); auto v4 = v2.createCopy(); diff --git a/modules/juce_data_structures/values/juce_ValueTree.h b/modules/juce_data_structures/values/juce_ValueTree.h index 5357c6e422..3b649d470e 100644 --- a/modules/juce_data_structures/values/juce_ValueTree.h +++ b/modules/juce_data_structures/values/juce_ValueTree.h @@ -430,7 +430,7 @@ public: The caller must delete the object that is returned. @see fromXml, toXmlString */ - XmlElement* createXml() const; + std::unique_ptr createXml() const; /** Tries to recreate a tree from its XML representation. This isn't designed to cope with random XML data - it should only be fed XML that was created @@ -442,7 +442,7 @@ public: This is quite handy for debugging purposes, as it provides a quick way to view a tree. @see createXml() */ - String toXmlString() const; + String toXmlString (const XmlElement::TextFormat& format = {}) const; //============================================================================== /** Stores this tree (and all its children) in a binary format. diff --git a/modules/juce_events/interprocess/juce_NetworkServiceDiscovery.cpp b/modules/juce_events/interprocess/juce_NetworkServiceDiscovery.cpp index 1e5474f5e0..3175ad06a4 100644 --- a/modules/juce_events/interprocess/juce_NetworkServiceDiscovery.cpp +++ b/modules/juce_events/interprocess/juce_NetworkServiceDiscovery.cpp @@ -65,7 +65,7 @@ void NetworkServiceDiscovery::Advertiser::sendBroadcast() auto localAddress = IPAddress::getLocalAddress(); message.setAttribute ("address", localAddress.toString()); auto broadcastAddress = IPAddress::getInterfaceBroadcastAddress (localAddress); - auto data = message.createDocument ({}, true, false); + auto data = message.toString (XmlElement::TextFormat().singleLine().withoutHeader()); socket.write (broadcastAddress.toString(), broadcastPort, data.toRawUTF8(), (int) data.getNumBytesAsUTF8()); } diff --git a/modules/juce_gui_basics/properties/juce_PropertyPanel.cpp b/modules/juce_gui_basics/properties/juce_PropertyPanel.cpp index e0f6292171..e72e805858 100644 --- a/modules/juce_gui_basics/properties/juce_PropertyPanel.cpp +++ b/modules/juce_gui_basics/properties/juce_PropertyPanel.cpp @@ -319,9 +319,9 @@ void PropertyPanel::removeSection (int sectionIndex) } //============================================================================== -XmlElement* PropertyPanel::getOpennessState() const +std::unique_ptr PropertyPanel::getOpennessState() const { - auto* xml = new XmlElement ("PROPERTYPANELSTATE"); + auto xml = std::make_unique ("PROPERTYPANELSTATE"); xml->setAttribute ("scrollPos", viewport.getViewPositionY()); diff --git a/modules/juce_gui_basics/properties/juce_PropertyPanel.h b/modules/juce_gui_basics/properties/juce_PropertyPanel.h index 3fc2241766..35d2e9d715 100644 --- a/modules/juce_gui_basics/properties/juce_PropertyPanel.h +++ b/modules/juce_gui_basics/properties/juce_PropertyPanel.h @@ -123,13 +123,10 @@ public: //============================================================================== /** Saves the current state of open/closed sections so it can be restored later. - - The caller is responsible for deleting the object that is returned. To restore this state, use restoreOpennessState(). - @see restoreOpennessState */ - XmlElement* getOpennessState() const; + std::unique_ptr getOpennessState() const; /** Restores a previously saved arrangement of open/closed sections. diff --git a/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp b/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp index ac064df304..a1a7b2a44e 100644 --- a/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp +++ b/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp @@ -431,7 +431,7 @@ String TableHeaderComponent::toString() const e->setAttribute ("width", ci->width); } - return doc.createDocument ({}, true, false); + return doc.toString (XmlElement::TextFormat().singleLine().withoutHeader()); } void TableHeaderComponent::restoreFromString (const String& storedVersion) diff --git a/modules/juce_gui_basics/widgets/juce_TreeView.cpp b/modules/juce_gui_basics/widgets/juce_TreeView.cpp index c0f39d4ff6..3568035d9f 100644 --- a/modules/juce_gui_basics/widgets/juce_TreeView.cpp +++ b/modules/juce_gui_basics/widgets/juce_TreeView.cpp @@ -610,7 +610,7 @@ static void addAllSelectedItemIds (TreeViewItem* item, XmlElement& parent) addAllSelectedItemIds (item->getSubItem(i), parent); } -XmlElement* TreeView::getOpennessState (const bool alsoIncludeScrollPosition) const +std::unique_ptr TreeView::getOpennessState (const bool alsoIncludeScrollPosition) const { XmlElement* e = nullptr; @@ -627,7 +627,7 @@ XmlElement* TreeView::getOpennessState (const bool alsoIncludeScrollPosition) co } } - return e; + return std::unique_ptr (e); } void TreeView::restoreOpennessState (const XmlElement& newState, const bool restoreStoredSelection) @@ -1858,9 +1858,9 @@ void TreeViewItem::restoreOpennessState (const XmlElement& e) } } -XmlElement* TreeViewItem::getOpennessState() const +std::unique_ptr TreeViewItem::getOpennessState() const { - return getOpennessState (true); + return std::unique_ptr (getOpennessState (true)); } XmlElement* TreeViewItem::getOpennessState (const bool canReturnNull) const diff --git a/modules/juce_gui_basics/widgets/juce_TreeView.h b/modules/juce_gui_basics/widgets/juce_TreeView.h index 741ce99c1c..66642f5852 100644 --- a/modules/juce_gui_basics/widgets/juce_TreeView.h +++ b/modules/juce_gui_basics/widgets/juce_TreeView.h @@ -514,7 +514,7 @@ public: @see TreeView::getOpennessState, restoreOpennessState */ - XmlElement* getOpennessState() const; + std::unique_ptr getOpennessState() const; /** Restores the openness of this item and all its sub-items from a saved state. @@ -818,7 +818,7 @@ public: so this can also be restored @see restoreOpennessState */ - XmlElement* getOpennessState (bool alsoIncludeScrollPosition) const; + std::unique_ptr getOpennessState (bool alsoIncludeScrollPosition) const; /** Restores a previously saved arrangement of open/closed nodes. diff --git a/modules/juce_product_unlocking/marketplace/juce_OnlineUnlockStatus.cpp b/modules/juce_product_unlocking/marketplace/juce_OnlineUnlockStatus.cpp index 891499a518..cc39c9f2fc 100644 --- a/modules/juce_product_unlocking/marketplace/juce_OnlineUnlockStatus.cpp +++ b/modules/juce_product_unlocking/marketplace/juce_OnlineUnlockStatus.cpp @@ -73,7 +73,7 @@ struct KeyFileUtils static String encryptXML (const XmlElement& xml, RSAKey privateKey) { MemoryOutputStream text; - text << xml.createDocument (StringRef(), true); + text << xml.toString (XmlElement::TextFormat().singleLine()); BigInteger val; val.loadFromMemoryBlock (text.getMemoryBlock());