Browse Source

Minor tidying-up.

tags/2021-05-28
jules 13 years ago
parent
commit
deeab7f818
3 changed files with 153 additions and 143 deletions
  1. +4
    -14
      modules/juce_core/containers/juce_PropertySet.h
  2. +143
    -128
      modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp
  3. +6
    -1
      modules/juce_data_structures/app_properties/juce_PropertiesFile.h

+ 4
- 14
modules/juce_core/containers/juce_PropertySet.h View File

@@ -46,18 +46,15 @@ class JUCE_API PropertySet
public:
//==============================================================================
/** Creates an empty PropertySet.
@param ignoreCaseOfKeyNames if true, the names of properties are compared in a
case-insensitive way
@param ignoreCaseOfKeyNames if true, the names of properties are compared in a
case-insensitive way
*/
PropertySet (bool ignoreCaseOfKeyNames = false);
/** Creates a copy of another PropertySet.
*/
/** Creates a copy of another PropertySet. */
PropertySet (const PropertySet& other);
/** Copies another PropertySet over this one.
*/
/** Copies another PropertySet over this one. */
PropertySet& operator= (const PropertySet& other);
/** Destructor. */
@@ -152,7 +149,6 @@ public:
//==============================================================================
/** Deletes a property.
@param keyName the name of the property to delete. (This mustn't be an empty string)
*/
void removeValue (const String& keyName);
@@ -172,17 +168,13 @@ public:
//==============================================================================
/** Returns an XML element which encapsulates all the items in this property set.
The string parameter is the tag name that should be used for the node.
@see restoreFromXml
*/
XmlElement* 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.
@see createXml
*/
void restoreFromXml (const XmlElement& xml);
@@ -208,12 +200,10 @@ public:
PropertySet* getFallbackPropertySet() const noexcept { return fallbackProperties; }
protected:
//==============================================================================
/** Subclasses can override this to be told when one of the properies has been changed. */
virtual void propertyChanged();
private:
//==============================================================================
StringPairArray properties;
PropertySet* fallbackProperties;
CriticalSection lock;


+ 143
- 128
modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp View File

