xref: /haiku/src/apps/debugger/settings/DebuggerSettingsManager.cpp (revision d284f7cc43cc0d1106c3b0c40e62c58107648573)
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 
27 DebuggerSettingsManager::DebuggerSettingsManager()
28 	:
29 	SettingsManager(),
30 	fLock("settings manager"),
31 	fRecentTeamSettings(kMaxRecentTeamSettings, true),
32 	fUiSettingsFactory(NULL)
33 {
34 }
35 
36 
37 DebuggerSettingsManager::~DebuggerSettingsManager()
38 {
39 	_Unset();
40 }
41 
42 
43 status_t
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
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
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
122 DebuggerSettingsManager::_Unset()
123 {
124 	fRecentTeamSettings.MakeEmpty();
125 }
126 
127 
128 status_t
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
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
203 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