LMMS
Loading...
Searching...
No Matches
juce_PropertiesFile.cpp
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26namespace juce
27{
28
30{
31 constexpr static const int magicNumber = (int) ByteOrder::makeInt ('P', 'R', 'O', 'P');
32 constexpr static const int magicNumberCompressed = (int) ByteOrder::makeInt ('C', 'P', 'R', 'P');
33
34 constexpr static const char* const fileTag = "PROPERTIES";
35 constexpr static const char* const valueTag = "VALUE";
36 constexpr static const char* const nameAttribute = "name";
37 constexpr static const char* const valueAttribute = "val";
38}
39
40//==============================================================================
50
52{
53 // mustn't have illegal characters in this name..
55
56 #if JUCE_MAC || JUCE_IOS
57 File dir (commonToAllUsers ? "/Library/"
58 : "~/Library/");
59
60 if (osxLibrarySubFolder != "Preferences"
61 && ! osxLibrarySubFolder.startsWith ("Application Support")
62 && ! osxLibrarySubFolder.startsWith ("Containers"))
63 {
64 /* The PropertiesFile class always used to put its settings files in "Library/Preferences", but Apple
65 have changed their advice, and now stipulate that settings should go in "Library/Application Support",
66 or Library/Containers/[app_bundle_id] for a sandboxed app.
67
68 Because older apps would be broken by a silent change in this class's behaviour, you must now
69 explicitly set the osxLibrarySubFolder value to indicate which path you want to use.
70
71 In newer apps, you should always set this to "Application Support"
72 or "Application Support/YourSubFolderName".
73
74 If your app needs to load settings files that were created by older versions of juce and
75 you want to maintain backwards-compatibility, then you can set this to "Preferences".
76 But.. for better Apple-compliance, the recommended approach would be to write some code that
77 finds your old settings files in ~/Library/Preferences, moves them to ~/Library/Application Support,
78 and then uses the new path.
79 */
81
82 dir = dir.getChildFile ("Application Support");
83 }
84 else
85 {
87 }
88
89 if (folderName.isNotEmpty())
90 dir = dir.getChildFile (folderName);
91
92 #elif JUCE_LINUX || JUCE_BSD || JUCE_ANDROID
93 auto dir = File (commonToAllUsers ? "/var" : "~")
94 .getChildFile (folderName.isNotEmpty() ? folderName
95 : ("." + applicationName));
96
97 #elif JUCE_WINDOWS
100
101 if (dir == File())
102 return {};
103
104 dir = dir.getChildFile (folderName.isNotEmpty() ? folderName
106 #endif
107
108 return (filenameSuffix.startsWithChar (L'.')
111}
112
113
114//==============================================================================
116 : PropertySet (o.ignoreCaseOfKeyNames),
117 file (f), options (o)
118{
119 reload();
120}
121
123 : PropertySet (o.ignoreCaseOfKeyNames),
124 file (o.getDefaultFile()), options (o)
125{
126 reload();
127}
128
130{
132
133 if (pl != nullptr && ! pl->isLocked())
134 return false; // locking failure..
135
136 loadedOk = (! file.exists()) || loadAsBinary() || loadAsXml();
137 return loadedOk;
138}
139
144
146{
147 return options.processLock != nullptr ? new InterProcessLock::ScopedLockType (*options.processLock) : nullptr;
148}
149
151{
152 const ScopedLock sl (getLock());
153 return (! needsWriting) || save();
154}
155
157{
158 const ScopedLock sl (getLock());
159 return needsWriting;
160}
161
162void PropertiesFile::setNeedsToBeSaved (const bool needsToBeSaved_)
163{
164 const ScopedLock sl (getLock());
165 needsWriting = needsToBeSaved_;
166}
167
169{
170 const ScopedLock sl (getLock());
171
172 stopTimer();
173
174 if (options.doNotSave
175 || file == File()
176 || file.isDirectory()
177 || ! file.getParentDirectory().createDirectory())
178 return false;
179
180 if (options.storageFormat == storeAsXML)
181 return saveAsXml();
182
183 return saveAsBinary();
184}
185
187{
189 {
190 for (auto* e : doc->getChildWithTagNameIterator (PropertyFileConstants::valueTag))
191 {
192 auto name = e->getStringAttribute (PropertyFileConstants::nameAttribute);
193
194 if (name.isNotEmpty())
195 getAllProperties().set (name,
196 e->getFirstChildElement() != nullptr
197 ? e->getFirstChildElement()->toString (XmlElement::TextFormat().singleLine().withoutHeader())
198 : e->getStringAttribute (PropertyFileConstants::valueAttribute));
199 }
200
201 return true;
202 }
203
204 return false;
205}
206
208{
210 auto& props = getAllProperties();
211
212 for (int i = 0; i < props.size(); ++i)
213 {
215 e->setAttribute (PropertyFileConstants::nameAttribute, props.getAllKeys() [i]);
216
217 // if the value seems to contain xml, store it as such..
218 if (auto childElement = parseXML (props.getAllValues() [i]))
219 e->addChildElement (childElement.release());
220 else
221 e->setAttribute (PropertyFileConstants::valueAttribute, props.getAllValues() [i]);
222 }
223
225
226 if (pl != nullptr && ! pl->isLocked())
227 return false; // locking failure..
228
229 if (doc.writeTo (file, {}))
230 {
231 needsWriting = false;
232 return true;
233 }
234
235 return false;
236}
237
239{
240 FileInputStream fileStream (file);
241
242 if (fileStream.openedOk())
243 {
244 auto magicNumber = fileStream.readInt();
245
247 {
248 SubregionStream subStream (&fileStream, 4, -1, false);
249 GZIPDecompressorInputStream gzip (subStream);
250 return loadAsBinary (gzip);
251 }
252
253 if (magicNumber == PropertyFileConstants::magicNumber)
254 return loadAsBinary (fileStream);
255 }
256
257 return false;
258}
259
261{
262 BufferedInputStream in (input, 2048);
263
264 int numValues = in.readInt();
265
266 while (--numValues >= 0 && ! in.isExhausted())
267 {
268 auto key = in.readString();
269 auto value = in.readString();
270 jassert (key.isNotEmpty());
271
272 if (key.isNotEmpty())
273 getAllProperties().set (key, value);
274 }
275
276 return true;
277}
278
280{
282
283 if (pl != nullptr && ! pl->isLocked())
284 return false; // locking failure..
285
286 TemporaryFile tempFile (file);
287
288 {
289 FileOutputStream out (tempFile.getFile());
290
291 if (! out.openedOk())
292 return false;
293
294 if (options.storageFormat == storeAsCompressedBinary)
295 {
297 out.flush();
298
300
301 if (! writeToStream (zipped))
302 return false;
303 }
304 else
305 {
306 // have you set up the storage option flags correctly?
307 jassert (options.storageFormat == storeAsBinary);
308
310
311 if (! writeToStream (out))
312 return false;
313 }
314 }
315
316 if (! tempFile.overwriteTargetFileWithTemporary())
317 return false;
318
319 needsWriting = false;
320 return true;
321}
322
324{
325 auto& props = getAllProperties();
326 auto& keys = props.getAllKeys();
327 auto& values = props.getAllValues();
328 auto numProperties = props.size();
329
330 if (! out.writeInt (numProperties))
331 return false;
332
333 for (int i = 0; i < numProperties; ++i)
334 {
335 if (! out.writeString (keys[i])) return false;
336 if (! out.writeString (values[i])) return false;
337 }
338
339 return true;
340}
341
346
348{
350 needsWriting = true;
351
352 if (options.millisecondsBeforeSaving > 0)
353 startTimer (options.millisecondsBeforeSaving);
354 else if (options.millisecondsBeforeSaving == 0)
355 saveIfNeeded();
356}
357
358} // namespace juce
#define nullptr
Definition DistrhoDefines.h:75
static File getSpecialLocation(const SpecialLocationType type)
Definition File.cpp:1642
Definition juce_BufferedInputStream.h:37
static constexpr uint16 makeInt(uint8 leastSig, uint8 mostSig) noexcept
Definition juce_ByteOrder.h:185
void sendChangeMessage()
Definition juce_ChangeBroadcaster.cpp:65
Definition juce_File.h:45
File getChildFile(StringRef relativeOrAbsolutePath) const
Definition juce_File.cpp:412
@ userApplicationDataDirectory
Definition juce_File.h:889
@ commonApplicationDataDirectory
Definition juce_File.h:901
File withFileExtension(StringRef newExtension) const
Definition juce_File.cpp:699
static String createLegalFileName(const String &fileNameToFix)
Definition juce_File.cpp:835
Definition juce_FileInputStream.h:35
bool openedOk() const noexcept
Definition juce_FileInputStream.h:67
Definition juce_FileOutputStream.h:35
Definition juce_GZIPCompressorOutputStream.h:39
Definition juce_GZIPDecompressorInputStream.h:39
Definition juce_InputStream.h:37
virtual int readInt()
Definition juce_InputStream.cpp:88
Definition juce_InterProcessLock.h:72
Definition juce_OutputStream.h:38
~PropertiesFile() override
Definition juce_PropertiesFile.cpp:140
void timerCallback() override
Definition juce_PropertiesFile.cpp:342
bool loadAsBinary()
Definition juce_PropertiesFile.cpp:238
PropertiesFile(const Options &options)
Definition juce_PropertiesFile.cpp:122
File file
Definition juce_PropertiesFile.h:237
void setNeedsToBeSaved(bool needsToBeSaved)
Definition juce_PropertiesFile.cpp:162
const std::unique_ptr< InterProcessLock::ScopedLockType > ProcessScopedLock
Definition juce_PropertiesFile.h:241
bool loadedOk
Definition juce_PropertiesFile.h:239
bool reload()
Definition juce_PropertiesFile.cpp:129
Options options
Definition juce_PropertiesFile.h:238
bool needsWriting
Definition juce_PropertiesFile.h:239
bool writeToStream(OutputStream &)
Definition juce_PropertiesFile.cpp:323
bool saveAsBinary()
Definition juce_PropertiesFile.cpp:279
bool needsToBeSaved() const
Definition juce_PropertiesFile.cpp:156
bool saveIfNeeded()
Definition juce_PropertiesFile.cpp:150
bool save()
Definition juce_PropertiesFile.cpp:168
InterProcessLock::ScopedLockType * createProcessLock() const
Definition juce_PropertiesFile.cpp:145
void propertyChanged() override
Definition juce_PropertiesFile.cpp:347
bool loadAsXml()
Definition juce_PropertiesFile.cpp:186
@ storeAsBinary
Definition juce_PropertiesFile.h:53
@ storeAsCompressedBinary
Definition juce_PropertiesFile.h:54
@ storeAsXML
Definition juce_PropertiesFile.h:55
bool saveAsXml()
Definition juce_PropertiesFile.cpp:207
StringPairArray & getAllProperties() noexcept
Definition juce_PropertySet.h:154
const CriticalSection & getLock() const noexcept
Definition juce_PropertySet.h:157
PropertySet(bool ignoreCaseOfKeyNames=false)
Definition juce_PropertySet.cpp:26
Definition juce_SubregionStream.h:35
Definition juce_TemporaryFile.h:65
bool overwriteTargetFileWithTemporary() const
Definition juce_TemporaryFile.cpp:93
const File & getFile() const noexcept
Definition juce_TemporaryFile.h:126
void stopTimer() noexcept
Definition juce_Timer.cpp:357
void startTimer(int intervalInMilliseconds) noexcept
Definition juce_Timer.cpp:332
Definition juce_XmlElement.h:83
XmlElement * createNewChildElement(StringRef tagName)
Definition juce_XmlElement.cpp:733
void writeTo(OutputStream &output, const TextFormat &format={}) const
Definition juce_XmlElement.cpp:359
* e
Definition inflate.c:1404
register unsigned i
Definition inflate.c:1575
unsigned f
Definition inflate.c:1572
static PuglViewHint int value
Definition pugl.h:1708
static const char * name
Definition pugl.h:1582
#define jassert(expression)
#define jassertfalse
float in
Definition lilv_test.c:1460
float out
Definition lilv_test.c:1461
Definition juce_PropertiesFile.cpp:30
static constexpr const char *const nameAttribute
Definition juce_PropertiesFile.cpp:36
static constexpr const char *const fileTag
Definition juce_PropertiesFile.cpp:34
static constexpr const char *const valueTag
Definition juce_PropertiesFile.cpp:35
static constexpr const char *const valueAttribute
Definition juce_PropertiesFile.cpp:37
static constexpr const int magicNumberCompressed
Definition juce_PropertiesFile.cpp:32
static constexpr const int magicNumber
Definition juce_PropertiesFile.cpp:31
Definition carla_juce.cpp:31
CriticalSection::ScopedLockType ScopedLock
Definition juce_CriticalSection.h:186
std::unique_ptr< XmlElement > parseXMLIfTagMatches(const String &textToParse, StringRef requiredTag)
Definition juce_XmlDocument.cpp:51
std::unique_ptr< XmlElement > parseXML(const String &textToParse)
Definition juce_XmlDocument.cpp:41
#define false
Definition ordinals.h:83
Definition juce_PropertiesFile.h:61
Options()
Definition juce_PropertiesFile.cpp:41
StorageFormat storageFormat
Definition juce_PropertiesFile.h:134
File getDefaultFile() const
Definition juce_PropertiesFile.cpp:51
InterProcessLock * processLock
Definition juce_PropertiesFile.h:143
String osxLibrarySubFolder
Definition juce_PropertiesFile.h:104
String filenameSuffix
Definition juce_PropertiesFile.h:79
String folderName
Definition juce_PropertiesFile.h:84
String applicationName
Definition juce_PropertiesFile.h:69
bool commonToAllUsers
Definition juce_PropertiesFile.h:109
bool doNotSave
Definition juce_PropertiesFile.h:118
bool ignoreCaseOfKeyNames
Definition juce_PropertiesFile.h:115
int millisecondsBeforeSaving
Definition juce_PropertiesFile.h:128
Definition juce_XmlElement.h:136
JUCE_NODISCARD TextFormat withoutHeader() const
Definition juce_XmlElement.cpp:345
JUCE_NODISCARD TextFormat singleLine() const
Definition juce_XmlElement.cpp:338
static LV2_State_Status save(LV2_Handle instance, LV2_State_Store_Function store, void *callback_data, uint32_t flags, const LV2_Feature *const *features)
Definition test.c:161
ZCONST char * key
Definition crypt.c:587
typedef int(UZ_EXP MsgFn)()