1 /*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2016, Rene Gollent, rene@gollent.com.
4 * Distributed under the terms of the MIT License.
5 */
6
7
8 #include "DebuggerSettingsManager.h"
9
10 #include <new>
11
12 #include <Directory.h>
13 #include <File.h>
14 #include <FindDirectory.h>
15
16 #include <AutoDeleter.h>
17 #include <AutoLocker.h>
18
19 #include "TeamSettings.h"
20
21
22 static const char* const kSettingsDirPath = "Debugger";
23 static const char* const kGlobalSettingsName = "Global";
24 static const int32 kMaxRecentTeamSettings = 10;
25
26
DebuggerSettingsManager()27 DebuggerSettingsManager::DebuggerSettingsManager()
28 :
29 SettingsManager(),
30 fLock("settings manager"),
31 fRecentTeamSettings(kMaxRecentTeamSettings, true),
32 fUiSettingsFactory(NULL)
33 {
34 }
35
36
~DebuggerSettingsManager()37 DebuggerSettingsManager::~DebuggerSettingsManager()
38 {
39 _Unset();
40 }
41
42
43 status_t
Init(TeamUiSettingsFactory * factory)44 DebuggerSettingsManager::Init(TeamUiSettingsFactory* factory)
45 {
46 // check the lock
47 status_t error = fLock.InitCheck();
48 if (error != B_OK)
49 return error;
50
51 fUiSettingsFactory = factory;
52
53 // get and create our settings directory
54 if (find_directory(B_USER_SETTINGS_DIRECTORY, &fSettingsPath, true) == B_OK
55 && fSettingsPath.Append(kSettingsDirPath) == B_OK
56 && create_directory(fSettingsPath.Path(), 0700) == B_OK
57 && fSettingsPath.Append(kGlobalSettingsName) == B_OK) {
58 // load the settings
59 _LoadSettings();
60 } else {
61 // something went wrong -- clear the path
62 fSettingsPath.Unset();
63 }
64
65 return B_OK;
66 }
67
68
69 status_t
LoadTeamSettings(const char * teamName,TeamSettings & settings)70 DebuggerSettingsManager::LoadTeamSettings(const char* teamName, TeamSettings& settings)
71 {
72 AutoLocker<BLocker> locker(fLock);
73
74 int32 index = _TeamSettingsIndex(teamName);
75 if (index < 0)
76 return B_ENTRY_NOT_FOUND;
77
78 try {
79 settings = *fRecentTeamSettings.ItemAt(index);
80 return B_OK;
81 } catch (std::bad_alloc&) {
82 return B_NO_MEMORY;
83 }
84 }
85
86
87 status_t
SaveTeamSettings(const TeamSettings & _settings)88 DebuggerSettingsManager::SaveTeamSettings(const TeamSettings& _settings)
89 {
90 AutoLocker<BLocker> locker(fLock);
91
92 TeamSettings* settings;
93 int32 index = _TeamSettingsIndex(_settings.TeamName());
94 if (index >= 0) {
95 settings = fRecentTeamSettings.RemoveItemAt(index);
96 } else {
97 settings = new(std::nothrow) TeamSettings;
98 if (settings == NULL)
99 return B_NO_MEMORY;
100
101 // enforce recent limit
102 while (fRecentTeamSettings.CountItems() >= kMaxRecentTeamSettings)
103 delete fRecentTeamSettings.RemoveItemAt(0);
104
105 }
106 ObjectDeleter<TeamSettings> settingsDeleter(settings);
107
108 try {
109 *settings = _settings;
110 if (!fRecentTeamSettings.AddItem(settings))
111 return B_NO_MEMORY;
112 settingsDeleter.Detach();
113
114 return _SaveSettings();
115 } catch (std::bad_alloc&) {
116 return B_NO_MEMORY;
117 }
118 }
119
120
121 void
_Unset()122 DebuggerSettingsManager::_Unset()
123 {
124 fRecentTeamSettings.MakeEmpty();
125 }
126
127
128 status_t
_LoadSettings()129 DebuggerSettingsManager::_LoadSettings()
130 {
131 _Unset();
132
133 if (fSettingsPath.Path() == NULL)
134 return B_ENTRY_NOT_FOUND;
135
136 // read the settings file
137 BFile file;
138 status_t error = file.SetTo(fSettingsPath.Path(), B_READ_ONLY);
139 if (error != B_OK)
140 return error;
141
142 BMessage archive;
143 error = archive.Unflatten(&file);
144 if (error != B_OK)
145 return error;
146
147 // unarchive the recent team settings
148 BMessage childArchive;
149 for (int32 i = 0; archive.FindMessage("teamSettings", i, &childArchive)
150 == B_OK; i++) {
151 TeamSettings* settings = new(std::nothrow) TeamSettings;
152 if (settings == NULL)
153 return B_NO_MEMORY;
154
155 error = settings->SetTo(childArchive, *fUiSettingsFactory);
156 if (error != B_OK) {
157 delete settings;
158 continue;
159 }
160
161 if (!fRecentTeamSettings.AddItem(settings)) {
162 delete settings;
163 return B_NO_MEMORY;
164 }
165 }
166
167 return B_OK;
168 }
169
170
171 status_t
_SaveSettings()172 DebuggerSettingsManager::_SaveSettings()
173 {
174 if (fSettingsPath.Path() == NULL)
175 return B_ENTRY_NOT_FOUND;
176
177 // archive the recent team settings
178 BMessage archive;
179 for (int32 i = 0; TeamSettings* settings = fRecentTeamSettings.ItemAt(i);
180 i++) {
181 BMessage childArchive;
182 status_t error = settings->WriteTo(childArchive);
183 if (error != B_OK)
184 return error;
185
186 error = archive.AddMessage("teamSettings", &childArchive);
187 if (error != B_OK)
188 return error;
189 }
190
191 // open the settings file
192 BFile file;
193 status_t error = file.SetTo(fSettingsPath.Path(),
194 B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
195 if (error != B_OK)
196 return error;
197
198 return archive.Flatten(&file);
199 }
200
201
202 int32
_TeamSettingsIndex(const char * teamName) const203 DebuggerSettingsManager::_TeamSettingsIndex(const char* teamName) const
204 {
205 for (int32 i = 0; TeamSettings* settings = fRecentTeamSettings.ItemAt(i);
206 i++) {
207 if (settings->TeamName() == teamName)
208 return i;
209 }
210
211 return -1;
212 }
213