Audacity  3.0.3
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 
28 FileConfig::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),
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 
93 void FileConfig::SetPath(const wxString& strPath)
94 {
95  mConfig->SetPath(strPath);
96 }
97 
98 const wxString& FileConfig::GetPath() const
99 {
100  return mConfig->GetPath();
101 }
102 
103 bool FileConfig::GetFirstGroup(wxString& str, long& lIndex) const
104 {
105  return mConfig->GetFirstGroup(str, lIndex);
106 }
107 
108 bool FileConfig::GetNextGroup(wxString& str, long& lIndex) const
109 {
110  return mConfig->GetNextGroup(str, lIndex);
111 }
112 
113 bool FileConfig::GetFirstEntry(wxString& str, long& lIndex) const
114 {
115  return mConfig->GetFirstEntry(str, lIndex);
116 }
117 
118 bool FileConfig::GetNextEntry(wxString& str, long& lIndex) const
119 {
120  return mConfig->GetNextEntry(str, lIndex);
121 }
122 
123 size_t FileConfig::GetNumberOfEntries(bool bRecursive) const
124 {
125  return mConfig->GetNumberOfEntries(bRecursive);
126 }
127 
128 size_t FileConfig::GetNumberOfGroups(bool bRecursive) const
129 {
130  return mConfig->GetNumberOfGroups(bRecursive);
131 }
132 
133 bool FileConfig::HasGroup(const wxString& strName) const
134 {
135  return mConfig->HasGroup(strName);
136 }
137 
138 bool FileConfig::HasEntry(const wxString& strName) const
139 {
140  return mConfig->HasEntry(strName);
141 }
142 
143 bool 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 
189 bool 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 
199 bool 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 
209 bool 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 
219 bool 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 
239 bool FileConfig::DoReadString(const wxString& key, wxString *pStr) const
240 {
241  return mConfig->Read(key, pStr);
242 }
243 
244 bool FileConfig::DoReadLong(const wxString& key, long *pl) const
245 {
246  return mConfig->Read(key, pl);
247 }
248 
249 #if wxUSE_BASE64
250 bool FileConfig::DoReadBinary(const wxString& key, wxMemoryBuffer* buf) const
251 {
252  return mConfig->Read(key, buf);
253 }
254 #endif // wxUSE_BASE64
255 
256 bool 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 
266 bool 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
277 bool 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
FileConfig::RenameGroup
virtual bool RenameGroup(const wxString &oldName, const wxString &newName) wxOVERRIDE
Definition: FileConfig.cpp:199
FileConfig::SetPath
virtual void SetPath(const wxString &strPath) wxOVERRIDE
Definition: FileConfig.cpp:93
FileConfig::RenameEntry
virtual bool RenameEntry(const wxString &oldName, const wxString &newName) wxOVERRIDE
Definition: FileConfig.cpp:189
FileConfig::DoReadLong
virtual bool DoReadLong(const wxString &key, long *pl) const wxOVERRIDE
Definition: FileConfig.cpp:244
FileConfig::mDirty
bool mDirty
Definition: FileConfig.h:98
FileConfig::mAppName
const wxString mAppName
Definition: FileConfig.h:83
FileConfig::mVendorName
const wxString mVendorName
Definition: FileConfig.h:84
FileConfig::DoWriteLong
virtual bool DoWriteLong(const wxString &key, long lValue) wxOVERRIDE
Definition: FileConfig.cpp:266
FileConfig::HasEntry
virtual bool HasEntry(const wxString &strName) const wxOVERRIDE
Definition: FileConfig.cpp:138
FileConfig::GetNumberOfEntries
virtual size_t GetNumberOfEntries(bool bRecursive=false) const wxOVERRIDE
Definition: FileConfig.cpp:123
FileConfig.h
FileConfig::HasGroup
virtual bool HasGroup(const wxString &strName) const wxOVERRIDE
Definition: FileConfig.cpp:133
FileConfig::DeleteEntry
virtual bool DeleteEntry(const wxString &key, bool bDeleteGroupIfEmpty=true) wxOVERRIDE
Definition: FileConfig.cpp:209
FileConfig::DoReadString
virtual bool DoReadString(const wxString &key, wxString *pStr) const wxOVERRIDE
Definition: FileConfig.cpp:239
FileConfig::GetFirstGroup
virtual bool GetFirstGroup(wxString &str, long &lIndex) const wxOVERRIDE
Definition: FileConfig.cpp:103
FileConfig::mLocalFilename
const wxString mLocalFilename
Definition: FileConfig.h:85
FileConfig::GetFirstEntry
virtual bool GetFirstEntry(wxString &str, long &lIndex) const wxOVERRIDE
Definition: FileConfig.cpp:113
FileConfig::GetNextEntry
virtual bool GetNextEntry(wxString &str, long &lIndex) const wxOVERRIDE
Definition: FileConfig.cpp:118
FileConfig::GetNextGroup
virtual bool GetNextGroup(wxString &str, long &lIndex) const wxOVERRIDE
Definition: FileConfig.cpp:108
FilePath
wxString FilePath
Definition: Project.h:20
FileConfig::mConfig
std::unique_ptr< wxFileConfig > mConfig
Definition: FileConfig.h:90
FileConfig::mStyle
const long mStyle
Definition: FileConfig.h:87
FileConfig::Init
void Init()
Definition: FileConfig.cpp:45
FileConfig::mGlobalFilename
const wxString mGlobalFilename
Definition: FileConfig.h:86
FileConfig::DeleteGroup
virtual bool DeleteGroup(const wxString &key) wxOVERRIDE
Definition: FileConfig.cpp:219
FileConfig::Flush
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:143
key
static const AudacityProject::AttachedObjects::RegisteredFactory key
Definition: CommandManager.cpp:201
FileConfig::~FileConfig
virtual ~FileConfig()
Definition: FileConfig.cpp:88
FileConfig::GetNumberOfGroups
virtual size_t GetNumberOfGroups(bool bRecursive=false) const wxOVERRIDE
Definition: FileConfig.cpp:128
FileConfig::Warn
virtual void Warn()=0
Override to notify the user of error conditions involving writability of config files.
FileConfig::DeleteAll
virtual bool DeleteAll() wxOVERRIDE
Definition: FileConfig.cpp:229
FileConfig::FileConfig
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
FileConfig::DoWriteString
virtual bool DoWriteString(const wxString &key, const wxString &szValue) wxOVERRIDE
Definition: FileConfig.cpp:256
FileConfig::mConv
const wxMBConv & mConv
Definition: FileConfig.h:88
FileConfig::GetPath
virtual const wxString & GetPath() const wxOVERRIDE
Definition: FileConfig.cpp:98