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