@@ -49,7 +49,7 @@ File PropertiesFile::Options::getDefaultFile() const
// mustn't have illegal characters in this name..
jassert (applicationName == File::createLegalFileName (applicationName));
#if JUCE_MAC || JUCE_IOS
#if JUCE_MAC || JUCE_IOS
File dir (commonToAllUsers ? "/Library/"
: "~/Library/");
@@ -81,12 +81,12 @@ File PropertiesFile::Options::getDefaultFile() const
if (folderName.isNotEmpty())
dir = dir.getChildFile (folderName);
#elif JUCE_LINUX || JUCE_ANDROID
#elif JUCE_LINUX || JUCE_ANDROID
const File dir ((commonToAllUsers ? "/var/" : "~/")
+ (folderName.isNotEmpty() ? folderName
: ("." + applicationName)));
#elif JUCE_WINDOWS
#elif JUCE_WINDOWS
File dir (File::getSpecialLocation (commonToAllUsers ? File::commonApplicationDataDirectory
: File::userApplicationDataDirectory));
@@ -95,7 +95,7 @@ File PropertiesFile::Options::getDefaultFile() const
dir = dir.getChildFile (folderName.isNotEmpty() ? folderName
: applicationName);
#endif
#endif
return dir.getChildFile (applicationName)
.withFileExtension (filenameSuffix);
@@ -121,90 +121,17 @@ PropertiesFile::PropertiesFile (const Options& options_)
void PropertiesFile::initialise()
{
// You need to correctly specify just one storage format for the file
ProcessScopedLock pl (createProcessLock());
if (pl != nullptr && ! pl->isLocked())
return; // locking failure..
ScopedPointer<InputStream> fileStream (file.createInputStream());
if (fileStream != nullptr)
{
int magicNumber = fileStream->readInt();
if (magicNumber == PropertyFileConstants::magicNumberCompressed)
{
fileStream = new GZIPDecompressorInputStream (new SubregionStream (fileStream.release(), 4, -1, true), true);
magicNumber = PropertyFileConstants::magicNumber;
}
if (magicNumber == PropertyFileConstants::magicNumber)
{
loadedOk = true;
BufferedInputStream in (fileStream.release(), 2048, true);
int numValues = in.readInt();
while (--numValues >= 0 && ! in.isExhausted())
{
const String key (in.readString());
const String value (in.readString());
jassert (key.isNotEmpty());
if (key.isNotEmpty())
getAllProperties().set (key, value);
}
}
else
{
// Not a binary props file - let's see if it's XML..
fileStream = nullptr;
XmlDocument parser (file);
ScopedPointer<XmlElement> doc (parser.getDocumentElement (true));
if (doc != nullptr && doc->hasTagName (PropertyFileConstants::fileTag))
{
doc = parser.getDocumentElement();
if (doc != nullptr)
{
loadedOk = true;
forEachXmlChildElementWithTagName (*doc, e, PropertyFileConstants::valueTag)
{
const String name (e->getStringAttribute (PropertyFileConstants::nameAttribute));
if (name.isNotEmpty())
{
getAllProperties().set (name,
e->getFirstChildElement() != nullptr
? e->getFirstChildElement()->createDocument (String::empty, true)
: e->getStringAttribute (PropertyFileConstants::valueAttribute));
}
}
}
else
{
// 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.
}
}
}
}
else
{
loadedOk = ! file.exists();
}
loadedOk = (! file.exists()) || loadAsBinary() || loadAsXml();
}
PropertiesFile::~PropertiesFile()
{
if (! saveIfNeeded())
jassertfalse;
saveIfNeeded();
}
InterProcessLock::ScopedLockType* PropertiesFile::createProcessLock() const
@@ -242,79 +169,167 @@ bool PropertiesFile::save()
return false;
if (options.storageFormat == storeAsXML)
return saveAsXml();
else
return saveAsBinary();
}
bool PropertiesFile::loadAsXml()
{
XmlDocument parser (file);
ScopedPointer<XmlElement> doc (parser.getDocumentElement (true));
if (doc != nullptr && doc->hasTagName (PropertyFileConstants::fileTag))
{
XmlElement doc (PropertyFileConstants::fileTag);
doc = parser.getDocumentElement();
for (int i = 0; i < getAllProperties().size(); ++i)
if (doc != nullptr)
{
XmlElement* const e = doc.createNewChildElement (PropertyFileConstants::valueTag);
e->setAttribute (PropertyFileConstants::nameAttribute, getAllProperties().getAllKeys() [i]);
forEachXmlChildElementWithTagName (*doc, e, PropertyFileConstants::valueTag)
{
const String name (e->getStringAttribute (PropertyFileConstants::nameAttribute));
// if the value seems to contain xml, store it as such..
XmlElement* const childElement = XmlDocument::parse (getAllProperties().getAllValues() [i]);
if (name.isNotEmpty())
{
getAllProperties().set (name,
e->getFirstChildElement() != nullptr
? e->getFirstChildElement()->createDocument (String::empty, true)
: e->getStringAttribute (PropertyFileConstants::valueAttribute));
}
}
if (childElement != nullptr)
e->addChildElement (childElement);
else
e->setAttribute (PropertyFileConstants::valueAttribute,
getAllProperties().getAllValues() [i]);
return true;
}
else
{
// 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;
}
bool PropertiesFile::saveAsXml()
{
XmlElement doc (PropertyFileConstants::fileTag);
for (int i = 0; i < getAllProperties().size(); ++i)
{
XmlElement* const e = doc.createNewChildElement (PropertyFileConstants::valueTag);
e->setAttribute (PropertyFileConstants::nameAttribute, getAllProperties().getAllKeys() [i]);
// if the value seems to contain xml, store it as such..
XmlElement* const childElement = XmlDocument::parse (getAllProperties().getAllValues() [i]);
ProcessScopedLock pl (createProcessLock());
if (childElement != nullptr)
e->addChildElement (childElement);
else
e->setAttribute (PropertyFileConstants::valueAttribute,
getAllProperties().getAllValues() [i]);
}
ProcessScopedLock pl (createProcessLock());
if (pl != nullptr && ! pl->isLocked())
return false; // locking failure..
if (doc.writeToFile (file, String::empty))
{
needsWriting = false;
return true;
}
if (pl != nullptr && ! pl->isLocked())
return false; // locking failure..
return false;
}
if (doc.writeToFile (file, String::empty))
bool PropertiesFile::loadAsBinary()
{
FileInputStream fileStream (file);
if (fileStream.openedOk())
{
const int magicNumber = fileStream.readInt();
if (magicNumber == PropertyFileConstants::magicNumberCompressed)
{
needsWriting = false;
return true;
SubregionStream subStream (&fileStream, 4, -1, false);
GZIPDecompressorInputStream gzip (subStream);
return loadAsBinary (gzip);
}
else if (magicNumber == PropertyFileConstants::magicNumber)
{
return loadAsBinary (fileStream);
}
}
else
return false;
}
bool PropertiesFile::loadAsBinary (InputStream& input)
{
BufferedInputStream in (input, 2048);
int numValues = in.readInt();
while (--numValues >= 0 && ! in.isExhausted())
{
ProcessScopedLock pl (createProcessLock());
const String key (in.readString());
const String value (in.readString());
jassert (key.isNotEmpty());
if (key.isNotEmpty())
getAllProperties().set (key, value);
}
return true;
}
bool PropertiesFile::saveAsBinary()
{
ProcessScopedLock pl (createProcessLock());
if (pl != nullptr && ! pl->isLocked())
return false; // locking failure..
if (pl != nullptr && ! pl->isLocked())
return false; // locking failure..
TemporaryFile tempFile (file);
ScopedPointer <OutputStream> out (tempFile.getFile().createOutputStream());
TemporaryFile tempFile (file);
ScopedPointer <OutputStream> out (tempFile.getFile().createOutputStream());
if (out != nullptr)
if (out != nullptr)
{
if (options.storageFormat == storeAsCompressedBinary)
{
if (options.storageFormat == storeAsCompressedBinary)
{
out->writeInt (PropertyFileConstants::magicNumberCompressed);
out->flush();
out->writeInt (PropertyFileConstants::magicNumberCompressed);
out->flush();
out = new GZIPCompressorOutputStream (out.release(), 9, true);
}
else
{
// have you set up the storage option flags correctly?
jassert (options.storageFormat == storeAsBinary);
out = new GZIPCompressorOutputStream (out.release(), 9, true);
}
else
{
// have you set up the storage option flags correctly?
jassert (options.storageFormat == storeAsBinary);
out->writeInt (PropertyFileConstants::magicNumber);
}
out->writeInt (PropertyFileConstants::magicNumber);
}
const int numProperties = getAllProperties().size();
const int numProperties = getAllProperties().size();
out->writeInt (numProperties);
out->writeInt (numProperties);
for (int i = 0; i < numProperties; ++i)
{
out->writeString (getAllProperties().getAllKeys() [i]);
out->writeString (getAllProperties().getAllValues() [i]);
}
for (int i = 0; i < numProperties; ++i)
{
out->writeString (getAllProperties().getAllKeys() [i]);
out->writeString (getAllProperties().getAllValues() [i]);
}
out = nullptr;
out = nullptr;
if (tempFile.overwriteTargetFileWithTemporary())
{
needsWriting = false;
return true;
}
if (tempFile.overwriteTargetFileWithTemporary())
{
needsWriting = false;
return true;
}
}


+ 6
- 1
modules/juce_data_structures/app_properties/juce_PropertiesFile.h View File

@@ -212,7 +212,7 @@ public:
//==============================================================================
/** Returns the file that's being used. */
File getFile() const { return file; }
const File& getFile() const noexcept { return file; }
protected:
@@ -230,6 +230,11 @@ private:
void timerCallback();
void initialise();
bool saveAsXml();
bool saveAsBinary();
bool loadAsXml();
bool loadAsBinary();
bool loadAsBinary (InputStream&);
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PropertiesFile);
};


Loading…
Cancel
Save