Audacity 3.2.0
FileConfig.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 FileConfig.cpp
6
7 Leland Lucius
8
9**********************************************************************/
10
11#include <errno.h>
12#include <wx/wfstream.h>
13
14#include "FileConfig.h"
15
16#include <cerrno> // for ENOENT
17
18#if !defined(F_OK)
19#define F_OK 0x00
20#endif
21#if !defined(W_OK)
22#define W_OK 0x02
23#endif
24#if !defined(R_OK)
25#define R_OK 0x04
26#endif
27
28FileConfig::FileConfig(const wxString& appName,
29 const wxString& vendorName,
30 const wxString& localFilename,
31 const wxString& globalFilename,
32 long style,
33 const wxMBConv& conv)
34: wxConfigBase(appName, vendorName, localFilename, globalFilename, style),
35 mAppName(appName),
36 mVendorName(vendorName),
37 mLocalFilename(localFilename),
38 mGlobalFilename(globalFilename),
39 mStyle(style),
40 mConv(conv.Clone()),//pass to Init() instead?
41 mDirty(false)
42{
43}
44
46{
47 while (true)
48 {
49 mConfig = std::make_unique<wxFileConfig>
51
52 // Prevent wxFileConfig from attempting a Flush() during object deletion. This happens
53 // because we don't use the wxFileConfig::Flush() method and so the wxFileConfig dirty
54 // flag never gets reset. During deletion, the dirty flag is checked and a Flush()
55 // performed. This can (and probably will) create bogus temporary files.
56 mConfig->DisableAutoSave();
57
58 bool canRead = false;
59 bool canWrite = false;
60 int fd;
61
62 fd = wxOpen(mLocalFilename, O_RDONLY, S_IREAD);
63 if (fd != -1 || errno == ENOENT)
64 {
65 canRead = true;
66 if (fd != -1)
67 {
68 wxClose(fd);
69 }
70 }
71
72 fd = wxOpen(mLocalFilename, O_WRONLY | O_CREAT, S_IWRITE);
73 if (fd != -1)
74 {
75 canWrite = true;
76 wxClose(fd);
77 }
78
79 if (canRead && canWrite)
80 {
81 break;
82 }
83
84 Warn();
85 }
86}
87
89{
90 wxASSERT(mDirty == false);
91}
92
93void FileConfig::SetPath(const wxString& strPath)
94{
95 mConfig->SetPath(strPath);
96}
97
98const wxString& FileConfig::GetPath() const
99{
100 return mConfig->GetPath();
101}
102
103bool FileConfig::GetFirstGroup(wxString& str, long& lIndex) const
104{
105 return mConfig->GetFirstGroup(str, lIndex);
106}
107
108bool FileConfig::GetNextGroup(wxString& str, long& lIndex) const
109{
110 return mConfig->GetNextGroup(str, lIndex);
111}
112
113bool FileConfig::GetFirstEntry(wxString& str, long& lIndex) const
114{
115 return mConfig->GetFirstEntry(str, lIndex);
116}
117
118bool FileConfig::GetNextEntry(wxString& str, long& lIndex) const
119{
120 return mConfig->GetNextEntry(str, lIndex);
121}
122
123size_t FileConfig::GetNumberOfEntries(bool bRecursive) const
124{
125 return mConfig->GetNumberOfEntries(bRecursive);
126}
127
128size_t FileConfig::GetNumberOfGroups(bool bRecursive) const
129{
130 return mConfig->GetNumberOfGroups(bRecursive);
131}
132
133bool FileConfig::HasGroup(const wxString& strName) const
134{
135 return mConfig->HasGroup(strName);
136}
137
138bool FileConfig::HasEntry(const wxString& strName) const
139{
140 return mConfig->HasEntry(strName);
141}
142
143bool FileConfig::Flush(bool WXUNUSED(bCurrentOnly))
144{
145 if (!mDirty)
146 {
147 return true;
148 }
149
150 while (true)
151 {
152 FilePath backup = mLocalFilename + ".bkp";
153
154 if (!wxFileExists(backup) || (wxRemove(backup) == 0))
155 {
156 if (!wxFileExists(mLocalFilename) || (wxRename(mLocalFilename, backup) == 0))
157 {
158 wxFileOutputStream stream(mLocalFilename);
159 if (stream.IsOk())
160 {
161 if (mConfig->Save(stream))
162 {
163 stream.Sync();
164 if (stream.IsOk() && stream.Close())
165 {
166 if (!wxFileExists(backup) || (wxRemove(backup) == 0))
167 {
168 mDirty = false;
169 return true;
170 }
171 }
172 }
173 }
174
175 if (wxFileExists(backup))
176 {
177 wxRemove(mLocalFilename);
178 wxRename(backup, mLocalFilename);
179 }
180 }
181 }
182
183 Warn();
184 }
185
186 return false;
187}
188
189bool FileConfig::RenameEntry(const wxString& oldName, const wxString& newName)
190{
191 auto res = mConfig->RenameEntry(oldName, newName);
192 if (res)
193 {
194 mDirty = true;
195 }
196 return res;
197}
198
199bool FileConfig::RenameGroup(const wxString& oldName, const wxString& newName)
200{
201 auto res = mConfig->RenameGroup(oldName, newName);
202 if (res)
203 {
204 mDirty = true;
205 }
206 return res;
207}
208
209bool FileConfig::DeleteEntry(const wxString& key, bool bDeleteGroupIfEmpty)
210{
211 auto res = mConfig->DeleteEntry(key, bDeleteGroupIfEmpty);
212 if (res)
213 {
214 mDirty = true;
215 }
216 return res;
217}
218
219bool FileConfig::DeleteGroup(const wxString& key)
220{
221 auto res = mConfig->DeleteGroup(key);
222 if (res)
223 {
224 mDirty = true;
225 }
226 return res;
227}
228
230{
231 auto res = mConfig->DeleteAll();
232 if (res)
233 {
234 mDirty = true;
235 }
236 return res;
237}
238
239bool FileConfig::DoReadString(const wxString& key, wxString *pStr) const
240{
241 return mConfig->Read(key, pStr);
242}
243
244bool FileConfig::DoReadLong(const wxString& key, long *pl) const
245{
246 return mConfig->Read(key, pl);
247}
248
249#if wxUSE_BASE64
250bool FileConfig::DoReadBinary(const wxString& key, wxMemoryBuffer* buf) const
251{
252 return mConfig->Read(key, buf);
253}
254#endif // wxUSE_BASE64
255
256bool FileConfig::DoWriteString(const wxString& key, const wxString& szValue)
257{
258 bool res = mConfig->Write(key, szValue);
259 if (res)
260 {
261 mDirty = true;
262 }
263 return res;
264}
265
266bool FileConfig::DoWriteLong(const wxString& key, long lValue)
267{
268 bool res = mConfig->Write(key, lValue);
269 if (res)
270 {
271 mDirty = true;
272 }
273 return res;
274}
275
276#if wxUSE_BASE64
277bool FileConfig::DoWriteBinary(const wxString& key, const wxMemoryBuffer& buf)
278{
279 bool res = mConfig->Write(key, buf);
280 if (res)
281 {
282 mDirty = true;
283 }
284 return res;
285}
286#endif // wxUSE_BASE64
287
289{
290}
static const AudacityProject::AttachedObjects::RegisteredFactory key
#define str(a)
wxString FilePath
Definition: Project.h:20
virtual bool DeleteEntry(const wxString &key, bool bDeleteGroupIfEmpty=true) wxOVERRIDE
Definition: FileConfig.cpp:209
FileConfig(const wxString &appName=wxEmptyString, const wxString &vendorName=wxEmptyString, const wxString &localFilename=wxEmptyString, const wxString &globalFilename=wxEmptyString, long style=wxCONFIG_USE_LOCAL_FILE|wxCONFIG_USE_GLOBAL_FILE, const wxMBConv &conv=wxConvAuto())
Definition: FileConfig.cpp:28
const wxString mVendorName
Definition: FileConfig.h:85
bool mDirty
Definition: FileConfig.h:99
virtual void Warn()
Definition: FileConfig.cpp:288
virtual bool GetNextEntry(wxString &str, long &lIndex) const wxOVERRIDE
Definition: FileConfig.cpp:118
virtual bool DeleteAll() wxOVERRIDE
Definition: FileConfig.cpp:229
virtual bool GetNextGroup(wxString &str, long &lIndex) const wxOVERRIDE
Definition: FileConfig.cpp:108
const wxString mGlobalFilename
Definition: FileConfig.h:87
virtual bool HasEntry(const wxString &strName) const wxOVERRIDE
Definition: FileConfig.cpp:138
virtual size_t GetNumberOfEntries(bool bRecursive=false) const wxOVERRIDE
Definition: FileConfig.cpp:123
const long mStyle
Definition: FileConfig.h:88
virtual ~FileConfig()
Definition: FileConfig.cpp:88
virtual bool DoReadLong(const wxString &key, long *pl) const wxOVERRIDE
Definition: FileConfig.cpp:244
virtual size_t GetNumberOfGroups(bool bRecursive=false) const wxOVERRIDE
Definition: FileConfig.cpp:128
virtual bool DeleteGroup(const wxString &key) wxOVERRIDE
Definition: FileConfig.cpp:219
const wxString mAppName
Definition: FileConfig.h:84
virtual bool RenameEntry(const wxString &oldName, const wxString &newName) wxOVERRIDE
Definition: FileConfig.cpp:189
std::unique_ptr< wxMBConv > mConv
Definition: FileConfig.h:89
virtual bool GetFirstGroup(wxString &str, long &lIndex) const wxOVERRIDE
Definition: FileConfig.cpp:103
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:143
virtual const wxString & GetPath() const wxOVERRIDE
Definition: FileConfig.cpp:98
virtual bool HasGroup(const wxString &strName) const wxOVERRIDE
Definition: FileConfig.cpp:133
std::unique_ptr< wxFileConfig > mConfig
Definition: FileConfig.h:91
virtual bool DoWriteString(const wxString &key, const wxString &szValue) wxOVERRIDE
Definition: FileConfig.cpp:256
virtual void SetPath(const wxString &strPath) wxOVERRIDE
Definition: FileConfig.cpp:93
virtual bool RenameGroup(const wxString &oldName, const wxString &newName) wxOVERRIDE
Definition: FileConfig.cpp:199
virtual bool GetFirstEntry(wxString &str, long &lIndex) const wxOVERRIDE
Definition: FileConfig.cpp:113
const wxString mLocalFilename
Definition: FileConfig.h:86
virtual bool DoWriteLong(const wxString &key, long lValue) wxOVERRIDE
Definition: FileConfig.cpp:266
void Init()
Definition: FileConfig.cpp:45
virtual bool DoReadString(const wxString &key, wxString *pStr) const wxOVERRIDE
Definition: FileConfig.cpp:239