tcp: Add APICall trace entry and move TRACEs into locked parts.
[haiku.git] / src / add-ons / translators / shared / TranslatorSettings.cpp
blob97c9db2fcb4fb43cf03964aefca4c2345fd5e7cb
1 /*****************************************************************************/
2 // TranslatorSettings
3 // Written by Michael Wilber, OBOS Translation Kit Team
4 //
5 // TranslatorSettings.cpp
6 //
7 // This class manages (saves/loads/locks/unlocks) the settings
8 // for a Translator.
9 //
11 // Copyright (c) 2004 OpenBeOS Project
13 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 /*****************************************************************************/
32 #include <string.h>
33 #include <File.h>
34 #include <FindDirectory.h>
35 #include <TranslatorFormats.h>
36 // for B_TRANSLATOR_EXT_*
37 #include "TranslatorSettings.h"
39 // ---------------------------------------------------------------
40 // Constructor
42 // Sets the default settings, location for the settings file
43 // and sets the reference count to 1
45 // Preconditions:
47 // Parameters:
49 // Postconditions:
51 // Returns:
52 // ---------------------------------------------------------------
53 TranslatorSettings::TranslatorSettings(const char *settingsFile,
54 const TranSetting *defaults, int32 defCount)
55 : fLock("TranslatorSettings Lock")
57 if (find_directory(B_USER_SETTINGS_DIRECTORY, &fSettingsPath))
58 fSettingsPath.SetTo("/tmp");
59 fSettingsPath.Append(settingsFile);
61 fRefCount = 1;
63 if (defCount > 0) {
64 fDefaults = defaults;
65 fDefCount = defCount;
66 } else {
67 fDefaults = NULL;
68 fDefCount = 0;
71 // Add Default Settings
72 // (Used when loading from the settings file or from
73 // a BMessage fails)
74 const TranSetting *defs = fDefaults;
75 for (int32 i = 0; i < fDefCount; i++) {
76 switch (defs[i].dataType) {
77 case TRAN_SETTING_BOOL:
78 fSettingsMsg.AddBool(defs[i].name,
79 static_cast<bool>(defs[i].defaultVal));
80 break;
82 case TRAN_SETTING_INT32:
83 fSettingsMsg.AddInt32(defs[i].name, defs[i].defaultVal);
84 break;
86 default:
87 // ASSERT here? Erase the bogus setting entry instead?
88 break;
93 // ---------------------------------------------------------------
94 // Acquire
96 // Returns a pointer to the TranslatorSettings and increments
97 // the reference count.
99 // Preconditions:
101 // Parameters:
103 // Postconditions:
105 // Returns: pointer to this TranslatorSettings object
106 // ---------------------------------------------------------------
107 TranslatorSettings *
108 TranslatorSettings::Acquire()
110 TranslatorSettings *psettings = NULL;
112 fLock.Lock();
113 fRefCount++;
114 psettings = this;
115 fLock.Unlock();
117 return psettings;
120 // ---------------------------------------------------------------
121 // Release
123 // Decrements the reference count and deletes the
124 // TranslatorSettings if the reference count is zero.
126 // Preconditions:
128 // Parameters:
130 // Postconditions:
132 // Returns: pointer to this TranslatorSettings object if
133 // the reference count is greater than zero, returns NULL
134 // if the reference count is zero and the TranslatorSettings
135 // object has been deleted
136 // ---------------------------------------------------------------
137 TranslatorSettings *
138 TranslatorSettings::Release()
140 TranslatorSettings *psettings = NULL;
142 fLock.Lock();
143 fRefCount--;
144 if (fRefCount > 0) {
145 psettings = this;
146 fLock.Unlock();
147 } else
148 delete this;
149 // delete this object and
150 // release locks
152 return psettings;
155 // ---------------------------------------------------------------
156 // Destructor
158 // Does nothing!
160 // Preconditions:
162 // Parameters:
164 // Postconditions:
166 // Returns:
167 // ---------------------------------------------------------------
168 TranslatorSettings::~TranslatorSettings()
172 // ---------------------------------------------------------------
173 // LoadSettings
175 // Loads the settings by reading them from the default
176 // settings file.
178 // Preconditions:
180 // Parameters:
182 // Postconditions:
184 // Returns: B_OK if there were no errors or an error code from
185 // BFile::SetTo() or BMessage::Unflatten() if there were errors
186 // ---------------------------------------------------------------
187 status_t
188 TranslatorSettings::LoadSettings()
190 status_t result;
192 fLock.Lock();
194 // Don't try to open the settings file if there are
195 // no settings that need to be loaded
196 if (fDefCount > 0) {
197 BFile settingsFile;
198 result = settingsFile.SetTo(fSettingsPath.Path(), B_READ_ONLY);
199 if (result == B_OK) {
200 BMessage msg;
201 result = msg.Unflatten(&settingsFile);
202 if (result == B_OK)
203 result = LoadSettings(&msg);
205 } else
206 result = B_OK;
208 fLock.Unlock();
210 return result;
213 // ---------------------------------------------------------------
214 // LoadSettings
216 // Loads the settings from a BMessage passed to the function.
218 // Preconditions:
220 // Parameters: pmsg pointer to BMessage that contains the
221 // settings
223 // Postconditions:
225 // Returns: B_BAD_VALUE if pmsg is NULL or invalid options
226 // have been found, B_OK if there were no
227 // errors or an error code from BMessage::FindBool() or
228 // BMessage::ReplaceBool() if there were other errors
229 // ---------------------------------------------------------------
230 status_t
231 TranslatorSettings::LoadSettings(BMessage *pmsg)
233 if (pmsg == NULL)
234 return B_BAD_VALUE;
236 fLock.Lock();
237 const TranSetting *defaults = fDefaults;
238 for (int32 i = 0; i < fDefCount; i++) {
239 switch (defaults[i].dataType) {
240 case TRAN_SETTING_BOOL:
242 bool value;
243 if (pmsg->FindBool(defaults[i].name, &value) != B_OK) {
244 if (fSettingsMsg.HasBool(defaults[i].name))
245 break;
246 else
247 value = static_cast<bool>(defaults[i].defaultVal);
250 fSettingsMsg.ReplaceBool(defaults[i].name, value);
251 break;
254 case TRAN_SETTING_INT32:
256 int32 value;
257 if (pmsg->FindInt32(defaults[i].name, &value) != B_OK) {
258 if (fSettingsMsg.HasInt32(defaults[i].name))
259 break;
260 else
261 value = defaults[i].defaultVal;
264 fSettingsMsg.ReplaceInt32(defaults[i].name, value);
265 break;
268 default:
269 // TODO: ASSERT here? Erase the bogus setting entry instead?
270 break;
274 fLock.Unlock();
275 return B_OK;
278 // ---------------------------------------------------------------
279 // SaveSettings
281 // Saves the settings as a flattened BMessage to the default
282 // settings file
284 // Preconditions:
286 // Parameters:
288 // Postconditions:
290 // Returns: B_OK if no errors or an error code from BFile::SetTo()
291 // or BMessage::Flatten() if there were errors
292 // ---------------------------------------------------------------
293 status_t
294 TranslatorSettings::SaveSettings()
296 status_t result;
298 fLock.Lock();
300 // Only write out settings file if there are
301 // actual settings stored by this object
302 if (fDefCount > 0) {
303 BFile settingsFile;
304 result = settingsFile.SetTo(fSettingsPath.Path(),
305 B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
306 if (result == B_OK)
307 result = fSettingsMsg.Flatten(&settingsFile);
308 } else
309 result = B_OK;
311 fLock.Unlock();
313 return result;
316 // ---------------------------------------------------------------
317 // GetConfigurationMessage
319 // Saves the current settings to the BMessage passed to the
320 // function
322 // Preconditions:
324 // Parameters: pmsg pointer to BMessage where the settings
325 // will be stored
327 // Postconditions:
329 // Returns: B_OK if there were no errors or an error code from
330 // BMessage::RemoveName() or BMessage::AddBool() if there were
331 // errors
332 // ---------------------------------------------------------------
333 status_t
334 TranslatorSettings::GetConfigurationMessage(BMessage *pmsg)
336 status_t result = B_BAD_VALUE;
338 if (pmsg) {
339 int32 i;
340 for (i = 0; i < fDefCount; i++) {
341 result = pmsg->RemoveName(fDefaults[i].name);
342 if (result != B_OK && result != B_NAME_NOT_FOUND)
343 break;
345 if (i == fDefCount) {
346 fLock.Lock();
347 result = B_OK;
349 const TranSetting *defs = fDefaults;
350 for (i = 0; i < fDefCount && result >= B_OK; i++) {
351 switch (defs[i].dataType) {
352 case TRAN_SETTING_BOOL:
353 result = pmsg->AddBool(defs[i].name,
354 SetGetBool(defs[i].name));
355 break;
357 case TRAN_SETTING_INT32:
358 result = pmsg->AddInt32(defs[i].name,
359 SetGetInt32(defs[i].name));
360 break;
362 default:
363 // ASSERT here? Erase the bogus setting entry instead?
364 break;
368 fLock.Unlock();
372 return result;
375 // ---------------------------------------------------------------
376 // FindTranSetting
378 // Returns a pointer to the TranSetting with the given name
381 // Preconditions:
383 // Parameters: name name of the TranSetting to find
386 // Postconditions:
388 // Returns: NULL if the TranSetting cannot be found, or a pointer
389 // to the desired TranSetting if it is found
390 // ---------------------------------------------------------------
391 const TranSetting *
392 TranslatorSettings::FindTranSetting(const char *name)
394 for (int32 i = 0; i < fDefCount; i++) {
395 if (!strcmp(fDefaults[i].name, name))
396 return fDefaults + i;
398 return NULL;
401 // ---------------------------------------------------------------
402 // SetGetBool
404 // Sets the state of the bool setting identified by the given name
407 // Preconditions:
409 // Parameters: name identifies the setting to set or get
411 // pbool the new value for the bool, or, if null,
412 // it indicates that the caller wants to Get
413 // rather than Set
415 // Postconditions:
417 // Returns: the prior value of the setting
418 // ---------------------------------------------------------------
419 bool
420 TranslatorSettings::SetGetBool(const char *name, bool *pbool)
422 bool bprevValue;
424 fLock.Lock();
426 const TranSetting *def = FindTranSetting(name);
427 if (def) {
428 fSettingsMsg.FindBool(def->name, &bprevValue);
429 if (pbool)
430 fSettingsMsg.ReplaceBool(def->name, *pbool);
431 } else
432 bprevValue = false;
434 fLock.Unlock();
436 return bprevValue;
439 // ---------------------------------------------------------------
440 // SetGetInt32
442 // Sets the state of the int32 setting identified by the given name
445 // Preconditions:
447 // Parameters: name identifies the setting to set or get
449 // pint32 the new value for the setting, or, if null,
450 // it indicates that the caller wants to Get
451 // rather than Set
453 // Postconditions:
455 // Returns: the prior value of the setting
456 // ---------------------------------------------------------------
457 int32
458 TranslatorSettings::SetGetInt32(const char *name, int32 *pint32)
460 int32 prevValue;
462 fLock.Lock();
464 const TranSetting *def = FindTranSetting(name);
465 if (def) {
466 fSettingsMsg.FindInt32(def->name, &prevValue);
467 if (pint32)
468 fSettingsMsg.ReplaceInt32(def->name, *pint32);
469 } else
470 prevValue = 0;
472 fLock.Unlock();
474 return prevValue;